@@ -179,7 +179,8 @@ func (d Decimal) String() string {
179179// StringFromInt64 is an internal method for converting int64
180180// and scale to a string (for numbers up to 19 digits)
181181func (d Decimal ) stringFromInt64 (value int64 , scale int ) string {
182- var buf [32 ]byte
182+
183+ var buf [48 ]byte
183184 pos := 0
184185
185186 negative := value < 0
@@ -196,12 +197,21 @@ func (d Decimal) stringFromInt64(value int64, scale int) string {
196197 length := len (str )
197198
198199 if scale == 0 {
200+ if pos + length > len (buf ) {
201+ return d .Decimal .String ()
202+ }
199203 copy (buf [pos :], str )
200204 pos += length
201205 return string (buf [:pos ])
202206 }
203207
204208 if scale >= length {
209+
210+ required := 2 + (scale - length ) + length
211+ if pos + required > len (buf ) {
212+ return d .Decimal .String ()
213+ }
214+
205215 buf [pos ] = '0'
206216 buf [pos + 1 ] = '.'
207217 pos += 2
@@ -215,42 +225,54 @@ func (d Decimal) stringFromInt64(value int64, scale int) string {
215225 copy (buf [pos :], str )
216226 pos += length
217227 } else {
228+
218229 integerLen := length - scale
230+
231+ required := integerLen + 1 + scale
232+ if pos + required > len (buf ) {
233+ return d .Decimal .String ()
234+ }
235+
219236 copy (buf [pos :], str [:integerLen ])
220237 pos += integerLen
221238
222- fractionalPart := str [integerLen :]
223-
224- fractionalPart = strings .TrimRight (fractionalPart , "0" )
239+ buf [pos ] = '.'
240+ pos ++
225241
226- if len (fractionalPart ) > 0 {
227- buf [pos ] = '.'
228- pos ++
229- copy (buf [pos :], fractionalPart )
230- pos += len (fractionalPart )
231- }
242+ copy (buf [pos :], str [integerLen :])
243+ pos += scale
232244 }
233245
234246 return string (buf [:pos ])
235247}
236-
237248func (d Decimal ) handleMinInt64 (scale int ) string {
238-
239249 const minInt64Str = "9223372036854775808"
240250
241- if scale == 0 {
242- return "-" + minInt64Str
243- }
244-
245- var buf [32 ]byte
251+ var buf [48 ]byte
246252 pos := 0
247253
248254 buf [pos ] = '-'
249255 pos ++
250256
251257 length := len (minInt64Str )
252258
259+ if scale == 0 {
260+ if pos + length > len (buf ) {
261+ return "-" + minInt64Str // Fallback.
262+ }
263+ copy (buf [pos :], minInt64Str )
264+ pos += length
265+ return string (buf [:pos ])
266+ }
267+
253268 if scale >= length {
269+ required := 2 + (scale - length ) + length
270+ if pos + required > len (buf ) {
271+ // Fallback.
272+ result := "0." + strings .Repeat ("0" , scale - length ) + minInt64Str
273+ return "-" + result
274+ }
275+
254276 buf [pos ] = '0'
255277 buf [pos + 1 ] = '.'
256278 pos += 2
@@ -265,6 +287,11 @@ func (d Decimal) handleMinInt64(scale int) string {
265287 pos += length
266288 } else {
267289 integerLen := length - scale
290+ required := integerLen + 1 + scale
291+ if pos + required > len (buf ) {
292+ return d .Decimal .String () // Fallback
293+ }
294+
268295 copy (buf [pos :], minInt64Str [:integerLen ])
269296 pos += integerLen
270297
0 commit comments