mirror of
https://github.com/DaveGamble/cJSON.git
synced 2023-08-10 21:13:26 +03:00
Compare commits
3 Commits
v1.7.5
...
less-magic
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d48d988d7e | ||
|
|
15d9ec8b07 | ||
|
|
f07a3b7cb3 |
24
CHANGELOG.md
24
CHANGELOG.md
@@ -1,27 +1,3 @@
|
|||||||
1.7.5
|
|
||||||
=====
|
|
||||||
Fixes:
|
|
||||||
------
|
|
||||||
* Fix a bug in the JSON Patch implementation of `cJSON Utils` (see #251), thanks @bobkocisko.
|
|
||||||
|
|
||||||
1.7.4
|
|
||||||
=====
|
|
||||||
Fixes:
|
|
||||||
------
|
|
||||||
* Fix potential use after free if the `string` parameter to `cJSON_AddItemToObject` is an alias of the `string` property of the object that is added (#248). Thanks @hhallen for reporting.
|
|
||||||
|
|
||||||
1.7.3
|
|
||||||
=====
|
|
||||||
Fixes:
|
|
||||||
------
|
|
||||||
* Fix potential double free, thanks @projectgus for reporting (see #241)
|
|
||||||
|
|
||||||
1.7.2
|
|
||||||
=====
|
|
||||||
Fixes:
|
|
||||||
------
|
|
||||||
* Fix the use of GNUInstallDirs variables and the pkgconfig file. Thanks @zeerd for reporting (see #240)
|
|
||||||
|
|
||||||
1.7.1
|
1.7.1
|
||||||
=====
|
=====
|
||||||
Fixes:
|
Fixes:
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ include(GNUInstallDirs)
|
|||||||
|
|
||||||
set(PROJECT_VERSION_MAJOR 1)
|
set(PROJECT_VERSION_MAJOR 1)
|
||||||
set(PROJECT_VERSION_MINOR 7)
|
set(PROJECT_VERSION_MINOR 7)
|
||||||
set(PROJECT_VERSION_PATCH 5)
|
set(PROJECT_VERSION_PATCH 1)
|
||||||
set(CJSON_VERSION_SO 1)
|
set(CJSON_VERSION_SO 1)
|
||||||
set(CJSON_UTILS_VERSION_SO 1)
|
set(CJSON_UTILS_VERSION_SO 1)
|
||||||
set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
|
set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
|
||||||
@@ -107,6 +107,12 @@ endforeach()
|
|||||||
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${supported_compiler_flags}")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${supported_compiler_flags}")
|
||||||
|
|
||||||
|
#variables for pkg-config
|
||||||
|
set(prefix "${CMAKE_INSTALL_PREFIX}")
|
||||||
|
set(libdir "${CMAKE_INSTALL_LIBDIR}")
|
||||||
|
set(version "${PROJECT_VERSION}")
|
||||||
|
set(includedir "${CMAKE_INSTALL_INCLUDEDIR}")
|
||||||
|
|
||||||
option(BUILD_SHARED_LIBS "Build shared libraries" ON)
|
option(BUILD_SHARED_LIBS "Build shared libraries" ON)
|
||||||
option(ENABLE_TARGET_EXPORT "Enable exporting of CMake targets. Disable when it causes problems!" ON)
|
option(ENABLE_TARGET_EXPORT "Enable exporting of CMake targets. Disable when it causes problems!" ON)
|
||||||
|
|
||||||
@@ -143,15 +149,15 @@ endif()
|
|||||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/library_config/libcjson.pc.in"
|
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/library_config/libcjson.pc.in"
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/libcjson.pc" @ONLY)
|
"${CMAKE_CURRENT_BINARY_DIR}/libcjson.pc" @ONLY)
|
||||||
|
|
||||||
install(FILES cJSON.h DESTINATION "${CMAKE_INSTALL_FULL_INCLUDEDIR}/cjson")
|
install(FILES cJSON.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/cjson")
|
||||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/libcjson.pc" DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}/pkgconfig")
|
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/libcjson.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
|
||||||
install(TARGETS "${CJSON_LIB}" DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}" EXPORT "${CJSON_LIB}")
|
install(TARGETS "${CJSON_LIB}" DESTINATION "${CMAKE_INSTALL_LIBDIR}" EXPORT "${CJSON_LIB}")
|
||||||
if (BUILD_SHARED_AND_STATIC_LIBS)
|
if (BUILD_SHARED_AND_STATIC_LIBS)
|
||||||
install(TARGETS "${CJSON_LIB}-static" DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}")
|
install(TARGETS "${CJSON_LIB}-static" DESTINATION "${CMAKE_INSTALL_LIBDIR}")
|
||||||
endif()
|
endif()
|
||||||
if(ENABLE_TARGET_EXPORT)
|
if(ENABLE_TARGET_EXPORT)
|
||||||
# export library information for CMake projects
|
# export library information for CMake projects
|
||||||
install(EXPORT "${CJSON_LIB}" DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}/cmake/cJSON")
|
install(EXPORT "${CJSON_LIB}" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/cJSON")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set_target_properties("${CJSON_LIB}"
|
set_target_properties("${CJSON_LIB}"
|
||||||
@@ -182,15 +188,15 @@ if(ENABLE_CJSON_UTILS)
|
|||||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/library_config/libcjson_utils.pc.in"
|
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/library_config/libcjson_utils.pc.in"
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/libcjson_utils.pc" @ONLY)
|
"${CMAKE_CURRENT_BINARY_DIR}/libcjson_utils.pc" @ONLY)
|
||||||
|
|
||||||
install(TARGETS "${CJSON_UTILS_LIB}" DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}" EXPORT "${CJSON_UTILS_LIB}")
|
install(TARGETS "${CJSON_UTILS_LIB}" DESTINATION "${CMAKE_INSTALL_LIBDIR}" EXPORT "${CJSON_UTILS_LIB}")
|
||||||
if (BUILD_SHARED_AND_STATIC_LIBS)
|
if (BUILD_SHARED_AND_STATIC_LIBS)
|
||||||
install(TARGETS "${CJSON_UTILS_LIB}-static" DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}")
|
install(TARGETS "${CJSON_UTILS_LIB}-static" DESTINATION "${CMAKE_INSTALL_LIBDIR}")
|
||||||
endif()
|
endif()
|
||||||
install(FILES cJSON_Utils.h DESTINATION "${CMAKE_INSTALL_FULL_INCLUDEDIR}/cjson")
|
install(FILES cJSON_Utils.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/cjson")
|
||||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/libcjson_utils.pc" DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}/pkgconfig")
|
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/libcjson_utils.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
|
||||||
if(ENABLE_TARGET_EXPORT)
|
if(ENABLE_TARGET_EXPORT)
|
||||||
# export library information for CMake projects
|
# export library information for CMake projects
|
||||||
install(EXPORT "${CJSON_UTILS_LIB}" DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}/cmake/cJSON")
|
install(EXPORT "${CJSON_UTILS_LIB}" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/cJSON")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set_target_properties("${CJSON_UTILS_LIB}"
|
set_target_properties("${CJSON_UTILS_LIB}"
|
||||||
@@ -210,7 +216,7 @@ configure_file(
|
|||||||
# Install package config files
|
# Install package config files
|
||||||
install(FILES ${PROJECT_BINARY_DIR}/cJSONConfig.cmake
|
install(FILES ${PROJECT_BINARY_DIR}/cJSONConfig.cmake
|
||||||
${PROJECT_BINARY_DIR}/cJSONConfigVersion.cmake
|
${PROJECT_BINARY_DIR}/cJSONConfigVersion.cmake
|
||||||
DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}/cmake/cJSON")
|
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/cJSON")
|
||||||
|
|
||||||
option(ENABLE_CJSON_TEST "Enable building cJSON test" ON)
|
option(ENABLE_CJSON_TEST "Enable building cJSON test" ON)
|
||||||
if(ENABLE_CJSON_TEST)
|
if(ENABLE_CJSON_TEST)
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ Current Maintainer: [Max Bruckner](https://github.com/FSMaxB)
|
|||||||
* [Ajay Bhargav](https://github.com/ajaybhargav)
|
* [Ajay Bhargav](https://github.com/ajaybhargav)
|
||||||
* [Alper Akcan](https://github.com/alperakcan)
|
* [Alper Akcan](https://github.com/alperakcan)
|
||||||
* [Anton Sergeev](https://github.com/anton-sergeev)
|
* [Anton Sergeev](https://github.com/anton-sergeev)
|
||||||
* [Bob Kocisko](https://github.com/bobkocisko)
|
|
||||||
* [Christian Schulze](https://github.com/ChristianSch)
|
* [Christian Schulze](https://github.com/ChristianSch)
|
||||||
* [Casperinous](https://github.com/Casperinous)
|
* [Casperinous](https://github.com/Casperinous)
|
||||||
* [Debora Grosse](https://github.com/DeboraG)
|
* [Debora Grosse](https://github.com/DeboraG)
|
||||||
@@ -43,5 +42,3 @@ Current Maintainer: [Max Bruckner](https://github.com/FSMaxB)
|
|||||||
* [yangfl](https://github.com/yangfl)
|
* [yangfl](https://github.com/yangfl)
|
||||||
|
|
||||||
And probably more people on [SourceForge](https://sourceforge.net/p/cjson/bugs/search/?q=status%3Aclosed-rejected+or+status%3Aclosed-out-of-date+or+status%3Awont-fix+or+status%3Aclosed-fixed+or+status%3Aclosed&page=0)
|
And probably more people on [SourceForge](https://sourceforge.net/p/cjson/bugs/search/?q=status%3Aclosed-rejected+or+status%3Aclosed-out-of-date+or+status%3Awont-fix+or+status%3Aclosed-fixed+or+status%3Aclosed&page=0)
|
||||||
|
|
||||||
Also thanks to all the people who reported bugs and suggested new features.
|
|
||||||
|
|||||||
2
Makefile
2
Makefile
@@ -8,7 +8,7 @@ CJSON_TEST_SRC = cJSON.c test.c
|
|||||||
|
|
||||||
LDLIBS = -lm
|
LDLIBS = -lm
|
||||||
|
|
||||||
LIBVERSION = 1.7.5
|
LIBVERSION = 1.7.1
|
||||||
CJSON_SOVERSION = 1
|
CJSON_SOVERSION = 1
|
||||||
UTILS_SOVERSION = 1
|
UTILS_SOVERSION = 1
|
||||||
|
|
||||||
|
|||||||
132
cJSON.c
132
cJSON.c
@@ -82,7 +82,7 @@ CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *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 != 5)
|
#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 1)
|
||||||
#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
|
||||||
|
|
||||||
@@ -145,6 +145,9 @@ static void *internal_realloc(void *pointer, size_t size)
|
|||||||
#define internal_realloc realloc
|
#define internal_realloc realloc
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Compile time strlen for string literals */
|
||||||
|
#define static_strlen(literal) ((size_t)(sizeof(literal) - sizeof("")))
|
||||||
|
|
||||||
static internal_hooks global_hooks = { internal_malloc, internal_free, internal_realloc };
|
static internal_hooks global_hooks = { internal_malloc, internal_free, internal_realloc };
|
||||||
|
|
||||||
static unsigned char* cJSON_strdup(const unsigned char* string, const internal_hooks * const hooks)
|
static unsigned char* cJSON_strdup(const unsigned char* string, const internal_hooks * const hooks)
|
||||||
@@ -280,7 +283,7 @@ static cJSON_bool parse_number(cJSON * const item, parse_buffer * const input_bu
|
|||||||
/* copy the number into a temporary buffer and replace '.' with the decimal point
|
/* copy the number into a temporary buffer and replace '.' with the decimal point
|
||||||
* of the current locale (for strtod)
|
* of the current locale (for strtod)
|
||||||
* This also takes care of '\0' not necessarily being available for marking the end of the input */
|
* This also takes care of '\0' not necessarily being available for marking the end of the input */
|
||||||
for (i = 0; (i < (sizeof(number_c_string) - 1)) && can_access_at_index(input_buffer, i); i++)
|
for (i = 0; (i < (sizeof(number_c_string) - sizeof(""))) && can_access_at_index(input_buffer, i); i++)
|
||||||
{
|
{
|
||||||
switch (buffer_at_offset(input_buffer)[i])
|
switch (buffer_at_offset(input_buffer)[i])
|
||||||
{
|
{
|
||||||
@@ -506,7 +509,7 @@ static cJSON_bool print_number(const cJSON * const item, printbuffer * const out
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* sprintf failed or buffer overrun occured */
|
/* sprintf failed or buffer overrun occured */
|
||||||
if ((length < 0) || (length > (int)(sizeof(number_buffer) - 1)))
|
if ((length < 0) || (length > (int)(sizeof(number_buffer) - sizeof(""))))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -585,14 +588,14 @@ static unsigned char utf16_literal_to_utf8(const unsigned char * const input_poi
|
|||||||
unsigned char sequence_length = 0;
|
unsigned char sequence_length = 0;
|
||||||
unsigned char first_byte_mark = 0;
|
unsigned char first_byte_mark = 0;
|
||||||
|
|
||||||
if ((input_end - first_sequence) < 6)
|
if ((input_end - first_sequence) < ((int)static_strlen("\\uXXXX")))
|
||||||
{
|
{
|
||||||
/* input ends unexpectedly */
|
/* input ends unexpectedly */
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the first utf16 sequence */
|
/* get the first utf16 sequence */
|
||||||
first_code = parse_hex4(first_sequence + 2);
|
first_code = parse_hex4(first_sequence + static_strlen("\\u"));
|
||||||
|
|
||||||
/* check that the code is valid */
|
/* check that the code is valid */
|
||||||
if (((first_code >= 0xDC00) && (first_code <= 0xDFFF)))
|
if (((first_code >= 0xDC00) && (first_code <= 0xDFFF)))
|
||||||
@@ -603,11 +606,11 @@ static unsigned char utf16_literal_to_utf8(const unsigned char * const input_poi
|
|||||||
/* UTF16 surrogate pair */
|
/* UTF16 surrogate pair */
|
||||||
if ((first_code >= 0xD800) && (first_code <= 0xDBFF))
|
if ((first_code >= 0xD800) && (first_code <= 0xDBFF))
|
||||||
{
|
{
|
||||||
const unsigned char *second_sequence = first_sequence + 6;
|
const unsigned char *second_sequence = first_sequence + static_strlen("\\uXXXX");
|
||||||
unsigned int second_code = 0;
|
unsigned int second_code = 0;
|
||||||
sequence_length = 12; /* \uXXXX\uXXXX */
|
sequence_length = static_strlen("\\uXXXX\\uXXXX");
|
||||||
|
|
||||||
if ((input_end - second_sequence) < 6)
|
if ((input_end - second_sequence) < ((int)static_strlen("\\uXXXX")))
|
||||||
{
|
{
|
||||||
/* input ends unexpectedly */
|
/* input ends unexpectedly */
|
||||||
goto fail;
|
goto fail;
|
||||||
@@ -620,7 +623,7 @@ static unsigned char utf16_literal_to_utf8(const unsigned char * const input_poi
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* get the second utf16 sequence */
|
/* get the second utf16 sequence */
|
||||||
second_code = parse_hex4(second_sequence + 2);
|
second_code = parse_hex4(second_sequence + static_strlen("\\u"));
|
||||||
/* check that the code is valid */
|
/* check that the code is valid */
|
||||||
if ((second_code < 0xDC00) || (second_code > 0xDFFF))
|
if ((second_code < 0xDC00) || (second_code > 0xDFFF))
|
||||||
{
|
{
|
||||||
@@ -634,7 +637,7 @@ static unsigned char utf16_literal_to_utf8(const unsigned char * const input_poi
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sequence_length = 6; /* \uXXXX */
|
sequence_length = static_strlen("\\uXXXX");
|
||||||
codepoint = first_code;
|
codepoint = first_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -698,8 +701,8 @@ fail:
|
|||||||
/* Parse the input text into an unescaped cinput, and populate item. */
|
/* Parse the input text into an unescaped cinput, and populate item. */
|
||||||
static cJSON_bool parse_string(cJSON * const item, parse_buffer * const input_buffer)
|
static cJSON_bool parse_string(cJSON * const item, parse_buffer * const input_buffer)
|
||||||
{
|
{
|
||||||
const unsigned char *input_pointer = buffer_at_offset(input_buffer) + 1;
|
const unsigned char *input_pointer = buffer_at_offset(input_buffer) + static_strlen("\"");
|
||||||
const unsigned char *input_end = buffer_at_offset(input_buffer) + 1;
|
const unsigned char *input_end = buffer_at_offset(input_buffer) + static_strlen("\"");
|
||||||
unsigned char *output_pointer = NULL;
|
unsigned char *output_pointer = NULL;
|
||||||
unsigned char *output = NULL;
|
unsigned char *output = NULL;
|
||||||
|
|
||||||
@@ -718,7 +721,7 @@ static cJSON_bool parse_string(cJSON * const item, parse_buffer * const input_bu
|
|||||||
/* is escape sequence */
|
/* is escape sequence */
|
||||||
if (input_end[0] == '\\')
|
if (input_end[0] == '\\')
|
||||||
{
|
{
|
||||||
if ((size_t)(input_end + 1 - input_buffer->content) >= input_buffer->length)
|
if ((size_t)(input_end + sizeof("") - input_buffer->content) >= input_buffer->length)
|
||||||
{
|
{
|
||||||
/* prevent buffer overflow when last input character is a backslash */
|
/* prevent buffer overflow when last input character is a backslash */
|
||||||
goto fail;
|
goto fail;
|
||||||
@@ -753,7 +756,7 @@ static cJSON_bool parse_string(cJSON * const item, parse_buffer * const input_bu
|
|||||||
/* escape sequence */
|
/* escape sequence */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned char sequence_length = 2;
|
unsigned char sequence_length = static_strlen("\\X");
|
||||||
if ((input_end - input_pointer) < 1)
|
if ((input_end - input_pointer) < 1)
|
||||||
{
|
{
|
||||||
goto fail;
|
goto fail;
|
||||||
@@ -868,10 +871,10 @@ static cJSON_bool print_string_ptr(const unsigned char * const input, printbuffe
|
|||||||
escape_characters++;
|
escape_characters++;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (*input_pointer < 32)
|
if (*input_pointer < '\x20')
|
||||||
{
|
{
|
||||||
/* UTF-16 escape sequence uXXXX */
|
/* UTF-16 escape sequence */
|
||||||
escape_characters += 5;
|
escape_characters += static_strlen("uXXXX");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -888,7 +891,7 @@ static cJSON_bool print_string_ptr(const unsigned char * const input, printbuffe
|
|||||||
if (escape_characters == 0)
|
if (escape_characters == 0)
|
||||||
{
|
{
|
||||||
output[0] = '\"';
|
output[0] = '\"';
|
||||||
memcpy(output + 1, input, output_length);
|
memcpy(output + static_strlen("\""), input, output_length);
|
||||||
output[output_length + 1] = '\"';
|
output[output_length + 1] = '\"';
|
||||||
output[output_length + 2] = '\0';
|
output[output_length + 2] = '\0';
|
||||||
|
|
||||||
@@ -896,11 +899,11 @@ static cJSON_bool print_string_ptr(const unsigned char * const input, printbuffe
|
|||||||
}
|
}
|
||||||
|
|
||||||
output[0] = '\"';
|
output[0] = '\"';
|
||||||
output_pointer = output + 1;
|
output_pointer = output + static_strlen("\"");
|
||||||
/* copy the string */
|
/* copy the string */
|
||||||
for (input_pointer = input; *input_pointer != '\0'; (void)input_pointer++, output_pointer++)
|
for (input_pointer = input; *input_pointer != '\0'; (void)input_pointer++, output_pointer++)
|
||||||
{
|
{
|
||||||
if ((*input_pointer > 31) && (*input_pointer != '\"') && (*input_pointer != '\\'))
|
if ((*input_pointer >= '\x20') && (*input_pointer != '\"') && (*input_pointer != '\\'))
|
||||||
{
|
{
|
||||||
/* normal character, copy */
|
/* normal character, copy */
|
||||||
*output_pointer = *input_pointer;
|
*output_pointer = *input_pointer;
|
||||||
@@ -935,7 +938,7 @@ static cJSON_bool print_string_ptr(const unsigned char * const input, printbuffe
|
|||||||
default:
|
default:
|
||||||
/* escape and print as unicode codepoint */
|
/* escape and print as unicode codepoint */
|
||||||
sprintf((char*)output_pointer, "u%04x", *input_pointer);
|
sprintf((char*)output_pointer, "u%04x", *input_pointer);
|
||||||
output_pointer += 4;
|
output_pointer += static_strlen("XXXX");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -968,7 +971,7 @@ static parse_buffer *buffer_skip_whitespace(parse_buffer * const buffer)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (can_access_at_index(buffer, 0) && (buffer_at_offset(buffer)[0] <= 32))
|
while (can_access_at_index(buffer, 0) && (buffer_at_offset(buffer)[0] <= '\x20'))
|
||||||
{
|
{
|
||||||
buffer->offset++;
|
buffer->offset++;
|
||||||
}
|
}
|
||||||
@@ -989,9 +992,9 @@ static parse_buffer *skip_utf8_bom(parse_buffer * const buffer)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (can_access_at_index(buffer, 4) && (strncmp((const char*)buffer_at_offset(buffer), "\xEF\xBB\xBF", 3) == 0))
|
if (can_access_at_index(buffer, sizeof("\xEF\xBB\xBF")) && (strncmp((const char*)buffer_at_offset(buffer), "\xEF\xBB\xBF", static_strlen("\xEF\xBB\xBF")) == 0))
|
||||||
{
|
{
|
||||||
buffer->offset += 3;
|
buffer->offset += static_strlen("\xEF\xBB\xBF");
|
||||||
}
|
}
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
@@ -1219,25 +1222,25 @@ static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buf
|
|||||||
|
|
||||||
/* parse the different types of values */
|
/* parse the different types of values */
|
||||||
/* null */
|
/* null */
|
||||||
if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "null", 4) == 0))
|
if (can_read(input_buffer, static_strlen("null")) && (strncmp((const char*)buffer_at_offset(input_buffer), "null", static_strlen("null")) == 0))
|
||||||
{
|
{
|
||||||
item->type = cJSON_NULL;
|
item->type = cJSON_NULL;
|
||||||
input_buffer->offset += 4;
|
input_buffer->offset += static_strlen("null");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
/* false */
|
/* false */
|
||||||
if (can_read(input_buffer, 5) && (strncmp((const char*)buffer_at_offset(input_buffer), "false", 5) == 0))
|
if (can_read(input_buffer, static_strlen("false")) && (strncmp((const char*)buffer_at_offset(input_buffer), "false", static_strlen("false")) == 0))
|
||||||
{
|
{
|
||||||
item->type = cJSON_False;
|
item->type = cJSON_False;
|
||||||
input_buffer->offset += 5;
|
input_buffer->offset += static_strlen("false");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
/* true */
|
/* true */
|
||||||
if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "true", 4) == 0))
|
if (can_read(input_buffer, static_strlen("true")) && (strncmp((const char*)buffer_at_offset(input_buffer), "true", static_strlen("true")) == 0))
|
||||||
{
|
{
|
||||||
item->type = cJSON_True;
|
item->type = cJSON_True;
|
||||||
item->valueint = 1;
|
item->valueint = 1;
|
||||||
input_buffer->offset += 4;
|
input_buffer->offset += static_strlen("true");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
/* string */
|
/* string */
|
||||||
@@ -1277,7 +1280,7 @@ static cJSON_bool print_value(const cJSON * const item, printbuffer * const outp
|
|||||||
switch ((item->type) & 0xFF)
|
switch ((item->type) & 0xFF)
|
||||||
{
|
{
|
||||||
case cJSON_NULL:
|
case cJSON_NULL:
|
||||||
output = ensure(output_buffer, 5);
|
output = ensure(output_buffer, sizeof("null"));
|
||||||
if (output == NULL)
|
if (output == NULL)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -1286,7 +1289,7 @@ static cJSON_bool print_value(const cJSON * const item, printbuffer * const outp
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
case cJSON_False:
|
case cJSON_False:
|
||||||
output = ensure(output_buffer, 6);
|
output = ensure(output_buffer, sizeof("false"));
|
||||||
if (output == NULL)
|
if (output == NULL)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -1295,7 +1298,7 @@ static cJSON_bool print_value(const cJSON * const item, printbuffer * const outp
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
case cJSON_True:
|
case cJSON_True:
|
||||||
output = ensure(output_buffer, 5);
|
output = ensure(output_buffer, sizeof("true"));
|
||||||
if (output == NULL)
|
if (output == NULL)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -1311,6 +1314,10 @@ static cJSON_bool print_value(const cJSON * const item, printbuffer * const outp
|
|||||||
size_t raw_length = 0;
|
size_t raw_length = 0;
|
||||||
if (item->valuestring == NULL)
|
if (item->valuestring == NULL)
|
||||||
{
|
{
|
||||||
|
if (!output_buffer->noalloc)
|
||||||
|
{
|
||||||
|
output_buffer->hooks.deallocate(output_buffer->buffer);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1446,7 +1453,7 @@ static cJSON_bool print_array(const cJSON * const item, printbuffer * const outp
|
|||||||
|
|
||||||
/* Compose the output array. */
|
/* Compose the output array. */
|
||||||
/* opening square bracket */
|
/* opening square bracket */
|
||||||
output_pointer = ensure(output_buffer, 1);
|
output_pointer = ensure(output_buffer, static_strlen("["));
|
||||||
if (output_pointer == NULL)
|
if (output_pointer == NULL)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -1465,8 +1472,8 @@ static cJSON_bool print_array(const cJSON * const item, printbuffer * const outp
|
|||||||
update_offset(output_buffer);
|
update_offset(output_buffer);
|
||||||
if (current_element->next)
|
if (current_element->next)
|
||||||
{
|
{
|
||||||
length = (size_t) (output_buffer->format ? 2 : 1);
|
length = (size_t) (output_buffer->format ? static_strlen(", ") : static_strlen(","));
|
||||||
output_pointer = ensure(output_buffer, length + 1);
|
output_pointer = ensure(output_buffer, length + sizeof(""));
|
||||||
if (output_pointer == NULL)
|
if (output_pointer == NULL)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -1482,7 +1489,7 @@ static cJSON_bool print_array(const cJSON * const item, printbuffer * const outp
|
|||||||
current_element = current_element->next;
|
current_element = current_element->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
output_pointer = ensure(output_buffer, 2);
|
output_pointer = ensure(output_buffer, sizeof("]"));
|
||||||
if (output_pointer == NULL)
|
if (output_pointer == NULL)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -1616,8 +1623,8 @@ static cJSON_bool print_object(const cJSON * const item, printbuffer * const out
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Compose the output: */
|
/* Compose the output: */
|
||||||
length = (size_t) (output_buffer->format ? 2 : 1); /* fmt: {\n */
|
length = (size_t) (output_buffer->format ? static_strlen("{\n") : static_strlen("{"));
|
||||||
output_pointer = ensure(output_buffer, length + 1);
|
output_pointer = ensure(output_buffer, length + sizeof(""));
|
||||||
if (output_pointer == NULL)
|
if (output_pointer == NULL)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -1655,7 +1662,7 @@ static cJSON_bool print_object(const cJSON * const item, printbuffer * const out
|
|||||||
}
|
}
|
||||||
update_offset(output_buffer);
|
update_offset(output_buffer);
|
||||||
|
|
||||||
length = (size_t) (output_buffer->format ? 2 : 1);
|
length = (size_t) (output_buffer->format ? static_strlen(":\t") : static_strlen(":"));
|
||||||
output_pointer = ensure(output_buffer, length);
|
output_pointer = ensure(output_buffer, length);
|
||||||
if (output_pointer == NULL)
|
if (output_pointer == NULL)
|
||||||
{
|
{
|
||||||
@@ -1676,8 +1683,8 @@ static cJSON_bool print_object(const cJSON * const item, printbuffer * const out
|
|||||||
update_offset(output_buffer);
|
update_offset(output_buffer);
|
||||||
|
|
||||||
/* print comma if not last */
|
/* print comma if not last */
|
||||||
length = (size_t) ((output_buffer->format ? 1 : 0) + (current_item->next ? 1 : 0));
|
length = (size_t) ((output_buffer->format ? static_strlen(",") : static_strlen("")) + (current_item->next ? static_strlen(",") : static_strlen("")));
|
||||||
output_pointer = ensure(output_buffer, length + 1);
|
output_pointer = ensure(output_buffer, length + sizeof(""));
|
||||||
if (output_pointer == NULL)
|
if (output_pointer == NULL)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -1697,7 +1704,7 @@ static cJSON_bool print_object(const cJSON * const item, printbuffer * const out
|
|||||||
current_item = current_item->next;
|
current_item = current_item->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
output_pointer = ensure(output_buffer, output_buffer->format ? (output_buffer->depth + 1) : 2);
|
output_pointer = ensure(output_buffer, output_buffer->format ? (output_buffer->depth - 1 + sizeof("}")) : sizeof("}"));
|
||||||
if (output_pointer == NULL)
|
if (output_pointer == NULL)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -1895,37 +1902,32 @@ static void* cast_away_const(const void* string)
|
|||||||
|
|
||||||
static cJSON_bool add_item_to_object(cJSON * const object, const char * const string, cJSON * const item, const internal_hooks * const hooks, const cJSON_bool constant_key)
|
static cJSON_bool add_item_to_object(cJSON * const object, const char * const string, cJSON * const item, const internal_hooks * const hooks, const cJSON_bool constant_key)
|
||||||
{
|
{
|
||||||
char *new_key = NULL;
|
|
||||||
int new_type = cJSON_Invalid;
|
|
||||||
|
|
||||||
if ((object == NULL) || (string == NULL) || (item == NULL))
|
if ((object == NULL) || (string == NULL) || (item == NULL))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (constant_key)
|
|
||||||
{
|
|
||||||
new_key = (char*)cast_away_const(string);
|
|
||||||
new_type = item->type | cJSON_StringIsConst;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
new_key = (char*)cJSON_strdup((const unsigned char*)string, hooks);
|
|
||||||
if (new_key == NULL)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
new_type = item->type & ~cJSON_StringIsConst;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(item->type & cJSON_StringIsConst) && (item->string != NULL))
|
if (!(item->type & cJSON_StringIsConst) && (item->string != NULL))
|
||||||
{
|
{
|
||||||
hooks->deallocate(item->string);
|
hooks->deallocate(item->string);
|
||||||
}
|
}
|
||||||
|
|
||||||
item->string = new_key;
|
if (constant_key)
|
||||||
item->type = new_type;
|
{
|
||||||
|
item->string = (char*)cast_away_const(string);
|
||||||
|
item->type |= cJSON_StringIsConst;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *key = (char*)cJSON_strdup((const unsigned char*)string, hooks);
|
||||||
|
if (key == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
item->string = key;
|
||||||
|
item->type &= ~cJSON_StringIsConst;
|
||||||
|
}
|
||||||
|
|
||||||
return add_item_to_array(object, item);
|
return add_item_to_array(object, item);
|
||||||
}
|
}
|
||||||
@@ -2670,7 +2672,7 @@ CJSON_PUBLIC(void) cJSON_Minify(char *json)
|
|||||||
{
|
{
|
||||||
json++;
|
json++;
|
||||||
}
|
}
|
||||||
json += 2;
|
json += static_strlen("*/");
|
||||||
}
|
}
|
||||||
else if (*json == '\"')
|
else if (*json == '\"')
|
||||||
{
|
{
|
||||||
|
|||||||
2
cJSON.h
2
cJSON.h
@@ -31,7 +31,7 @@ extern "C"
|
|||||||
/* 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 5
|
#define CJSON_VERSION_PATCH 1
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
|||||||
@@ -988,12 +988,6 @@ static int apply_patch(cJSON *object, const cJSON *patch, const cJSON_bool case_
|
|||||||
cJSON_AddItemToObject(parent, (char*)child_pointer, value);
|
cJSON_AddItemToObject(parent, (char*)child_pointer, value);
|
||||||
value = NULL;
|
value = NULL;
|
||||||
}
|
}
|
||||||
else /* parent is not an object */
|
|
||||||
{
|
|
||||||
/* Couldn't find object to add to. */
|
|
||||||
status = 9;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (value != NULL)
|
if (value != NULL)
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
set(CJSON_UTILS_FOUND @ENABLE_CJSON_UTILS@)
|
set(CJSON_UTILS_FOUND @ENABLE_CJSON_UTILS@)
|
||||||
|
|
||||||
# The include directories used by cJSON
|
# The include directories used by cJSON
|
||||||
set(CJSON_INCLUDE_DIRS "@CMAKE_INSTALL_FULL_INCLUDEDIR@")
|
set(CJSON_INCLUDE_DIRS "@prefix@/@includedir@")
|
||||||
set(CJSON_INCLUDE_DIR "@CMAKE_INSTALL_FULL_INCLUDEDIR@")
|
set(CJSON_INCLUDE_DIR "@prefix@/@includedir@")
|
||||||
|
|
||||||
get_filename_component(_dir "${CMAKE_CURRENT_LIST_FILE}" PATH)
|
get_filename_component(_dir "${CMAKE_CURRENT_LIST_FILE}" PATH)
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
libdir=@CMAKE_INSTALL_FULL_LIBDIR@
|
prefix=@prefix@
|
||||||
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
|
libdir=${prefix}/@libdir@
|
||||||
|
includedir=${prefix}/@includedir@
|
||||||
|
|
||||||
Name: libcjson
|
Name: libcjson
|
||||||
Version: @PROJECT_VERSION@
|
Version: @version@
|
||||||
Description: Ultralightweight JSON parser in ANSI C
|
Description: Ultralightweight JSON parser in ANSI C
|
||||||
URL: https://github.com/DaveGamble/cJSON
|
URL: https://github.com/DaveGamble/cJSON
|
||||||
Libs: -L${libdir} -lcjson
|
Libs: -L${libdir} -lcjson
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
libdir=@CMAKE_INSTALL_FULL_LIBDIR@
|
prefix=@prefix@
|
||||||
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
|
libdir=${prefix}/@libdir@
|
||||||
|
includedir=${prefix}/@includedir@
|
||||||
|
|
||||||
Name: libcjson_utils
|
Name: libcjson_utils
|
||||||
Version: @PROJECT_VERSION@
|
Version: @version@
|
||||||
Description: An implementation of JSON Pointer, Patch and Merge Patch based on cJSON.
|
Description: An implementation of JSON Pointer, Patch and Merge Patch based on cJSON.
|
||||||
URL: https://github.com/DaveGamble/cJSON
|
URL: https://github.com/DaveGamble/cJSON
|
||||||
Libs: -L${libdir} -lcjson_utils
|
Libs: -L${libdir} -lcjson_utils
|
||||||
|
|||||||
@@ -80,12 +80,5 @@
|
|||||||
"doc": { "foo": ["bar"] },
|
"doc": { "foo": ["bar"] },
|
||||||
"patch": [ { "op": "add", "path": "/foo/-", "value": ["abc", "def"] }],
|
"patch": [ { "op": "add", "path": "/foo/-", "value": ["abc", "def"] }],
|
||||||
"expected": {"foo": ["bar", ["abc", "def"]] }
|
"expected": {"foo": ["bar", ["abc", "def"]] }
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"comment": "15",
|
|
||||||
"doc": {"foo": {"bar": 1}},
|
|
||||||
"patch": [{"op": "add", "path": "/foo/bar/baz", "value": "5"}],
|
|
||||||
"error": "attempting to add to subfield of non-object"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -508,25 +508,6 @@ static void cjson_create_array_reference_should_create_an_array_reference(void)
|
|||||||
cJSON_Delete(number_reference);
|
cJSON_Delete(number_reference);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cjson_add_item_to_object_should_not_use_after_free_when_string_is_aliased(void)
|
|
||||||
{
|
|
||||||
cJSON *object = cJSON_CreateObject();
|
|
||||||
cJSON *number = cJSON_CreateNumber(42);
|
|
||||||
char *name = (char*)cJSON_strdup((const unsigned char*)"number", &global_hooks);
|
|
||||||
|
|
||||||
TEST_ASSERT_NOT_NULL(object);
|
|
||||||
TEST_ASSERT_NOT_NULL(number);
|
|
||||||
TEST_ASSERT_NOT_NULL(name);
|
|
||||||
|
|
||||||
number->string = name;
|
|
||||||
|
|
||||||
/* The following should not have a use after free
|
|
||||||
* that would show up in valgrind or with AddressSanitizer */
|
|
||||||
cJSON_AddItemToObject(object, number->string, number);
|
|
||||||
|
|
||||||
cJSON_Delete(object);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
UNITY_BEGIN();
|
UNITY_BEGIN();
|
||||||
@@ -549,7 +530,6 @@ int main(void)
|
|||||||
RUN_TEST(cjson_create_string_reference_should_create_a_string_reference);
|
RUN_TEST(cjson_create_string_reference_should_create_a_string_reference);
|
||||||
RUN_TEST(cjson_create_object_reference_should_create_an_object_reference);
|
RUN_TEST(cjson_create_object_reference_should_create_an_object_reference);
|
||||||
RUN_TEST(cjson_create_array_reference_should_create_an_array_reference);
|
RUN_TEST(cjson_create_array_reference_should_create_an_array_reference);
|
||||||
RUN_TEST(cjson_add_item_to_object_should_not_use_after_free_when_string_is_aliased);
|
|
||||||
|
|
||||||
return UNITY_END();
|
return UNITY_END();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user