@@ -312,9 +312,11 @@ static cJSON_bool parse_number(cJSON * const item, parse_buffer * const input_bu
312
312
{
313
313
double number = 0 ;
314
314
unsigned char * after_end = NULL ;
315
- unsigned char number_c_string [ 64 ] ;
315
+ unsigned char * number_c_string ;
316
316
unsigned char decimal_point = get_decimal_point ();
317
317
size_t i = 0 ;
318
+ size_t number_string_length = 0 ;
319
+ cJSON_bool has_decimal_point = false;
318
320
319
321
if ((input_buffer == NULL ) || (input_buffer -> content == NULL ))
320
322
{
@@ -324,7 +326,7 @@ static cJSON_bool parse_number(cJSON * const item, parse_buffer * const input_bu
324
326
/* copy the number into a temporary buffer and replace '.' with the decimal point
325
327
* of the current locale (for strtod)
326
328
* This also takes care of '\0' not necessarily being available for marking the end of the input */
327
- for (i = 0 ; ( i < ( sizeof ( number_c_string ) - 1 )) && can_access_at_index (input_buffer , i ); i ++ )
329
+ for (i = 0 ; can_access_at_index (input_buffer , i ); i ++ )
328
330
{
329
331
switch (buffer_at_offset (input_buffer )[i ])
330
332
{
@@ -342,23 +344,47 @@ static cJSON_bool parse_number(cJSON * const item, parse_buffer * const input_bu
342
344
case '-' :
343
345
case 'e' :
344
346
case 'E' :
345
- number_c_string [ i ] = buffer_at_offset ( input_buffer )[ i ] ;
347
+ number_string_length ++ ;
346
348
break ;
347
349
348
350
case '.' :
349
- number_c_string [i ] = decimal_point ;
351
+ number_string_length ++ ;
352
+ has_decimal_point = true;
350
353
break ;
351
354
352
355
default :
353
356
goto loop_end ;
354
357
}
355
358
}
356
359
loop_end :
360
+ /* malloc for temporary buffer, add 1 for '\0' */
361
+ number_c_string = (unsigned char * ) input_buffer -> hooks .allocate (number_string_length + 1 );
362
+ if (number_c_string == NULL )
363
+ {
364
+ return false; /* allocation failure */
365
+ }
366
+
367
+ memcpy (number_c_string , buffer_at_offset (input_buffer ), number_string_length );
368
+ number_c_string [number_string_length ] = '\0' ;
369
+
370
+ if (has_decimal_point )
371
+ {
372
+ for (i = 0 ; i < number_string_length ; i ++ )
373
+ {
374
+ if (number_c_string [i ] == '.' )
375
+ {
376
+ /* replace '.' with the decimal point of the current locale (for strtod) */
377
+ number_c_string [i ] = decimal_point ;
378
+ }
379
+ }
380
+ }
357
381
number_c_string [i ] = '\0' ;
358
382
359
383
number = strtod ((const char * )number_c_string , (char * * )& after_end );
360
384
if (number_c_string == after_end )
361
385
{
386
+ /* free the temporary buffer */
387
+ input_buffer -> hooks .deallocate (number_c_string );
362
388
return false; /* parse_error */
363
389
}
364
390
@@ -381,6 +407,8 @@ static cJSON_bool parse_number(cJSON * const item, parse_buffer * const input_bu
381
407
item -> type = cJSON_Number ;
382
408
383
409
input_buffer -> offset += (size_t )(after_end - number_c_string );
410
+ /* free the temporary buffer */
411
+ input_buffer -> hooks .deallocate (number_c_string );
384
412
return true;
385
413
}
386
414
0 commit comments