diff --git a/doc/changes/misc_fixes/mr.2447.md b/doc/changes/misc_fixes/mr.2447.md new file mode 100644 index 000000000..d3ff087c2 --- /dev/null +++ b/doc/changes/misc_fixes/mr.2447.md @@ -0,0 +1 @@ +Update cJSON to 1.7.18. diff --git a/src/external/cjson/cjson/CHANGELOG.md b/src/external/cjson/cjson/CHANGELOG.md index ef5325dea..de1d8e663 100644 --- a/src/external/cjson/cjson/CHANGELOG.md +++ b/src/external/cjson/cjson/CHANGELOG.md @@ -1,3 +1,39 @@ +1.7.18 (May 13, 2024) +====== +Fixes: +------ +* Add NULL check to cJSON_SetValuestring()(CVE-2024-31755), see #839 and #840 +* Remove non-functional list handling of compiler flags, see #851 +* Fix heap buffer overflow, see #852 +* remove misused optimization flag -01, see #854 +* Set free'd pointers to NULL whenever they are not reassigned immediately after, see #855 and #833 + +1.7.17 (Dec 26, 2023) +====== +Fixes: +------ +* Fix null reference in cJSON_SetValuestring(CVE-2023-50472), see #809 +* Fix null reference in cJSON_InsertItemInArray(CVE-2023-50471), see #809 and #810 + +1.7.16 (Jul 5, 2023) +====== +Features: +------ +* Add an option for ENABLE_CJSON_VERSION_SO in CMakeLists.txt, see #534 +* Add cmake_policy to CMakeLists.txt, see #163 +* Add cJSON_SetBoolValue, see #639 +* Add meson documentation, see #761 + +Fixes: +------ +* Fix memory leak in merge_patch, see #611 +* Fix conflicting target names 'uninstall', see #617 +* Bump cmake version to 3.0 and use new version syntax, see #587 +* Print int without decimal places, see #630 +* Fix 'cjson_utils-static' target not exist, see #625 +* Add allocate check for replace_item_in_object, see #675 +* Fix a null pointer crash in cJSON_ReplaceItemViaPointer, see #726 + 1.7.15 (Aug 25, 2021) ====== Fixes: diff --git a/src/external/cjson/cjson/CONTRIBUTORS.md b/src/external/cjson/cjson/CONTRIBUTORS.md index f113ab222..494d5d689 100644 --- a/src/external/cjson/cjson/CONTRIBUTORS.md +++ b/src/external/cjson/cjson/CONTRIBUTORS.md @@ -10,8 +10,10 @@ Current Maintainer: Contributors: * [Ajay Bhargav](https://github.com/ajaybhargav) +* [AlexanderVasiljev](https://github.com/AlexanderVasiljev) * [Alper Akcan](https://github.com/alperakcan) * [Andrew Tang](https://github.com/singku) +* [Andy](https://github.com/mlh0101) * [Anton Sergeev](https://github.com/anton-sergeev) * [Benbuck Nason](https://github.com/bnason-nf) * [Bernt Johan Damslora](https://github.com/bjda) @@ -29,25 +31,33 @@ Contributors: * [Fabrice Fontaine](https://github.com/ffontaine) * Ian Mobley * Irwan Djadjadi +* [hopper-vul](https://github.com/hopper-vul) * [HuKeping](https://github.com/HuKeping) * [IvanVoid](https://github.com/npi3pak) * [Jakub Wilk](https://github.com/jwilk) * [Jiri Zouhar](https://github.com/loigu) * [Jonathan Fether](https://github.com/jfether) +* [Joshua Arulsamy](https://github.com/jarulsamy) * [Julian Ste](https://github.com/julian-st) * [Julián Vásquez](https://github.com/juvasquezg) +* [Junbo Zheng](https://github.com/Junbo-Zheng) * [Kevin Branigan](https://github.com/kbranigan) * [Kevin Sapper](https://github.com/sappo) * [Kyle Chisholm](https://github.com/ChisholmKyle) * [Linus Wallgren](https://github.com/ecksun) +* [Luo Jin](https://github.com/Up-wind) +* [Max](https://github.com/maebex) +* [MaxBrandtner](https://github.com/MaxBrandtner) * [Mateusz Szafoni](https://github.com/raiden00pl) * Mike Pontillo * [miaoerduo](https://github.com/miaoerduo) +* [mohawk2](https://github.com/mohawk2) * [Mike Jerris](https://github.com/mjerris) * [Mike Robinson](https://github.com/mhrobinson) * [Moorthy](https://github.com/moorthy-bs) * [myd7349](https://github.com/myd7349) * [NancyLi1013](https://github.com/NancyLi1013) +* [Orri](https://github.com/sbvoxel) * Paulo Antonio Alvarez * [Paweł Malowany](https://github.com/PawelMalowany) * [Pawel Winogrodzki](https://github.com/PawelWMS) @@ -61,10 +71,14 @@ Contributors: * [Romain Porte](https://github.com/MicroJoe) * [SANJEEV BA](https://github.com/basanjeev) * [Sang-Heon Jeon](https://github.com/lntuition) +* [Sayan Bandyopadhyay](https://github.com/saynb) * [Simon Sobisch](https://github.com/GitMensch) * [Simon Ricaldone](https://github.com/simon-p-r) +* [Stoian Ivanov](https://github.com/sdrsdr) +* [SuperH-0630](https://github.com/SuperH-0630) * [Square789](https://github.com/Square789) * [Stephan Gatzka](https://github.com/gatzka) +* [Tony Langhammer](https://github.com/BigBrainAFK) * [Vemake](https://github.com/vemakereporter) * [Wei Tan](https://github.com/tan-wei) * [Weston Schmidt](https://github.com/schmidtw) @@ -73,6 +87,7 @@ Contributors: * [yuta-oxo](https://github.com/yuta-oxo) * [Zach Hindes](https://github.com/zhindes) * [Zhao Zhixu](https://github.com/zhaozhixu) +* [10km](https://github.com/10km) And probably more people on [SourceForge](https://sourceforge.net/p/cjson/bugs/search/?q=status%3Aclosed-rejected+or+status%3Aclosed-out-of-date+or+status%3Awont-fix+or+status%3Aclosed-fixed+or+status%3Aclosed&page=0) diff --git a/src/external/cjson/cjson/cJSON.c b/src/external/cjson/cjson/cJSON.c index 3063f74e9..61483d903 100644 --- a/src/external/cjson/cjson/cJSON.c +++ b/src/external/cjson/cjson/cJSON.c @@ -96,9 +96,9 @@ CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void) return (const char*) (global_error.json + global_error.position); } -CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item) +CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item) { - if (!cJSON_IsString(item)) + if (!cJSON_IsString(item)) { return NULL; } @@ -106,9 +106,9 @@ CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item) return item->valuestring; } -CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item) +CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item) { - if (!cJSON_IsNumber(item)) + if (!cJSON_IsNumber(item)) { return (double) NAN; } @@ -117,7 +117,7 @@ CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item) } /* This is a safeguard to prevent copy-pasters from using incompatible C and header files */ -#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 15) +#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 18) #error cJSON.h and cJSON.c have different versions. Make sure that both have the same. #endif @@ -263,10 +263,12 @@ CJSON_PUBLIC(void) cJSON_Delete(cJSON *item) if (!(item->type & cJSON_IsReference) && (item->valuestring != NULL)) { global_hooks.deallocate(item->valuestring); + item->valuestring = NULL; } if (!(item->type & cJSON_StringIsConst) && (item->string != NULL)) { global_hooks.deallocate(item->string); + item->string = NULL; } global_hooks.deallocate(item); item = next; @@ -397,11 +399,17 @@ CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number) return object->valuedouble = number; } +/* Note: when passing a NULL valuestring, cJSON_SetValuestring treats this as an error and return NULL */ CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring) { char *copy = NULL; /* if object's type is not cJSON_String or is cJSON_IsReference, it should not set valuestring */ - if (!(object->type & cJSON_String) || (object->type & cJSON_IsReference)) + if ((object == NULL) || !(object->type & cJSON_String) || (object->type & cJSON_IsReference)) + { + return NULL; + } + /* return NULL if the object is corrupted or valuestring is NULL */ + if (object->valuestring == NULL || valuestring == NULL) { return NULL; } @@ -511,7 +519,7 @@ static unsigned char* ensure(printbuffer * const p, size_t needed) return NULL; } - + memcpy(newbuffer, p->buffer, p->offset + 1); p->hooks.deallocate(p->buffer); } @@ -562,6 +570,10 @@ static cJSON_bool print_number(const cJSON * const item, printbuffer * const out { length = sprintf((char*)number_buffer, "null"); } + else if(d == (double)item->valueint) + { + length = sprintf((char*)number_buffer, "%d", item->valueint); + } else { /* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */ @@ -884,6 +896,7 @@ fail: if (output != NULL) { input_buffer->hooks.deallocate(output); + output = NULL; } if (input_pointer != NULL) @@ -1103,7 +1116,7 @@ CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer } buffer.content = (const unsigned char*)value; - buffer.length = buffer_length; + buffer.length = buffer_length; buffer.offset = 0; buffer.hooks = global_hooks; @@ -1226,6 +1239,7 @@ static unsigned char *print(const cJSON * const item, cJSON_bool format, const i /* free the buffer */ hooks->deallocate(buffer->buffer); + buffer->buffer = NULL; } return printed; @@ -1234,11 +1248,13 @@ fail: if (buffer->buffer != NULL) { hooks->deallocate(buffer->buffer); + buffer->buffer = NULL; } if (printed != NULL) { hooks->deallocate(printed); + printed = NULL; } return NULL; @@ -1279,6 +1295,7 @@ CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON if (!print_value(item, &p)) { global_hooks.deallocate(p.buffer); + p.buffer = NULL; return NULL; } @@ -1650,6 +1667,11 @@ static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_bu current_item = new_item; } + if (cannot_access_at_index(input_buffer, 1)) + { + goto fail; /* nothing comes after the comma */ + } + /* parse the name of the child */ input_buffer->offset++; buffer_skip_whitespace(input_buffer); @@ -2260,7 +2282,7 @@ CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON { cJSON *after_inserted = NULL; - if (which < 0) + if (which < 0 || newitem == NULL) { return false; } @@ -2271,6 +2293,11 @@ CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON return add_item_to_array(array, newitem); } + if (after_inserted != array->child && after_inserted->prev == NULL) { + /* return false if after_inserted is a corrupted array item */ + return false; + } + newitem->next = after_inserted; newitem->prev = after_inserted->prev; after_inserted->prev = newitem; @@ -2287,7 +2314,7 @@ CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement) { - if ((parent == NULL) || (replacement == NULL) || (item == NULL)) + if ((parent == NULL) || (parent->child == NULL) || (replacement == NULL) || (item == NULL)) { return false; } @@ -2357,6 +2384,11 @@ static cJSON_bool replace_item_in_object(cJSON *object, const char *string, cJSO cJSON_free(replacement->string); } replacement->string = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks); + if (replacement->string == NULL) + { + return false; + } + replacement->type &= ~cJSON_StringIsConst; return cJSON_ReplaceItemViaPointer(object, get_object_item(object, string, case_sensitive), replacement); @@ -2689,7 +2721,7 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int co if (a && a->child) { a->child->prev = n; } - + return a; } @@ -3107,4 +3139,5 @@ CJSON_PUBLIC(void *) cJSON_malloc(size_t size) CJSON_PUBLIC(void) cJSON_free(void *object) { global_hooks.deallocate(object); + object = NULL; } diff --git a/src/external/cjson/cjson/cJSON.h b/src/external/cjson/cjson/cJSON.h index 92907a2cd..88cf0bcfa 100644 --- a/src/external/cjson/cjson/cJSON.h +++ b/src/external/cjson/cjson/cJSON.h @@ -81,7 +81,7 @@ then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJ /* project version */ #define CJSON_VERSION_MAJOR 1 #define CJSON_VERSION_MINOR 7 -#define CJSON_VERSION_PATCH 15 +#define CJSON_VERSION_PATCH 18 #include @@ -279,6 +279,13 @@ CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number); /* Change the valuestring of a cJSON_String object, only takes effect when type of object is cJSON_String */ CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring); +/* If the object is not a boolean type this does nothing and returns cJSON_Invalid else it returns the new type*/ +#define cJSON_SetBoolValue(object, boolValue) ( \ + (object != NULL && ((object)->type & (cJSON_False|cJSON_True))) ? \ + (object)->type=((object)->type &(~(cJSON_False|cJSON_True)))|((boolValue)?cJSON_True:cJSON_False) : \ + cJSON_Invalid\ +) + /* Macro for iterating over an array or object */ #define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)