From fe1840393531e8a5fa4d6118b5257ded05d15e68 Mon Sep 17 00:00:00 2001 From: Max Bruckner Date: Fri, 3 Feb 2017 12:13:17 +0100 Subject: [PATCH 1/6] Compiler flag -Wundef + fix incorrect macro --- CMakeLists.txt | 2 +- Makefile | 2 +- cJSON.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2fffabf..706e5e2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,7 +15,7 @@ set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT option(ENABLE_CUSTOM_COMPILER_FLAGS "Enables custom compiler flags for Clang and GCC" ON) if (ENABLE_CUSTOM_COMPILER_FLAGS) if(("${CMAKE_C_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_C_COMPILER_ID}" MATCHES "Clang")) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c89 -pedantic -Wall -Wextra -Werror -Wstrict-prototypes -Wwrite-strings -Wshadow -Winit-self -Wcast-align -Wformat=2 -Wmissing-prototypes -Wstrict-overflow=2 -Wcast-qual -Wc++-compat") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c89 -pedantic -Wall -Wextra -Werror -Wstrict-prototypes -Wwrite-strings -Wshadow -Winit-self -Wcast-align -Wformat=2 -Wmissing-prototypes -Wstrict-overflow=2 -Wcast-qual -Wc++-compat -Wundef") endif() endif() diff --git a/Makefile b/Makefile index 532cd99..b8a8e08 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,7 @@ INSTALL_LIBRARY_PATH = $(DESTDIR)$(PREFIX)/$(LIBRARY_PATH) INSTALL ?= cp -a -R_CFLAGS = -fPIC -std=c89 -pedantic -Wall -Werror -Wstrict-prototypes -Wwrite-strings -Wshadow -Winit-self -Wcast-align -Wformat=2 -Wmissing-prototypes -Wstrict-overflow=2 -Wcast-qual -Wc++-compat $(CFLAGS) +R_CFLAGS = -fPIC -std=c89 -pedantic -Wall -Werror -Wstrict-prototypes -Wwrite-strings -Wshadow -Winit-self -Wcast-align -Wformat=2 -Wmissing-prototypes -Wstrict-overflow=2 -Wcast-qual -Wc++-compat -Wundef $(CFLAGS) uname := $(shell sh -c 'uname -s 2>/dev/null || echo false') diff --git a/cJSON.c b/cJSON.c index 80c0973..12e78cf 100644 --- a/cJSON.c +++ b/cJSON.c @@ -245,7 +245,7 @@ static int pow2gt (int x) #if INTEGER_SIZE & 0x1100 /* at least 32 bit */ x |= x >> 16; #endif -#if INT_SIZE & 0x1000 /* 64 bit */ +#if INTEGER_SIZE & 0x1000 /* 64 bit */ x |= x >> 32; #endif From b182ced1d676d20899893a792391e8ababf66468 Mon Sep 17 00:00:00 2001 From: Max Bruckner Date: Fri, 3 Feb 2017 12:21:36 +0100 Subject: [PATCH 2/6] Compiler flag -Wswitch-default + add defaults --- CMakeLists.txt | 2 +- Makefile | 2 +- cJSON.c | 9 +++++++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 706e5e2..0261d88 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,7 +15,7 @@ set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT option(ENABLE_CUSTOM_COMPILER_FLAGS "Enables custom compiler flags for Clang and GCC" ON) if (ENABLE_CUSTOM_COMPILER_FLAGS) if(("${CMAKE_C_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_C_COMPILER_ID}" MATCHES "Clang")) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c89 -pedantic -Wall -Wextra -Werror -Wstrict-prototypes -Wwrite-strings -Wshadow -Winit-self -Wcast-align -Wformat=2 -Wmissing-prototypes -Wstrict-overflow=2 -Wcast-qual -Wc++-compat -Wundef") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c89 -pedantic -Wall -Wextra -Werror -Wstrict-prototypes -Wwrite-strings -Wshadow -Winit-self -Wcast-align -Wformat=2 -Wmissing-prototypes -Wstrict-overflow=2 -Wcast-qual -Wc++-compat -Wundef -Wswitch-default") endif() endif() diff --git a/Makefile b/Makefile index b8a8e08..33be51a 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,7 @@ INSTALL_LIBRARY_PATH = $(DESTDIR)$(PREFIX)/$(LIBRARY_PATH) INSTALL ?= cp -a -R_CFLAGS = -fPIC -std=c89 -pedantic -Wall -Werror -Wstrict-prototypes -Wwrite-strings -Wshadow -Winit-self -Wcast-align -Wformat=2 -Wmissing-prototypes -Wstrict-overflow=2 -Wcast-qual -Wc++-compat -Wundef $(CFLAGS) +R_CFLAGS = -fPIC -std=c89 -pedantic -Wall -Werror -Wstrict-prototypes -Wwrite-strings -Wshadow -Winit-self -Wcast-align -Wformat=2 -Wmissing-prototypes -Wstrict-overflow=2 -Wcast-qual -Wc++-compat -Wundef -Wswitch-default $(CFLAGS) uname := $(shell sh -c 'uname -s 2>/dev/null || echo false') diff --git a/cJSON.c b/cJSON.c index 12e78cf..3025dfd 100644 --- a/cJSON.c +++ b/cJSON.c @@ -645,6 +645,9 @@ static const char *parse_string(cJSON *item, const char *str, const char **ep) /* depending on the length in bytes this determines the * encoding ofthe first UTF8 byte */ *--ptr2 = (uc | firstByteMark[len]); + default: + *ep = str; + return NULL; } ptr2 += len; break; @@ -1032,6 +1035,9 @@ static char *print_value(const cJSON *item, int depth, cjbool fmt, printbuffer * case cJSON_Object: out = print_object(item, depth, fmt, p); break; + default: + out = NULL; + break; } } else @@ -1062,6 +1068,9 @@ static char *print_value(const cJSON *item, int depth, cjbool fmt, printbuffer * case cJSON_Object: out = print_object(item, depth, fmt, 0); break; + default: + out = NULL; + break; } } From 28b9ba4334e0f7309e867e874a31f395c0ac2474 Mon Sep 17 00:00:00 2001 From: Max Bruckner Date: Fri, 3 Feb 2017 15:59:00 +0100 Subject: [PATCH 3/6] Change all internal strings to unsigned char* --- cJSON.c | 246 +++++++++++++++++++++++++------------------------- cJSON_Utils.c | 128 +++++++++++++------------- 2 files changed, 187 insertions(+), 187 deletions(-) diff --git a/cJSON.c b/cJSON.c index 3025dfd..0244009 100644 --- a/cJSON.c +++ b/cJSON.c @@ -51,11 +51,11 @@ typedef int cjbool; #define true ((cjbool)1) #define false ((cjbool)0) -static const char *global_ep = NULL; +static const unsigned char *global_ep = NULL; const char *cJSON_GetErrorPtr(void) { - return global_ep; + return (const char*) global_ep; } extern const char* cJSON_Version(void) @@ -67,7 +67,7 @@ extern const char* cJSON_Version(void) } /* case insensitive strcmp */ -static int cJSON_strcasecmp(const char *s1, const char *s2) +static int cJSON_strcasecmp(const unsigned char *s1, const unsigned char *s2) { if (!s1) { @@ -77,7 +77,7 @@ static int cJSON_strcasecmp(const char *s1, const char *s2) { return 1; } - for(; tolower(*(const unsigned char *)s1) == tolower(*(const unsigned char *)s2); ++s1, ++s2) + for(; tolower(*s1) == tolower(*s2); ++s1, ++s2) { if (*s1 == '\0') { @@ -85,24 +85,24 @@ static int cJSON_strcasecmp(const char *s1, const char *s2) } } - return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2); + return tolower(*s1) - tolower(*s2); } static void *(*cJSON_malloc)(size_t sz) = malloc; static void (*cJSON_free)(void *ptr) = free; -static char* cJSON_strdup(const char* str) +static unsigned char* cJSON_strdup(const unsigned char* str) { size_t len = 0; - char *copy = NULL; + unsigned char *copy = NULL; if (str == NULL) { return NULL; } - len = strlen(str) + 1; - if (!(copy = (char*)cJSON_malloc(len))) + len = strlen((const char*)str) + 1; + if (!(copy = (unsigned char*)cJSON_malloc(len))) { return NULL; } @@ -162,7 +162,7 @@ void cJSON_Delete(cJSON *c) } /* Parse the input text to generate a number, and populate the result into item. */ -static const char *parse_number(cJSON *item, const char *num) +static const unsigned char *parse_number(cJSON *item, const unsigned char *num) { double n = 0; double sign = 1; @@ -254,16 +254,16 @@ static int pow2gt (int x) typedef struct { - char *buffer; + unsigned char *buffer; int length; int offset; cjbool noalloc; } printbuffer; /* realloc printbuffer if necessary to have at least "needed" bytes more */ -static char* ensure(printbuffer *p, int needed) +static unsigned char* ensure(printbuffer *p, int needed) { - char *newbuffer = NULL; + unsigned char *newbuffer = NULL; int newsize = 0; if (!p || !p->buffer) { @@ -280,7 +280,7 @@ static char* ensure(printbuffer *p, int needed) } newsize = pow2gt(needed); - newbuffer = (char*)cJSON_malloc(newsize); + newbuffer = (unsigned char*)cJSON_malloc(newsize); if (!newbuffer) { cJSON_free(p->buffer); @@ -303,20 +303,20 @@ static char* ensure(printbuffer *p, int needed) /* calculate the new length of the string in a printbuffer */ static int update(const printbuffer *p) { - char *str = NULL; + unsigned char *str = NULL; if (!p || !p->buffer) { return 0; } str = p->buffer + p->offset; - return p->offset + strlen(str); + return p->offset + strlen((char*)str); } /* Render the number nicely from the given item into a string. */ -static char *print_number(const cJSON *item, printbuffer *p) +static unsigned char *print_number(const cJSON *item, printbuffer *p) { - char *str = NULL; + unsigned char *str = NULL; double d = item->valuedouble; /* special case for 0. */ if (d == 0) @@ -327,11 +327,11 @@ static char *print_number(const cJSON *item, printbuffer *p) } else { - str = (char*)cJSON_malloc(2); + str = (unsigned char*)cJSON_malloc(2); } if (str) { - strcpy(str,"0"); + strcpy((char*)str,"0"); } } /* value is an int */ @@ -344,11 +344,11 @@ static char *print_number(const cJSON *item, printbuffer *p) else { /* 2^64+1 can be represented in 21 chars. */ - str = (char*)cJSON_malloc(21); + str = (unsigned char*)cJSON_malloc(21); } if (str) { - sprintf(str, "%d", item->valueint); + sprintf((char*)str, "%d", item->valueint); } } /* value is a floating point number */ @@ -362,26 +362,26 @@ static char *print_number(const cJSON *item, printbuffer *p) else { /* This is a nice tradeoff. */ - str=(char*)cJSON_malloc(64); + str = (unsigned char*)cJSON_malloc(64); } if (str) { /* This checks for NaN and Infinity */ if ((d * 0) != 0) { - sprintf(str, "null"); + sprintf((char*)str, "null"); } else if ((fabs(floor(d) - d) <= DBL_EPSILON) && (fabs(d) < 1.0e60)) { - sprintf(str, "%.0f", d); + sprintf((char*)str, "%.0f", d); } else if ((fabs(d) < 1.0e-6) || (fabs(d) > 1.0e9)) { - sprintf(str, "%e", d); + sprintf((char*)str, "%e", d); } else { - sprintf(str, "%f", d); + sprintf((char*)str, "%f", d); } } } @@ -389,7 +389,7 @@ static char *print_number(const cJSON *item, printbuffer *p) } /* parse 4 digit hexadecimal number */ -static unsigned parse_hex4(const char *str) +static unsigned parse_hex4(const unsigned char *str) { unsigned h = 0; /* first digit */ @@ -487,12 +487,12 @@ static const unsigned char firstByteMark[7] = }; /* Parse the input text into an unescaped cstring, and populate item. */ -static const char *parse_string(cJSON *item, const char *str, const char **ep) +static const unsigned char *parse_string(cJSON *item, const unsigned char *str, const unsigned char **ep) { - const char *ptr = str + 1; - const char *end_ptr =str + 1; - char *ptr2 = NULL; - char *out = NULL; + const unsigned char *ptr = str + 1; + const unsigned char *end_ptr =str + 1; + unsigned char *ptr2 = NULL; + unsigned char *out = NULL; int len = 0; unsigned uc = 0; unsigned uc2 = 0; @@ -520,12 +520,12 @@ static const char *parse_string(cJSON *item, const char *str, const char **ep) } /* This is at most how long we need for the string, roughly. */ - out = (char*)cJSON_malloc(len + 1); + out = (unsigned char*)cJSON_malloc(len + 1); if (!out) { return NULL; } - item->valuestring = out; /* assign here so out will be deleted during cJSON_Delete() later */ + item->valuestring = (char*)out; /* assign here so out will be deleted during cJSON_Delete() later */ item->type = cJSON_String; ptr = str + 1; @@ -668,11 +668,11 @@ static const char *parse_string(cJSON *item, const char *str, const char **ep) } /* Render the cstring provided to an escaped version that can be printed. */ -static char *print_string_ptr(const char *str, printbuffer *p) +static unsigned char *print_string_ptr(const unsigned char *str, printbuffer *p) { - const char *ptr = NULL; - char *ptr2 = NULL; - char *out = NULL; + const unsigned char *ptr = NULL; + unsigned char *ptr2 = NULL; + unsigned char *out = NULL; int len = 0; cjbool flag = false; unsigned char token = '\0'; @@ -686,13 +686,13 @@ static char *print_string_ptr(const char *str, printbuffer *p) } else { - out = (char*)cJSON_malloc(3); + out = (unsigned char*)cJSON_malloc(3); } if (!out) { return NULL; } - strcpy(out, "\"\""); + strcpy((char*)out, "\"\""); return out; } @@ -716,7 +716,7 @@ static char *print_string_ptr(const char *str, printbuffer *p) } else { - out = (char*)cJSON_malloc(len + 3); + out = (unsigned char*)cJSON_malloc(len + 3); } if (!out) { @@ -725,7 +725,7 @@ static char *print_string_ptr(const char *str, printbuffer *p) ptr2 = out; *ptr2++ = '\"'; - strcpy(ptr2, str); + strcpy((char*)ptr2, (const char*)str); ptr2[len] = '\"'; ptr2[len + 1] = '\0'; @@ -754,7 +754,7 @@ static char *print_string_ptr(const char *str, printbuffer *p) } else { - out = (char*)cJSON_malloc(len + 3); + out = (unsigned char*)cJSON_malloc(len + 3); } if (!out) { @@ -767,7 +767,7 @@ static char *print_string_ptr(const char *str, printbuffer *p) /* copy the string */ while (*ptr) { - if (((unsigned char)*ptr > 31) && (*ptr != '\"') && (*ptr != '\\')) + if ((*ptr > 31) && (*ptr != '\"') && (*ptr != '\\')) { /* normal character, copy */ *ptr2++ = *ptr++; @@ -801,7 +801,7 @@ static char *print_string_ptr(const char *str, printbuffer *p) break; default: /* escape and print as unicode codepoint */ - sprintf(ptr2, "u%04x", token); + sprintf((char*)ptr2, "u%04x", token); ptr2 += 5; break; } @@ -814,23 +814,23 @@ static char *print_string_ptr(const char *str, printbuffer *p) } /* Invoke print_string_ptr (which is useful) on an item. */ -static char *print_string(const cJSON *item, printbuffer *p) +static unsigned char *print_string(const cJSON *item, printbuffer *p) { - return print_string_ptr(item->valuestring, p); + return print_string_ptr((unsigned char*)item->valuestring, p); } /* Predeclare these prototypes. */ -static const char *parse_value(cJSON *item, const char *value, const char **ep); -static char *print_value(const cJSON *item, int depth, cjbool fmt, printbuffer *p); -static const char *parse_array(cJSON *item, const char *value, const char **ep); -static char *print_array(const cJSON *item, int depth, cjbool fmt, printbuffer *p); -static const char *parse_object(cJSON *item, const char *value, const char **ep); -static char *print_object(const cJSON *item, int depth, cjbool fmt, printbuffer *p); +static const unsigned char *parse_value(cJSON *item, const unsigned char *value, const unsigned char **ep); +static unsigned char *print_value(const cJSON *item, int depth, cjbool fmt, printbuffer *p); +static const unsigned char *parse_array(cJSON *item, const unsigned char *value, const unsigned char **ep); +static unsigned char *print_array(const cJSON *item, int depth, cjbool fmt, printbuffer *p); +static const unsigned char *parse_object(cJSON *item, const unsigned char *value, const unsigned char **ep); +static unsigned char *print_object(const cJSON *item, int depth, cjbool fmt, printbuffer *p); /* Utility to jump whitespace and cr/lf */ -static const char *skip(const char *in) +static const unsigned char *skip(const unsigned char *in) { - while (in && *in && ((unsigned char)*in<=32)) + while (in && *in && (*in <= 32)) { in++; } @@ -841,9 +841,9 @@ static const char *skip(const char *in) /* Parse an object - create a new root, and populate. */ cJSON *cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cjbool require_null_terminated) { - const char *end = NULL; + const unsigned char *end = NULL; /* use global error pointer if no specific one was given */ - const char **ep = return_parse_end ? return_parse_end : &global_ep; + const unsigned char **ep = return_parse_end ? (const unsigned char**)return_parse_end : &global_ep; cJSON *c = cJSON_New_Item(); *ep = NULL; if (!c) /* memory fail */ @@ -851,7 +851,7 @@ cJSON *cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cjb return NULL; } - end = parse_value(c, skip(value), ep); + end = parse_value(c, skip((const unsigned char*)value), ep); if (!end) { /* parse failure. ep is set. */ @@ -872,7 +872,7 @@ cJSON *cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cjb } if (return_parse_end) { - *return_parse_end = end; + *return_parse_end = (const char*)end; } return c; @@ -887,18 +887,18 @@ cJSON *cJSON_Parse(const char *value) /* Render a cJSON item/entity/structure to text. */ char *cJSON_Print(const cJSON *item) { - return print_value(item, 0, 1, 0); + return (char*)print_value(item, 0, 1, 0); } char *cJSON_PrintUnformatted(const cJSON *item) { - return print_value(item, 0, 0, 0); + return (char*)print_value(item, 0, 0, 0); } char *cJSON_PrintBuffered(const cJSON *item, int prebuffer, cjbool fmt) { printbuffer p; - p.buffer = (char*)cJSON_malloc(prebuffer); + p.buffer = (unsigned char*)cJSON_malloc(prebuffer); if (!p.buffer) { return NULL; @@ -907,13 +907,13 @@ char *cJSON_PrintBuffered(const cJSON *item, int prebuffer, cjbool fmt) p.offset = 0; p.noalloc = false; - return print_value(item, 0, fmt, &p); + return (char*)print_value(item, 0, fmt, &p); } -int cJSON_PrintPreallocated(cJSON *item,char *buf, const int len, const cjbool fmt) +int cJSON_PrintPreallocated(cJSON *item, char *buf, const int len, const cjbool fmt) { printbuffer p; - p.buffer = buf; + p.buffer = (unsigned char*)buf; p.length = len; p.offset = 0; p.noalloc = true; @@ -921,7 +921,7 @@ int cJSON_PrintPreallocated(cJSON *item,char *buf, const int len, const cjbool f } /* Parser core - when encountering text, process appropriately. */ -static const char *parse_value(cJSON *item, const char *value, const char **ep) +static const unsigned char *parse_value(cJSON *item, const unsigned char *value, const unsigned char **ep) { if (!value) { @@ -930,17 +930,17 @@ static const char *parse_value(cJSON *item, const char *value, const char **ep) } /* parse the different types of values */ - if (!strncmp(value, "null", 4)) + if (!strncmp((const char*)value, "null", 4)) { item->type = cJSON_NULL; return value + 4; } - if (!strncmp(value, "false", 5)) + if (!strncmp((const char*)value, "false", 5)) { item->type = cJSON_False; return value + 5; } - if (!strncmp(value, "true", 4)) + if (!strncmp((const char*)value, "true", 4)) { item->type = cJSON_True; item->valueint = 1; @@ -969,9 +969,9 @@ static const char *parse_value(cJSON *item, const char *value, const char **ep) } /* Render a value to text. */ -static char *print_value(const cJSON *item, int depth, cjbool fmt, printbuffer *p) +static unsigned char *print_value(const cJSON *item, int depth, cjbool fmt, printbuffer *p) { - char *out = NULL; + unsigned char *out = NULL; if (!item) { @@ -985,21 +985,21 @@ static char *print_value(const cJSON *item, int depth, cjbool fmt, printbuffer * out = ensure(p, 5); if (out) { - strcpy(out, "null"); + strcpy((char*)out, "null"); } break; case cJSON_False: out = ensure(p, 6); if (out) { - strcpy(out, "false"); + strcpy((char*)out, "false"); } break; case cJSON_True: out = ensure(p, 5); if (out) { - strcpy(out, "true"); + strcpy((char*)out, "true"); } break; case cJSON_Number: @@ -1045,19 +1045,19 @@ static char *print_value(const cJSON *item, int depth, cjbool fmt, printbuffer * switch ((item->type) & 0xFF) { case cJSON_NULL: - out = cJSON_strdup("null"); + out = cJSON_strdup((const unsigned char*)"null"); break; case cJSON_False: - out = cJSON_strdup("false"); + out = cJSON_strdup((const unsigned char*)"false"); break; case cJSON_True: - out = cJSON_strdup("true"); + out = cJSON_strdup((const unsigned char*)"true"); break; case cJSON_Number: out = print_number(item, 0); break; case cJSON_Raw: - out = cJSON_strdup(item->valuestring); + out = cJSON_strdup((unsigned char*)item->valuestring); break; case cJSON_String: out = print_string(item, 0); @@ -1078,7 +1078,7 @@ static char *print_value(const cJSON *item, int depth, cjbool fmt, printbuffer * } /* Build an array from input text. */ -static const char *parse_array(cJSON *item,const char *value,const char **ep) +static const unsigned char *parse_array(cJSON *item, const unsigned char *value, const unsigned char **ep) { cJSON *child = NULL; if (*value != '[') @@ -1145,12 +1145,12 @@ static const char *parse_array(cJSON *item,const char *value,const char **ep) } /* Render an array to text */ -static char *print_array(const cJSON *item, int depth, cjbool fmt, printbuffer *p) +static unsigned char *print_array(const cJSON *item, int depth, cjbool fmt, printbuffer *p) { - char **entries; - char *out = NULL; - char *ptr = NULL; - char *ret = NULL; + unsigned char **entries; + unsigned char *out = NULL; + unsigned char *ptr = NULL; + unsigned char *ret = NULL; int len = 5; cJSON *child = item->child; int numentries = 0; @@ -1174,11 +1174,11 @@ static char *print_array(const cJSON *item, int depth, cjbool fmt, printbuffer * } else { - out = (char*)cJSON_malloc(3); + out = (unsigned char*)cJSON_malloc(3); } if (out) { - strcpy(out,"[]"); + strcpy((char*)out, "[]"); } return out; @@ -1235,12 +1235,12 @@ static char *print_array(const cJSON *item, int depth, cjbool fmt, printbuffer * else { /* Allocate an array to hold the pointers to all printed values */ - entries = (char**)cJSON_malloc(numentries * sizeof(char*)); + entries = (unsigned char**)cJSON_malloc(numentries * sizeof(unsigned char*)); if (!entries) { return NULL; } - memset(entries, '\0', numentries * sizeof(char*)); + memset(entries, '\0', numentries * sizeof(unsigned char*)); /* Retrieve all the results: */ child = item->child; @@ -1250,7 +1250,7 @@ static char *print_array(const cJSON *item, int depth, cjbool fmt, printbuffer * entries[i++] = ret; if (ret) { - len += strlen(ret) + 2 + (fmt ? 1 : 0); + len += strlen((char*)ret) + 2 + (fmt ? 1 : 0); } else { @@ -1262,7 +1262,7 @@ static char *print_array(const cJSON *item, int depth, cjbool fmt, printbuffer * /* If we didn't fail, try to malloc the output string */ if (!fail) { - out = (char*)cJSON_malloc(len); + out = (unsigned char*)cJSON_malloc(len); } /* If that fails, we fail. */ if (!out) @@ -1291,7 +1291,7 @@ static char *print_array(const cJSON *item, int depth, cjbool fmt, printbuffer * *ptr = '\0'; for (i = 0; i < numentries; i++) { - tmplen = strlen(entries[i]); + tmplen = strlen((char*)entries[i]); memcpy(ptr, entries[i], tmplen); ptr += tmplen; if (i != (numentries - 1)) @@ -1314,7 +1314,7 @@ static char *print_array(const cJSON *item, int depth, cjbool fmt, printbuffer * } /* Build an object from the text. */ -static const char *parse_object(cJSON *item, const char *value, const char **ep) +static const unsigned char *parse_object(cJSON *item, const unsigned char *value, const unsigned char **ep) { cJSON *child = NULL; if (*value != '{') @@ -1409,14 +1409,14 @@ static const char *parse_object(cJSON *item, const char *value, const char **ep) } /* Render an object to text. */ -static char *print_object(const cJSON *item, int depth, cjbool fmt, printbuffer *p) +static unsigned char *print_object(const cJSON *item, int depth, cjbool fmt, printbuffer *p) { - char **entries = NULL; - char **names = NULL; - char *out = NULL; - char *ptr = NULL; - char *ret = NULL; - char *str = NULL; + unsigned char **entries = NULL; + unsigned char **names = NULL; + unsigned char *out = NULL; + unsigned char *ptr = NULL; + unsigned char *ret = NULL; + unsigned char *str = NULL; int len = 7; int i = 0; int j = 0; @@ -1441,7 +1441,7 @@ static char *print_object(const cJSON *item, int depth, cjbool fmt, printbuffer } else { - out = (char*)cJSON_malloc(fmt ? depth + 4 : 3); + out = (unsigned char*)cJSON_malloc(fmt ? depth + 4 : 3); } if (!out) { @@ -1500,7 +1500,7 @@ static char *print_object(const cJSON *item, int depth, cjbool fmt, printbuffer } /* print key */ - if (!print_string_ptr(child->string, p)) + if (!print_string_ptr((unsigned char*)child->string, p)) { return NULL; } @@ -1567,19 +1567,19 @@ static char *print_object(const cJSON *item, int depth, cjbool fmt, printbuffer else { /* Allocate space for the names and the objects */ - entries = (char**)cJSON_malloc(numentries * sizeof(char*)); + entries = (unsigned char**)cJSON_malloc(numentries * sizeof(unsigned char*)); if (!entries) { return NULL; } - names = (char**)cJSON_malloc(numentries * sizeof(char*)); + names = (unsigned char**)cJSON_malloc(numentries * sizeof(unsigned char*)); if (!names) { cJSON_free(entries); return NULL; } - memset(entries, '\0', sizeof(char*) * numentries); - memset(names, '\0', sizeof(char*) * numentries); + memset(entries, '\0', sizeof(unsigned char*) * numentries); + memset(names, '\0', sizeof(unsigned char*) * numentries); /* Collect all the results into our arrays: */ child = item->child; @@ -1590,11 +1590,11 @@ static char *print_object(const cJSON *item, int depth, cjbool fmt, printbuffer } while (child && !fail) { - names[i] = str = print_string_ptr(child->string, 0); /* print key */ + names[i] = str = print_string_ptr((unsigned char*)child->string, 0); /* print key */ entries[i++] = ret = print_value(child, depth, fmt, 0); if (str && ret) { - len += strlen(ret) + strlen(str) + 2 + (fmt ? 2 + depth : 0); + len += strlen((char*)ret) + strlen((char*)str) + 2 + (fmt ? 2 + depth : 0); } else { @@ -1606,7 +1606,7 @@ static char *print_object(const cJSON *item, int depth, cjbool fmt, printbuffer /* Try to allocate the output string */ if (!fail) { - out = (char*)cJSON_malloc(len); + out = (unsigned char*)cJSON_malloc(len); } if (!out) { @@ -1650,7 +1650,7 @@ static char *print_object(const cJSON *item, int depth, cjbool fmt, printbuffer *ptr++='\t'; } } - tmplen = strlen(names[i]); + tmplen = strlen((char*)names[i]); memcpy(ptr, names[i], tmplen); ptr += tmplen; *ptr++ = ':'; @@ -1658,8 +1658,8 @@ static char *print_object(const cJSON *item, int depth, cjbool fmt, printbuffer { *ptr++ = '\t'; } - strcpy(ptr, entries[i]); - ptr += strlen(entries[i]); + strcpy((char*)ptr, (char*)entries[i]); + ptr += strlen((char*)entries[i]); if (i != (numentries - 1)) { *ptr++ = ','; @@ -1717,14 +1717,14 @@ cJSON *cJSON_GetArrayItem(const cJSON *array, int item) cJSON *cJSON_GetObjectItem(const cJSON *object, const char *string) { cJSON *c = object ? object->child : NULL; - while (c && cJSON_strcasecmp(c->string, string)) + while (c && cJSON_strcasecmp((unsigned char*)c->string, (const unsigned char*)string)) { c = c->next; } return c; } -cjbool cJSON_HasObjectItem(const cJSON *object,const char *string) +cjbool cJSON_HasObjectItem(const cJSON *object, const char *string) { return cJSON_GetObjectItem(object, string) ? 1 : 0; } @@ -1787,7 +1787,7 @@ void cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item) { cJSON_free(item->string); } - item->string = cJSON_strdup(string); + item->string = (char*)cJSON_strdup((const unsigned char*)string); cJSON_AddItemToArray(object,item); } @@ -1862,7 +1862,7 @@ cJSON *cJSON_DetachItemFromObject(cJSON *object, const char *string) { int i = 0; cJSON *c = object->child; - while (c && cJSON_strcasecmp(c->string,string)) + while (c && cJSON_strcasecmp((unsigned char*)c->string, (const unsigned char*)string)) { i++; c = c->next; @@ -1941,7 +1941,7 @@ void cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem { int i = 0; cJSON *c = object->child; - while(c && cJSON_strcasecmp(c->string, string)) + while(c && cJSON_strcasecmp((unsigned char*)c->string, (const unsigned char*)string)) { i++; c = c->next; @@ -1954,7 +1954,7 @@ void cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem cJSON_free(newitem->string); } - newitem->string = cJSON_strdup(string); + newitem->string = (char*)cJSON_strdup((const unsigned char*)string); cJSON_ReplaceItemInArray(object, i, newitem); } } @@ -2023,7 +2023,7 @@ cJSON *cJSON_CreateString(const char *string) if(item) { item->type = cJSON_String; - item->valuestring = cJSON_strdup(string); + item->valuestring = (char*)cJSON_strdup((const unsigned char*)string); if(!item->valuestring) { cJSON_Delete(item); @@ -2040,7 +2040,7 @@ extern cJSON *cJSON_CreateRaw(const char *raw) if(item) { item->type = cJSON_Raw; - item->valuestring = cJSON_strdup(raw); + item->valuestring = (char*)cJSON_strdup((const unsigned char*)raw); if(!item->valuestring) { cJSON_Delete(item); @@ -2211,7 +2211,7 @@ cJSON *cJSON_Duplicate(const cJSON *item, cjbool recurse) newitem->valuedouble = item->valuedouble; if (item->valuestring) { - newitem->valuestring = cJSON_strdup(item->valuestring); + newitem->valuestring = (char*)cJSON_strdup((unsigned char*)item->valuestring); if (!newitem->valuestring) { cJSON_Delete(newitem); @@ -2220,7 +2220,7 @@ cJSON *cJSON_Duplicate(const cJSON *item, cjbool recurse) } if (item->string) { - newitem->string = (item->type&cJSON_StringIsConst) ? item->string : cJSON_strdup(item->string); + newitem->string = (item->type&cJSON_StringIsConst) ? item->string : (char*)cJSON_strdup((unsigned char*)item->string); if (!newitem->string) { cJSON_Delete(newitem); @@ -2262,7 +2262,7 @@ cJSON *cJSON_Duplicate(const cJSON *item, cjbool recurse) void cJSON_Minify(char *json) { - char *into = json; + unsigned char *into = (unsigned char*)json; while (*json) { if (*json == ' ') diff --git a/cJSON_Utils.c b/cJSON_Utils.c index 8b5f4b8..762b277 100644 --- a/cJSON_Utils.c +++ b/cJSON_Utils.c @@ -4,13 +4,13 @@ #include #include "cJSON_Utils.h" -static char* cJSONUtils_strdup(const char* str) +static unsigned char* cJSONUtils_strdup(const unsigned char* str) { size_t len = 0; - char *copy = NULL; + unsigned char *copy = NULL; - len = strlen(str) + 1; - if (!(copy = (char*)malloc(len))) + len = strlen((const char*)str) + 1; + if (!(copy = (unsigned char*)malloc(len))) { return NULL; } @@ -19,7 +19,7 @@ static char* cJSONUtils_strdup(const char* str) return copy; } -static int cJSONUtils_strcasecmp(const char *s1, const char *s2) +static int cJSONUtils_strcasecmp(const unsigned char *s1, const unsigned char *s2) { if (!s1) { @@ -37,11 +37,11 @@ static int cJSONUtils_strcasecmp(const char *s1, const char *s2) } } - return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2); + return tolower(*s1) - tolower(*s2); } /* JSON Pointer implementation: */ -static int cJSONUtils_Pstrcasecmp(const char *a, const char *e) +static int cJSONUtils_Pstrcasecmp(const unsigned char *a, const unsigned char *e) { if (!a || !e) { @@ -76,7 +76,7 @@ static int cJSONUtils_Pstrcasecmp(const char *a, const char *e) return 0; } -static int cJSONUtils_PointerEncodedstrlen(const char *s) +static int cJSONUtils_PointerEncodedstrlen(const unsigned char *s) { int l = 0; for (; *s; s++, l++) @@ -90,7 +90,7 @@ static int cJSONUtils_PointerEncodedstrlen(const char *s) return l; } -static void cJSONUtils_PointerEncodedstrcpy(char *d, const char *s) +static void cJSONUtils_PointerEncodedstrcpy(unsigned char *d, const unsigned char *s) { for (; *s; s++) { @@ -122,33 +122,33 @@ char *cJSONUtils_FindPointerFromObjectTo(cJSON *object, cJSON *target) if (object == target) { /* found */ - return cJSONUtils_strdup(""); + return (char*)cJSONUtils_strdup((const unsigned char*)""); } /* recursively search all children of the object */ for (obj = object->child; obj; obj = obj->next, c++) { - char *found = cJSONUtils_FindPointerFromObjectTo(obj, target); + unsigned char *found = (unsigned char*)cJSONUtils_FindPointerFromObjectTo(obj, target); if (found) { if ((type & 0xFF) == cJSON_Array) { /* reserve enough memory for a 64 bit integer + '/' and '\0' */ - char *ret = (char*)malloc(strlen(found) + 23); - sprintf(ret, "/%d%s", c, found); /* / */ + unsigned char *ret = (unsigned char*)malloc(strlen((char*)found) + 23); + sprintf((char*)ret, "/%d%s", c, found); /* / */ free(found); - return ret; + return (char*)ret; } else if ((type & 0xFF) == cJSON_Object) { - char *ret = (char*)malloc(strlen(found) + cJSONUtils_PointerEncodedstrlen(obj->string) + 2); + unsigned char *ret = (unsigned char*)malloc(strlen((char*)found) + cJSONUtils_PointerEncodedstrlen((unsigned char*)obj->string) + 2); *ret = '/'; - cJSONUtils_PointerEncodedstrcpy(ret + 1, obj->string); - strcat(ret, found); + cJSONUtils_PointerEncodedstrcpy(ret + 1, (unsigned char*)obj->string); + strcat((char*)ret, (char*)found); free(found); - return ret; + return (char*)ret; } /* reached leaf of the tree, found nothing */ @@ -185,7 +185,7 @@ cJSON *cJSONUtils_GetPointer(cJSON *object, const char *pointer) { object = object->child; /* GetObjectItem. */ - while (object && cJSONUtils_Pstrcasecmp(object->string, pointer)) + while (object && cJSONUtils_Pstrcasecmp((unsigned char*)object->string, (const unsigned char*)pointer)) { object = object->next; } @@ -205,9 +205,9 @@ cJSON *cJSONUtils_GetPointer(cJSON *object, const char *pointer) } /* JSON Patch implementation. */ -static void cJSONUtils_InplaceDecodePointerString(char *string) +static void cJSONUtils_InplaceDecodePointerString(unsigned char *string) { - char *s2 = string; + unsigned char *s2 = string; if (string == NULL) { return; @@ -225,10 +225,10 @@ static void cJSONUtils_InplaceDecodePointerString(char *string) *s2 = '\0'; } -static cJSON *cJSONUtils_PatchDetach(cJSON *object, const char *path) +static cJSON *cJSONUtils_PatchDetach(cJSON *object, const unsigned char *path) { - char *parentptr = NULL; - char *childptr = NULL; + unsigned char *parentptr = NULL; + unsigned char *childptr = NULL; cJSON *parent = NULL; cJSON *ret = NULL; @@ -238,7 +238,7 @@ static cJSON *cJSONUtils_PatchDetach(cJSON *object, const char *path) return NULL; } - childptr = strrchr(parentptr, '/'); /* last '/' */ + childptr = (unsigned char*)strrchr((char*)parentptr, '/'); /* last '/' */ if (childptr == NULL) { free(parentptr); @@ -247,7 +247,7 @@ static cJSON *cJSONUtils_PatchDetach(cJSON *object, const char *path) /* split strings */ *childptr++ = '\0'; - parent = cJSONUtils_GetPointer(object, parentptr); + parent = cJSONUtils_GetPointer(object, (char*)parentptr); cJSONUtils_InplaceDecodePointerString(childptr); if (!parent) @@ -257,11 +257,11 @@ static cJSON *cJSONUtils_PatchDetach(cJSON *object, const char *path) } else if ((parent->type & 0xFF) == cJSON_Array) { - ret = cJSON_DetachItemFromArray(parent, atoi(childptr)); + ret = cJSON_DetachItemFromArray(parent, atoi((char*)childptr)); } else if ((parent->type & 0xFF) == cJSON_Object) { - ret = cJSON_DetachItemFromObject(parent, childptr); + ret = cJSON_DetachItemFromObject(parent, (char*)childptr); } free(parentptr); @@ -304,7 +304,7 @@ static int cJSONUtils_Compare(cJSON *a, cJSON *b) { int err = 0; /* compare object keys */ - if (cJSONUtils_strcasecmp(a->string, b->string)) + if (cJSONUtils_strcasecmp((unsigned char*)a->string, (unsigned char*)b->string)) { /* missing member */ return -6; @@ -334,8 +334,8 @@ static int cJSONUtils_ApplyPatch(cJSON *object, cJSON *patch) cJSON *value = NULL; cJSON *parent = NULL; int opcode = 0; - char *parentptr = NULL; - char *childptr = NULL; + unsigned char *parentptr = NULL; + unsigned char *childptr = NULL; op = cJSON_GetObjectItem(patch, "op"); path = cJSON_GetObjectItem(patch, "path"); @@ -381,7 +381,7 @@ static int cJSONUtils_ApplyPatch(cJSON *object, cJSON *patch) if ((opcode == 1) || (opcode == 2)) { /* Get rid of old. */ - cJSON_Delete(cJSONUtils_PatchDetach(object, path->valuestring)); + cJSON_Delete(cJSONUtils_PatchDetach(object, (unsigned char*)path->valuestring)); if (opcode == 1) { /* For Remove, this is job done. */ @@ -402,7 +402,7 @@ static int cJSONUtils_ApplyPatch(cJSON *object, cJSON *patch) if (opcode == 3) { /* move */ - value = cJSONUtils_PatchDetach(object, from->valuestring); + value = cJSONUtils_PatchDetach(object, (unsigned char*)from->valuestring); } if (opcode == 4) { @@ -443,13 +443,13 @@ static int cJSONUtils_ApplyPatch(cJSON *object, cJSON *patch) /* Now, just add "value" to "path". */ /* split pointer in parent and child */ - parentptr = cJSONUtils_strdup(path->valuestring); - childptr = strrchr(parentptr, '/'); + parentptr = cJSONUtils_strdup((unsigned char*)path->valuestring); + childptr = (unsigned char*)strrchr((char*)parentptr, '/'); if (childptr) { *childptr++ = '\0'; } - parent = cJSONUtils_GetPointer(object, parentptr); + parent = cJSONUtils_GetPointer(object, (char*)parentptr); cJSONUtils_InplaceDecodePointerString(childptr); /* add, remove, replace, move, copy, test. */ @@ -462,19 +462,19 @@ static int cJSONUtils_ApplyPatch(cJSON *object, cJSON *patch) } else if ((parent->type & 0xFF) == cJSON_Array) { - if (!strcmp(childptr, "-")) + if (!strcmp((char*)childptr, "-")) { cJSON_AddItemToArray(parent, value); } else { - cJSON_InsertItemInArray(parent, atoi(childptr), value); + cJSON_InsertItemInArray(parent, atoi((char*)childptr), value); } } else if ((parent->type & 0xFF) == cJSON_Object) { - cJSON_DeleteItemFromObject(parent, childptr); - cJSON_AddItemToObject(parent, childptr, value); + cJSON_DeleteItemFromObject(parent, (char*)childptr); + cJSON_AddItemToObject(parent, (char*)childptr, value); } else { @@ -509,20 +509,20 @@ int cJSONUtils_ApplyPatches(cJSON *object, cJSON *patches) return 0; } -static void cJSONUtils_GeneratePatch(cJSON *patches, const char *op, const char *path, const char *suffix, cJSON *val) +static void cJSONUtils_GeneratePatch(cJSON *patches, const unsigned char *op, const unsigned char *path, const unsigned char *suffix, cJSON *val) { cJSON *patch = cJSON_CreateObject(); - cJSON_AddItemToObject(patch, "op", cJSON_CreateString(op)); + cJSON_AddItemToObject(patch, "op", cJSON_CreateString((const char*)op)); if (suffix) { - char *newpath = (char*)malloc(strlen(path) + cJSONUtils_PointerEncodedstrlen(suffix) + 2); - cJSONUtils_PointerEncodedstrcpy(newpath + sprintf(newpath, "%s/", path), suffix); - cJSON_AddItemToObject(patch, "path", cJSON_CreateString(newpath)); + unsigned char *newpath = (unsigned char*)malloc(strlen((const char*)path) + cJSONUtils_PointerEncodedstrlen(suffix) + 2); + cJSONUtils_PointerEncodedstrcpy(newpath + sprintf((char*)newpath, "%s/", (const char*)path), suffix); + cJSON_AddItemToObject(patch, "path", cJSON_CreateString((const char*)newpath)); free(newpath); } else { - cJSON_AddItemToObject(patch, "path", cJSON_CreateString(path)); + cJSON_AddItemToObject(patch, "path", cJSON_CreateString((const char*)path)); } if (val) { @@ -533,14 +533,14 @@ static void cJSONUtils_GeneratePatch(cJSON *patches, const char *op, const char void cJSONUtils_AddPatchToArray(cJSON *array, const char *op, const char *path, cJSON *val) { - cJSONUtils_GeneratePatch(array, op, path, 0, val); + cJSONUtils_GeneratePatch(array, (const unsigned char*)op, (const unsigned char*)path, 0, val); } -static void cJSONUtils_CompareToPatch(cJSON *patches, const char *path, cJSON *from, cJSON *to) +static void cJSONUtils_CompareToPatch(cJSON *patches, const unsigned char *path, cJSON *from, cJSON *to) { if ((from->type & 0xFF) != (to->type & 0xFF)) { - cJSONUtils_GeneratePatch(patches, "replace", path, 0, to); + cJSONUtils_GeneratePatch(patches, (const unsigned char*)"replace", path, 0, to); return; } @@ -549,37 +549,37 @@ static void cJSONUtils_CompareToPatch(cJSON *patches, const char *path, cJSON *f case cJSON_Number: if ((from->valueint != to->valueint) || (from->valuedouble != to->valuedouble)) { - cJSONUtils_GeneratePatch(patches, "replace", path, 0, to); + cJSONUtils_GeneratePatch(patches, (const unsigned char*)"replace", path, 0, to); } return; case cJSON_String: if (strcmp(from->valuestring, to->valuestring) != 0) { - cJSONUtils_GeneratePatch(patches, "replace", path, 0, to); + cJSONUtils_GeneratePatch(patches, (const unsigned char*)"replace", path, 0, to); } return; case cJSON_Array: { int c = 0; - char *newpath = (char*)malloc(strlen(path) + 23); /* Allow space for 64bit int. */ + unsigned char *newpath = (unsigned char*)malloc(strlen((const char*)path) + 23); /* Allow space for 64bit int. */ /* generate patches for all array elements that exist in "from" and "to" */ for (c = 0, from = from->child, to = to->child; from && to; from = from->next, to = to->next, c++) { - sprintf(newpath, "%s/%d", path, c); /* path of the current array element */ + sprintf((char*)newpath, "%s/%d", path, c); /* path of the current array element */ cJSONUtils_CompareToPatch(patches, newpath, from, to); } /* remove leftover elements from 'from' that are not in 'to' */ for (; from; from = from->next, c++) { - sprintf(newpath, "%d", c); - cJSONUtils_GeneratePatch(patches, "remove", path, newpath, 0); + sprintf((char*)newpath, "%d", c); + cJSONUtils_GeneratePatch(patches, (const unsigned char*)"remove", path, newpath, 0); } /* add new elements in 'to' that were not in 'from' */ for (; to; to = to->next, c++) { - cJSONUtils_GeneratePatch(patches, "add", path, "-", to); + cJSONUtils_GeneratePatch(patches, (const unsigned char*)"add", path, (const unsigned char*)"-", to); } free(newpath); return; @@ -597,12 +597,12 @@ static void cJSONUtils_CompareToPatch(cJSON *patches, const char *path, cJSON *f /* for all object values in the object with more of them */ while (a || b) { - int diff = (!a) ? 1 : ((!b) ? -1 : cJSONUtils_strcasecmp(a->string, b->string)); + int diff = (!a) ? 1 : ((!b) ? -1 : cJSONUtils_strcasecmp((unsigned char*)a->string, (unsigned char*)b->string)); if (!diff) { /* both object keys are the same */ - char *newpath = (char*)malloc(strlen(path) + cJSONUtils_PointerEncodedstrlen(a->string) + 2); - cJSONUtils_PointerEncodedstrcpy(newpath + sprintf(newpath, "%s/", path), a->string); + unsigned char *newpath = (unsigned char*)malloc(strlen((const char*)path) + cJSONUtils_PointerEncodedstrlen((unsigned char*)a->string) + 2); + cJSONUtils_PointerEncodedstrcpy(newpath + sprintf((char*)newpath, "%s/", path), (unsigned char*)a->string); /* create a patch for the element */ cJSONUtils_CompareToPatch(patches, newpath, a, b); free(newpath); @@ -612,13 +612,13 @@ static void cJSONUtils_CompareToPatch(cJSON *patches, const char *path, cJSON *f else if (diff < 0) { /* object element doesn't exist in 'to' --> remove it */ - cJSONUtils_GeneratePatch(patches, "remove", path, a->string, 0); + cJSONUtils_GeneratePatch(patches, (const unsigned char*)"remove", path, (unsigned char*)a->string, 0); a = a->next; } else { /* object element doesn't exist in 'from' --> add it */ - cJSONUtils_GeneratePatch(patches, "add", path, b->string, b); + cJSONUtils_GeneratePatch(patches, (const unsigned char*)"add", path, (unsigned char*)b->string, b); b = b->next; } } @@ -633,7 +633,7 @@ static void cJSONUtils_CompareToPatch(cJSON *patches, const char *path, cJSON *f cJSON* cJSONUtils_GeneratePatches(cJSON *from, cJSON *to) { cJSON *patches = cJSON_CreateArray(); - cJSONUtils_CompareToPatch(patches, "", from, to); + cJSONUtils_CompareToPatch(patches, (const unsigned char*)"", from, to); return patches; } @@ -651,7 +651,7 @@ static cJSON *cJSONUtils_SortList(cJSON *list) return list; } - while (ptr && ptr->next && (cJSONUtils_strcasecmp(ptr->string, ptr->next->string) < 0)) + while (ptr && ptr->next && (cJSONUtils_strcasecmp((unsigned char*)ptr->string, (unsigned char*)ptr->next->string) < 0)) { /* Test for list sorted. */ ptr = ptr->next; @@ -688,7 +688,7 @@ static cJSON *cJSONUtils_SortList(cJSON *list) while (first && second) /* Merge the sub-lists */ { - if (cJSONUtils_strcasecmp(first->string, second->string) < 0) + if (cJSONUtils_strcasecmp((unsigned char*)first->string, (unsigned char*)second->string) < 0) { if (!list) { From ecd5678527a6bc422da694e5be9e9979878fe6a0 Mon Sep 17 00:00:00 2001 From: Max Bruckner Date: Fri, 3 Feb 2017 16:34:19 +0100 Subject: [PATCH 4/6] Change all internal sizes to size_t --- cJSON.c | 111 ++++++++++++++++++++++++++++++++++---------------- cJSON_Utils.c | 16 ++++---- 2 files changed, 84 insertions(+), 43 deletions(-) diff --git a/cJSON.c b/cJSON.c index 0244009..559b967 100644 --- a/cJSON.c +++ b/cJSON.c @@ -255,16 +255,23 @@ static int pow2gt (int x) typedef struct { unsigned char *buffer; - int length; - int offset; + size_t length; + size_t offset; cjbool noalloc; } printbuffer; /* realloc printbuffer if necessary to have at least "needed" bytes more */ -static unsigned char* ensure(printbuffer *p, int needed) +static unsigned char* ensure(printbuffer *p, size_t needed) { unsigned char *newbuffer = NULL; - int newsize = 0; + size_t newsize = 0; + + if (needed > INT_MAX) + { + /* sizes bigger than INT_MAX are currently not supported */ + return NULL; + } + if (!p || !p->buffer) { return NULL; @@ -301,7 +308,7 @@ static unsigned char* ensure(printbuffer *p, int needed) } /* calculate the new length of the string in a printbuffer */ -static int update(const printbuffer *p) +static size_t update(const printbuffer *p) { unsigned char *str = NULL; if (!p || !p->buffer) @@ -493,7 +500,7 @@ static const unsigned char *parse_string(cJSON *item, const unsigned char *str, const unsigned char *end_ptr =str + 1; unsigned char *ptr2 = NULL; unsigned char *out = NULL; - int len = 0; + size_t len = 0; unsigned uc = 0; unsigned uc2 = 0; @@ -673,7 +680,7 @@ static unsigned char *print_string_ptr(const unsigned char *str, printbuffer *p) const unsigned char *ptr = NULL; unsigned char *ptr2 = NULL; unsigned char *out = NULL; - int len = 0; + size_t len = 0; cjbool flag = false; unsigned char token = '\0'; @@ -821,11 +828,11 @@ static unsigned char *print_string(const cJSON *item, printbuffer *p) /* Predeclare these prototypes. */ static const unsigned char *parse_value(cJSON *item, const unsigned char *value, const unsigned char **ep); -static unsigned char *print_value(const cJSON *item, int depth, cjbool fmt, printbuffer *p); +static unsigned char *print_value(const cJSON *item, size_t depth, cjbool fmt, printbuffer *p); static const unsigned char *parse_array(cJSON *item, const unsigned char *value, const unsigned char **ep); -static unsigned char *print_array(const cJSON *item, int depth, cjbool fmt, printbuffer *p); +static unsigned char *print_array(const cJSON *item, size_t depth, cjbool fmt, printbuffer *p); static const unsigned char *parse_object(cJSON *item, const unsigned char *value, const unsigned char **ep); -static unsigned char *print_object(const cJSON *item, int depth, cjbool fmt, printbuffer *p); +static unsigned char *print_object(const cJSON *item, size_t depth, cjbool fmt, printbuffer *p); /* Utility to jump whitespace and cr/lf */ static const unsigned char *skip(const unsigned char *in) @@ -969,7 +976,7 @@ static const unsigned char *parse_value(cJSON *item, const unsigned char *value } /* Render a value to text. */ -static unsigned char *print_value(const cJSON *item, int depth, cjbool fmt, printbuffer *p) +static unsigned char *print_value(const cJSON *item, size_t depth, cjbool fmt, printbuffer *p) { unsigned char *out = NULL; @@ -1145,16 +1152,16 @@ static const unsigned char *parse_array(cJSON *item, const unsigned char *value, } /* Render an array to text */ -static unsigned char *print_array(const cJSON *item, int depth, cjbool fmt, printbuffer *p) +static unsigned char *print_array(const cJSON *item, size_t depth, cjbool fmt, printbuffer *p) { unsigned char **entries; unsigned char *out = NULL; unsigned char *ptr = NULL; unsigned char *ret = NULL; - int len = 5; + size_t len = 5; cJSON *child = item->child; - int numentries = 0; - int i = 0; + size_t numentries = 0; + size_t i = 0; cjbool fail = false; size_t tmplen = 0; @@ -1409,7 +1416,7 @@ static const unsigned char *parse_object(cJSON *item, const unsigned char *value } /* Render an object to text. */ -static unsigned char *print_object(const cJSON *item, int depth, cjbool fmt, printbuffer *p) +static unsigned char *print_object(const cJSON *item, size_t depth, cjbool fmt, printbuffer *p) { unsigned char **entries = NULL; unsigned char **names = NULL; @@ -1417,11 +1424,11 @@ static unsigned char *print_object(const cJSON *item, int depth, cjbool fmt, pri unsigned char *ptr = NULL; unsigned char *ret = NULL; unsigned char *str = NULL; - int len = 7; - int i = 0; - int j = 0; + size_t len = 7; + size_t i = 0; + size_t j = 0; cJSON *child = item->child; - int numentries = 0; + size_t numentries = 0; cjbool fail = false; size_t tmplen = 0; @@ -1693,12 +1700,15 @@ static unsigned char *print_object(const cJSON *item, int depth, cjbool fmt, pri int cJSON_GetArraySize(const cJSON *array) { cJSON *c = array->child; - int i = 0; + size_t i = 0; while(c) { i++; c = c->next; } + + /* FIXME: Can overflow here. Cannot be fixed without breaking the API */ + return i; } @@ -1860,7 +1870,7 @@ void cJSON_DeleteItemFromArray(cJSON *array, int which) cJSON *cJSON_DetachItemFromObject(cJSON *object, const char *string) { - int i = 0; + size_t i = 0; cJSON *c = object->child; while (c && cJSON_strcasecmp((unsigned char*)c->string, (const unsigned char*)string)) { @@ -1939,7 +1949,7 @@ void cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem) void cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem) { - int i = 0; + size_t i = 0; cJSON *c = object->child; while(c && cJSON_strcasecmp((unsigned char*)c->string, (const unsigned char*)string)) { @@ -2076,11 +2086,18 @@ cJSON *cJSON_CreateObject(void) /* Create Arrays: */ cJSON *cJSON_CreateIntArray(const int *numbers, int count) { - int i = 0; + size_t i = 0; cJSON *n = NULL; cJSON *p = NULL; - cJSON *a = cJSON_CreateArray(); - for(i = 0; a && (i < count); i++) + cJSON *a = NULL; + + if (count < 0) + { + return NULL; + } + + a = cJSON_CreateArray(); + for(i = 0; a && (i < (size_t)count); i++) { n = cJSON_CreateNumber(numbers[i]); if (!n) @@ -2104,11 +2121,19 @@ cJSON *cJSON_CreateIntArray(const int *numbers, int count) cJSON *cJSON_CreateFloatArray(const float *numbers, int count) { - int i = 0; + size_t i = 0; cJSON *n = NULL; cJSON *p = NULL; - cJSON *a = cJSON_CreateArray(); - for(i = 0; a && (i < count); i++) + cJSON *a = NULL; + + if (count < 0) + { + return NULL; + } + + a = cJSON_CreateArray(); + + for(i = 0; a && (i < (size_t)count); i++) { n = cJSON_CreateNumber(numbers[i]); if(!n) @@ -2132,11 +2157,19 @@ cJSON *cJSON_CreateFloatArray(const float *numbers, int count) cJSON *cJSON_CreateDoubleArray(const double *numbers, int count) { - int i = 0; + size_t i = 0; cJSON *n = NULL; cJSON *p = NULL; - cJSON *a = cJSON_CreateArray(); - for(i = 0;a && (i < count); i++) + cJSON *a = NULL; + + if (count < 0) + { + return NULL; + } + + a = cJSON_CreateArray(); + + for(i = 0;a && (i < (size_t)count); i++) { n = cJSON_CreateNumber(numbers[i]); if(!n) @@ -2160,11 +2193,19 @@ cJSON *cJSON_CreateDoubleArray(const double *numbers, int count) cJSON *cJSON_CreateStringArray(const char **strings, int count) { - int i = 0; + size_t i = 0; cJSON *n = NULL; cJSON *p = NULL; - cJSON *a = cJSON_CreateArray(); - for (i = 0; a && (i < count); i++) + cJSON *a = NULL; + + if (count < 0) + { + return NULL; + } + + a = cJSON_CreateArray(); + + for (i = 0; a && (i < (size_t)count); i++) { n = cJSON_CreateString(strings[i]); if(!n) diff --git a/cJSON_Utils.c b/cJSON_Utils.c index 762b277..db8e7e8 100644 --- a/cJSON_Utils.c +++ b/cJSON_Utils.c @@ -76,9 +76,9 @@ static int cJSONUtils_Pstrcasecmp(const unsigned char *a, const unsigned char *e return 0; } -static int cJSONUtils_PointerEncodedstrlen(const unsigned char *s) +static size_t cJSONUtils_PointerEncodedstrlen(const unsigned char *s) { - int l = 0; + size_t l = 0; for (; *s; s++, l++) { if ((*s == '~') || (*s == '/')) @@ -116,7 +116,7 @@ static void cJSONUtils_PointerEncodedstrcpy(unsigned char *d, const unsigned cha char *cJSONUtils_FindPointerFromObjectTo(cJSON *object, cJSON *target) { int type = object->type; - int c = 0; + size_t c = 0; cJSON *obj = 0; if (object == target) @@ -135,7 +135,7 @@ char *cJSONUtils_FindPointerFromObjectTo(cJSON *object, cJSON *target) { /* reserve enough memory for a 64 bit integer + '/' and '\0' */ unsigned char *ret = (unsigned char*)malloc(strlen((char*)found) + 23); - sprintf((char*)ret, "/%d%s", c, found); /* / */ + sprintf((char*)ret, "/%lu%s", c, found); /* / */ free(found); return (char*)ret; @@ -168,7 +168,7 @@ cJSON *cJSONUtils_GetPointer(cJSON *object, const char *pointer) { if ((object->type & 0xFF) == cJSON_Array) { - int which = 0; + size_t which = 0; /* parse array index */ while ((*pointer >= '0') && (*pointer <= '9')) { @@ -562,18 +562,18 @@ static void cJSONUtils_CompareToPatch(cJSON *patches, const unsigned char *path, case cJSON_Array: { - int c = 0; + size_t c = 0; unsigned char *newpath = (unsigned char*)malloc(strlen((const char*)path) + 23); /* Allow space for 64bit int. */ /* generate patches for all array elements that exist in "from" and "to" */ for (c = 0, from = from->child, to = to->child; from && to; from = from->next, to = to->next, c++) { - sprintf((char*)newpath, "%s/%d", path, c); /* path of the current array element */ + sprintf((char*)newpath, "%s/%lu", path, c); /* path of the current array element */ cJSONUtils_CompareToPatch(patches, newpath, from, to); } /* remove leftover elements from 'from' that are not in 'to' */ for (; from; from = from->next, c++) { - sprintf((char*)newpath, "%d", c); + sprintf((char*)newpath, "%lu", c); cJSONUtils_GeneratePatch(patches, (const unsigned char*)"remove", path, newpath, 0); } /* add new elements in 'to' that were not in 'from' */ From 41e2837df1b1091643aff073f2313f6ff3cc10f4 Mon Sep 17 00:00:00 2001 From: Max Bruckner Date: Fri, 3 Feb 2017 16:34:50 +0100 Subject: [PATCH 5/6] Fix potentially undefined behavior when filling valueint If the number is bigger or smaller than the biggest or smallest integer, the behavior would be undefined. This commit defines it as saturation behavior. --- cJSON.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/cJSON.c b/cJSON.c index 559b967..b16853e 100644 --- a/cJSON.c +++ b/cJSON.c @@ -225,7 +225,19 @@ static const unsigned char *parse_number(cJSON *item, const unsigned char *num) n = sign * n * pow(10.0, (scale + subscale * signsubscale)); item->valuedouble = n; - item->valueint = (int)n; + /* use saturation in case of overflow */ + if (n >= INT_MAX) + { + item->valueint = INT_MAX; + } + else if (n <= INT_MIN) + { + item->valueint = INT_MIN; + } + else + { + item->valueint = (int)n; + } item->type = cJSON_Number; return num; @@ -2021,7 +2033,20 @@ cJSON *cJSON_CreateNumber(double num) { item->type = cJSON_Number; item->valuedouble = num; - item->valueint = (int)num; + + /* use saturation in case of overflow */ + if (num >= INT_MAX) + { + item->valueint = INT_MAX; + } + else if (num <= INT_MIN) + { + item->valueint = INT_MIN; + } + else + { + item->valueint = (int)num; + } } return item; From 3d3bfc6a4df3b455e2148c53e6a3a229230966d1 Mon Sep 17 00:00:00 2001 From: Max Bruckner Date: Fri, 3 Feb 2017 18:34:37 +0100 Subject: [PATCH 6/6] Compiler flag -Wconversion Makes type conversions explicit, if they alter a value --- CMakeLists.txt | 2 +- Makefile | 2 +- cJSON.c | 102 ++++++++++++++++++++++++++++++++----------------- cJSON_Utils.c | 10 ++++- test.c | 8 ++-- 5 files changed, 81 insertions(+), 43 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0261d88..e3726ad 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,7 +15,7 @@ set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT option(ENABLE_CUSTOM_COMPILER_FLAGS "Enables custom compiler flags for Clang and GCC" ON) if (ENABLE_CUSTOM_COMPILER_FLAGS) if(("${CMAKE_C_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_C_COMPILER_ID}" MATCHES "Clang")) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c89 -pedantic -Wall -Wextra -Werror -Wstrict-prototypes -Wwrite-strings -Wshadow -Winit-self -Wcast-align -Wformat=2 -Wmissing-prototypes -Wstrict-overflow=2 -Wcast-qual -Wc++-compat -Wundef -Wswitch-default") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c89 -pedantic -Wall -Wextra -Werror -Wstrict-prototypes -Wwrite-strings -Wshadow -Winit-self -Wcast-align -Wformat=2 -Wmissing-prototypes -Wstrict-overflow=2 -Wcast-qual -Wc++-compat -Wundef -Wswitch-default -Wconversion") endif() endif() diff --git a/Makefile b/Makefile index 33be51a..7a22a5b 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,7 @@ INSTALL_LIBRARY_PATH = $(DESTDIR)$(PREFIX)/$(LIBRARY_PATH) INSTALL ?= cp -a -R_CFLAGS = -fPIC -std=c89 -pedantic -Wall -Werror -Wstrict-prototypes -Wwrite-strings -Wshadow -Winit-self -Wcast-align -Wformat=2 -Wmissing-prototypes -Wstrict-overflow=2 -Wcast-qual -Wc++-compat -Wundef -Wswitch-default $(CFLAGS) +R_CFLAGS = -fPIC -std=c89 -pedantic -Wall -Werror -Wstrict-prototypes -Wwrite-strings -Wshadow -Winit-self -Wcast-align -Wformat=2 -Wmissing-prototypes -Wstrict-overflow=2 -Wcast-qual -Wc++-compat -Wundef -Wswitch-default -Wconversion $(CFLAGS) uname := $(shell sh -c 'uname -s 2>/dev/null || echo false') diff --git a/cJSON.c b/cJSON.c index b16853e..80b804d 100644 --- a/cJSON.c +++ b/cJSON.c @@ -298,7 +298,7 @@ static unsigned char* ensure(printbuffer *p, size_t needed) return NULL; } - newsize = pow2gt(needed); + newsize = (size_t) pow2gt((int)needed); newbuffer = (unsigned char*)cJSON_malloc(newsize); if (!newbuffer) { @@ -410,19 +410,20 @@ static unsigned char *print_number(const cJSON *item, printbuffer *p) /* parse 4 digit hexadecimal number */ static unsigned parse_hex4(const unsigned char *str) { - unsigned h = 0; + unsigned int h = 0; + /* first digit */ if ((*str >= '0') && (*str <= '9')) { - h += (*str) - '0'; + h += (unsigned int) (*str) - '0'; } else if ((*str >= 'A') && (*str <= 'F')) { - h += 10 + (*str) - 'A'; + h += (unsigned int) 10 + (*str) - 'A'; } else if ((*str >= 'a') && (*str <= 'f')) { - h += 10 + (*str) - 'a'; + h += (unsigned int) 10 + (*str) - 'a'; } else /* invalid */ { @@ -435,15 +436,15 @@ static unsigned parse_hex4(const unsigned char *str) str++; if ((*str >= '0') && (*str <= '9')) { - h += (*str) - '0'; + h += (unsigned int) (*str) - '0'; } else if ((*str >= 'A') && (*str <= 'F')) { - h += 10 + (*str) - 'A'; + h += (unsigned int) 10 + (*str) - 'A'; } else if ((*str >= 'a') && (*str <= 'f')) { - h += 10 + (*str) - 'a'; + h += (unsigned int) 10 + (*str) - 'a'; } else /* invalid */ { @@ -455,15 +456,15 @@ static unsigned parse_hex4(const unsigned char *str) str++; if ((*str >= '0') && (*str <= '9')) { - h += (*str) - '0'; + h += (unsigned int) (*str) - '0'; } else if ((*str >= 'A') && (*str <= 'F')) { - h += 10 + (*str) - 'A'; + h += (unsigned int) 10 + (*str) - 'A'; } else if ((*str >= 'a') && (*str <= 'f')) { - h += 10 + (*str) - 'a'; + h += (unsigned int) 10 + (*str) - 'a'; } else /* invalid */ { @@ -475,15 +476,15 @@ static unsigned parse_hex4(const unsigned char *str) str++; if ((*str >= '0') && (*str <= '9')) { - h += (*str) - '0'; + h += (unsigned int) (*str) - '0'; } else if ((*str >= 'A') && (*str <= 'F')) { - h += 10 + (*str) - 'A'; + h += (unsigned int) 10 + (*str) - 'A'; } else if ((*str >= 'a') && (*str <= 'f')) { - h += 10 + (*str) - 'a'; + h += (unsigned int) 10 + (*str) - 'a'; } else /* invalid */ { @@ -650,20 +651,20 @@ static const unsigned char *parse_string(cJSON *item, const unsigned char *str, switch (len) { case 4: /* 10xxxxxx */ - *--ptr2 = ((uc | 0x80) & 0xBF); + *--ptr2 = (unsigned char)((uc | 0x80) & 0xBF); uc >>= 6; case 3: /* 10xxxxxx */ - *--ptr2 = ((uc | 0x80) & 0xBF); + *--ptr2 = (unsigned char)((uc | 0x80) & 0xBF); uc >>= 6; case 2: /* 10xxxxxx */ - *--ptr2 = ((uc | 0x80) & 0xBF); + *--ptr2 = (unsigned char)((uc | 0x80) & 0xBF); uc >>= 6; case 1: /* depending on the length in bytes this determines the * encoding ofthe first UTF8 byte */ - *--ptr2 = (uc | firstByteMark[len]); + *--ptr2 = (unsigned char)((uc | firstByteMark[len]) & 0xFF); default: *ep = str; return NULL; @@ -728,7 +729,7 @@ static unsigned char *print_string_ptr(const unsigned char *str, printbuffer *p) /* no characters have to be escaped */ if (!flag) { - len = ptr - str; + len = (size_t)(ptr - str); if (p) { out = ensure(p, len + 3); @@ -917,12 +918,19 @@ char *cJSON_PrintUnformatted(const cJSON *item) char *cJSON_PrintBuffered(const cJSON *item, int prebuffer, cjbool fmt) { printbuffer p; - p.buffer = (unsigned char*)cJSON_malloc(prebuffer); + + if (prebuffer < 0) + { + return false; + } + + p.buffer = (unsigned char*)cJSON_malloc((size_t)prebuffer); if (!p.buffer) { return NULL; } - p.length = prebuffer; + + p.length = (size_t)prebuffer; p.offset = 0; p.noalloc = false; @@ -932,11 +940,17 @@ char *cJSON_PrintBuffered(const cJSON *item, int prebuffer, cjbool fmt) int cJSON_PrintPreallocated(cJSON *item, char *buf, const int len, const cjbool fmt) { printbuffer p; + + if (len < 0) + { + return false; + } + p.buffer = (unsigned char*)buf; - p.length = len; + p.length = (size_t)len; p.offset = 0; p.noalloc = true; - return print_value(item,0,fmt,&p) != NULL; + return print_value(item, 0, fmt, &p) != NULL; } /* Parser core - when encountering text, process appropriately. */ @@ -1546,7 +1560,7 @@ static unsigned char *print_object(const cJSON *item, size_t depth, cjbool fmt, p->offset = update(p); /* print comma if not last */ - len = (fmt ? 1 : 0) + (child->next ? 1 : 0); + len = (size_t) (fmt ? 1 : 0) + (child->next ? 1 : 0); ptr = ensure(p, len + 1); if (!ptr) { @@ -1709,7 +1723,7 @@ static unsigned char *print_object(const cJSON *item, size_t depth, cjbool fmt, } /* Get Array size/item / object item. */ -int cJSON_GetArraySize(const cJSON *array) +int cJSON_GetArraySize(const cJSON *array) { cJSON *c = array->child; size_t i = 0; @@ -1721,7 +1735,7 @@ int cJSON_GetArraySize(const cJSON *array) /* FIXME: Can overflow here. Cannot be fixed without breaking the API */ - return i; + return (int)i; } cJSON *cJSON_GetArrayItem(const cJSON *array, int item) @@ -1843,7 +1857,7 @@ void cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *it cJSON_AddItemToObject(object, string, create_reference(item)); } -cJSON *cJSON_DetachItemFromArray(cJSON *array, int which) +static cJSON *DetachItemFromArray(cJSON *array, size_t which) { cJSON *c = array->child; while (c && (which > 0)) @@ -1874,6 +1888,15 @@ cJSON *cJSON_DetachItemFromArray(cJSON *array, int which) return c; } +cJSON *cJSON_DetachItemFromArray(cJSON *array, int which) +{ + if (which < 0) + { + return NULL; + } + + return DetachItemFromArray(array, (size_t)which); +} void cJSON_DeleteItemFromArray(cJSON *array, int which) { @@ -1891,7 +1914,7 @@ cJSON *cJSON_DetachItemFromObject(cJSON *object, const char *string) } if (c) { - return cJSON_DetachItemFromArray(object, i); + return DetachItemFromArray(object, i); } return NULL; @@ -1929,7 +1952,7 @@ void cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem) } } -void cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem) +static void ReplaceItemInArray(cJSON *array, size_t which, cJSON *newitem) { cJSON *c = array->child; while (c && (which > 0)) @@ -1958,6 +1981,15 @@ void cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem) c->next = c->prev = NULL; cJSON_Delete(c); } +void cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem) +{ + if (which < 0) + { + return; + } + + ReplaceItemInArray(array, (size_t)which, newitem); +} void cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem) { @@ -1977,7 +2009,7 @@ void cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem } newitem->string = (char*)cJSON_strdup((const unsigned char*)string); - cJSON_ReplaceItemInArray(object, i, newitem); + ReplaceItemInArray(object, i, newitem); } } @@ -2368,21 +2400,21 @@ void cJSON_Minify(char *json) else if (*json == '\"') { /* string literals, which are \" sensitive. */ - *into++ = *json++; + *into++ = (unsigned char)*json++; while (*json && (*json != '\"')) { if (*json == '\\') { - *into++=*json++; + *into++ = (unsigned char)*json++; } - *into++ = *json++; + *into++ = (unsigned char)*json++; } - *into++ = *json++; + *into++ = (unsigned char)*json++; } else { /* All other characters. */ - *into++ = *json++; + *into++ = (unsigned char)*json++; } } diff --git a/cJSON_Utils.c b/cJSON_Utils.c index db8e7e8..608a66c 100644 --- a/cJSON_Utils.c +++ b/cJSON_Utils.c @@ -2,6 +2,8 @@ #include #include #include +#include + #include "cJSON_Utils.h" static unsigned char* cJSONUtils_strdup(const unsigned char* str) @@ -172,14 +174,18 @@ cJSON *cJSONUtils_GetPointer(cJSON *object, const char *pointer) /* parse array index */ while ((*pointer >= '0') && (*pointer <= '9')) { - which = (10 * which) + (*pointer++ - '0'); + which = (10 * which) + (size_t)(*pointer++ - '0'); } if (*pointer && (*pointer != '/')) { /* not end of string or new path token */ return NULL; } - object = cJSON_GetArrayItem(object, which); + if (which > INT_MAX) + { + return NULL; + } + object = cJSON_GetArrayItem(object, (int)which); } else if ((object->type & 0xFF) == cJSON_Object) { diff --git a/test.c b/test.c index 2af8a26..9277497 100644 --- a/test.c +++ b/test.c @@ -97,8 +97,8 @@ static int print_preallocated(cJSON *root) char *out = NULL; char *buf = NULL; char *buf_fail = NULL; - int len = 0; - int len_fail = 0; + size_t len = 0; + size_t len_fail = 0; /* formatted print */ out = cJSON_Print(root); @@ -123,7 +123,7 @@ static int print_preallocated(cJSON *root) } /* Print to buffer */ - if (!cJSON_PrintPreallocated(root, buf, len, 1)) { + if (!cJSON_PrintPreallocated(root, buf, (int)len, 1)) { printf("cJSON_PrintPreallocated failed!\n"); if (strcmp(out, buf) != 0) { printf("cJSON_PrintPreallocated not the same as cJSON_Print!\n"); @@ -140,7 +140,7 @@ static int print_preallocated(cJSON *root) printf("%s\n", buf); /* force it to fail */ - if (cJSON_PrintPreallocated(root, buf_fail, len_fail, 1)) { + if (cJSON_PrintPreallocated(root, buf_fail, (int)len_fail, 1)) { printf("cJSON_PrintPreallocated failed to show error with insufficient memory!\n"); printf("cJSON_Print result:\n%s\n", out); printf("cJSON_PrintPreallocated result:\n%s\n", buf_fail);