Compare commits

...

11 Commits

Author SHA1 Message Date
Max Bruckner
b7ce06224b Release version 1.4.3 2017-03-19 11:05:33 +01:00
Max Bruckner
227d3398d6 Fix the pragmas for Wcast-qual with old gcc versions 2017-03-18 17:52:33 +01:00
Max Bruckner
466eb8e3f8 Fix wconversion with old gcc (e.g. 4.3) 2017-03-18 17:52:04 +01:00
Max Bruckner
4ec6e76ea2 tests: print_number: Fix build on 32bit ppc (and potentially others) 2017-03-18 13:25:18 +01:00
Max Bruckner
a1b37d0abe Release Version 1.4.2 2017-03-16 01:28:23 +01:00
Max Bruckner
3d971db426 README: Mention supported cmake and make versions 2017-03-16 01:25:57 +01:00
Max Bruckner
30e1e7af7c CMake: Support cmake down to 2.8.5 2017-03-16 01:09:26 +01:00
Max Bruckner
76e5296d0d CMake: Fix per target disabling of compiler flags
The compiler flag detection was working incorrectly.
2017-03-16 00:22:53 +01:00
Max Bruckner
c597601cf1 tests: run cJSON_test{,_utils} along with the other tests 2017-03-15 20:11:19 +01:00
Max Bruckner
e3d5798896 Release version 1.4.1 2017-03-15 20:11:19 +01:00
Max Bruckner
cf1842dc6f fix: print_number didn't abort when out of memory 2017-03-15 00:09:45 +01:00
8 changed files with 83 additions and 54 deletions

View File

@@ -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 0) set(PROJECT_VERSION_PATCH 3)
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)

View File

@@ -10,7 +10,7 @@ UTILS_TEST_SRC = cJSON.c cJSON_Utils.c test_utils.c
LDLIBS = -lm LDLIBS = -lm
LIBVERSION = 1.4.0 LIBVERSION = 1.4.3
CJSON_SOVERSION = 1 CJSON_SOVERSION = 1
UTILS_SOVERSION = 1 UTILS_SOVERSION = 1

View File

@@ -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.

64
cJSON.c
View File

@@ -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 != 0) #if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 4) || (CJSON_VERSION_PATCH != 3)
#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
@@ -372,28 +372,30 @@ static cJSON_bool print_number(const cJSON * const item, printbuffer * const out
/* This is a nice tradeoff. */ /* This is a nice tradeoff. */
output_pointer = ensure(output_buffer, 64, hooks); output_pointer = ensure(output_buffer, 64, hooks);
if (output_pointer != NULL) if (output_pointer == NULL)
{ {
/* This checks for NaN and Infinity */ return false;
if ((d * 0) != 0) }
{
length = sprintf((char*)output_pointer, "null"); /* This checks for NaN and Infinity */
} if ((d * 0) != 0)
else if ((fabs(floor(d) - d) <= DBL_EPSILON) && (fabs(d) < 1.0e60)) {
{ length = sprintf((char*)output_pointer, "null");
/* integer */ }
length = sprintf((char*)output_pointer, "%.0f", d); else if ((fabs(floor(d) - d) <= DBL_EPSILON) && (fabs(d) < 1.0e60))
trim_zeroes = false; /* don't remove zeroes for "big integers" */ {
} /* integer */
else if ((fabs(d) < 1.0e-6) || (fabs(d) > 1.0e9)) length = sprintf((char*)output_pointer, "%.0f", d);
{ trim_zeroes = false; /* don't remove zeroes for "big integers" */
length = sprintf((char*)output_pointer, "%e", d); }
trim_zeroes = false; /* don't remove zeroes in engineering notation */ else if ((fabs(d) < 1.0e-6) || (fabs(d) > 1.0e9))
} {
else length = sprintf((char*)output_pointer, "%e", d);
{ trim_zeroes = false; /* don't remove zeroes in engineering notation */
length = sprintf((char*)output_pointer, "%f", d); }
} else
{
length = sprintf((char*)output_pointer, "%f", d);
} }
/* sprintf failed */ /* sprintf failed */
@@ -1224,7 +1226,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)
{ {
@@ -1360,7 +1362,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)
{ {
@@ -1398,7 +1400,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)
{ {
@@ -1419,7 +1421,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)
{ {
@@ -1578,6 +1580,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)
{ {
@@ -1589,13 +1595,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)
{ {

View File

@@ -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 0 #define CJSON_VERSION_PATCH 3
#include <stddef.h> #include <stddef.h>

View File

@@ -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';

View File

@@ -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()

View File

@@ -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)