Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b0dfcde04c | ||
|
|
1934059554 | ||
|
|
cc84a446be | ||
|
|
e58f7ec027 | ||
|
|
4bfb880093 | ||
|
|
b7ce06224b | ||
|
|
227d3398d6 | ||
|
|
466eb8e3f8 | ||
|
|
4ec6e76ea2 | ||
|
|
a1b37d0abe | ||
|
|
3d971db426 | ||
|
|
30e1e7af7c | ||
|
|
76e5296d0d | ||
|
|
c597601cf1 |
@@ -1,7 +1,5 @@
|
|||||||
set(CMAKE_LEGACY_CYGWIN_WIN32 0)
|
set(CMAKE_LEGACY_CYGWIN_WIN32 0)
|
||||||
cmake_minimum_required(VERSION 2.8)
|
cmake_minimum_required(VERSION 2.8.5)
|
||||||
|
|
||||||
subdirs(tests fuzzing)
|
|
||||||
|
|
||||||
include(GNUInstallDirs)
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
@@ -9,7 +7,7 @@ project(cJSON C)
|
|||||||
|
|
||||||
set(PROJECT_VERSION_MAJOR 1)
|
set(PROJECT_VERSION_MAJOR 1)
|
||||||
set(PROJECT_VERSION_MINOR 4)
|
set(PROJECT_VERSION_MINOR 4)
|
||||||
set(PROJECT_VERSION_PATCH 1)
|
set(PROJECT_VERSION_PATCH 4)
|
||||||
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}")
|
||||||
@@ -78,10 +76,13 @@ foreach(compiler_flag ${custom_compiler_flags})
|
|||||||
|
|
||||||
CHECK_C_COMPILER_FLAG(${compiler_flag} "FLAG_SUPPORTED_${current_variable}")
|
CHECK_C_COMPILER_FLAG(${compiler_flag} "FLAG_SUPPORTED_${current_variable}")
|
||||||
if (FLAG_SUPPORTED_${current_variable})
|
if (FLAG_SUPPORTED_${current_variable})
|
||||||
|
list(APPEND supported_compiler_flags)
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${compiler_flag}")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${compiler_flag}")
|
||||||
endif()
|
endif()
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${supported_compiler_flags}")
|
||||||
|
|
||||||
#variables for pkg-config
|
#variables for pkg-config
|
||||||
set(prefix "${CMAKE_INSTALL_PREFIX}")
|
set(prefix "${CMAKE_INSTALL_PREFIX}")
|
||||||
set(libdir "${CMAKE_INSTALL_LIBDIR}")
|
set(libdir "${CMAKE_INSTALL_LIBDIR}")
|
||||||
@@ -167,9 +168,30 @@ if(ENABLE_CJSON_TEST)
|
|||||||
add_executable("${TEST_CJSON}" test.c)
|
add_executable("${TEST_CJSON}" test.c)
|
||||||
target_link_libraries("${TEST_CJSON}" "${CJSON_LIB}")
|
target_link_libraries("${TEST_CJSON}" "${CJSON_LIB}")
|
||||||
|
|
||||||
|
add_test(NAME ${TEST_CJSON} COMMAND "${CMAKE_CURRENT_BINARY_DIR}/${TEST_CJSON}")
|
||||||
|
|
||||||
|
# Disable -fsanitize=float-divide-by-zero for cJSON_test
|
||||||
|
if (FLAG_SUPPORTED_fsanitizefloatdividebyzero)
|
||||||
|
if ("${CMAKE_VERSION}" VERSION_LESS "2.8.12")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-sanitize=float-divide-by-zero")
|
||||||
|
else()
|
||||||
|
target_compile_options(${TEST_CJSON} PRIVATE "-fno-sanitize=float-divide-by-zero")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
if(ENABLE_CJSON_UTILS)
|
if(ENABLE_CJSON_UTILS)
|
||||||
set(TEST_CJSON_UTILS cJSON_test_utils)
|
set(TEST_CJSON_UTILS cJSON_test_utils)
|
||||||
add_executable("${TEST_CJSON_UTILS}" test_utils.c)
|
add_executable("${TEST_CJSON_UTILS}" test_utils.c)
|
||||||
target_link_libraries("${TEST_CJSON_UTILS}" "${CJSON_UTILS_LIB}")
|
target_link_libraries("${TEST_CJSON_UTILS}" "${CJSON_UTILS_LIB}")
|
||||||
|
|
||||||
|
add_test(NAME ${TEST_CJSON_UTILS} COMMAND "${CMAKE_CURRENT_BINARY_DIR}/${TEST_CJSON_UTILS}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
#"check" target that automatically builds everything and runs the tests
|
||||||
|
add_custom_target(check
|
||||||
|
COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure
|
||||||
|
DEPENDS ${TEST_CJSON} ${TEST_CJSON_UTILS})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
add_subdirectory(tests)
|
||||||
|
add_subdirectory(fuzzing)
|
||||||
|
|||||||
2
Makefile
2
Makefile
@@ -10,7 +10,7 @@ UTILS_TEST_SRC = cJSON.c cJSON_Utils.c test_utils.c
|
|||||||
|
|
||||||
LDLIBS = -lm
|
LDLIBS = -lm
|
||||||
|
|
||||||
LIBVERSION = 1.4.1
|
LIBVERSION = 1.4.4
|
||||||
CJSON_SOVERSION = 1
|
CJSON_SOVERSION = 1
|
||||||
UTILS_SOVERSION = 1
|
UTILS_SOVERSION = 1
|
||||||
|
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ Because the entire library is only one C file and one header file, you can just
|
|||||||
cJSON is written in ANSI C (C89) in order to support as many platforms and compilers as possible.
|
cJSON is written in ANSI C (C89) in order to support as many platforms and compilers as possible.
|
||||||
|
|
||||||
#### CMake
|
#### CMake
|
||||||
With CMake, cJSON supports a full blown build system. This way you get the most features. With CMake it is recommended to do an out of tree build, meaning the compiled files are put in a directory separate from the source files. So in order to build cJSON with CMake on a Unix platform, make a `build` directory and run CMake inside it.
|
With CMake, cJSON supports a full blown build system. This way you get the most features. CMake with an equal or higher version than 2.8.5 is supported. With CMake it is recommended to do an out of tree build, meaning the compiled files are put in a directory separate from the source files. So in order to build cJSON with CMake on a Unix platform, make a `build` directory and run CMake inside it.
|
||||||
|
|
||||||
```
|
```
|
||||||
mkdir build
|
mkdir build
|
||||||
@@ -97,10 +97,8 @@ make
|
|||||||
make DESTDIR=$pkgdir install
|
make DESTDIR=$pkgdir install
|
||||||
```
|
```
|
||||||
|
|
||||||
CMake supports a lot of different platforms, not only UNIX Makefiles, but only UNIX Makefiles have been tested. It works on GNU/Linux and has been confirmed to compile on some versions of macOS, Cygwin, FreeBSD, Solaris and OpenIndiana.
|
|
||||||
|
|
||||||
#### Makefile
|
#### Makefile
|
||||||
If you don't have CMake available, but still have make. You can use the makefile to build cJSON:
|
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.
|
Run this command in the directory with the source code and it will automatically compile static and shared libraries and a little test program.
|
||||||
|
|
||||||
|
|||||||
35
cJSON.c
35
cJSON.c
@@ -47,7 +47,7 @@ CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 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 != 4) || (CJSON_VERSION_PATCH != 1)
|
#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 4) || (CJSON_VERSION_PATCH != 4)
|
||||||
#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
|
||||||
|
|
||||||
@@ -253,13 +253,19 @@ static unsigned char* ensure(printbuffer * const p, size_t needed, const interna
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((p->length > 0) && (p->offset >= p->length))
|
||||||
|
{
|
||||||
|
/* make sure that offset is valid */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (needed > INT_MAX)
|
if (needed > INT_MAX)
|
||||||
{
|
{
|
||||||
/* sizes bigger than INT_MAX are currently not supported */
|
/* sizes bigger than INT_MAX are currently not supported */
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
needed += p->offset;
|
needed += p->offset + 1;
|
||||||
if (needed <= p->length)
|
if (needed <= p->length)
|
||||||
{
|
{
|
||||||
return p->buffer + p->offset;
|
return p->buffer + p->offset;
|
||||||
@@ -270,8 +276,7 @@ static unsigned char* ensure(printbuffer * const p, size_t needed, const interna
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* calculate new buffer size */
|
/* calculate new buffer size */
|
||||||
newsize = needed * 2;
|
if (newsize > (INT_MAX / 2))
|
||||||
if (newsize > INT_MAX)
|
|
||||||
{
|
{
|
||||||
/* overflow of int, use INT_MAX if possible */
|
/* overflow of int, use INT_MAX if possible */
|
||||||
if (needed <= INT_MAX)
|
if (needed <= INT_MAX)
|
||||||
@@ -283,6 +288,10 @@ static unsigned char* ensure(printbuffer * const p, size_t needed, const interna
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
newsize = needed * 2;
|
||||||
|
}
|
||||||
|
|
||||||
if (hooks->reallocate != NULL)
|
if (hooks->reallocate != NULL)
|
||||||
{
|
{
|
||||||
@@ -1226,7 +1235,7 @@ static cJSON_bool print_array(const cJSON * const item, const size_t depth, cons
|
|||||||
update_offset(output_buffer);
|
update_offset(output_buffer);
|
||||||
if (current_element->next)
|
if (current_element->next)
|
||||||
{
|
{
|
||||||
length = format ? 2 : 1;
|
length = (size_t) (format ? 2 : 1);
|
||||||
output_pointer = ensure(output_buffer, length + 1, hooks);
|
output_pointer = ensure(output_buffer, length + 1, hooks);
|
||||||
if (output_pointer == NULL)
|
if (output_pointer == NULL)
|
||||||
{
|
{
|
||||||
@@ -1362,7 +1371,7 @@ static cJSON_bool print_object(const cJSON * const item, const size_t depth, con
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Compose the output: */
|
/* Compose the output: */
|
||||||
length = format ? 2 : 1; /* fmt: {\n */
|
length = (size_t) (format ? 2 : 1); /* fmt: {\n */
|
||||||
output_pointer = ensure(output_buffer, length + 1, hooks);
|
output_pointer = ensure(output_buffer, length + 1, hooks);
|
||||||
if (output_pointer == NULL)
|
if (output_pointer == NULL)
|
||||||
{
|
{
|
||||||
@@ -1400,7 +1409,7 @@ static cJSON_bool print_object(const cJSON * const item, const size_t depth, con
|
|||||||
}
|
}
|
||||||
update_offset(output_buffer);
|
update_offset(output_buffer);
|
||||||
|
|
||||||
length = format ? 2 : 1;
|
length = (size_t) (format ? 2 : 1);
|
||||||
output_pointer = ensure(output_buffer, length, hooks);
|
output_pointer = ensure(output_buffer, length, hooks);
|
||||||
if (output_pointer == NULL)
|
if (output_pointer == NULL)
|
||||||
{
|
{
|
||||||
@@ -1421,7 +1430,7 @@ static cJSON_bool print_object(const cJSON * const item, const size_t depth, con
|
|||||||
update_offset(output_buffer);
|
update_offset(output_buffer);
|
||||||
|
|
||||||
/* print comma if not last */
|
/* print comma if not last */
|
||||||
length = (size_t) (format ? 1 : 0) + (current_item->next ? 1 : 0);
|
length = (size_t) ((format ? 1 : 0) + (current_item->next ? 1 : 0));
|
||||||
output_pointer = ensure(output_buffer, length + 1, hooks);
|
output_pointer = ensure(output_buffer, length + 1, hooks);
|
||||||
if (output_pointer == NULL)
|
if (output_pointer == NULL)
|
||||||
{
|
{
|
||||||
@@ -1580,6 +1589,10 @@ CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSO
|
|||||||
item->type &= ~cJSON_StringIsConst;
|
item->type &= ~cJSON_StringIsConst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined (__clang__) || ((__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))))
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#endif
|
||||||
|
#pragma GCC diagnostic ignored "-Wcast-qual"
|
||||||
/* Add an item to an object with constant string as key */
|
/* Add an item to an object with constant string as key */
|
||||||
CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item)
|
CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item)
|
||||||
{
|
{
|
||||||
@@ -1591,13 +1604,13 @@ CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJ
|
|||||||
{
|
{
|
||||||
global_hooks.deallocate(item->string);
|
global_hooks.deallocate(item->string);
|
||||||
}
|
}
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wcast-qual"
|
|
||||||
item->string = (char*)string;
|
item->string = (char*)string;
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
item->type |= cJSON_StringIsConst;
|
item->type |= cJSON_StringIsConst;
|
||||||
cJSON_AddItemToArray(object, item);
|
cJSON_AddItemToArray(object, item);
|
||||||
}
|
}
|
||||||
|
#if defined (__clang__) || ((__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))))
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item)
|
CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item)
|
||||||
{
|
{
|
||||||
|
|||||||
7
cJSON.h
7
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 4
|
#define CJSON_VERSION_MINOR 4
|
||||||
#define CJSON_VERSION_PATCH 1
|
#define CJSON_VERSION_PATCH 4
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
@@ -132,8 +132,9 @@ CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
|
|||||||
CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
|
CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
|
||||||
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
|
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
|
||||||
CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);
|
CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);
|
||||||
/* Render a cJSON entity to text using a buffer already allocated in memory with length buf_len. Returns 1 on success and 0 on failure. */
|
/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */
|
||||||
CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buf, const int len, const cJSON_bool fmt);
|
/* NOTE: If you are printing numbers, the buffer hat to be 63 bytes bigger then the printed JSON (worst case) */
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
|
||||||
/* Delete a cJSON entity and all subentities. */
|
/* Delete a cJSON entity and all subentities. */
|
||||||
CJSON_PUBLIC(void) cJSON_Delete(cJSON *c);
|
CJSON_PUBLIC(void) cJSON_Delete(cJSON *c);
|
||||||
|
|
||||||
|
|||||||
@@ -230,11 +230,11 @@ static void cJSONUtils_InplaceDecodePointerString(unsigned char *string)
|
|||||||
|
|
||||||
for (; *string; (void)s2++, string++)
|
for (; *string; (void)s2++, string++)
|
||||||
{
|
{
|
||||||
*s2 = (*string != '~')
|
*s2 = (unsigned char) ((*string != '~')
|
||||||
? (*string)
|
? (*string)
|
||||||
: ((*(++string) == '0')
|
: ((*(++string) == '0')
|
||||||
? '~'
|
? '~'
|
||||||
: '/');
|
: '/'));
|
||||||
}
|
}
|
||||||
|
|
||||||
*s2 = '\0';
|
*s2 = '\0';
|
||||||
|
|||||||
@@ -2,14 +2,20 @@ if(ENABLE_CJSON_TEST)
|
|||||||
add_library(unity unity/src/unity.c)
|
add_library(unity unity/src/unity.c)
|
||||||
|
|
||||||
# Disable -Werror for Unity
|
# Disable -Werror for Unity
|
||||||
list(FIND custom_compiler_flags "-Werror" werror_found)
|
if (FLAG_SUPPORTED_Werror)
|
||||||
if (werror_found)
|
if ("${CMAKE_VERSION}" VERSION_LESS "2.8.12")
|
||||||
target_compile_options(unity PRIVATE "-Wno-error")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-error")
|
||||||
|
else()
|
||||||
|
target_compile_options(unity PRIVATE "-Wno-error")
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
# Disable -fvisibility=hidden for Unity
|
# Disable -fvisibility=hidden for Unity
|
||||||
list(FIND custom_compiler_flags "-fvisibility=hidden" visibility_found)
|
if (FLAG_SUPPORTED_fvisibilityhidden)
|
||||||
if (visibility_found)
|
if ("${CMAKE_VERSION}" VERSION_LESS "2.8.12")
|
||||||
target_compile_options(unity PRIVATE "-fvisibility=default")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=default")
|
||||||
|
else()
|
||||||
|
target_compile_options(unity PRIVATE "-fvisibility=default")
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
#copy test files
|
#copy test files
|
||||||
@@ -46,20 +52,17 @@ if(ENABLE_CJSON_TEST)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
#"check" target that automatically builds everything and runs the tests
|
|
||||||
add_custom_target(check
|
|
||||||
COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure
|
|
||||||
DEPENDS ${unity_tests})
|
|
||||||
|
|
||||||
foreach(unity_test ${unity_tests})
|
foreach(unity_test ${unity_tests})
|
||||||
add_executable("${unity_test}" "${unity_test}.c")
|
add_executable("${unity_test}" "${unity_test}.c")
|
||||||
target_link_libraries("${unity_test}" "${CJSON_LIB}" unity test-common)
|
target_link_libraries("${unity_test}" "${CJSON_LIB}" unity test-common)
|
||||||
if(MEMORYCHECK_COMMAND)
|
if(MEMORYCHECK_COMMAND)
|
||||||
add_test(NAME "${unity_test}"
|
add_test(NAME "${unity_test}"
|
||||||
COMMAND "${MEMORYCHECK_COMMAND}" ${MEMORYCHECK_COMMAND_OPTIONS} "./${unity_test}")
|
COMMAND "${MEMORYCHECK_COMMAND}" ${MEMORYCHECK_COMMAND_OPTIONS} "${CMAKE_CURRENT_BINARY_DIR}/${unity_test}")
|
||||||
else()
|
else()
|
||||||
add_test(NAME "${unity_test}"
|
add_test(NAME "${unity_test}"
|
||||||
COMMAND "./${unity_test}")
|
COMMAND "./${unity_test}")
|
||||||
endif()
|
endif()
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
|
add_dependencies(check ${unity_tests})
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ static void print_number_should_print_negative_integers(void)
|
|||||||
{
|
{
|
||||||
assert_print_number("-1", -1);
|
assert_print_number("-1", -1);
|
||||||
assert_print_number("-32768", -32768);
|
assert_print_number("-32768", -32768);
|
||||||
assert_print_number("-2147483648", -2147483648);
|
assert_print_number("-2147483648", -2147483648.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_number_should_print_positive_integers(void)
|
static void print_number_should_print_positive_integers(void)
|
||||||
|
|||||||
Reference in New Issue
Block a user