summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOle Troan <otroan@employees.org>2024-05-06 11:34:17 +0200
committerDamjan Marion <dmarion@0xa5.net>2024-05-07 09:59:00 +0000
commit4013851e42b94ebfa0a2ae398c58ecc9ea9b5c95 (patch)
treecb0c0a989770d4f37d3a6175152f5b297016797b
parentee98c9dd8ed82334f0082778e56ef3a120db70e2 (diff)
api: upgrade cjson and fix realloc
Upgrade cJSON library to patchlevel 17. Replace internal realloc added earlier 36217e3ca. Type: fix Fixes: 36217e3ca Change-Id: I7d8a80dc4241e9f952895d24adca8fa2d873e746 Signed-off-by: Ole Troan <otroan@employees.org>
-rwxr-xr-xsrc/tools/vppapigen/vppapigen_c.py8
-rw-r--r--src/vlibmemory/memclnt_api.c1
-rw-r--r--src/vppinfra/cJSON.c185
-rw-r--r--src/vppinfra/cJSON.h23
4 files changed, 125 insertions, 92 deletions
diff --git a/src/tools/vppapigen/vppapigen_c.py b/src/tools/vppapigen/vppapigen_c.py
index fb7de0a023f..b55066db366 100755
--- a/src/tools/vppapigen/vppapigen_c.py
+++ b/src/tools/vppapigen/vppapigen_c.py
@@ -365,7 +365,7 @@ class FromJSON:
write(" char *p = cJSON_GetStringValue(item);\n")
write(" size_t plen = strlen(p);\n")
write(
- " {msgvar} = cJSON_realloc({msgvar}, {msgsize} + plen, {msgsize});\n".format(
+ " {msgvar} = cJSON_realloc({msgvar}, {msgsize} + plen);\n".format(
msgvar=msgvar, msgsize=msgsize
)
)
@@ -434,7 +434,7 @@ class FromJSON:
cJSON *array = cJSON_GetObjectItem(o, "{n}");
int size = cJSON_GetArraySize(array);
{lfield} = size;
- {realloc} = cJSON_realloc({realloc}, {msgsize} + sizeof({t}) * size, {msgsize});
+ {realloc} = cJSON_realloc({realloc}, {msgsize} + sizeof({t}) * size);
{t} *d = (void *){realloc} + {msgsize};
{msgsize} += sizeof({t}) * size;
for (i = 0; i < size; i++) {{
@@ -461,12 +461,12 @@ class FromJSON:
write(
" {realloc} = cJSON_realloc({realloc}, {msgsize} + "
- "vec_len(s), {msgsize});\n".format(
+ "vec_len(s));\n".format(
msgvar=msgvar, msgsize=msgsize, realloc=realloc
)
)
write(
- " memcpy((void *){realloc} + {msgsize}, s, "
+ " clib_memcpy((void *){realloc} + {msgsize}, s, "
"vec_len(s));\n".format(realloc=realloc, msgsize=msgsize)
)
write(" {msgsize} += vec_len(s);\n".format(msgsize=msgsize))
diff --git a/src/vlibmemory/memclnt_api.c b/src/vlibmemory/memclnt_api.c
index d4106b10559..b0b0c72eae0 100644
--- a/src/vlibmemory/memclnt_api.c
+++ b/src/vlibmemory/memclnt_api.c
@@ -197,6 +197,7 @@ vlib_api_init (void)
cJSON_Hooks cjson_hooks = {
.malloc_fn = clib_mem_alloc,
.free_fn = clib_mem_free,
+ .realloc_fn = clib_mem_realloc,
};
cJSON_InitHooks (&cjson_hooks);
diff --git a/src/vppinfra/cJSON.c b/src/vppinfra/cJSON.c
index 448435de4dc..24e0110ed08 100644
--- a/src/vppinfra/cJSON.c
+++ b/src/vppinfra/cJSON.c
@@ -20,6 +20,7 @@
THE SOFTWARE.
*/
/* clang-format off */
+
/* cJSON */
/* JSON parser in C. */
@@ -96,9 +97,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 +107,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,8 +118,9 @@ 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 != 14)
- #error cJSON.h and cJSON.c have different versions. Make sure that both have the same.
+#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || \
+ (CJSON_VERSION_PATCH != 17)
+#error cJSON.h and cJSON.c have different versions. Make sure that both have the same.
#endif
CJSON_PUBLIC(const char*) cJSON_Version(void)
@@ -157,7 +159,7 @@ typedef struct internal_hooks
{
void *(CJSON_CDECL *allocate)(size_t size);
void (CJSON_CDECL *deallocate)(void *pointer);
- void *(CJSON_CDECL *reallocate)(void *pointer, size_t new_size, size_t old_size);
+ void *(CJSON_CDECL *reallocate) (void *pointer, size_t size);
} internal_hooks;
#if defined(_MSC_VER)
@@ -170,20 +172,17 @@ static void CJSON_CDECL internal_free(void *pointer)
{
free(pointer);
}
+static void *CJSON_CDECL
+internal_realloc (void *pointer, size_t size)
+{
+ return realloc (pointer, size);
+}
#else
#define internal_malloc malloc
#define internal_free free
+#define internal_realloc realloc
#endif
-static void * CJSON_CDECL internal_realloc(void *pointer, size_t new_size,
- size_t old_size)
-{
- return realloc(pointer, new_size);
-}
-
-static void *
-cjson_realloc_internal (void *ptr, size_t new_size, size_t old_size);
-
/* strlen of character literals resolved at compile time */
#define static_strlen(string_literal) (sizeof(string_literal) - sizeof(""))
@@ -217,8 +216,8 @@ CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks)
/* Reset hooks */
global_hooks.allocate = malloc;
global_hooks.deallocate = free;
- global_hooks.reallocate = internal_realloc;
- return;
+ global_hooks.reallocate = realloc;
+ return;
}
global_hooks.allocate = malloc;
@@ -233,16 +232,11 @@ CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks)
global_hooks.deallocate = hooks->free_fn;
}
- /* use realloc only if both free and malloc are used */
- global_hooks.reallocate = NULL;
- if ((global_hooks.allocate == malloc) && (global_hooks.deallocate == free))
- {
- global_hooks.reallocate = internal_realloc;
- }
- else
- {
- global_hooks.reallocate = cjson_realloc_internal;
- }
+ global_hooks.reallocate = realloc;
+ if (hooks->realloc_fn != NULL)
+ {
+ global_hooks.reallocate = hooks->realloc_fn;
+ }
}
/* Internal constructor. */
@@ -405,14 +399,22 @@ 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))
- {
- return NULL;
- }
+ 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;
+ }
if (strlen(valuestring) <= strlen(object->valuestring))
{
strcpy(object->valuestring, valuestring);
@@ -443,27 +445,6 @@ typedef struct
internal_hooks hooks;
} printbuffer;
-static void *
-cjson_realloc_internal (void *ptr, size_t new_size, size_t old_size)
-{
- size_t copy_size;
- if (old_size < new_size)
- copy_size = old_size;
- else
- copy_size = new_size;
-
- unsigned char *newbuffer = global_hooks.allocate(new_size);
- if (!newbuffer)
- {
- global_hooks.deallocate(ptr);
- return NULL;
- }
-
- memcpy (newbuffer, ptr, copy_size);
- global_hooks.deallocate (ptr);
- return newbuffer;
-}
-
/* realloc printbuffer if necessary to have at least "needed" bytes more */
static unsigned char* ensure(printbuffer * const p, size_t needed)
{
@@ -515,14 +496,35 @@ static unsigned char* ensure(printbuffer * const p, size_t needed)
newsize = needed * 2;
}
- newbuffer = p->hooks.reallocate (p->buffer, newsize, p->length);
- if (newbuffer == NULL)
- {
- p->hooks.deallocate(p->buffer);
- p->length = 0;
- p->buffer = NULL;
- return NULL;
- }
+ if (p->hooks.reallocate != NULL)
+ {
+ /* reallocate with realloc if available */
+ newbuffer = (unsigned char *) p->hooks.reallocate (p->buffer, newsize);
+ if (newbuffer == NULL)
+ {
+ p->hooks.deallocate (p->buffer);
+ p->length = 0;
+ p->buffer = NULL;
+
+ return NULL;
+ }
+ }
+ else
+ {
+ /* otherwise reallocate manually */
+ newbuffer = (unsigned char *) p->hooks.allocate (newsize);
+ if (!newbuffer)
+ {
+ p->hooks.deallocate (p->buffer);
+ p->length = 0;
+ p->buffer = NULL;
+
+ return NULL;
+ }
+
+ memcpy (newbuffer, p->buffer, p->offset + 1);
+ p->hooks.deallocate (p->buffer);
+ }
p->length = newsize;
p->buffer = newbuffer;
@@ -570,6 +572,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 */
@@ -1111,7 +1117,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;
@@ -1216,11 +1222,13 @@ static unsigned char *print(const cJSON * const item, cJSON_bool format, const i
/* check if reallocate is available */
if (hooks->reallocate != NULL)
{
- printed = (unsigned char*) hooks->reallocate(buffer->buffer, buffer->offset + 1, default_buffer_size);
- if (printed == NULL) {
- goto fail;
- }
- buffer->buffer = NULL;
+ printed = (unsigned char *) hooks->reallocate (buffer->buffer,
+ buffer->offset + 1);
+ if (printed == NULL)
+ {
+ goto fail;
+ }
+ buffer->buffer = NULL;
}
else /* otherwise copy the JSON over to a new buffer */
{
@@ -1658,8 +1666,13 @@ static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_bu
current_item = new_item;
}
- /* parse the name of the child */
- input_buffer->offset++;
+ 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);
if (!parse_string(current_item, input_buffer))
{
@@ -2268,10 +2281,10 @@ CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON
{
cJSON *after_inserted = NULL;
- if (which < 0)
- {
- return false;
- }
+ if (which < 0 || newitem == NULL)
+ {
+ return false;
+ }
after_inserted = get_array_item(array, (size_t)which);
if (after_inserted == NULL)
@@ -2279,6 +2292,12 @@ 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;
@@ -2295,7 +2314,8 @@ 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;
}
@@ -2365,6 +2385,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);
@@ -2639,9 +2664,9 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count)
for (i = 0; a && (i < (size_t) count); i++)
{
- n = cJSON_CreateNumber(numbers[i]);
- if(!n)
- {
+ n = cJSON_CreateNumber (numbers[i]);
+ if (!n)
+ {
cJSON_Delete(a);
return NULL;
}
@@ -2988,7 +3013,7 @@ CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item)
CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive)
{
- if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF)) || cJSON_IsInvalid(a))
+ if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF)))
{
return false;
}
@@ -3121,7 +3146,7 @@ CJSON_PUBLIC(void) cJSON_free(void *object)
global_hooks.deallocate(object);
}
-CJSON_PUBLIC(void *) cJSON_realloc(void *object, size_t new_size, size_t old_size)
+CJSON_PUBLIC (void *) cJSON_realloc (void *object, size_t size)
{
- return global_hooks.reallocate(object, new_size, old_size);
+ return global_hooks.reallocate (object, size);
}
diff --git a/src/vppinfra/cJSON.h b/src/vppinfra/cJSON.h
index 1474c4e5c49..1c98dfac70e 100644
--- a/src/vppinfra/cJSON.h
+++ b/src/vppinfra/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 14
+#define CJSON_VERSION_PATCH 17
#include <stddef.h>
@@ -127,8 +127,7 @@ typedef struct cJSON_Hooks
/* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */
void *(CJSON_CDECL *malloc_fn)(size_t sz);
void (CJSON_CDECL *free_fn)(void *ptr);
- void *(CJSON_CDECL *realloc_fn) (void *ptr, size_t new_size,
- size_t old_size);
+ void *(CJSON_CDECL *realloc_fn) (void *ptr, size_t sz);
} cJSON_Hooks;
typedef int cJSON_bool;
@@ -256,9 +255,10 @@ CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
* case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */
CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);
-/* Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n') from strings.
- * The input pointer json cannot point to a read-only address area, such as a string constant,
- * but should point to a readable and writable adress area. */
+/* Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n')
+ * from strings. The input pointer json cannot point to a read-only address
+ * area, such as a string constant,
+ * but should point to a readable and writable address area. */
CJSON_PUBLIC(void) cJSON_Minify(char *json);
/* Helper functions for creating and adding items to an object at the same time.
@@ -281,14 +281,21 @@ 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)
/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */
CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
CJSON_PUBLIC(void) cJSON_free(void *object);
-CJSON_PUBLIC (void *)
-cJSON_realloc (void *object, size_t new_size, size_t old_size);
+CJSON_PUBLIC (void *) cJSON_realloc (void *object, size_t size);
#ifdef __cplusplus
}