78
78
#endif
79
79
80
80
#ifndef NAN
81
+ #ifdef _WIN32
82
+ #define NAN sqrt (-1.0 )
83
+ #else
81
84
#define NAN 0.0 /0.0
82
85
#endif
86
+ #endif
83
87
84
88
typedef struct {
85
89
const unsigned char *json;
@@ -120,7 +124,7 @@ CJSON_AS4CPP_PUBLIC(double) cJSON_AS4CPP_GetNumberValue(const cJSON * const item
120
124
}
121
125
122
126
/* This is a safeguard to prevent copy-pasters from using incompatible C and header files */
123
- #if (CJSON_AS4CPP_VERSION_MAJOR != 1) || (CJSON_AS4CPP_VERSION_MINOR != 7) || (CJSON_AS4CPP_VERSION_PATCH != 14 )
127
+ #if (CJSON_AS4CPP_VERSION_MAJOR != 1) || (CJSON_AS4CPP_VERSION_MINOR != 7) || (CJSON_AS4CPP_VERSION_PATCH != 18 )
124
128
#error cJSON.h and cJSON.c have different versions. Make sure that both have the same.
125
129
#endif
126
130
@@ -266,10 +270,12 @@ CJSON_AS4CPP_PUBLIC(void) cJSON_AS4CPP_Delete(cJSON *item)
266
270
if (!(item->type & cJSON_AS4CPP_IsReference) && (item->valuestring != NULL ))
267
271
{
268
272
global_hooks.deallocate (item->valuestring );
273
+ item->valuestring = NULL ;
269
274
}
270
275
if (!(item->type & cJSON_AS4CPP_StringIsConst) && (item->string != NULL ))
271
276
{
272
277
global_hooks.deallocate (item->string );
278
+ item->string = NULL ;
273
279
}
274
280
global_hooks.deallocate (item);
275
281
item = next;
@@ -411,17 +417,34 @@ CJSON_AS4CPP_PUBLIC(double) cJSON_AS4CPP_SetNumberHelper(cJSON *object, double n
411
417
return object->valuedouble = number;
412
418
}
413
419
420
+ /* Note: when passing a NULL valuestring, cJSON_AS4CPP_SetValuestring treats this as an error and return NULL */
414
421
CJSON_AS4CPP_PUBLIC (char *) cJSON_AS4CPP_SetValuestring(cJSON *object, const char *valuestring)
415
422
{
416
423
char *copy = NULL ;
424
+ size_t v1_len;
425
+ size_t v2_len;
417
426
/* if object's type is not cJSON_AS4CPP_String or is cJSON_AS4CPP_IsReference, it should not set valuestring */
418
- if (!(object->type & cJSON_AS4CPP_String) || (object->type & cJSON_AS4CPP_IsReference))
427
+ if ((object == NULL ) || !(object->type & cJSON_AS4CPP_String) || (object->type & cJSON_AS4CPP_IsReference))
419
428
{
420
429
return NULL ;
421
430
}
422
- if (strlen (valuestring) <= strlen (object->valuestring ))
431
+ /* return NULL if the object is corrupted or valuestring is NULL */
432
+ if (object->valuestring == NULL || valuestring == NULL )
423
433
{
424
- memcpy (object->valuestring , valuestring, strlen (valuestring) + sizeof (" " ));
434
+ return NULL ;
435
+ }
436
+
437
+ v1_len = strlen (valuestring);
438
+ v2_len = strlen (object->valuestring );
439
+
440
+ if (v1_len <= v2_len)
441
+ {
442
+ /* strcpy does not handle overlapping string: [X1, X2] [Y1, Y2] => X2 < Y1 or Y2 < X1 */
443
+ if (!( valuestring + v1_len < object->valuestring || object->valuestring + v2_len < valuestring ))
444
+ {
445
+ return NULL ;
446
+ }
447
+ strcpy (object->valuestring , valuestring);
425
448
return object->valuestring ;
426
449
}
427
450
copy = (char *) cJSON_AS4CPP_strdup ((const unsigned char *)valuestring, &global_hooks);
@@ -525,10 +548,8 @@ static unsigned char* ensure(printbuffer * const p, size_t needed)
525
548
526
549
return NULL ;
527
550
}
528
- if (newbuffer)
529
- {
530
- memcpy (newbuffer, p->buffer , p->offset + 1 );
531
- }
551
+
552
+ memcpy (newbuffer, p->buffer , p->offset + 1 );
532
553
p->hooks .deallocate (p->buffer );
533
554
}
534
555
p->length = newsize;
@@ -905,6 +926,7 @@ static cJSON_AS4CPP_bool parse_string(cJSON * const item, parse_buffer * const i
905
926
if (output != NULL )
906
927
{
907
928
input_buffer->hooks .deallocate (output);
929
+ output = NULL ;
908
930
}
909
931
910
932
if (input_pointer != NULL )
@@ -1185,7 +1207,6 @@ CJSON_AS4CPP_PUBLIC(cJSON *) cJSON_AS4CPP_ParseWithLengthOpts(const char *value,
1185
1207
{
1186
1208
*return_parse_end = (const char *)local_error.json + local_error.position ;
1187
1209
}
1188
-
1189
1210
/* NOTE: disabled due to thread safety (see note at the top of this file).
1190
1211
global_error = local_error;
1191
1212
*/
@@ -1253,6 +1274,7 @@ static unsigned char *print(const cJSON * const item, cJSON_AS4CPP_bool format,
1253
1274
1254
1275
/* free the buffer */
1255
1276
hooks->deallocate (buffer->buffer );
1277
+ buffer->buffer = NULL ;
1256
1278
}
1257
1279
1258
1280
return printed;
@@ -1261,11 +1283,13 @@ static unsigned char *print(const cJSON * const item, cJSON_AS4CPP_bool format,
1261
1283
if (buffer->buffer != NULL )
1262
1284
{
1263
1285
hooks->deallocate (buffer->buffer );
1286
+ buffer->buffer = NULL ;
1264
1287
}
1265
1288
1266
1289
if (printed != NULL )
1267
1290
{
1268
1291
hooks->deallocate (printed);
1292
+ printed = NULL ;
1269
1293
}
1270
1294
1271
1295
return NULL ;
@@ -1306,6 +1330,7 @@ CJSON_AS4CPP_PUBLIC(char *) cJSON_AS4CPP_PrintBuffered(const cJSON *item, int pr
1306
1330
if (!print_value (item, &p))
1307
1331
{
1308
1332
global_hooks.deallocate (p.buffer );
1333
+ p.buffer = NULL ;
1309
1334
return NULL ;
1310
1335
}
1311
1336
@@ -1677,6 +1702,11 @@ static cJSON_AS4CPP_bool parse_object(cJSON * const item, parse_buffer * const i
1677
1702
current_item = new_item;
1678
1703
}
1679
1704
1705
+ if (cannot_access_at_index (input_buffer, 1 ))
1706
+ {
1707
+ goto fail; /* nothing comes after the comma */
1708
+ }
1709
+
1680
1710
/* parse the name of the child */
1681
1711
input_buffer->offset ++;
1682
1712
buffer_skip_whitespace (input_buffer);
@@ -2209,7 +2239,7 @@ CJSON_AS4CPP_PUBLIC(cJSON*) cJSON_AS4CPP_AddArrayToObject(cJSON * const object,
2209
2239
2210
2240
CJSON_AS4CPP_PUBLIC (cJSON *) cJSON_AS4CPP_DetachItemViaPointer(cJSON *parent, cJSON * const item)
2211
2241
{
2212
- if ((parent == NULL ) || (item == NULL ))
2242
+ if ((parent == NULL ) || (item == NULL ) || (item != parent-> child && item-> prev == NULL ) )
2213
2243
{
2214
2244
return NULL ;
2215
2245
}
@@ -2287,7 +2317,7 @@ CJSON_AS4CPP_PUBLIC(cJSON_AS4CPP_bool) cJSON_AS4CPP_InsertItemInArray(cJSON *arr
2287
2317
{
2288
2318
cJSON *after_inserted = NULL ;
2289
2319
2290
- if (which < 0 )
2320
+ if (which < 0 || newitem == NULL )
2291
2321
{
2292
2322
return false ;
2293
2323
}
@@ -2298,6 +2328,11 @@ CJSON_AS4CPP_PUBLIC(cJSON_AS4CPP_bool) cJSON_AS4CPP_InsertItemInArray(cJSON *arr
2298
2328
return add_item_to_array (array, newitem);
2299
2329
}
2300
2330
2331
+ if (after_inserted != array->child && after_inserted->prev == NULL ) {
2332
+ /* return false if after_inserted is a corrupted array item */
2333
+ return false ;
2334
+ }
2335
+
2301
2336
newitem->next = after_inserted;
2302
2337
newitem->prev = after_inserted->prev ;
2303
2338
after_inserted->prev = newitem;
@@ -2314,7 +2349,7 @@ CJSON_AS4CPP_PUBLIC(cJSON_AS4CPP_bool) cJSON_AS4CPP_InsertItemInArray(cJSON *arr
2314
2349
2315
2350
CJSON_AS4CPP_PUBLIC (cJSON_AS4CPP_bool) cJSON_AS4CPP_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement)
2316
2351
{
2317
- if ((parent == NULL ) || (replacement == NULL ) || (item == NULL ))
2352
+ if ((parent == NULL ) || (parent-> child == NULL ) || ( replacement == NULL ) || (item == NULL ))
2318
2353
{
2319
2354
return false ;
2320
2355
}
@@ -2384,6 +2419,11 @@ static cJSON_AS4CPP_bool replace_item_in_object(cJSON *object, const char *strin
2384
2419
cJSON_AS4CPP_free (replacement->string );
2385
2420
}
2386
2421
replacement->string = (char *)cJSON_AS4CPP_strdup ((const unsigned char *)string, &global_hooks);
2422
+ if (replacement->string == NULL )
2423
+ {
2424
+ return false ;
2425
+ }
2426
+
2387
2427
replacement->type &= ~cJSON_AS4CPP_StringIsConst;
2388
2428
2389
2429
return cJSON_AS4CPP_ReplaceItemViaPointer (object, get_object_item (object, string, case_sensitive), replacement);
@@ -2608,6 +2648,7 @@ CJSON_AS4CPP_PUBLIC(cJSON *) cJSON_AS4CPP_CreateIntArray(const int *numbers, int
2608
2648
}
2609
2649
2610
2650
a = cJSON_AS4CPP_CreateArray ();
2651
+
2611
2652
for (i = 0 ; a && (i < (size_t )count); i++)
2612
2653
{
2613
2654
n = cJSON_AS4CPP_CreateNumber (numbers[i]);
@@ -2626,7 +2667,10 @@ CJSON_AS4CPP_PUBLIC(cJSON *) cJSON_AS4CPP_CreateIntArray(const int *numbers, int
2626
2667
}
2627
2668
p = n;
2628
2669
}
2629
- a->child ->prev = n;
2670
+
2671
+ if (a && a->child ) {
2672
+ a->child ->prev = n;
2673
+ }
2630
2674
2631
2675
return a;
2632
2676
}
@@ -2663,7 +2707,10 @@ CJSON_AS4CPP_PUBLIC(cJSON *) cJSON_AS4CPP_CreateFloatArray(const float *numbers,
2663
2707
}
2664
2708
p = n;
2665
2709
}
2666
- a->child ->prev = n;
2710
+
2711
+ if (a && a->child ) {
2712
+ a->child ->prev = n;
2713
+ }
2667
2714
2668
2715
return a;
2669
2716
}
@@ -2682,7 +2729,7 @@ CJSON_AS4CPP_PUBLIC(cJSON *) cJSON_AS4CPP_CreateDoubleArray(const double *number
2682
2729
2683
2730
a = cJSON_AS4CPP_CreateArray ();
2684
2731
2685
- for (i = 0 ;a && (i < (size_t )count); i++)
2732
+ for (i = 0 ; a && (i < (size_t )count); i++)
2686
2733
{
2687
2734
n = cJSON_AS4CPP_CreateNumber (numbers[i]);
2688
2735
if (!n)
@@ -2700,7 +2747,10 @@ CJSON_AS4CPP_PUBLIC(cJSON *) cJSON_AS4CPP_CreateDoubleArray(const double *number
2700
2747
}
2701
2748
p = n;
2702
2749
}
2703
- a->child ->prev = n;
2750
+
2751
+ if (a && a->child ) {
2752
+ a->child ->prev = n;
2753
+ }
2704
2754
2705
2755
return a;
2706
2756
}
@@ -2737,13 +2787,23 @@ CJSON_AS4CPP_PUBLIC(cJSON *) cJSON_AS4CPP_CreateStringArray(const char *const *s
2737
2787
}
2738
2788
p = n;
2739
2789
}
2740
- a->child ->prev = n;
2790
+
2791
+ if (a && a->child ) {
2792
+ a->child ->prev = n;
2793
+ }
2741
2794
2742
2795
return a;
2743
2796
}
2744
2797
2745
2798
/* Duplication */
2799
+ cJSON * cJSON_AS4CPP_Duplicate_rec (const cJSON *item, size_t depth, cJSON_AS4CPP_bool recurse);
2800
+
2746
2801
CJSON_AS4CPP_PUBLIC (cJSON *) cJSON_AS4CPP_Duplicate(const cJSON *item, cJSON_AS4CPP_bool recurse)
2802
+ {
2803
+ return cJSON_AS4CPP_Duplicate_rec (item, 0 , recurse );
2804
+ }
2805
+
2806
+ cJSON * cJSON_AS4CPP_Duplicate_rec (const cJSON *item, size_t depth, cJSON_AS4CPP_bool recurse)
2747
2807
{
2748
2808
cJSON *newitem = NULL ;
2749
2809
cJSON *child = NULL ;
@@ -2790,7 +2850,10 @@ CJSON_AS4CPP_PUBLIC(cJSON *) cJSON_AS4CPP_Duplicate(const cJSON *item, cJSON_AS4
2790
2850
child = item->child ;
2791
2851
while (child != NULL )
2792
2852
{
2793
- newchild = cJSON_AS4CPP_Duplicate (child, true ); /* Duplicate (with recurse) each item in the ->next chain */
2853
+ if (depth >= CJSON_AS4CPP_CIRCULAR_LIMIT) {
2854
+ goto fail;
2855
+ }
2856
+ newchild = cJSON_AS4CPP_Duplicate_rec (child, depth + 1 , true ); /* Duplicate (with recurse) each item in the ->next chain */
2794
2857
if (!newchild)
2795
2858
{
2796
2859
goto fail;
@@ -3025,7 +3088,7 @@ CJSON_AS4CPP_PUBLIC(cJSON_AS4CPP_bool) cJSON_AS4CPP_IsRaw(const cJSON * const it
3025
3088
3026
3089
CJSON_AS4CPP_PUBLIC (cJSON_AS4CPP_bool) cJSON_AS4CPP_Compare(const cJSON * const a, const cJSON * const b, const cJSON_AS4CPP_bool case_sensitive)
3027
3090
{
3028
- if ((a == NULL ) || (b == NULL ) || ((a->type & 0xFF ) != (b->type & 0xFF )) || cJSON_AS4CPP_IsInvalid (a) )
3091
+ if ((a == NULL ) || (b == NULL ) || ((a->type & 0xFF ) != (b->type & 0xFF )))
3029
3092
{
3030
3093
return false ;
3031
3094
}
@@ -3156,4 +3219,5 @@ CJSON_AS4CPP_PUBLIC(void *) cJSON_AS4CPP_malloc(size_t size)
3156
3219
CJSON_AS4CPP_PUBLIC (void ) cJSON_AS4CPP_free(void *object)
3157
3220
{
3158
3221
global_hooks.deallocate (object);
3222
+ object = NULL ;
3159
3223
}
0 commit comments