mirror of
https://github.com/red031000/nitrogfx.git
synced 2025-06-18 13:15:35 -04:00
update cJSON to fix CVE-2024-31755
This commit is contained in:
parent
f4e3666719
commit
bd3b638fc7
82
cJSON.c
82
cJSON.c
@ -96,9 +96,9 @@ CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void)
|
|||||||
return (const char*) (global_error.json + global_error.position);
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -106,9 +106,9 @@ CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item)
|
|||||||
return item->valuestring;
|
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;
|
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 */
|
/* 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.
|
#error cJSON.h and cJSON.c have different versions. Make sure that both have the same.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -263,10 +263,12 @@ CJSON_PUBLIC(void) cJSON_Delete(cJSON *item)
|
|||||||
if (!(item->type & cJSON_IsReference) && (item->valuestring != NULL))
|
if (!(item->type & cJSON_IsReference) && (item->valuestring != NULL))
|
||||||
{
|
{
|
||||||
global_hooks.deallocate(item->valuestring);
|
global_hooks.deallocate(item->valuestring);
|
||||||
|
item->valuestring = NULL;
|
||||||
}
|
}
|
||||||
if (!(item->type & cJSON_StringIsConst) && (item->string != NULL))
|
if (!(item->type & cJSON_StringIsConst) && (item->string != NULL))
|
||||||
{
|
{
|
||||||
global_hooks.deallocate(item->string);
|
global_hooks.deallocate(item->string);
|
||||||
|
item->string = NULL;
|
||||||
}
|
}
|
||||||
global_hooks.deallocate(item);
|
global_hooks.deallocate(item);
|
||||||
item = next;
|
item = next;
|
||||||
@ -397,16 +399,33 @@ CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number)
|
|||||||
return object->valuedouble = 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)
|
CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring)
|
||||||
{
|
{
|
||||||
char *copy = NULL;
|
char *copy = NULL;
|
||||||
|
size_t v1_len;
|
||||||
|
size_t v2_len;
|
||||||
/* if object's type is not cJSON_String or is cJSON_IsReference, it should not set valuestring */
|
/* 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 (strlen(valuestring) <= strlen(object->valuestring))
|
/* return NULL if the object is corrupted or valuestring is NULL */
|
||||||
|
if (object->valuestring == NULL || valuestring == NULL)
|
||||||
{
|
{
|
||||||
|
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);
|
strcpy(object->valuestring, valuestring);
|
||||||
return object->valuestring;
|
return object->valuestring;
|
||||||
}
|
}
|
||||||
@ -511,7 +530,7 @@ static unsigned char* ensure(printbuffer * const p, size_t needed)
|
|||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(newbuffer, p->buffer, p->offset + 1);
|
memcpy(newbuffer, p->buffer, p->offset + 1);
|
||||||
p->hooks.deallocate(p->buffer);
|
p->hooks.deallocate(p->buffer);
|
||||||
}
|
}
|
||||||
@ -562,6 +581,10 @@ static cJSON_bool print_number(const cJSON * const item, printbuffer * const out
|
|||||||
{
|
{
|
||||||
length = sprintf((char*)number_buffer, "null");
|
length = sprintf((char*)number_buffer, "null");
|
||||||
}
|
}
|
||||||
|
else if(d == (double)item->valueint)
|
||||||
|
{
|
||||||
|
length = sprintf((char*)number_buffer, "%d", item->valueint);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */
|
/* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */
|
||||||
@ -884,6 +907,7 @@ fail:
|
|||||||
if (output != NULL)
|
if (output != NULL)
|
||||||
{
|
{
|
||||||
input_buffer->hooks.deallocate(output);
|
input_buffer->hooks.deallocate(output);
|
||||||
|
output = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input_pointer != NULL)
|
if (input_pointer != NULL)
|
||||||
@ -1103,7 +1127,7 @@ CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer
|
|||||||
}
|
}
|
||||||
|
|
||||||
buffer.content = (const unsigned char*)value;
|
buffer.content = (const unsigned char*)value;
|
||||||
buffer.length = buffer_length;
|
buffer.length = buffer_length;
|
||||||
buffer.offset = 0;
|
buffer.offset = 0;
|
||||||
buffer.hooks = global_hooks;
|
buffer.hooks = global_hooks;
|
||||||
|
|
||||||
@ -1226,6 +1250,7 @@ static unsigned char *print(const cJSON * const item, cJSON_bool format, const i
|
|||||||
|
|
||||||
/* free the buffer */
|
/* free the buffer */
|
||||||
hooks->deallocate(buffer->buffer);
|
hooks->deallocate(buffer->buffer);
|
||||||
|
buffer->buffer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return printed;
|
return printed;
|
||||||
@ -1234,11 +1259,13 @@ fail:
|
|||||||
if (buffer->buffer != NULL)
|
if (buffer->buffer != NULL)
|
||||||
{
|
{
|
||||||
hooks->deallocate(buffer->buffer);
|
hooks->deallocate(buffer->buffer);
|
||||||
|
buffer->buffer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (printed != NULL)
|
if (printed != NULL)
|
||||||
{
|
{
|
||||||
hooks->deallocate(printed);
|
hooks->deallocate(printed);
|
||||||
|
printed = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1279,6 +1306,7 @@ CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON
|
|||||||
if (!print_value(item, &p))
|
if (!print_value(item, &p))
|
||||||
{
|
{
|
||||||
global_hooks.deallocate(p.buffer);
|
global_hooks.deallocate(p.buffer);
|
||||||
|
p.buffer = NULL;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1650,6 +1678,11 @@ static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_bu
|
|||||||
current_item = new_item;
|
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 */
|
/* parse the name of the child */
|
||||||
input_buffer->offset++;
|
input_buffer->offset++;
|
||||||
buffer_skip_whitespace(input_buffer);
|
buffer_skip_whitespace(input_buffer);
|
||||||
@ -2182,7 +2215,7 @@ CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * c
|
|||||||
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item)
|
CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item)
|
||||||
{
|
{
|
||||||
if ((parent == NULL) || (item == NULL))
|
if ((parent == NULL) || (item == NULL) || (item != parent->child && item->prev == NULL))
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -2260,7 +2293,7 @@ CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON
|
|||||||
{
|
{
|
||||||
cJSON *after_inserted = NULL;
|
cJSON *after_inserted = NULL;
|
||||||
|
|
||||||
if (which < 0)
|
if (which < 0 || newitem == NULL)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -2271,6 +2304,11 @@ CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON
|
|||||||
return add_item_to_array(array, newitem);
|
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->next = after_inserted;
|
||||||
newitem->prev = after_inserted->prev;
|
newitem->prev = after_inserted->prev;
|
||||||
after_inserted->prev = newitem;
|
after_inserted->prev = newitem;
|
||||||
@ -2287,7 +2325,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)
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
@ -2357,6 +2395,11 @@ static cJSON_bool replace_item_in_object(cJSON *object, const char *string, cJSO
|
|||||||
cJSON_free(replacement->string);
|
cJSON_free(replacement->string);
|
||||||
}
|
}
|
||||||
replacement->string = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks);
|
replacement->string = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks);
|
||||||
|
if (replacement->string == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
replacement->type &= ~cJSON_StringIsConst;
|
replacement->type &= ~cJSON_StringIsConst;
|
||||||
|
|
||||||
return cJSON_ReplaceItemViaPointer(object, get_object_item(object, string, case_sensitive), replacement);
|
return cJSON_ReplaceItemViaPointer(object, get_object_item(object, string, case_sensitive), replacement);
|
||||||
@ -2689,12 +2732,19 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int co
|
|||||||
if (a && a->child) {
|
if (a && a->child) {
|
||||||
a->child->prev = n;
|
a->child->prev = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Duplication */
|
/* Duplication */
|
||||||
|
cJSON * cJSON_Duplicate_rec(const cJSON *item, size_t depth, cJSON_bool recurse);
|
||||||
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse)
|
CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse)
|
||||||
|
{
|
||||||
|
return cJSON_Duplicate_rec(item, 0, recurse );
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON * cJSON_Duplicate_rec(const cJSON *item, size_t depth, cJSON_bool recurse)
|
||||||
{
|
{
|
||||||
cJSON *newitem = NULL;
|
cJSON *newitem = NULL;
|
||||||
cJSON *child = NULL;
|
cJSON *child = NULL;
|
||||||
@ -2741,7 +2791,10 @@ CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse)
|
|||||||
child = item->child;
|
child = item->child;
|
||||||
while (child != NULL)
|
while (child != NULL)
|
||||||
{
|
{
|
||||||
newchild = cJSON_Duplicate(child, true); /* Duplicate (with recurse) each item in the ->next chain */
|
if(depth >= CJSON_CIRCULAR_LIMIT) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
newchild = cJSON_Duplicate_rec(child, depth + 1, true); /* Duplicate (with recurse) each item in the ->next chain */
|
||||||
if (!newchild)
|
if (!newchild)
|
||||||
{
|
{
|
||||||
goto fail;
|
goto fail;
|
||||||
@ -3107,4 +3160,5 @@ CJSON_PUBLIC(void *) cJSON_malloc(size_t size)
|
|||||||
CJSON_PUBLIC(void) cJSON_free(void *object)
|
CJSON_PUBLIC(void) cJSON_free(void *object)
|
||||||
{
|
{
|
||||||
global_hooks.deallocate(object);
|
global_hooks.deallocate(object);
|
||||||
|
object = NULL;
|
||||||
}
|
}
|
||||||
|
15
cJSON.h
15
cJSON.h
@ -81,7 +81,7 @@ then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJ
|
|||||||
/* project version */
|
/* project version */
|
||||||
#define CJSON_VERSION_MAJOR 1
|
#define CJSON_VERSION_MAJOR 1
|
||||||
#define CJSON_VERSION_MINOR 7
|
#define CJSON_VERSION_MINOR 7
|
||||||
#define CJSON_VERSION_PATCH 15
|
#define CJSON_VERSION_PATCH 18
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
@ -137,6 +137,12 @@ typedef int cJSON_bool;
|
|||||||
#define CJSON_NESTING_LIMIT 1000
|
#define CJSON_NESTING_LIMIT 1000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Limits the length of circular references can be before cJSON rejects to parse them.
|
||||||
|
* This is to prevent stack overflows. */
|
||||||
|
#ifndef CJSON_CIRCULAR_LIMIT
|
||||||
|
#define CJSON_CIRCULAR_LIMIT 10000
|
||||||
|
#endif
|
||||||
|
|
||||||
/* returns the version of cJSON as a string */
|
/* returns the version of cJSON as a string */
|
||||||
CJSON_PUBLIC(const char*) cJSON_Version(void);
|
CJSON_PUBLIC(const char*) cJSON_Version(void);
|
||||||
|
|
||||||
@ -279,6 +285,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 */
|
/* 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);
|
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 */
|
/* 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)
|
#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user