···1+1.7.18 (May 13, 2024)
2+======
3+Fixes:
4+------
5+* Add NULL check to cJSON_SetValuestring()(CVE-2024-31755), see #839 and #840
6+* Remove non-functional list handling of compiler flags, see #851
7+* Fix heap buffer overflow, see #852
8+* remove misused optimization flag -01, see #854
9+* Set free'd pointers to NULL whenever they are not reassigned immediately after, see #855 and #833
10+11+1.7.17 (Dec 26, 2023)
12+======
13+Fixes:
14+------
15+* Fix null reference in cJSON_SetValuestring(CVE-2023-50472), see #809
16+* Fix null reference in cJSON_InsertItemInArray(CVE-2023-50471), see #809 and #810
17+18+1.7.16 (Jul 5, 2023)
19+======
20+Features:
21+------
22+* Add an option for ENABLE_CJSON_VERSION_SO in CMakeLists.txt, see #534
23+* Add cmake_policy to CMakeLists.txt, see #163
24+* Add cJSON_SetBoolValue, see #639
25+* Add meson documentation, see #761
26+27+Fixes:
28+------
29+* Fix memory leak in merge_patch, see #611
30+* Fix conflicting target names 'uninstall', see #617
31+* Bump cmake version to 3.0 and use new version syntax, see #587
32+* Print int without decimal places, see #630
33+* Fix 'cjson_utils-static' target not exist, see #625
34+* Add allocate check for replace_item_in_object, see #675
35+* Fix a null pointer crash in cJSON_ReplaceItemViaPointer, see #726
36+371.7.15 (Aug 25, 2021)
38======
39Fixes:
···96 return (const char*) (global_error.json + global_error.position);
97}
9899-CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item)
100{
101- if (!cJSON_IsString(item))
102 {
103 return NULL;
104 }
···106 return item->valuestring;
107}
108109-CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item)
110{
111- if (!cJSON_IsNumber(item))
112 {
113 return (double) NAN;
114 }
···117}
118119/* This is a safeguard to prevent copy-pasters from using incompatible C and header files */
120-#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 15)
121 #error cJSON.h and cJSON.c have different versions. Make sure that both have the same.
122#endif
123···263 if (!(item->type & cJSON_IsReference) && (item->valuestring != NULL))
264 {
265 global_hooks.deallocate(item->valuestring);
0266 }
267 if (!(item->type & cJSON_StringIsConst) && (item->string != NULL))
268 {
269 global_hooks.deallocate(item->string);
0270 }
271 global_hooks.deallocate(item);
272 item = next;
···397 return object->valuedouble = number;
398}
3990400CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring)
401{
402 char *copy = NULL;
403 /* if object's type is not cJSON_String or is cJSON_IsReference, it should not set valuestring */
404- if (!(object->type & cJSON_String) || (object->type & cJSON_IsReference))
00000405 {
406 return NULL;
407 }
···511512 return NULL;
513 }
514-515 memcpy(newbuffer, p->buffer, p->offset + 1);
516 p->hooks.deallocate(p->buffer);
517 }
···562 {
563 length = sprintf((char*)number_buffer, "null");
564 }
0000565 else
566 {
567 /* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */
···884 if (output != NULL)
885 {
886 input_buffer->hooks.deallocate(output);
0887 }
888889 if (input_pointer != NULL)
···1103 }
11041105 buffer.content = (const unsigned char*)value;
1106- buffer.length = buffer_length;
1107 buffer.offset = 0;
1108 buffer.hooks = global_hooks;
1109···12261227 /* free the buffer */
1228 hooks->deallocate(buffer->buffer);
01229 }
12301231 return printed;
···1234 if (buffer->buffer != NULL)
1235 {
1236 hooks->deallocate(buffer->buffer);
01237 }
12381239 if (printed != NULL)
1240 {
1241 hooks->deallocate(printed);
01242 }
12431244 return NULL;
···1279 if (!print_value(item, &p))
1280 {
1281 global_hooks.deallocate(p.buffer);
01282 return NULL;
1283 }
1284···1648 current_item->next = new_item;
1649 new_item->prev = current_item;
1650 current_item = new_item;
000001651 }
16521653 /* parse the name of the child */
···2260{
2261 cJSON *after_inserted = NULL;
22622263- if (which < 0)
2264 {
2265 return false;
2266 }
···2271 return add_item_to_array(array, newitem);
2272 }
2273000002274 newitem->next = after_inserted;
2275 newitem->prev = after_inserted->prev;
2276 after_inserted->prev = newitem;
···22872288CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement)
2289{
2290- if ((parent == NULL) || (replacement == NULL) || (item == NULL))
2291 {
2292 return false;
2293 }
···2357 cJSON_free(replacement->string);
2358 }
2359 replacement->string = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks);
000002360 replacement->type &= ~cJSON_StringIsConst;
23612362 return cJSON_ReplaceItemViaPointer(object, get_object_item(object, string, case_sensitive), replacement);
···2689 if (a && a->child) {
2690 a->child->prev = n;
2691 }
2692-2693 return a;
2694}
2695···3107CJSON_PUBLIC(void) cJSON_free(void *object)
3108{
3109 global_hooks.deallocate(object);
03110}
···96 return (const char*) (global_error.json + global_error.position);
97}
9899+CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item)
100{
101+ if (!cJSON_IsString(item))
102 {
103 return NULL;
104 }
···106 return item->valuestring;
107}
108109+CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item)
110{
111+ if (!cJSON_IsNumber(item))
112 {
113 return (double) NAN;
114 }
···117}
118119/* This is a safeguard to prevent copy-pasters from using incompatible C and header files */
120+#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 18)
121 #error cJSON.h and cJSON.c have different versions. Make sure that both have the same.
122#endif
123···263 if (!(item->type & cJSON_IsReference) && (item->valuestring != NULL))
264 {
265 global_hooks.deallocate(item->valuestring);
266+ item->valuestring = NULL;
267 }
268 if (!(item->type & cJSON_StringIsConst) && (item->string != NULL))
269 {
270 global_hooks.deallocate(item->string);
271+ item->string = NULL;
272 }
273 global_hooks.deallocate(item);
274 item = next;
···399 return object->valuedouble = number;
400}
401402+/* Note: when passing a NULL valuestring, cJSON_SetValuestring treats this as an error and return NULL */
403CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring)
404{
405 char *copy = NULL;
406 /* if object's type is not cJSON_String or is cJSON_IsReference, it should not set valuestring */
407+ if ((object == NULL) || !(object->type & cJSON_String) || (object->type & cJSON_IsReference))
408+ {
409+ return NULL;
410+ }
411+ /* return NULL if the object is corrupted or valuestring is NULL */
412+ if (object->valuestring == NULL || valuestring == NULL)
413 {
414 return NULL;
415 }
···519520 return NULL;
521 }
522+523 memcpy(newbuffer, p->buffer, p->offset + 1);
524 p->hooks.deallocate(p->buffer);
525 }
···570 {
571 length = sprintf((char*)number_buffer, "null");
572 }
573+ else if(d == (double)item->valueint)
574+ {
575+ length = sprintf((char*)number_buffer, "%d", item->valueint);
576+ }
577 else
578 {
579 /* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */
···896 if (output != NULL)
897 {
898 input_buffer->hooks.deallocate(output);
899+ output = NULL;
900 }
901902 if (input_pointer != NULL)
···1116 }
11171118 buffer.content = (const unsigned char*)value;
1119+ buffer.length = buffer_length;
1120 buffer.offset = 0;
1121 buffer.hooks = global_hooks;
1122···12391240 /* free the buffer */
1241 hooks->deallocate(buffer->buffer);
1242+ buffer->buffer = NULL;
1243 }
12441245 return printed;
···1248 if (buffer->buffer != NULL)
1249 {
1250 hooks->deallocate(buffer->buffer);
1251+ buffer->buffer = NULL;
1252 }
12531254 if (printed != NULL)
1255 {
1256 hooks->deallocate(printed);
1257+ printed = NULL;
1258 }
12591260 return NULL;
···1295 if (!print_value(item, &p))
1296 {
1297 global_hooks.deallocate(p.buffer);
1298+ p.buffer = NULL;
1299 return NULL;
1300 }
1301···1665 current_item->next = new_item;
1666 new_item->prev = current_item;
1667 current_item = new_item;
1668+ }
1669+1670+ if (cannot_access_at_index(input_buffer, 1))
1671+ {
1672+ goto fail; /* nothing comes after the comma */
1673 }
16741675 /* parse the name of the child */
···2282{
2283 cJSON *after_inserted = NULL;
22842285+ if (which < 0 || newitem == NULL)
2286 {
2287 return false;
2288 }
···2293 return add_item_to_array(array, newitem);
2294 }
22952296+ if (after_inserted != array->child && after_inserted->prev == NULL) {
2297+ /* return false if after_inserted is a corrupted array item */
2298+ return false;
2299+ }
2300+2301 newitem->next = after_inserted;
2302 newitem->prev = after_inserted->prev;
2303 after_inserted->prev = newitem;
···23142315CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement)
2316{
2317+ if ((parent == NULL) || (parent->child == NULL) || (replacement == NULL) || (item == NULL))
2318 {
2319 return false;
2320 }
···2384 cJSON_free(replacement->string);
2385 }
2386 replacement->string = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks);
2387+ if (replacement->string == NULL)
2388+ {
2389+ return false;
2390+ }
2391+2392 replacement->type &= ~cJSON_StringIsConst;
23932394 return cJSON_ReplaceItemViaPointer(object, get_object_item(object, string, case_sensitive), replacement);
···2721 if (a && a->child) {
2722 a->child->prev = n;
2723 }
2724+2725 return a;
2726}
2727···3139CJSON_PUBLIC(void) cJSON_free(void *object)
3140{
3141 global_hooks.deallocate(object);
3142+ object = NULL;
3143}
+8-1
src/external/cjson/cjson/cJSON.h
···81/* project version */
82#define CJSON_VERSION_MAJOR 1
83#define CJSON_VERSION_MINOR 7
84-#define CJSON_VERSION_PATCH 15
8586#include <stddef.h>
87···278#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
279/* Change the valuestring of a cJSON_String object, only takes effect when type of object is cJSON_String */
280CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring);
0000000281282/* Macro for iterating over an array or object */
283#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
···81/* project version */
82#define CJSON_VERSION_MAJOR 1
83#define CJSON_VERSION_MINOR 7
84+#define CJSON_VERSION_PATCH 18
8586#include <stddef.h>
87···278#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
279/* Change the valuestring of a cJSON_String object, only takes effect when type of object is cJSON_String */
280CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring);
281+282+/* If the object is not a boolean type this does nothing and returns cJSON_Invalid else it returns the new type*/
283+#define cJSON_SetBoolValue(object, boolValue) ( \
284+ (object != NULL && ((object)->type & (cJSON_False|cJSON_True))) ? \
285+ (object)->type=((object)->type &(~(cJSON_False|cJSON_True)))|((boolValue)?cJSON_True:cJSON_False) : \
286+ cJSON_Invalid\
287+)
288289/* Macro for iterating over an array or object */
290#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)