Compare commits
3 Commits
v1.7.7
...
less-magic
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d48d988d7e | ||
|
|
15d9ec8b07 | ||
|
|
f07a3b7cb3 |
42
CHANGELOG.md
42
CHANGELOG.md
@@ -1,45 +1,3 @@
|
||||
1.7.7
|
||||
=====
|
||||
Fixes:
|
||||
------
|
||||
* Fix a memory leak when realloc fails (see #267), thanks @AlfieDeng for reporting
|
||||
* Fix a typo in the header file (see #266), thanks @zhaozhixu
|
||||
|
||||
1.7.6
|
||||
=====
|
||||
Fixes:
|
||||
------
|
||||
* Add `SONAME` to the ELF files built by the Makefile (see #252), thanks @YanhaoMo for reporting
|
||||
* Add include guards and `extern "C"` to `cJSON_Utils.h` (see #256), thanks @daschfg for reporting
|
||||
|
||||
Other changes:
|
||||
--------------
|
||||
* Mark the Makefile as deprecated in the README.
|
||||
|
||||
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
|
||||
=====
|
||||
Fixes:
|
||||
|
||||
@@ -7,7 +7,7 @@ include(GNUInstallDirs)
|
||||
|
||||
set(PROJECT_VERSION_MAJOR 1)
|
||||
set(PROJECT_VERSION_MINOR 7)
|
||||
set(PROJECT_VERSION_PATCH 7)
|
||||
set(PROJECT_VERSION_PATCH 1)
|
||||
set(CJSON_VERSION_SO 1)
|
||||
set(CJSON_UTILS_VERSION_SO 1)
|
||||
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}")
|
||||
|
||||
#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(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"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/libcjson.pc" @ONLY)
|
||||
|
||||
install(FILES cJSON.h DESTINATION "${CMAKE_INSTALL_FULL_INCLUDEDIR}/cjson")
|
||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/libcjson.pc" DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}/pkgconfig")
|
||||
install(TARGETS "${CJSON_LIB}" DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}" EXPORT "${CJSON_LIB}")
|
||||
install(FILES cJSON.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/cjson")
|
||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/libcjson.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
|
||||
install(TARGETS "${CJSON_LIB}" DESTINATION "${CMAKE_INSTALL_LIBDIR}" EXPORT "${CJSON_LIB}")
|
||||
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()
|
||||
if(ENABLE_TARGET_EXPORT)
|
||||
# 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()
|
||||
|
||||
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"
|
||||
"${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)
|
||||
install(TARGETS "${CJSON_UTILS_LIB}-static" DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}")
|
||||
install(TARGETS "${CJSON_UTILS_LIB}-static" DESTINATION "${CMAKE_INSTALL_LIBDIR}")
|
||||
endif()
|
||||
install(FILES cJSON_Utils.h DESTINATION "${CMAKE_INSTALL_FULL_INCLUDEDIR}/cjson")
|
||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/libcjson_utils.pc" DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}/pkgconfig")
|
||||
install(FILES cJSON_Utils.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/cjson")
|
||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/libcjson_utils.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
|
||||
if(ENABLE_TARGET_EXPORT)
|
||||
# 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()
|
||||
|
||||
set_target_properties("${CJSON_UTILS_LIB}"
|
||||
@@ -210,7 +216,7 @@ configure_file(
|
||||
# Install package config files
|
||||
install(FILES ${PROJECT_BINARY_DIR}/cJSONConfig.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)
|
||||
if(ENABLE_CJSON_TEST)
|
||||
|
||||
@@ -7,7 +7,6 @@ Current Maintainer: [Max Bruckner](https://github.com/FSMaxB)
|
||||
* [Ajay Bhargav](https://github.com/ajaybhargav)
|
||||
* [Alper Akcan](https://github.com/alperakcan)
|
||||
* [Anton Sergeev](https://github.com/anton-sergeev)
|
||||
* [Bob Kocisko](https://github.com/bobkocisko)
|
||||
* [Christian Schulze](https://github.com/ChristianSch)
|
||||
* [Casperinous](https://github.com/Casperinous)
|
||||
* [Debora Grosse](https://github.com/DeboraG)
|
||||
@@ -41,8 +40,5 @@ Current Maintainer: [Max Bruckner](https://github.com/FSMaxB)
|
||||
* [Stephan Gatzka](https://github.com/gatzka)
|
||||
* [Weston Schmidt](https://github.com/schmidtw)
|
||||
* [yangfl](https://github.com/yangfl)
|
||||
* [Zhao Zhixu](https://github.com/zhaozhixu)
|
||||
|
||||
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.
|
||||
|
||||
13
Makefile
13
Makefile
@@ -8,13 +8,10 @@ CJSON_TEST_SRC = cJSON.c test.c
|
||||
|
||||
LDLIBS = -lm
|
||||
|
||||
LIBVERSION = 1.7.7
|
||||
LIBVERSION = 1.7.1
|
||||
CJSON_SOVERSION = 1
|
||||
UTILS_SOVERSION = 1
|
||||
|
||||
CJSON_SO_LDFLAG=-Wl,-soname=$(CJSON_LIBNAME).so.$(CJSON_SOVERSION)
|
||||
UTILS_SO_LDFLAG=-Wl,-soname=$(UTILS_LIBNAME).so.$(UTILS_SOVERSION)
|
||||
|
||||
PREFIX ?= /usr/local
|
||||
INCLUDE_PATH ?= include/cjson
|
||||
LIBRARY_PATH ?= lib
|
||||
@@ -26,7 +23,7 @@ INSTALL ?= cp -a
|
||||
|
||||
# validate gcc version for use fstack-protector-strong
|
||||
MIN_GCC_VERSION = "4.9"
|
||||
GCC_VERSION := "`$(CC) -dumpversion`"
|
||||
GCC_VERSION := "`gcc -dumpversion`"
|
||||
IS_GCC_ABOVE_MIN_VERSION := $(shell expr "$(GCC_VERSION)" ">=" "$(MIN_GCC_VERSION)")
|
||||
ifeq "$(IS_GCC_ABOVE_MIN_VERSION)" "1"
|
||||
CFLAGS += -fstack-protector-strong
|
||||
@@ -45,8 +42,6 @@ STATIC = a
|
||||
## create dynamic (shared) library on Darwin (base OS for MacOSX and IOS)
|
||||
ifeq (Darwin, $(uname))
|
||||
SHARED = dylib
|
||||
CJSON_SO_LDFLAG = ""
|
||||
UTILS_SO_LDFLAG = ""
|
||||
endif
|
||||
|
||||
#cJSON library names
|
||||
@@ -95,10 +90,10 @@ $(UTILS_STATIC): $(UTILS_OBJ)
|
||||
#shared libraries .so.1.0.0
|
||||
#cJSON
|
||||
$(CJSON_SHARED_VERSION): $(CJSON_OBJ)
|
||||
$(CC) -shared -o $@ $< $(CJSON_SO_LDFLAG) $(LDFLAGS)
|
||||
$(CC) -shared -o $@ $< $(LDFLAGS)
|
||||
#cJSON_Utils
|
||||
$(UTILS_SHARED_VERSION): $(UTILS_OBJ)
|
||||
$(CC) -shared -o $@ $< $(UTILS_SO_LDFLAG) $(LDFLAGS)
|
||||
$(CC) -shared -o $@ $< $(LDFLAGS)
|
||||
|
||||
#objects
|
||||
#cJSON
|
||||
|
||||
@@ -127,11 +127,9 @@ make DESTDIR=$pkgdir install
|
||||
On Windows CMake is usually used to create a Visual Studio solution file by running it inside the Developer Command Prompt for Visual Studio, for exact steps follow the official documentation from CMake and Microsoft and use the online search engine of your choice. The descriptions of the the options above still generally apply, although not all of them work on Windows.
|
||||
|
||||
#### Makefile
|
||||
**NOTE:** This Method is deprecated. Use CMake if at all possible. Makefile support is limited to fixing bugs.
|
||||
|
||||
If you don't have CMake available, but still have GNU make. You can use the makefile to build cJSON:
|
||||
|
||||
Run this command in the directory with the source code and it will automatically compile static and shared libraries and a little test program (not the full test suite).
|
||||
Run this command in the directory with the source code and it will automatically compile static and shared libraries and a little test program.
|
||||
|
||||
```
|
||||
make all
|
||||
|
||||
135
cJSON.c
135
cJSON.c
@@ -41,6 +41,7 @@
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <float.h>
|
||||
#include <limits.h>
|
||||
#include <ctype.h>
|
||||
|
||||
@@ -81,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 */
|
||||
#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 7)
|
||||
#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.
|
||||
#endif
|
||||
|
||||
@@ -144,6 +145,9 @@ static void *internal_realloc(void *pointer, size_t size)
|
||||
#define internal_realloc realloc
|
||||
#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 unsigned char* cJSON_strdup(const unsigned char* string, const internal_hooks * const hooks)
|
||||
@@ -279,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
|
||||
* of the current locale (for strtod)
|
||||
* 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])
|
||||
{
|
||||
@@ -505,7 +509,7 @@ static cJSON_bool print_number(const cJSON * const item, printbuffer * const out
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
@@ -584,14 +588,14 @@ static unsigned char utf16_literal_to_utf8(const unsigned char * const input_poi
|
||||
unsigned char sequence_length = 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 */
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
if (((first_code >= 0xDC00) && (first_code <= 0xDFFF)))
|
||||
@@ -602,11 +606,11 @@ static unsigned char utf16_literal_to_utf8(const unsigned char * const input_poi
|
||||
/* UTF16 surrogate pair */
|
||||
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;
|
||||
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 */
|
||||
goto fail;
|
||||
@@ -619,7 +623,7 @@ static unsigned char utf16_literal_to_utf8(const unsigned char * const input_poi
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
if ((second_code < 0xDC00) || (second_code > 0xDFFF))
|
||||
{
|
||||
@@ -633,7 +637,7 @@ static unsigned char utf16_literal_to_utf8(const unsigned char * const input_poi
|
||||
}
|
||||
else
|
||||
{
|
||||
sequence_length = 6; /* \uXXXX */
|
||||
sequence_length = static_strlen("\\uXXXX");
|
||||
codepoint = first_code;
|
||||
}
|
||||
|
||||
@@ -697,8 +701,8 @@ fail:
|
||||
/* Parse the input text into an unescaped cinput, and populate item. */
|
||||
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_end = 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) + static_strlen("\"");
|
||||
unsigned char *output_pointer = NULL;
|
||||
unsigned char *output = NULL;
|
||||
|
||||
@@ -717,7 +721,7 @@ static cJSON_bool parse_string(cJSON * const item, parse_buffer * const input_bu
|
||||
/* is escape sequence */
|
||||
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 */
|
||||
goto fail;
|
||||
@@ -752,7 +756,7 @@ static cJSON_bool parse_string(cJSON * const item, parse_buffer * const input_bu
|
||||
/* escape sequence */
|
||||
else
|
||||
{
|
||||
unsigned char sequence_length = 2;
|
||||
unsigned char sequence_length = static_strlen("\\X");
|
||||
if ((input_end - input_pointer) < 1)
|
||||
{
|
||||
goto fail;
|
||||
@@ -867,10 +871,10 @@ static cJSON_bool print_string_ptr(const unsigned char * const input, printbuffe
|
||||
escape_characters++;
|
||||
break;
|
||||
default:
|
||||
if (*input_pointer < 32)
|
||||
if (*input_pointer < '\x20')
|
||||
{
|
||||
/* UTF-16 escape sequence uXXXX */
|
||||
escape_characters += 5;
|
||||
/* UTF-16 escape sequence */
|
||||
escape_characters += static_strlen("uXXXX");
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -887,7 +891,7 @@ static cJSON_bool print_string_ptr(const unsigned char * const input, printbuffe
|
||||
if (escape_characters == 0)
|
||||
{
|
||||
output[0] = '\"';
|
||||
memcpy(output + 1, input, output_length);
|
||||
memcpy(output + static_strlen("\""), input, output_length);
|
||||
output[output_length + 1] = '\"';
|
||||
output[output_length + 2] = '\0';
|
||||
|
||||
@@ -895,11 +899,11 @@ static cJSON_bool print_string_ptr(const unsigned char * const input, printbuffe
|
||||
}
|
||||
|
||||
output[0] = '\"';
|
||||
output_pointer = output + 1;
|
||||
output_pointer = output + static_strlen("\"");
|
||||
/* copy the string */
|
||||
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 */
|
||||
*output_pointer = *input_pointer;
|
||||
@@ -934,7 +938,7 @@ static cJSON_bool print_string_ptr(const unsigned char * const input, printbuffe
|
||||
default:
|
||||
/* escape and print as unicode codepoint */
|
||||
sprintf((char*)output_pointer, "u%04x", *input_pointer);
|
||||
output_pointer += 4;
|
||||
output_pointer += static_strlen("XXXX");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -967,7 +971,7 @@ static parse_buffer *buffer_skip_whitespace(parse_buffer * const buffer)
|
||||
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++;
|
||||
}
|
||||
@@ -988,9 +992,9 @@ static parse_buffer *skip_utf8_bom(parse_buffer * const buffer)
|
||||
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;
|
||||
@@ -1113,10 +1117,10 @@ static unsigned char *print(const cJSON * const item, cJSON_bool format, const i
|
||||
if (hooks->reallocate != NULL)
|
||||
{
|
||||
printed = (unsigned char*) hooks->reallocate(buffer->buffer, buffer->offset + 1);
|
||||
buffer->buffer = NULL;
|
||||
if (printed == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
buffer->buffer = NULL;
|
||||
}
|
||||
else /* otherwise copy the JSON over to a new buffer */
|
||||
{
|
||||
@@ -1218,25 +1222,25 @@ static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buf
|
||||
|
||||
/* parse the different types of values */
|
||||
/* 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;
|
||||
input_buffer->offset += 4;
|
||||
input_buffer->offset += static_strlen("null");
|
||||
return true;
|
||||
}
|
||||
/* 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;
|
||||
input_buffer->offset += 5;
|
||||
input_buffer->offset += static_strlen("false");
|
||||
return 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->valueint = 1;
|
||||
input_buffer->offset += 4;
|
||||
input_buffer->offset += static_strlen("true");
|
||||
return true;
|
||||
}
|
||||
/* string */
|
||||
@@ -1276,7 +1280,7 @@ static cJSON_bool print_value(const cJSON * const item, printbuffer * const outp
|
||||
switch ((item->type) & 0xFF)
|
||||
{
|
||||
case cJSON_NULL:
|
||||
output = ensure(output_buffer, 5);
|
||||
output = ensure(output_buffer, sizeof("null"));
|
||||
if (output == NULL)
|
||||
{
|
||||
return false;
|
||||
@@ -1285,7 +1289,7 @@ static cJSON_bool print_value(const cJSON * const item, printbuffer * const outp
|
||||
return true;
|
||||
|
||||
case cJSON_False:
|
||||
output = ensure(output_buffer, 6);
|
||||
output = ensure(output_buffer, sizeof("false"));
|
||||
if (output == NULL)
|
||||
{
|
||||
return false;
|
||||
@@ -1294,7 +1298,7 @@ static cJSON_bool print_value(const cJSON * const item, printbuffer * const outp
|
||||
return true;
|
||||
|
||||
case cJSON_True:
|
||||
output = ensure(output_buffer, 5);
|
||||
output = ensure(output_buffer, sizeof("true"));
|
||||
if (output == NULL)
|
||||
{
|
||||
return false;
|
||||
@@ -1310,6 +1314,10 @@ static cJSON_bool print_value(const cJSON * const item, printbuffer * const outp
|
||||
size_t raw_length = 0;
|
||||
if (item->valuestring == NULL)
|
||||
{
|
||||
if (!output_buffer->noalloc)
|
||||
{
|
||||
output_buffer->hooks.deallocate(output_buffer->buffer);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1445,7 +1453,7 @@ static cJSON_bool print_array(const cJSON * const item, printbuffer * const outp
|
||||
|
||||
/* Compose the output array. */
|
||||
/* opening square bracket */
|
||||
output_pointer = ensure(output_buffer, 1);
|
||||
output_pointer = ensure(output_buffer, static_strlen("["));
|
||||
if (output_pointer == NULL)
|
||||
{
|
||||
return false;
|
||||
@@ -1464,8 +1472,8 @@ static cJSON_bool print_array(const cJSON * const item, printbuffer * const outp
|
||||
update_offset(output_buffer);
|
||||
if (current_element->next)
|
||||
{
|
||||
length = (size_t) (output_buffer->format ? 2 : 1);
|
||||
output_pointer = ensure(output_buffer, length + 1);
|
||||
length = (size_t) (output_buffer->format ? static_strlen(", ") : static_strlen(","));
|
||||
output_pointer = ensure(output_buffer, length + sizeof(""));
|
||||
if (output_pointer == NULL)
|
||||
{
|
||||
return false;
|
||||
@@ -1481,7 +1489,7 @@ static cJSON_bool print_array(const cJSON * const item, printbuffer * const outp
|
||||
current_element = current_element->next;
|
||||
}
|
||||
|
||||
output_pointer = ensure(output_buffer, 2);
|
||||
output_pointer = ensure(output_buffer, sizeof("]"));
|
||||
if (output_pointer == NULL)
|
||||
{
|
||||
return false;
|
||||
@@ -1615,8 +1623,8 @@ static cJSON_bool print_object(const cJSON * const item, printbuffer * const out
|
||||
}
|
||||
|
||||
/* Compose the output: */
|
||||
length = (size_t) (output_buffer->format ? 2 : 1); /* fmt: {\n */
|
||||
output_pointer = ensure(output_buffer, length + 1);
|
||||
length = (size_t) (output_buffer->format ? static_strlen("{\n") : static_strlen("{"));
|
||||
output_pointer = ensure(output_buffer, length + sizeof(""));
|
||||
if (output_pointer == NULL)
|
||||
{
|
||||
return false;
|
||||
@@ -1654,7 +1662,7 @@ static cJSON_bool print_object(const cJSON * const item, printbuffer * const out
|
||||
}
|
||||
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);
|
||||
if (output_pointer == NULL)
|
||||
{
|
||||
@@ -1675,8 +1683,8 @@ static cJSON_bool print_object(const cJSON * const item, printbuffer * const out
|
||||
update_offset(output_buffer);
|
||||
|
||||
/* print comma if not last */
|
||||
length = (size_t) ((output_buffer->format ? 1 : 0) + (current_item->next ? 1 : 0));
|
||||
output_pointer = ensure(output_buffer, length + 1);
|
||||
length = (size_t) ((output_buffer->format ? static_strlen(",") : static_strlen("")) + (current_item->next ? static_strlen(",") : static_strlen("")));
|
||||
output_pointer = ensure(output_buffer, length + sizeof(""));
|
||||
if (output_pointer == NULL)
|
||||
{
|
||||
return false;
|
||||
@@ -1696,7 +1704,7 @@ static cJSON_bool print_object(const cJSON * const item, printbuffer * const out
|
||||
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)
|
||||
{
|
||||
return false;
|
||||
@@ -1894,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)
|
||||
{
|
||||
char *new_key = NULL;
|
||||
int new_type = cJSON_Invalid;
|
||||
|
||||
if ((object == NULL) || (string == NULL) || (item == NULL))
|
||||
{
|
||||
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))
|
||||
{
|
||||
hooks->deallocate(item->string);
|
||||
}
|
||||
|
||||
item->string = new_key;
|
||||
item->type = new_type;
|
||||
if (constant_key)
|
||||
{
|
||||
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);
|
||||
}
|
||||
@@ -2669,7 +2672,7 @@ CJSON_PUBLIC(void) cJSON_Minify(char *json)
|
||||
{
|
||||
json++;
|
||||
}
|
||||
json += 2;
|
||||
json += static_strlen("*/");
|
||||
}
|
||||
else if (*json == '\"')
|
||||
{
|
||||
|
||||
4
cJSON.h
4
cJSON.h
@@ -31,7 +31,7 @@ extern "C"
|
||||
/* project version */
|
||||
#define CJSON_VERSION_MAJOR 1
|
||||
#define CJSON_VERSION_MINOR 7
|
||||
#define CJSON_VERSION_PATCH 7
|
||||
#define CJSON_VERSION_PATCH 1
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
@@ -156,7 +156,7 @@ CJSON_PUBLIC(void) cJSON_Delete(cJSON *c);
|
||||
|
||||
/* Returns the number of items in an array (or object). */
|
||||
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
|
||||
/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */
|
||||
/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
|
||||
/* Get item "string" from object. Case insensitive. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
|
||||
|
||||
@@ -988,12 +988,6 @@ static int apply_patch(cJSON *object, const cJSON *patch, const cJSON_bool case_
|
||||
cJSON_AddItemToObject(parent, (char*)child_pointer, value);
|
||||
value = NULL;
|
||||
}
|
||||
else /* parent is not an object */
|
||||
{
|
||||
/* Couldn't find object to add to. */
|
||||
status = 9;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (value != NULL)
|
||||
|
||||
@@ -20,14 +20,6 @@
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef cJSON_Utils__h
|
||||
#define cJSON_Utils__h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "cJSON.h"
|
||||
|
||||
/* Implement RFC6901 (https://tools.ietf.org/html/rfc6901) JSON Pointer spec. */
|
||||
@@ -80,9 +72,3 @@ CJSON_PUBLIC(char *) cJSONUtils_FindPointerFromObjectTo(const cJSON * const obje
|
||||
/* Sorts the members of the object into alphabetical order. */
|
||||
CJSON_PUBLIC(void) cJSONUtils_SortObject(cJSON * const object);
|
||||
CJSON_PUBLIC(void) cJSONUtils_SortObjectCaseSensitive(cJSON * const object);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
set(CJSON_UTILS_FOUND @ENABLE_CJSON_UTILS@)
|
||||
|
||||
# The include directories used by cJSON
|
||||
set(CJSON_INCLUDE_DIRS "@CMAKE_INSTALL_FULL_INCLUDEDIR@")
|
||||
set(CJSON_INCLUDE_DIR "@CMAKE_INSTALL_FULL_INCLUDEDIR@")
|
||||
set(CJSON_INCLUDE_DIRS "@prefix@/@includedir@")
|
||||
set(CJSON_INCLUDE_DIR "@prefix@/@includedir@")
|
||||
|
||||
get_filename_component(_dir "${CMAKE_CURRENT_LIST_FILE}" PATH)
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
libdir=@CMAKE_INSTALL_FULL_LIBDIR@
|
||||
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
|
||||
prefix=@prefix@
|
||||
libdir=${prefix}/@libdir@
|
||||
includedir=${prefix}/@includedir@
|
||||
|
||||
Name: libcjson
|
||||
Version: @PROJECT_VERSION@
|
||||
Version: @version@
|
||||
Description: Ultralightweight JSON parser in ANSI C
|
||||
URL: https://github.com/DaveGamble/cJSON
|
||||
Libs: -L${libdir} -lcjson
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
libdir=@CMAKE_INSTALL_FULL_LIBDIR@
|
||||
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
|
||||
prefix=@prefix@
|
||||
libdir=${prefix}/@libdir@
|
||||
includedir=${prefix}/@includedir@
|
||||
|
||||
Name: libcjson_utils
|
||||
Version: @PROJECT_VERSION@
|
||||
Version: @version@
|
||||
Description: An implementation of JSON Pointer, Patch and Merge Patch based on cJSON.
|
||||
URL: https://github.com/DaveGamble/cJSON
|
||||
Libs: -L${libdir} -lcjson_utils
|
||||
|
||||
@@ -80,12 +80,5 @@
|
||||
"doc": { "foo": ["bar"] },
|
||||
"patch": [ { "op": "add", "path": "/foo/-", "value": ["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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
UNITY_BEGIN();
|
||||
@@ -549,7 +530,6 @@ int main(void)
|
||||
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_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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user