From 5392f3576405f952eaea8626d451894b9b6bf771 Mon Sep 17 00:00:00 2001 From: sbiscigl Date: Mon, 20 Jan 2025 09:44:59 -0500 Subject: [PATCH] update cjson embedded dependency to 1.7.28 --- .../include/aws/core/external/cjson/cJSON.h | 15 ++- .../source/external/cjson/cJSON.cpp | 102 ++++++++++++++---- 2 files changed, 97 insertions(+), 20 deletions(-) diff --git a/src/aws-cpp-sdk-core/include/aws/core/external/cjson/cJSON.h b/src/aws-cpp-sdk-core/include/aws/core/external/cjson/cJSON.h index a069f3c7729..e47581c6288 100644 --- a/src/aws-cpp-sdk-core/include/aws/core/external/cjson/cJSON.h +++ b/src/aws-cpp-sdk-core/include/aws/core/external/cjson/cJSON.h @@ -92,7 +92,7 @@ then using the CJSON_AS4CPP_API_VISIBILITY flag to "export" the same symbols the /* project version */ #define CJSON_AS4CPP_VERSION_MAJOR 1 #define CJSON_AS4CPP_VERSION_MINOR 7 -#define CJSON_AS4CPP_VERSION_PATCH 14 +#define CJSON_AS4CPP_VERSION_PATCH 18 #include @@ -148,6 +148,12 @@ typedef int cJSON_AS4CPP_bool; #define CJSON_AS4CPP_NESTING_LIMIT 1000 #endif +/* Limits the length of circular references can be before cJSON rejects to parse them. + * This is to prevent stack overflows. */ +#ifndef CJSON_AS4CPP_CIRCULAR_LIMIT +#define CJSON_AS4CPP_CIRCULAR_LIMIT 10000 +#endif + /* returns the version of cJSON as a string */ CJSON_AS4CPP_PUBLIC(const char*) cJSON_AS4CPP_Version(void); @@ -293,6 +299,13 @@ CJSON_AS4CPP_PUBLIC(double) cJSON_AS4CPP_SetNumberHelper(cJSON *object, double n /* Change the valuestring of a cJSON_AS4CPP_String object, only takes effect when type of object is cJSON_AS4CPP_String */ CJSON_AS4CPP_PUBLIC(char*) cJSON_AS4CPP_SetValuestring(cJSON *object, const char *valuestring); +/* If the object is not a boolean type this does nothing and returns cJSON_AS4CPP_Invalid else it returns the new type*/ +#define cJSON_AS4CPP_SetBoolValue(object, boolValue) ( \ + (object != NULL && ((object)->type & (cJSON_AS4CPP_False|cJSON_AS4CPP_True))) ? \ + (object)->type=((object)->type &(~(cJSON_AS4CPP_False|cJSON_AS4CPP_True)))|((boolValue)?cJSON_AS4CPP_True:cJSON_AS4CPP_False) : \ + cJSON_AS4CPP_Invalid\ +) + /* Macro for iterating over an array or object */ #define cJSON_AS4CPP_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next) diff --git a/src/aws-cpp-sdk-core/source/external/cjson/cJSON.cpp b/src/aws-cpp-sdk-core/source/external/cjson/cJSON.cpp index cdcbf103e7c..34c3eb1f858 100644 --- a/src/aws-cpp-sdk-core/source/external/cjson/cJSON.cpp +++ b/src/aws-cpp-sdk-core/source/external/cjson/cJSON.cpp @@ -78,8 +78,12 @@ #endif #ifndef NAN +#ifdef _WIN32 +#define NAN sqrt(-1.0) +#else #define NAN 0.0/0.0 #endif +#endif typedef struct { const unsigned char *json; @@ -120,7 +124,7 @@ CJSON_AS4CPP_PUBLIC(double) cJSON_AS4CPP_GetNumberValue(const cJSON * const item } /* This is a safeguard to prevent copy-pasters from using incompatible C and header files */ -#if (CJSON_AS4CPP_VERSION_MAJOR != 1) || (CJSON_AS4CPP_VERSION_MINOR != 7) || (CJSON_AS4CPP_VERSION_PATCH != 14) +#if (CJSON_AS4CPP_VERSION_MAJOR != 1) || (CJSON_AS4CPP_VERSION_MINOR != 7) || (CJSON_AS4CPP_VERSION_PATCH != 18) #error cJSON.h and cJSON.c have different versions. Make sure that both have the same. #endif @@ -266,10 +270,12 @@ CJSON_AS4CPP_PUBLIC(void) cJSON_AS4CPP_Delete(cJSON *item) if (!(item->type & cJSON_AS4CPP_IsReference) && (item->valuestring != NULL)) { global_hooks.deallocate(item->valuestring); + item->valuestring = NULL; } if (!(item->type & cJSON_AS4CPP_StringIsConst) && (item->string != NULL)) { global_hooks.deallocate(item->string); + item->string = NULL; } global_hooks.deallocate(item); item = next; @@ -411,17 +417,34 @@ CJSON_AS4CPP_PUBLIC(double) cJSON_AS4CPP_SetNumberHelper(cJSON *object, double n return object->valuedouble = number; } +/* Note: when passing a NULL valuestring, cJSON_AS4CPP_SetValuestring treats this as an error and return NULL */ CJSON_AS4CPP_PUBLIC(char*) cJSON_AS4CPP_SetValuestring(cJSON *object, const char *valuestring) { char *copy = NULL; + size_t v1_len; + size_t v2_len; /* if object's type is not cJSON_AS4CPP_String or is cJSON_AS4CPP_IsReference, it should not set valuestring */ - if (!(object->type & cJSON_AS4CPP_String) || (object->type & cJSON_AS4CPP_IsReference)) + if ((object == NULL) || !(object->type & cJSON_AS4CPP_String) || (object->type & cJSON_AS4CPP_IsReference)) { return NULL; } - if (strlen(valuestring) <= strlen(object->valuestring)) + /* return NULL if the object is corrupted or valuestring is NULL */ + if (object->valuestring == NULL || valuestring == NULL) { - memcpy(object->valuestring, valuestring, strlen(valuestring) + sizeof("")); + return NULL; + } + + v1_len = strlen(valuestring); + v2_len = strlen(object->valuestring); + + if (v1_len <= v2_len) + { + /* strcpy does not handle overlapping string: [X1, X2] [Y1, Y2] => X2 < Y1 or Y2 < X1 */ + if (!( valuestring + v1_len < object->valuestring || object->valuestring + v2_len < valuestring )) + { + return NULL; + } + strcpy(object->valuestring, valuestring); return object->valuestring; } 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) return NULL; } - if (newbuffer) - { - memcpy(newbuffer, p->buffer, p->offset + 1); - } + + memcpy(newbuffer, p->buffer, p->offset + 1); p->hooks.deallocate(p->buffer); } p->length = newsize; @@ -905,6 +926,7 @@ static cJSON_AS4CPP_bool parse_string(cJSON * const item, parse_buffer * const i if (output != NULL) { input_buffer->hooks.deallocate(output); + output = NULL; } if (input_pointer != NULL) @@ -1185,7 +1207,6 @@ CJSON_AS4CPP_PUBLIC(cJSON *) cJSON_AS4CPP_ParseWithLengthOpts(const char *value, { *return_parse_end = (const char*)local_error.json + local_error.position; } - /* NOTE: disabled due to thread safety (see note at the top of this file). global_error = local_error; */ @@ -1253,6 +1274,7 @@ static unsigned char *print(const cJSON * const item, cJSON_AS4CPP_bool format, /* free the buffer */ hooks->deallocate(buffer->buffer); + buffer->buffer = NULL; } return printed; @@ -1261,11 +1283,13 @@ static unsigned char *print(const cJSON * const item, cJSON_AS4CPP_bool format, if (buffer->buffer != NULL) { hooks->deallocate(buffer->buffer); + buffer->buffer = NULL; } if (printed != NULL) { hooks->deallocate(printed); + printed = NULL; } return NULL; @@ -1306,6 +1330,7 @@ CJSON_AS4CPP_PUBLIC(char *) cJSON_AS4CPP_PrintBuffered(const cJSON *item, int pr if (!print_value(item, &p)) { global_hooks.deallocate(p.buffer); + p.buffer = NULL; return NULL; } @@ -1677,6 +1702,11 @@ static cJSON_AS4CPP_bool parse_object(cJSON * const item, parse_buffer * const i 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); @@ -2209,7 +2239,7 @@ CJSON_AS4CPP_PUBLIC(cJSON*) cJSON_AS4CPP_AddArrayToObject(cJSON * const object, CJSON_AS4CPP_PUBLIC(cJSON *) cJSON_AS4CPP_DetachItemViaPointer(cJSON *parent, cJSON * const item) { - if ((parent == NULL) || (item == NULL)) + if ((parent == NULL) || (item == NULL) || (item != parent->child && item->prev == NULL)) { return NULL; } @@ -2287,7 +2317,7 @@ CJSON_AS4CPP_PUBLIC(cJSON_AS4CPP_bool) cJSON_AS4CPP_InsertItemInArray(cJSON *arr { cJSON *after_inserted = NULL; - if (which < 0) + if (which < 0 || newitem == NULL) { return false; } @@ -2298,6 +2328,11 @@ CJSON_AS4CPP_PUBLIC(cJSON_AS4CPP_bool) cJSON_AS4CPP_InsertItemInArray(cJSON *arr 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; @@ -2314,7 +2349,7 @@ CJSON_AS4CPP_PUBLIC(cJSON_AS4CPP_bool) cJSON_AS4CPP_InsertItemInArray(cJSON *arr CJSON_AS4CPP_PUBLIC(cJSON_AS4CPP_bool) cJSON_AS4CPP_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; } @@ -2384,6 +2419,11 @@ static cJSON_AS4CPP_bool replace_item_in_object(cJSON *object, const char *strin cJSON_AS4CPP_free(replacement->string); } replacement->string = (char*)cJSON_AS4CPP_strdup((const unsigned char*)string, &global_hooks); + if (replacement->string == NULL) + { + return false; + } + replacement->type &= ~cJSON_AS4CPP_StringIsConst; 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 } a = cJSON_AS4CPP_CreateArray(); + for(i = 0; a && (i < (size_t)count); i++) { n = cJSON_AS4CPP_CreateNumber(numbers[i]); @@ -2626,7 +2667,10 @@ CJSON_AS4CPP_PUBLIC(cJSON *) cJSON_AS4CPP_CreateIntArray(const int *numbers, int } p = n; } - a->child->prev = n; + + if (a && a->child) { + a->child->prev = n; + } return a; } @@ -2663,7 +2707,10 @@ CJSON_AS4CPP_PUBLIC(cJSON *) cJSON_AS4CPP_CreateFloatArray(const float *numbers, } p = n; } - a->child->prev = n; + + if (a && a->child) { + a->child->prev = n; + } return a; } @@ -2682,7 +2729,7 @@ CJSON_AS4CPP_PUBLIC(cJSON *) cJSON_AS4CPP_CreateDoubleArray(const double *number a = cJSON_AS4CPP_CreateArray(); - for(i = 0;a && (i < (size_t)count); i++) + for(i = 0; a && (i < (size_t)count); i++) { n = cJSON_AS4CPP_CreateNumber(numbers[i]); if(!n) @@ -2700,7 +2747,10 @@ CJSON_AS4CPP_PUBLIC(cJSON *) cJSON_AS4CPP_CreateDoubleArray(const double *number } p = n; } - a->child->prev = n; + + if (a && a->child) { + a->child->prev = n; + } return a; } @@ -2737,13 +2787,23 @@ CJSON_AS4CPP_PUBLIC(cJSON *) cJSON_AS4CPP_CreateStringArray(const char *const *s } p = n; } - a->child->prev = n; + + if (a && a->child) { + a->child->prev = n; + } return a; } /* Duplication */ +cJSON * cJSON_AS4CPP_Duplicate_rec(const cJSON *item, size_t depth, cJSON_AS4CPP_bool recurse); + CJSON_AS4CPP_PUBLIC(cJSON *) cJSON_AS4CPP_Duplicate(const cJSON *item, cJSON_AS4CPP_bool recurse) +{ + return cJSON_AS4CPP_Duplicate_rec(item, 0, recurse ); +} + +cJSON * cJSON_AS4CPP_Duplicate_rec(const cJSON *item, size_t depth, cJSON_AS4CPP_bool recurse) { cJSON *newitem = NULL; cJSON *child = NULL; @@ -2790,7 +2850,10 @@ CJSON_AS4CPP_PUBLIC(cJSON *) cJSON_AS4CPP_Duplicate(const cJSON *item, cJSON_AS4 child = item->child; while (child != NULL) { - newchild = cJSON_AS4CPP_Duplicate(child, true); /* Duplicate (with recurse) each item in the ->next chain */ + if(depth >= CJSON_AS4CPP_CIRCULAR_LIMIT) { + goto fail; + } + newchild = cJSON_AS4CPP_Duplicate_rec(child, depth + 1, true); /* Duplicate (with recurse) each item in the ->next chain */ if (!newchild) { goto fail; @@ -3025,7 +3088,7 @@ CJSON_AS4CPP_PUBLIC(cJSON_AS4CPP_bool) cJSON_AS4CPP_IsRaw(const cJSON * const it CJSON_AS4CPP_PUBLIC(cJSON_AS4CPP_bool) cJSON_AS4CPP_Compare(const cJSON * const a, const cJSON * const b, const cJSON_AS4CPP_bool case_sensitive) { - if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF)) || cJSON_AS4CPP_IsInvalid(a)) + if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF))) { return false; } @@ -3156,4 +3219,5 @@ CJSON_AS4CPP_PUBLIC(void *) cJSON_AS4CPP_malloc(size_t size) CJSON_AS4CPP_PUBLIC(void) cJSON_AS4CPP_free(void *object) { global_hooks.deallocate(object); + object = NULL; }