A variation on ciao's method with comparable speeds:
ClearAll[f1] f1 = With[{s = Split[#, # != 0 &]}, Inner[PadRight[{#}, #2] &, Tr /@ s, Length /@ s, Join]]&; f1 @ {0, 0, 0, 10, 12, 5, 0, 1, 2, 0}
{0, 0, 0, 27, 0, 0, 0, 3, 0, 0}
And a faster method:
ClearAll[f2] f2 = With[{s = Internal`CopyListStructure[Split[Unitize@#], #]}, Inner[PadRight[{#}, #2] &, Tr /@ s, Length /@ s, Join]] &; f2 @ {0, 0, 0, 10, 12, 5, 0, 1, 2, 0}
{0, 0, 0, 27, 0, 0, 0, 3, 0, 0}
SeedRandom[1] rs = RandomInteger[5, 10000]; Equal @@ Through[{f1, f2, fn}@rs]
True
Needs["GeneralUtilities`"] BenchmarkPlot[{fn, f1, f2}, Range, Joined -> True, ImageSize -> Large, PlotLegends -> {"fn", "f1", "f2"}]

Finally, a method using SequenceSplit (slow for long lists but worth considering):
ClearAll[f0] f0 = Join @@ SequenceSplit[#, {a : Except[0] ..} :> PadRight[{+a}, Length@{a}]] &; f0 @ {0, 0, 0, 10, 12, 5, 0, 1, 2, 0}
{0, 0, 0, 27, 0, 0, 0, 3, 0, 0}