Compare commits

..

38 Commits

Author SHA1 Message Date
Max Bruckner
08738673be Reorder the context fields 2018-03-25 23:32:03 +02:00
Max Bruckner
1b001ab047 parse: Pull length calculation out. 2018-03-25 23:32:03 +02:00
Max Bruckner
409c2aaea7 cJSON_MakeDuplicateRecursive 2018-03-25 23:32:03 +02:00
Max Bruckner
e8f56bd194 Context: Add duplicate_recursive for cJSON_Duplicate 2018-03-25 23:32:03 +02:00
Max Bruckner
064eec8208 Change name from Configuration to Context 2018-03-25 23:32:03 +02:00
Max Bruckner
050f982608 cJSON_DuplicateConfiguration 2018-03-25 23:32:03 +02:00
Max Bruckner
d2d19127d3 cJSON_ConfigurationChangeParseEnd -> cJSON_ConfigurationGetParseEnd
This is probably a better approach than potentially having a pointer
that points to garbage on the stack and gets written to by cJSON.
2018-03-25 23:32:03 +02:00
Max Bruckner
691a83a479 cJSON_CreateConfig: Don't allow configuration, always use default 2018-03-25 23:32:03 +02:00
Max Bruckner
ae9dc3e7db cJSON_ConfigurationChangeAllowDataAfterJson 2018-03-25 23:32:03 +02:00
Max Bruckner
eeaaaac63e cJSON_ConfigurationChangeCaseSensitivity 2018-03-25 23:32:03 +02:00
Max Bruckner
78b5bed9a0 cJSON_ConfigurationChangeFormat 2018-03-25 23:32:03 +02:00
Max Bruckner
1a8f732749 cJSON_ConfigurationChangePrebufferSize 2018-03-25 23:32:03 +02:00
Max Bruckner
88c39fa2e4 cJSON_ConfigurationChangeParseEnd
Add a pointer to an end position of parsing to the cJSON_Configuration
object. (Essentially like return_parse_end, but as offset instead of
pointer).
2018-03-25 23:32:03 +02:00
Max Bruckner
9d801d64ea cJSON_CreateConfiguration, cJSON_ConfigurationChange{Allocators,Userdata} 2018-03-25 23:32:03 +02:00
Max Bruckner
877fac0f90 allocation helpers for allocating with a configuration 2018-03-25 23:32:03 +02:00
Max Bruckner
98e0b586ca Add cJSON_Allocators new style allocator struct 2018-03-25 23:32:03 +02:00
Max Bruckner
dd1ba72ce2 cJSON_Compare: Extract compare with internal_configuration 2018-03-25 23:32:03 +02:00
Max Bruckner
515d11f55a default_configuration: Macro for the internal_configuration defaults 2018-03-25 23:32:03 +02:00
Max Bruckner
ba8fe0f479 internal_configuration: Add case_sensitive 2018-03-25 23:32:03 +02:00
Max Bruckner
f02f79ecbb cJSON_ParseWithOpts: Extract pasrse with internal_configuration
Also introduces a allow_data_after_json property in the internal
configuration.
2018-03-25 23:32:03 +02:00
Max Bruckner
d4e81cfe57 cJSON_Delete: Extract delete_item with internal_configuration 2018-03-25 23:32:03 +02:00
Max Bruckner
7030dc7c5b Put buffer_size into internal_configuration 2018-03-25 23:32:03 +02:00
Max Bruckner
27977adc93 Put format into internal_configuration 2018-03-25 23:32:03 +02:00
Max Bruckner
677f0cb1bb Rename internal_hooks -> internal_configuration, cJSON_New_item -> create_item 2018-03-25 23:32:03 +02:00
Max Bruckner
3ebc06196a Gitignore: add CLion files 2018-03-25 23:31:36 +02:00
Max Bruckner
fd5281bdd8 cJSON: cjson_min: Wrap arguments in parentheses 2018-03-25 15:12:15 +02:00
Max Bruckner
1f4044a707 cJSON.c: Remove unused cast 2018-03-25 15:11:56 +02:00
Max Bruckner
08a2ad3c59 is_{nan,infinity}: Wrap macro arguments in parentheses 2018-03-25 14:25:46 +02:00
Max Bruckner
b06fb10f94 cJSON.c: Remove unnecessary includes 2018-03-25 14:20:48 +02:00
Max Bruckner
ce5f31ac47 Remove superfluous null checks in can_read/access_at_index macros 2018-03-25 13:01:49 +02:00
Max Bruckner
0715259635 cJSON_Compare: Performance improvement for objects
Check the size to prevent comparing objects equal if they are prefixes
of each other.
2018-03-25 13:01:10 +02:00
Max Bruckner
f4cc4d7c63 parse_value: Check only first character at first
This should improve performance
2018-03-25 13:01:10 +02:00
Max Bruckner
952b1017ab print_number: Introduce fast path for integers.
Thanks @Tangerino for suggesting this optimisation.
2018-03-25 13:01:10 +02:00
Max Bruckner
0914640d79 Extract helper: double_to_saturated_integer 2018-03-25 13:01:10 +02:00
Max Bruckner
5ed383a0d1 is_nan and is_infinity macros 2018-03-25 13:01:06 +02:00
Max Bruckner
3e2c29528a CMake: Remove -fsanitize=float-divide-by-zero
This is so that NaN and INFINITY values can be produced.
2018-03-25 13:00:12 +02:00
Max Bruckner
b2bbc11d44 Fix #234: Different argument names between declaration and definition 2018-03-25 13:00:12 +02:00
Max Bruckner
06f4152008 print: Comment about why the buffer is reallocated 2018-03-25 13:00:12 +02:00
35 changed files with 1059 additions and 641 deletions

View File

@@ -1,23 +0,0 @@
root = true
[*]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[Makefile]
indent_style = tab
indent_size = unset
# ignore external repositories and test inputs
[tests/{unity,json-patch-tests,inputs}/*]
indent_style = unset
indent_size = unset
end_of_line = unset
charset = unset
trim_trailing_whitespace = unset
insert_final_newline = unset

2
.gitattributes vendored
View File

@@ -1,2 +0,0 @@
* text=auto
/tests/inputs/* text eol=lf

View File

@@ -1,42 +1,3 @@
1.7.10
======
Fixes:
------
* Fix package config file for `libcjson`. Thanks @shiluotang for reporting (#321)
* Correctly split lists in `cJSON_Utils`'s merge sort. Thanks @andysCaplin for the fix (#322)
1.7.9
=====
Fixes:
------
* Fix a bug where `cJSON_GetObjectItemCaseSensitive` would pass a nullpointer to `strcmp` when called on an array (#315). Thanks @yuweol for reporting.
* Fix error in `cJSON_Utils` where the case sensitivity was not respected (#317). Thanks @yuta-oxo for fixing.
* Fix some warnings detected by the Visual Studio Static Analyzer (#307). Thanks @bnason-nf
1.7.8
=====
Fixes:
------
* cJSON now works with the `__stdcall` calling convention on Windows, see #295, thanks @zhindes for contributing
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:

View File

@@ -7,7 +7,7 @@ include(GNUInstallDirs)
set(PROJECT_VERSION_MAJOR 1)
set(PROJECT_VERSION_MINOR 7)
set(PROJECT_VERSION_PATCH 10)
set(PROJECT_VERSION_PATCH 5)
set(CJSON_VERSION_SO 1)
set(CJSON_UTILS_VERSION_SO 1)
set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
@@ -49,15 +49,11 @@ if (ENABLE_CUSTOM_COMPILER_FLAGS)
-Wswitch-enum
)
elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
# Disable warning c4001 - nonstandard extension 'single line comment' was used
# Define _CRT_SECURE_NO_WARNINGS to disable deprecation warnings for "insecure" C library functions
list(APPEND custom_compiler_flags
/GS
/Za
/sdl
/W4
/wd4001
/D_CRT_SECURE_NO_WARNINGS
)
endif()
endif()
@@ -68,7 +64,6 @@ if (ENABLE_SANITIZERS)
-fno-omit-frame-pointer
-fsanitize=address
-fsanitize=undefined
-fsanitize=float-divide-by-zero
-fsanitize=float-cast-overflow
-fsanitize-address-use-after-scope
-fsanitize=integer

View File

@@ -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)
* [Benbuck Nason](https://github.com/bnason-nf)
* [Bob Kocisko](https://github.com/bobkocisko)
* [Christian Schulze](https://github.com/ChristianSch)
* [Casperinous](https://github.com/Casperinous)
@@ -42,9 +41,6 @@ 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)
* [yuta-oxo](https://github.com/yuta-oxo)
* [Zach Hindes](https://github.com/zhindes)
* [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)

View File

@@ -8,13 +8,10 @@ CJSON_TEST_SRC = cJSON.c test.c
LDLIBS = -lm
LIBVERSION = 1.7.10
LIBVERSION = 1.7.5
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

View File

@@ -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
@@ -298,7 +296,6 @@ In this example we want to build and parse the following JSON:
Let's build the above JSON and print it to a string:
```c
//create a monitor with a list of supported resolutions
//NOTE: Returns a heap allocated string, you are required to free it after use.
char* create_monitor(void)
{
const unsigned int resolution_numbers[3][2] = {
@@ -374,7 +371,6 @@ end:
Alternatively we can use the `cJSON_Add...ToObject` helper functions to make our lifes a little easier:
```c
//NOTE: Returns a heap allocated string, you are required to free it after use.
char *create_monitor_with_helpers(void)
{
const unsigned int resolution_numbers[3][2] = {

913
cJSON.c

File diff suppressed because it is too large Load Diff

157
cJSON.h
View File

@@ -28,60 +28,10 @@ extern "C"
{
#endif
#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
#define __WINDOWS__
#endif
#ifdef __WINDOWS__
/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 3 define options:
CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols
CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default)
CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
For *nix builds that support visibility attribute, you can define similar behavior by
setting default visibility to hidden by adding
-fvisibility=hidden (for gcc)
or
-xldscope=hidden (for sun cc)
to CFLAGS
then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does
*/
#define CJSON_CDECL __cdecl
#define CJSON_STDCALL __stdcall
/* export symbols by default, this is necessary for copy pasting the C and header file */
#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)
#define CJSON_EXPORT_SYMBOLS
#endif
#if defined(CJSON_HIDE_SYMBOLS)
#define CJSON_PUBLIC(type) type CJSON_STDCALL
#elif defined(CJSON_EXPORT_SYMBOLS)
#define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL
#elif defined(CJSON_IMPORT_SYMBOLS)
#define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL
#endif
#else /* !__WINDOWS__ */
#define CJSON_CDECL
#define CJSON_STDCALL
#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY)
#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
#else
#define CJSON_PUBLIC(type) type
#endif
#endif
/* project version */
#define CJSON_VERSION_MAJOR 1
#define CJSON_VERSION_MINOR 7
#define CJSON_VERSION_PATCH 10
#define CJSON_VERSION_PATCH 5
#include <stddef.h>
@@ -124,13 +74,63 @@ typedef struct cJSON
typedef struct cJSON_Hooks
{
/* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */
void *(CJSON_CDECL *malloc_fn)(size_t sz);
void (CJSON_CDECL *free_fn)(void *ptr);
void *(*malloc_fn)(size_t sz);
void (*free_fn)(void *ptr);
} cJSON_Hooks;
/* new style allocators with userdata (e.g. for pool allocators) */
typedef struct cJSON_Allocators
{
void *(*allocate)(size_t size, void *userdata);
void (*deallocate)(void *pointer, void *userdata);
void *(*reallocate)(void *pointer, size_t size, void *userdata); /* optional */
} cJSON_Allocators;
typedef int cJSON_bool;
#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
#define __WINDOWS__
#endif
#ifdef __WINDOWS__
/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 2 define options:
CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols
CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default)
CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
For *nix builds that support visibility attribute, you can define similar behavior by
setting default visibility to hidden by adding
-fvisibility=hidden (for gcc)
or
-xldscope=hidden (for sun cc)
to CFLAGS
then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does
*/
/* export symbols by default, this is necessary for copy pasting the C and header file */
#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)
#define CJSON_EXPORT_SYMBOLS
#endif
#if defined(CJSON_HIDE_SYMBOLS)
#define CJSON_PUBLIC(type) type __stdcall
#elif defined(CJSON_EXPORT_SYMBOLS)
#define CJSON_PUBLIC(type) __declspec(dllexport) type __stdcall
#elif defined(CJSON_IMPORT_SYMBOLS)
#define CJSON_PUBLIC(type) __declspec(dllimport) type __stdcall
#endif
#else /* !WIN32 */
#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY)
#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
#else
#define CJSON_PUBLIC(type) type
#endif
#endif
/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them.
* This is to prevent stack overflows. */
#ifndef CJSON_NESTING_LIMIT
@@ -140,31 +140,68 @@ typedef int cJSON_bool;
/* returns the version of cJSON as a string */
CJSON_PUBLIC(const char*) cJSON_Version(void);
/* Supply malloc, realloc and free functions to cJSON */
typedef void* cJSON_Context;
/*
* Create a context object that can be passed to several functions
* to configure their behavior and/or take their output. It will be set to the default values
* initially, they can be changed later using the builder pattern by passing it to functions
* that change one setting.
*
* A cJSON_Context object is dynamically allocated and you are responsible to free it
* after use.
*
* If allocators is a NULL pointer, malloc and free are used.
*
* allocator_userdata can be used to pass custom data to your allocator (e.g. for pool allocators).
* */
CJSON_PUBLIC(cJSON_Context) cJSON_CreateContext(const cJSON_Allocators * const allocators, void *allocator_userdata);
/* Create a copy of an existing context */
CJSON_PUBLIC(cJSON_Context) cJSON_DuplicateContext(const cJSON_Context, const cJSON_Allocators * const allocators, void *allocator_userdata);
/* The following functions work on a context in order to set and retrieve data: */
/* Change the allocators of a cJSON_Context and reset the userdata */
CJSON_PUBLIC(cJSON_Context) cJSON_SetAllocators(cJSON_Context context, const cJSON_Allocators allocators);
/* Change the allocator userdata attached to a cJSON_Context */
CJSON_PUBLIC(cJSON_Context) cJSON_SetUserdata(cJSON_Context context, void *userdata);
/* Get the position relative to the JSON where the parser stopped, return 0 if invalid. */
CJSON_PUBLIC(size_t) cJSON_GetParseEnd(cJSON_Context context);
/* Set how many bytes should be initially allocated for printing */
CJSON_PUBLIC(cJSON_Context) cJSON_SetPrebufferSize(cJSON_Context context, const size_t buffer_size);
typedef enum { CJSON_FORMAT_MINIFIED = 0, CJSON_FORMAT_DEFAULT = 1 } cJSON_Format;
/* Change the format for printing */
CJSON_PUBLIC(cJSON_Context) cJSON_SetFormat(cJSON_Context context, cJSON_Format format);
/* Change the case sensitivity */
CJSON_PUBLIC(cJSON_Context) cJSON_MakeCaseSensitive(cJSON_Context context, cJSON_bool case_sensitive);
/* Change if data is allowed after the JSON */
CJSON_PUBLIC(cJSON_Context) cJSON_AllowDataAfterJson(cJSON_Context context, cJSON_bool allow_data_after_json);
/* Change if cJSON_Duplicate copies recursively */
CJSON_PUBLIC(cJSON_Context) cJSON_MakeDuplicateRecursive(cJSON_Context context, cJSON_bool recursive);
/* Supply malloc and free functions to cJSON globally */
CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks);
/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *json);
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *json, const char **return_parse_end, cJSON_bool require_null_terminated);
/* Render a cJSON entity to text for transfer/storage. */
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
/* Render a cJSON entity to text for transfer/storage without any formatting. */
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 */
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 format);
/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */
/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */
CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
/* Delete a cJSON entity and all subentities. */
CJSON_PUBLIC(void) cJSON_Delete(cJSON *c);
CJSON_PUBLIC(void) cJSON_Delete(cJSON *item);
/* 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);

View File

@@ -499,7 +499,6 @@ static cJSON *sort_list(cJSON *list, const cJSON_bool case_sensitive)
{
/* Split the lists */
second->prev->next = NULL;
second->prev = NULL;
}
/* Recursively sort the sub-lists. */
@@ -511,7 +510,7 @@ static cJSON *sort_list(cJSON *list, const cJSON_bool case_sensitive)
while ((first != NULL) && (second != NULL))
{
cJSON *smaller = NULL;
if (compare_strings((unsigned char*)first->string, (unsigned char*)second->string, case_sensitive) < 0)
if (compare_strings((unsigned char*)first->string, (unsigned char*)second->string, false) < 0)
{
smaller = first;
}

View File

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

View File

@@ -6,5 +6,5 @@ Version: @PROJECT_VERSION@
Description: Ultralightweight JSON parser in ANSI C
URL: https://github.com/DaveGamble/cJSON
Libs: -L${libdir} -lcjson
Libs.private: -lm
Libs.Private: -lm
Cflags: -I${includedir}

2
test.c
View File

@@ -256,7 +256,7 @@ static void create_objects(void)
cJSON_Delete(root);
}
int CJSON_CDECL main(void)
int main(void)
{
/* print the version */
printf("Version: %s\n", cJSON_Version());

View File

@@ -1,5 +1,5 @@
if(ENABLE_CJSON_TEST)
add_library(unity STATIC unity/src/unity.c)
add_library(unity "${CJSON_LIBRARY_TYPE}" unity/src/unity.c)
# Disable -Werror for Unity
if (FLAG_SUPPORTED_Werror)
@@ -57,6 +57,7 @@ if(ENABLE_CJSON_TEST)
compare_tests
cjson_add
readme_examples
context_tests
)
option(ENABLE_VALGRIND OFF "Enable the valgrind memory checker for the tests.")
@@ -72,9 +73,6 @@ if(ENABLE_CJSON_TEST)
foreach(unity_test ${unity_tests})
add_executable("${unity_test}" "${unity_test}.c")
if("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
target_sources(${unity_test} PRIVATE unity_setup.c)
endif()
target_link_libraries("${unity_test}" "${CJSON_LIB}" unity)
if(MEMORYCHECK_COMMAND)
add_test(NAME "${unity_test}"

View File

@@ -28,21 +28,15 @@
#include "unity/src/unity.h"
#include "common.h"
static void * CJSON_CDECL failing_malloc(size_t size)
static void *failing_malloc(size_t size)
{
(void)size;
return NULL;
}
/* work around MSVC error C2322: '...' address of dillimport '...' is not static */
static void CJSON_CDECL normal_free(void *pointer)
{
free(pointer);
}
static cJSON_Hooks failing_hooks = {
failing_malloc,
normal_free
free
};
static void cjson_add_null_should_add_null(void)
@@ -378,7 +372,7 @@ static void cjson_add_array_should_fail_on_allocation_failure(void)
cJSON_Delete(root);
}
int CJSON_CDECL main(void)
int main(void)
{
UNITY_BEGIN();

View File

@@ -33,11 +33,11 @@ void reset(cJSON *item) {
}
if ((item->valuestring != NULL) && !(item->type & cJSON_IsReference))
{
global_hooks.deallocate(item->valuestring);
global_context.allocators.deallocate(item->valuestring, global_context.userdata);
}
if ((item->string != NULL) && !(item->type & cJSON_StringIsConst))
{
global_hooks.deallocate(item->string);
global_context.allocators.deallocate(item->string, global_context.userdata);
}
memset(item, 0, sizeof(cJSON));

View File

@@ -186,7 +186,7 @@ static void cjson_compare_should_compare_objects(void)
false))
}
int CJSON_CDECL main(void)
int main(void)
{
UNITY_BEGIN();

278
tests/context_tests.c Normal file
View File

@@ -0,0 +1,278 @@
/*
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "unity/examples/unity_config.h"
#include "unity/src/unity.h"
#include "common.h"
static void create_context_should_create_a_context(void)
{
internal_context *context = NULL;
context = (internal_context*)cJSON_CreateContext(NULL, NULL);
TEST_ASSERT_NOT_NULL(context);
TEST_ASSERT_EQUAL_MESSAGE(context->buffer_size, 256, "buffer_size has an incorrect value.");
TEST_ASSERT_TRUE_MESSAGE(context->format, "format has an incorrect value.");
TEST_ASSERT_TRUE_MESSAGE(context->case_sensitive, "case_sensitive has an incorrect value.");
TEST_ASSERT_TRUE_MESSAGE(context->allow_data_after_json, "allow_data_after_json has an incorrect value.");
TEST_ASSERT_NULL_MESSAGE(context->userdata, "Userdata should be NULL");
TEST_ASSERT_TRUE_MESSAGE(context->duplicate_recursive, "Duplicating is not recursive.");
TEST_ASSERT_TRUE_MESSAGE(malloc_wrapper == context->allocators.allocate, "Wrong malloc.");
TEST_ASSERT_TRUE_MESSAGE(realloc_wrapper == context->allocators.reallocate, "Wrong realloc.");
TEST_ASSERT_TRUE_MESSAGE(free_wrapper == context->allocators.deallocate, "Wrong free.");
free(context);
}
static void* custom_allocator(size_t size, void *userdata)
{
*((size_t*)userdata) = size;
return malloc(size);
}
static void custom_deallocator(void *pointer, void *userdata)
{
*((size_t*)userdata) = (size_t)pointer;
free(pointer);
}
static void create_context_should_take_custom_allocators(void)
{
internal_context *context = NULL;
cJSON_Allocators allocators = {custom_allocator, custom_deallocator, NULL};
size_t userdata = 0;
context = (internal_context*)cJSON_CreateContext(&allocators, &userdata);
TEST_ASSERT_NOT_NULL(context);
TEST_ASSERT_EQUAL_MESSAGE(userdata, sizeof(internal_context), "custom allocator wasn't run properly.");
TEST_ASSERT_TRUE_MESSAGE(global_default_context.allocators.allocate == context->allocators.allocate, "Wrong allocator.");
TEST_ASSERT_TRUE_MESSAGE(global_default_context.allocators.deallocate == context->allocators.deallocate, "Wrong deallocator.");
TEST_ASSERT_TRUE_MESSAGE(global_default_context.allocators.reallocate == context->allocators.reallocate, "Wrong reallocator.");
custom_deallocator(context, &userdata);
}
static void create_context_should_not_take_incomplete_allocators(void)
{
cJSON_Allocators allocators1 = {custom_allocator, NULL, NULL};
cJSON_Allocators allocators2 = {NULL, custom_deallocator, NULL};
size_t userdata = 0;
TEST_ASSERT_NULL(cJSON_CreateContext(&allocators1, &userdata));
TEST_ASSERT_NULL(cJSON_CreateContext(&allocators2, &userdata));
}
static void duplicate_context_should_duplicate_a_context(void)
{
internal_context *context = NULL;
context = (internal_context*)cJSON_DuplicateContext(&global_context, NULL, NULL);
TEST_ASSERT_NOT_NULL(context);
TEST_ASSERT_EQUAL_MEMORY(&global_context, context, sizeof(internal_context));
free(context);
}
static void duplicate_context_should_take_custom_allocators(void)
{
internal_context *context = NULL;
cJSON_Allocators allocators = {custom_allocator, custom_deallocator, NULL};
size_t userdata = 0;
context = (internal_context*)cJSON_DuplicateContext(&global_context, &allocators, &userdata);
TEST_ASSERT_NOT_NULL(context);
TEST_ASSERT_EQUAL_MESSAGE(userdata, sizeof(internal_context), "custom allocator wasn't run properly");
TEST_ASSERT_EQUAL_MEMORY(&global_context, context, sizeof(internal_context));
free(context);
}
static void duplicate_context_should_not_take_incomplete_allocators(void)
{
cJSON_Allocators allocators1 = {custom_allocator, NULL, NULL};
cJSON_Allocators allocators2 = {NULL, custom_deallocator, NULL};
size_t userdata = 0;
TEST_ASSERT_NULL(cJSON_DuplicateContext(&global_context, &allocators1, &userdata));
TEST_ASSERT_NULL(cJSON_DuplicateContext(&global_context, &allocators2, &userdata));
}
static void set_allocators_should_set_allocators(void)
{
internal_context *context = NULL;
cJSON_Allocators allocators = {custom_allocator, custom_deallocator, NULL};
size_t userdata = 0;
context = (internal_context*)cJSON_CreateContext(&allocators, &userdata);
TEST_ASSERT_NOT_NULL(context);
context = (internal_context*)cJSON_SetAllocators(context, allocators);
TEST_ASSERT_NOT_NULL(context);
TEST_ASSERT_TRUE_MESSAGE(custom_allocator == context->allocators.allocate, "Wrong allocator.");
TEST_ASSERT_TRUE_MESSAGE(custom_deallocator == context->allocators.deallocate, "Wrong deallocator.");
TEST_ASSERT_NULL_MESSAGE(context->allocators.reallocate, "Reallocator is not null");
custom_deallocator(context, &userdata);
}
static void set_allocators_should_not_set_incomplete_allocators(void)
{
internal_context *context = NULL;
cJSON_Allocators allocators1 = {custom_allocator, NULL, NULL};
cJSON_Allocators allocators2 = {NULL, custom_deallocator, NULL};
context = (internal_context*)cJSON_CreateContext(NULL, NULL);
TEST_ASSERT_NOT_NULL(context);
TEST_ASSERT_NULL(cJSON_SetAllocators(context, allocators1));
TEST_ASSERT_NULL(cJSON_SetAllocators(context, allocators2));
free(context);
}
static void set_userdata_should_set_userdata(void)
{
internal_context *context = NULL;
size_t userdata = 0;
context = (internal_context*)cJSON_CreateContext(NULL, NULL);
TEST_ASSERT_NOT_NULL(context);
context = (internal_context*)cJSON_SetUserdata(context, &userdata);
TEST_ASSERT_TRUE_MESSAGE(context->userdata == &userdata, "Userdata is incorrect.");
free(context);
}
static void get_parse_end_should_get_the_parse_end(void)
{
internal_context context = global_default_context;
context.end_position = 42;
TEST_ASSERT_EQUAL_MESSAGE(cJSON_GetParseEnd(&context), 42, "Failed to get parse end.");
}
static void set_prebuffer_size_should_set_buffer_size(void)
{
internal_context *context = (internal_context*)cJSON_CreateContext(NULL, NULL);
TEST_ASSERT_NOT_NULL(context);
context = (internal_context*)cJSON_SetPrebufferSize(context, 1024);
TEST_ASSERT_NOT_NULL(context);
TEST_ASSERT_EQUAL_MESSAGE(context->buffer_size, 1024, "Didn't set the buffer size correctly.");
free(context);
}
static void set_prebuffer_size_should_not_allow_empty_sizes(void)
{
internal_context *context = (internal_context*)cJSON_CreateContext(NULL, NULL);
TEST_ASSERT_NOT_NULL(context);
TEST_ASSERT_NULL(cJSON_SetPrebufferSize(context, 0));
free(context);
}
static void set_format_should_set_format(void)
{
internal_context *context = (internal_context*)cJSON_CreateContext(NULL, NULL);
TEST_ASSERT_NOT_NULL(context);
context = (internal_context*)cJSON_SetFormat(context, CJSON_FORMAT_MINIFIED);
TEST_ASSERT_NOT_NULL(context);
TEST_ASSERT_FALSE_MESSAGE(context->format, "Failed to set CJSON_FORMAT_MINIFIED.");
context = (internal_context*)cJSON_SetFormat(context, CJSON_FORMAT_DEFAULT);
TEST_ASSERT_NOT_NULL(context);
TEST_ASSERT_TRUE_MESSAGE(context->format, "Failed to set CJSON_FORMAT_DEFAULT.");
TEST_ASSERT_NULL_MESSAGE(cJSON_SetFormat(context, (cJSON_Format)3), "Failed to detect invalid format.");
free(context);
}
static void make_case_sensitive_should_change_case_sensitivity(void)
{
internal_context *context = (internal_context*)cJSON_CreateContext(NULL, NULL);
TEST_ASSERT_NOT_NULL(context);
context = (internal_context*)cJSON_MakeCaseSensitive(context, false);
TEST_ASSERT_NOT_NULL(context);
TEST_ASSERT_FALSE_MESSAGE(context->case_sensitive, "Didn't set the case sensitivity correctly.");
free(context);
}
static void allow_data_after_json_should_change_allow_data_after_json(void)
{
internal_context *context = (internal_context*)cJSON_CreateContext(NULL, NULL);
TEST_ASSERT_NOT_NULL(context);
context = (internal_context*)cJSON_AllowDataAfterJson(context, false);
TEST_ASSERT_NOT_NULL(context);
TEST_ASSERT_FALSE_MESSAGE(context->allow_data_after_json, "Didn't set allow_data_after_json property correctly.");
free(context);
}
static void make_duplicate_recursive_should_make_duplicate_recursive(void)
{
internal_context *context = (internal_context*)cJSON_CreateContext(NULL, NULL);
TEST_ASSERT_NOT_NULL(context);
context = (internal_context*)cJSON_MakeDuplicateRecursive(context, false);
TEST_ASSERT_NOT_NULL(context);
TEST_ASSERT_FALSE_MESSAGE(context->duplicate_recursive, "Duplicating is not set correctly.");
free(context);
}
int main(void)
{
UNITY_BEGIN();
RUN_TEST(create_context_should_create_a_context);
RUN_TEST(create_context_should_take_custom_allocators);
RUN_TEST(create_context_should_not_take_incomplete_allocators);
RUN_TEST(duplicate_context_should_duplicate_a_context);
RUN_TEST(duplicate_context_should_take_custom_allocators);
RUN_TEST(duplicate_context_should_not_take_incomplete_allocators);
RUN_TEST(set_allocators_should_set_allocators);
RUN_TEST(set_allocators_should_not_set_incomplete_allocators);
RUN_TEST(set_userdata_should_set_userdata);
RUN_TEST(get_parse_end_should_get_the_parse_end);
RUN_TEST(set_prebuffer_size_should_set_buffer_size);
RUN_TEST(set_prebuffer_size_should_not_allow_empty_sizes);
RUN_TEST(set_format_should_set_format);
RUN_TEST(make_case_sensitive_should_change_case_sensitivity);
RUN_TEST(allow_data_after_json_should_change_allow_data_after_json);
RUN_TEST(make_duplicate_recursive_should_make_duplicate_recursive);
return UNITY_END();
}

View File

@@ -214,7 +214,6 @@
{ "doc": {"foo": null},
"patch": [{"op": "test", "path": "/foo", "value": null}],
"expected": {"foo": null},
"comment": "null value should be valid obj property" },
{ "doc": {"foo": null},
@@ -244,17 +243,14 @@
{ "doc": {"foo": {"foo": 1, "bar": 2}},
"patch": [{"op": "test", "path": "/foo", "value": {"bar": 2, "foo": 1}}],
"expected": {"foo": {"foo": 1, "bar": 2}},
"comment": "test should pass despite rearrangement" },
{ "doc": {"foo": [{"foo": 1, "bar": 2}]},
"patch": [{"op": "test", "path": "/foo", "value": [{"bar": 2, "foo": 1}]}],
"expected": {"foo": [{"foo": 1, "bar": 2}]},
"comment": "test should pass despite (nested) rearrangement" },
{ "doc": {"foo": {"bar": [1, 2, 5, 4]}},
"patch": [{"op": "test", "path": "/foo", "value": {"bar": [1, 2, 5, 4]}}],
"expected": {"foo": {"bar": [1, 2, 5, 4]}},
"comment": "test should pass - no error" },
{ "doc": {"foo": {"bar": [1, 2, 5, 4]}},
@@ -268,8 +264,7 @@
{ "comment": "Empty-string element",
"doc": { "": 1 },
"patch": [{"op": "test", "path": "/", "value": 1}],
"expected": { "": 1 } },
"patch": [{"op": "test", "path": "/", "value": 1}] },
{ "doc": {
"foo": ["bar", "baz"],
@@ -293,23 +288,8 @@
{"op": "test", "path": "/i\\j", "value": 5},
{"op": "test", "path": "/k\"l", "value": 6},
{"op": "test", "path": "/ ", "value": 7},
{"op": "test", "path": "/m~0n", "value": 8}],
"expected": {
"": 0,
" ": 7,
"a/b": 1,
"c%d": 2,
"e^f": 3,
"foo": [
"bar",
"baz"
],
"g|h": 4,
"i\\j": 5,
"k\"l": 6,
"m~n": 8
}
},
{"op": "test", "path": "/m~0n", "value": 8}] },
{ "comment": "Move to same location has no effect",
"doc": {"foo": 1},
"patch": [{"op": "move", "from": "/foo", "path": "/foo"}],
@@ -408,21 +388,11 @@
"patch": [ { "op": "copy", "path": "/-" } ],
"error": "missing 'from' parameter" },
{ "comment": "missing from location to copy",
"doc": { "foo": 1 },
"patch": [ { "op": "copy", "from": "/bar", "path": "/foo" } ],
"error": "missing 'from' location" },
{ "comment": "missing from parameter to move",
"doc": { "foo": 1 },
"patch": [ { "op": "move", "path": "" } ],
"error": "missing 'from' parameter" },
{ "comment": "missing from location to move",
"doc": { "foo": 1 },
"patch": [ { "op": "move", "from": "/bar", "path": "/foo" } ],
"error": "missing 'from' location" },
{ "comment": "duplicate ops",
"doc": { "foo": "bar" },
"patch": [ { "op": "add", "path": "/baz", "value": "qux",

View File

@@ -10,8 +10,7 @@
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
@@ -127,28 +126,6 @@ static void cjson_get_object_item_case_sensitive_should_get_object_items(void)
cJSON_Delete(item);
}
static void cjson_get_object_item_should_not_crash_with_array(void) {
cJSON *array = NULL;
cJSON *found = NULL;
array = cJSON_Parse("[1]");
found = cJSON_GetObjectItem(array, "name");
TEST_ASSERT_NULL(found);
cJSON_Delete(array);
}
static void cjson_get_object_item_case_sensitive_should_not_crash_with_array(void) {
cJSON *array = NULL;
cJSON *found = NULL;
array = cJSON_Parse("[1]");
found = cJSON_GetObjectItemCaseSensitive(array, "name");
TEST_ASSERT_NULL(found);
cJSON_Delete(array);
}
static void typecheck_functions_should_check_type(void)
{
cJSON invalid[1];
@@ -432,16 +409,18 @@ static void cjson_functions_shouldnt_crash_with_null_pointers(void)
cJSON_Delete(item);
}
static void * CJSON_CDECL failing_realloc(void *pointer, size_t size)
static void *failing_realloc(void *pointer, size_t size, void *userdata)
{
(void)size;
(void)pointer;
(void)userdata;
return NULL;
}
static void ensure_should_fail_on_failed_realloc(void)
{
printbuffer buffer = {NULL, 10, 0, 0, false, false, {&malloc, &free, &failing_realloc}};
printbuffer buffer = {NULL, 10, 0, 0, false, {256, 0, NULL, {malloc_wrapper, free_wrapper, failing_realloc}, false, true, true, true} };
buffer.context.userdata = &buffer;
buffer.buffer = (unsigned char*)malloc(100);
TEST_ASSERT_NOT_NULL(buffer.buffer);
@@ -451,10 +430,10 @@ static void ensure_should_fail_on_failed_realloc(void)
static void skip_utf8_bom_should_skip_bom(void)
{
const unsigned char string[] = "\xEF\xBB\xBF{}";
parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } };
parse_buffer buffer = { 0, 0, 0, 0, default_context };
buffer.content = string;
buffer.length = sizeof(string);
buffer.hooks = global_hooks;
buffer.context = global_context;
TEST_ASSERT_TRUE(skip_utf8_bom(&buffer) == &buffer);
TEST_ASSERT_EQUAL_UINT(3U, (unsigned int)buffer.offset);
@@ -463,10 +442,10 @@ static void skip_utf8_bom_should_skip_bom(void)
static void skip_utf8_bom_should_not_skip_bom_if_not_at_beginning(void)
{
const unsigned char string[] = " \xEF\xBB\xBF{}";
parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } };
parse_buffer buffer = { 0, 0, 0, 0, default_context };
buffer.content = string;
buffer.length = sizeof(string);
buffer.hooks = global_hooks;
buffer.context = global_context;
buffer.offset = 1;
TEST_ASSERT_NULL(skip_utf8_bom(&buffer));
@@ -534,7 +513,7 @@ static void cjson_add_item_to_object_should_not_use_after_free_when_string_is_al
{
cJSON *object = cJSON_CreateObject();
cJSON *number = cJSON_CreateNumber(42);
char *name = (char*)cJSON_strdup((const unsigned char*)"number", &global_hooks);
char *name = (char*)custom_strdup((const unsigned char*)"number", &global_context);
TEST_ASSERT_NOT_NULL(object);
TEST_ASSERT_NOT_NULL(number);
@@ -549,7 +528,25 @@ static void cjson_add_item_to_object_should_not_use_after_free_when_string_is_al
cJSON_Delete(object);
}
int CJSON_CDECL main(void)
static void is_nan_should_detect_nan(void)
{
double nan = 0.0/0.0;
TEST_ASSERT_TRUE(is_nan(nan));
TEST_ASSERT_FALSE(is_nan(1));
}
static void is_infinity_should_detect_infinity(void)
{
double negative_infinity = -1.0/0.0;
double positive_infinity = 1.0/0.0;
TEST_ASSERT_TRUE(is_infinity(negative_infinity));
TEST_ASSERT_TRUE(is_infinity(positive_infinity));
TEST_ASSERT_FALSE(is_infinity(1));
}
int main(void)
{
UNITY_BEGIN();
@@ -557,8 +554,6 @@ int CJSON_CDECL main(void)
RUN_TEST(cjson_array_foreach_should_not_dereference_null_pointer);
RUN_TEST(cjson_get_object_item_should_get_object_items);
RUN_TEST(cjson_get_object_item_case_sensitive_should_get_object_items);
RUN_TEST(cjson_get_object_item_should_not_crash_with_array);
RUN_TEST(cjson_get_object_item_case_sensitive_should_not_crash_with_array);
RUN_TEST(typecheck_functions_should_check_type);
RUN_TEST(cjson_should_not_parse_to_deeply_nested_jsons);
RUN_TEST(cjson_set_number_value_should_set_numbers);
@@ -574,6 +569,8 @@ int CJSON_CDECL main(void)
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);
RUN_TEST(is_nan_should_detect_nan);
RUN_TEST(is_infinity_should_detect_infinity);
return UNITY_END();
}

View File

@@ -44,10 +44,10 @@ static void assert_is_array(cJSON *array_item)
static void assert_not_array(const char *json)
{
parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } };
parse_buffer buffer = { 0, 0, 0, 0, default_context };
buffer.content = (const unsigned char*)json;
buffer.length = strlen(json) + sizeof("");
buffer.hooks = global_hooks;
buffer.context = global_context;
TEST_ASSERT_FALSE(parse_array(item, &buffer));
assert_is_invalid(item);
@@ -55,10 +55,10 @@ static void assert_not_array(const char *json)
static void assert_parse_array(const char *json)
{
parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } };
parse_buffer buffer = { 0, 0, 0, 0, default_context };
buffer.content = (const unsigned char*)json;
buffer.length = strlen(json) + sizeof("");
buffer.hooks = global_hooks;
buffer.context = global_context;
TEST_ASSERT_TRUE(parse_array(item, &buffer));
assert_is_array(item);
@@ -152,7 +152,7 @@ static void parse_array_should_not_parse_non_arrays(void)
assert_not_array("\"[]hello world!\n\"");
}
int CJSON_CDECL main(void)
int main(void)
{
/* initialize cJSON item */
memset(item, 0, sizeof(cJSON));

View File

@@ -195,7 +195,7 @@ static void test12_should_not_be_parsed(void)
}
}
int CJSON_CDECL main(void)
int main(void)
{
UNITY_BEGIN();
RUN_TEST(file_test1_should_be_parsed_and_printed);

View File

@@ -64,7 +64,7 @@ static void parse_hex4_should_parse_mixed_case(void)
TEST_ASSERT_EQUAL_INT(0xBEEF, parse_hex4((const unsigned char*)"BEEF"));
}
int CJSON_CDECL main(void)
int main(void)
{
UNITY_BEGIN();
RUN_TEST(parse_hex4_should_parse_all_combinations);

View File

@@ -45,7 +45,7 @@ static void assert_is_number(cJSON *number_item)
static void assert_parse_number(const char *string, int integer, double real)
{
parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } };
parse_buffer buffer = { 0, 0, 0, 0, default_context };
buffer.content = (const unsigned char*)string;
buffer.length = strlen(string) + sizeof("");
@@ -96,7 +96,7 @@ static void parse_number_should_parse_negative_reals(void)
assert_parse_number("-123e-128", 0, -123e-128);
}
int CJSON_CDECL main(void)
int main(void)
{
/* initialize cJSON item */
memset(item, 0, sizeof(cJSON));

View File

@@ -52,10 +52,10 @@ static void assert_is_child(cJSON *child_item, const char *name, int type)
static void assert_not_object(const char *json)
{
parse_buffer parsebuffer = { 0, 0, 0, 0, { 0, 0, 0 } };
parse_buffer parsebuffer = { 0, 0, 0, 0, default_context };
parsebuffer.content = (const unsigned char*)json;
parsebuffer.length = strlen(json) + sizeof("");
parsebuffer.hooks = global_hooks;
parsebuffer.context = global_context;
TEST_ASSERT_FALSE(parse_object(item, &parsebuffer));
assert_is_invalid(item);
@@ -64,10 +64,10 @@ static void assert_not_object(const char *json)
static void assert_parse_object(const char *json)
{
parse_buffer parsebuffer = { 0, 0, 0, 0, { 0, 0, 0 } };
parse_buffer parsebuffer = { 0, 0, 0, 0, default_context };
parsebuffer.content = (const unsigned char*)json;
parsebuffer.length = strlen(json) + sizeof("");
parsebuffer.hooks = global_hooks;
parsebuffer.context = global_context;
TEST_ASSERT_TRUE(parse_object(item, &parsebuffer));
assert_is_object(item);
@@ -162,7 +162,7 @@ static void parse_object_should_not_parse_non_objects(void)
assert_not_object("\"{}hello world!\n\"");
}
int CJSON_CDECL main(void)
int main(void)
{
/* initialize cJSON item */
memset(item, 0, sizeof(cJSON));

View File

@@ -45,24 +45,24 @@ static void assert_is_string(cJSON *string_item)
static void assert_parse_string(const char *string, const char *expected)
{
parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } };
parse_buffer buffer = { 0, 0, 0, 0, default_context };
buffer.content = (const unsigned char*)string;
buffer.length = strlen(string) + sizeof("");
buffer.hooks = global_hooks;
buffer.context = global_context;
TEST_ASSERT_TRUE_MESSAGE(parse_string(item, &buffer), "Couldn't parse string.");
assert_is_string(item);
TEST_ASSERT_EQUAL_STRING_MESSAGE(expected, item->valuestring, "The parsed result isn't as expected.");
global_hooks.deallocate(item->valuestring);
global_context.allocators.deallocate(item->valuestring, global_context.userdata);
item->valuestring = NULL;
}
static void assert_not_parse_string(const char * const string)
{
parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } };
parse_buffer buffer = { 0, 0, 0, 0, default_context };
buffer.content = (const unsigned char*)string;
buffer.length = strlen(string) + sizeof("");
buffer.hooks = global_hooks;
buffer.context = global_context;
TEST_ASSERT_FALSE_MESSAGE(parse_string(item, &buffer), "Malformed string should not be accepted.");
assert_is_invalid(item);
@@ -119,7 +119,7 @@ static void parse_string_should_parse_bug_94(void)
reset(item);
}
int CJSON_CDECL main(void)
int main(void)
{
/* initialize cJSON item and error pointer */
memset(item, 0, sizeof(cJSON));

View File

@@ -43,10 +43,10 @@ static void assert_is_value(cJSON *value_item, int type)
static void assert_parse_value(const char *string, int type)
{
parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } };
parse_buffer buffer = { 0, 0, 0, 0, default_context };
buffer.content = (const unsigned char*) string;
buffer.length = strlen(string) + sizeof("");
buffer.hooks = global_hooks;
buffer.context = global_context;
TEST_ASSERT_TRUE(parse_value(item, &buffer));
assert_is_value(item, type);
@@ -96,7 +96,7 @@ static void parse_value_should_parse_object(void)
reset(item);
}
int CJSON_CDECL main(void)
int main(void)
{
/* initialize cJSON item */
memset(item, 0, sizeof(cJSON));

View File

@@ -97,7 +97,7 @@ static void parse_with_opts_should_parse_utf8_bom(void)
cJSON_Delete(without_bom);
}
int CJSON_CDECL main(void)
int main(void)
{
UNITY_BEGIN();

View File

@@ -31,36 +31,36 @@ static void assert_print_array(const char * const expected, const char * const i
cJSON item[1];
printbuffer formatted_buffer = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } };
printbuffer unformatted_buffer = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } };
printbuffer formatted_buffer = { 0, 0, 0, 0, 0, default_context };
printbuffer unformatted_buffer = { 0, 0, 0, 0, 0, default_context };
parse_buffer parsebuffer = { 0, 0, 0, 0, { 0, 0, 0 } };
parse_buffer parsebuffer = { 0, 0, 0, 0, default_context };
parsebuffer.content = (const unsigned char*)input;
parsebuffer.length = strlen(input) + sizeof("");
parsebuffer.hooks = global_hooks;
parsebuffer.context = global_context;
/* buffer for formatted printing */
formatted_buffer.buffer = printed_formatted;
formatted_buffer.length = sizeof(printed_formatted);
formatted_buffer.offset = 0;
formatted_buffer.noalloc = true;
formatted_buffer.hooks = global_hooks;
formatted_buffer.context = global_context;
/* buffer for unformatted printing */
unformatted_buffer.buffer = printed_unformatted;
unformatted_buffer.length = sizeof(printed_unformatted);
unformatted_buffer.offset = 0;
unformatted_buffer.noalloc = true;
unformatted_buffer.hooks = global_hooks;
unformatted_buffer.context = global_context;
memset(item, 0, sizeof(item));
TEST_ASSERT_TRUE_MESSAGE(parse_array(item, &parsebuffer), "Failed to parse array.");
unformatted_buffer.format = false;
unformatted_buffer.context.format = false;
TEST_ASSERT_TRUE_MESSAGE(print_array(item, &unformatted_buffer), "Failed to print unformatted string.");
TEST_ASSERT_EQUAL_STRING_MESSAGE(input, printed_unformatted, "Unformatted array is not correct.");
formatted_buffer.format = true;
formatted_buffer.context.format = true;
TEST_ASSERT_TRUE_MESSAGE(print_array(item, &formatted_buffer), "Failed to print formatted string.");
TEST_ASSERT_EQUAL_STRING_MESSAGE(expected, printed_formatted, "Formatted array is not correct.");
@@ -87,7 +87,7 @@ static void print_array_should_print_arrays_with_multiple_elements(void)
assert_print_array("[1, null, true, false, [], \"hello\", {\n\t}]", "[1,null,true,false,[],\"hello\",{}]");
}
int CJSON_CDECL main(void)
int main(void)
{
/* initialize cJSON item */
UNITY_BEGIN();

View File

@@ -28,12 +28,12 @@ static void assert_print_number(const char *expected, double input)
{
unsigned char printed[1024];
cJSON item[1];
printbuffer buffer = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } };
printbuffer buffer = { 0, 0, 0, 0, 0, default_context };
buffer.buffer = printed;
buffer.length = sizeof(printed);
buffer.offset = 0;
buffer.noalloc = true;
buffer.hooks = global_hooks;
buffer.context = global_context;
memset(item, 0, sizeof(item));
cJSON_SetNumberValue(item, input);
@@ -89,7 +89,7 @@ static void print_number_should_print_non_number(void)
/* assert_print_number("null", -INFTY); */
}
int CJSON_CDECL main(void)
int main(void)
{
/* initialize cJSON item */
UNITY_BEGIN();

View File

@@ -31,37 +31,37 @@ static void assert_print_object(const char * const expected, const char * const
cJSON item[1];
printbuffer formatted_buffer = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } };
printbuffer unformatted_buffer = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } };
parse_buffer parsebuffer = { 0, 0, 0, 0, { 0, 0, 0 } };
printbuffer formatted_buffer = { 0, 0, 0, 0, 0, default_context };
printbuffer unformatted_buffer = { 0, 0, 0, 0, 0, default_context };
parse_buffer parsebuffer = { 0, 0, 0, 0, default_context };
/* buffer for parsing */
parsebuffer.content = (const unsigned char*)input;
parsebuffer.length = strlen(input) + sizeof("");
parsebuffer.hooks = global_hooks;
parsebuffer.context = global_context;
/* buffer for formatted printing */
formatted_buffer.buffer = printed_formatted;
formatted_buffer.length = sizeof(printed_formatted);
formatted_buffer.offset = 0;
formatted_buffer.noalloc = true;
formatted_buffer.hooks = global_hooks;
formatted_buffer.context = global_context;
/* buffer for unformatted printing */
unformatted_buffer.buffer = printed_unformatted;
unformatted_buffer.length = sizeof(printed_unformatted);
unformatted_buffer.offset = 0;
unformatted_buffer.noalloc = true;
unformatted_buffer.hooks = global_hooks;
unformatted_buffer.context = global_context;
memset(item, 0, sizeof(item));
TEST_ASSERT_TRUE_MESSAGE(parse_object(item, &parsebuffer), "Failed to parse object.");
unformatted_buffer.format = false;
unformatted_buffer.context.format = false;
TEST_ASSERT_TRUE_MESSAGE(print_object(item, &unformatted_buffer), "Failed to print unformatted string.");
TEST_ASSERT_EQUAL_STRING_MESSAGE(input, printed_unformatted, "Unformatted object is not correct.");
formatted_buffer.format = true;
formatted_buffer.context.format = true;
TEST_ASSERT_TRUE_MESSAGE(print_object(item, &formatted_buffer), "Failed to print formatted string.");
TEST_ASSERT_EQUAL_STRING_MESSAGE(expected, printed_formatted, "Formatted ojbect is not correct.");
@@ -88,7 +88,7 @@ static void print_object_should_print_objects_with_multiple_elements(void)
assert_print_object("{\n\t\"one\":\t1,\n\t\"NULL\":\tnull,\n\t\"TRUE\":\ttrue,\n\t\"FALSE\":\tfalse,\n\t\"array\":\t[],\n\t\"world\":\t\"hello\",\n\t\"object\":\t{\n\t}\n}", "{\"one\":1,\"NULL\":null,\"TRUE\":true,\"FALSE\":false,\"array\":[],\"world\":\"hello\",\"object\":{}}");
}
int CJSON_CDECL main(void)
int main(void)
{
/* initialize cJSON item */
UNITY_BEGIN();

View File

@@ -27,12 +27,12 @@
static void assert_print_string(const char *expected, const char *input)
{
unsigned char printed[1024];
printbuffer buffer = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } };
printbuffer buffer = { 0, 0, 0, 0, 0, default_context };
buffer.buffer = printed;
buffer.length = sizeof(printed);
buffer.offset = 0;
buffer.noalloc = true;
buffer.hooks = global_hooks;
buffer.context = global_context;
TEST_ASSERT_TRUE_MESSAGE(print_string_ptr((const unsigned char*)input, &buffer), "Failed to print string.");
TEST_ASSERT_EQUAL_STRING_MESSAGE(expected, printed, "The printed string isn't as expected.");
@@ -65,7 +65,7 @@ static void print_string_should_print_utf8(void)
assert_print_string("\"ü猫慕\"", "ü猫慕");
}
int CJSON_CDECL main(void)
int main(void)
{
/* initialize cJSON item */
UNITY_BEGIN();

View File

@@ -32,17 +32,18 @@ static void assert_print_value(const char *input)
{
unsigned char printed[1024];
cJSON item[1];
printbuffer buffer = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } };
parse_buffer parsebuffer = { 0, 0, 0, 0, { 0, 0, 0 } };
printbuffer buffer = { 0, 0, 0, 0, 0, default_context };
parse_buffer parsebuffer = { 0, 0, 0, 0, default_context };
buffer.buffer = printed;
buffer.length = sizeof(printed);
buffer.offset = 0;
buffer.noalloc = true;
buffer.hooks = global_hooks;
buffer.context = global_context;
buffer.context.format = false;
parsebuffer.content = (const unsigned char*)input;
parsebuffer.length = strlen(input) + sizeof("");
parsebuffer.hooks = global_hooks;
parsebuffer.context = global_context;
memset(item, 0, sizeof(item));
@@ -90,7 +91,7 @@ static void print_value_should_print_object(void)
assert_print_value("{}");
}
int CJSON_CDECL main(void)
int main(void)
{
/* initialize cJSON item */
UNITY_BEGIN();

View File

@@ -246,7 +246,7 @@ static void supports_full_hd_should_check_for_full_hd_support(void)
TEST_ASSERT_FALSE(supports_full_hd(monitor_without_hd));
}
int CJSON_CDECL main(void)
int main(void)
{
UNITY_BEGIN();

View File

@@ -1,3 +0,0 @@
// msvc doesn't support weak-linking, so we need to define these functions.
void setUp(void) { }
void tearDown(void) { }