Compare commits
41 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3c8935676a | ||
|
|
b93fd34044 | ||
|
|
687b1a2fe1 | ||
|
|
08d2bc766a | ||
|
|
465352fb99 | ||
|
|
19ff92da79 | ||
|
|
62bc2e3432 | ||
|
|
359567fdde | ||
|
|
0b5a7abf48 | ||
|
|
93688cbe72 | ||
|
|
6b249213dd | ||
|
|
09ebae8149 | ||
|
|
a43fa56a63 | ||
|
|
5a52eaddfd | ||
|
|
add86a6be8 | ||
|
|
c69134d017 | ||
|
|
563d861f92 | ||
|
|
6820448db5 | ||
|
|
d44b594ab3 | ||
|
|
f110bd2e58 | ||
|
|
5cd1dabb30 | ||
|
|
d606cbbc64 | ||
|
|
be749d7efa | ||
|
|
eaec82c3c5 | ||
|
|
cb1df2f88c | ||
|
|
2c914c073d | ||
|
|
4917024741 | ||
|
|
a3fadd44d1 | ||
|
|
feb05fb2fd | ||
|
|
26f38f4782 | ||
|
|
8e742e4869 | ||
|
|
543ab5d08a | ||
|
|
e2162adeed | ||
|
|
08103f048e | ||
|
|
ace800e444 | ||
|
|
00544a4a74 | ||
|
|
3550a5553d | ||
|
|
d9fe34bade | ||
|
|
f25b8448e4 | ||
|
|
ad2cb5b7ea | ||
|
|
f32703a7a1 |
23
.editorconfig
Normal file
23
.editorconfig
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
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
Normal file
2
.gitattributes
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
* text=auto
|
||||||
|
/tests/inputs/* text eol=lf
|
||||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -14,3 +14,5 @@ libcjson.so.*
|
|||||||
libcjson_utils.so.*
|
libcjson_utils.so.*
|
||||||
*.orig
|
*.orig
|
||||||
.vscode
|
.vscode
|
||||||
|
.idea
|
||||||
|
cmake-build-debug
|
||||||
|
|||||||
37
CHANGELOG.md
37
CHANGELOG.md
@@ -1,3 +1,40 @@
|
|||||||
|
1.7.12
|
||||||
|
======
|
||||||
|
Fixes:
|
||||||
|
------
|
||||||
|
* Fix infinite loop in `cJSON_Minify` (potential Denial of Service), thanks @Alanscut for reporting. See #354
|
||||||
|
* Fix link error for Visual Studio. Thanks @tan-wei, see #352
|
||||||
|
* Undefine `true` and `false` for `cJSON_Utils` before redefining them. Thanks @raiden00pl, see #347
|
||||||
|
|
||||||
|
|
||||||
|
1.7.11
|
||||||
|
======
|
||||||
|
Fixes:
|
||||||
|
------
|
||||||
|
* Fix a bug where cJSON_Minify could overflow it's buffer, both reading and writing. This is a security issue. (see #338). Big thanks @bigric3 for reporting.
|
||||||
|
* Unset `true` and `false` macros before setting them if they exist. See #339, thanks @raiden00pl for reporting
|
||||||
|
|
||||||
|
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
|
1.7.7
|
||||||
=====
|
=====
|
||||||
Fixes:
|
Fixes:
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ include(GNUInstallDirs)
|
|||||||
|
|
||||||
set(PROJECT_VERSION_MAJOR 1)
|
set(PROJECT_VERSION_MAJOR 1)
|
||||||
set(PROJECT_VERSION_MINOR 7)
|
set(PROJECT_VERSION_MINOR 7)
|
||||||
set(PROJECT_VERSION_PATCH 7)
|
set(PROJECT_VERSION_PATCH 12)
|
||||||
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}")
|
||||||
@@ -49,11 +49,15 @@ if (ENABLE_CUSTOM_COMPILER_FLAGS)
|
|||||||
-Wswitch-enum
|
-Wswitch-enum
|
||||||
)
|
)
|
||||||
elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
|
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
|
list(APPEND custom_compiler_flags
|
||||||
/GS
|
/GS
|
||||||
/Za
|
/Za
|
||||||
/sdl
|
/sdl
|
||||||
/W4
|
/W4
|
||||||
|
/wd4001
|
||||||
|
/D_CRT_SECURE_NO_WARNINGS
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -7,12 +7,14 @@ Current Maintainer: [Max Bruckner](https://github.com/FSMaxB)
|
|||||||
* [Ajay Bhargav](https://github.com/ajaybhargav)
|
* [Ajay Bhargav](https://github.com/ajaybhargav)
|
||||||
* [Alper Akcan](https://github.com/alperakcan)
|
* [Alper Akcan](https://github.com/alperakcan)
|
||||||
* [Anton Sergeev](https://github.com/anton-sergeev)
|
* [Anton Sergeev](https://github.com/anton-sergeev)
|
||||||
|
* [Benbuck Nason](https://github.com/bnason-nf)
|
||||||
* [Bob Kocisko](https://github.com/bobkocisko)
|
* [Bob Kocisko](https://github.com/bobkocisko)
|
||||||
* [Christian Schulze](https://github.com/ChristianSch)
|
* [Christian Schulze](https://github.com/ChristianSch)
|
||||||
* [Casperinous](https://github.com/Casperinous)
|
* [Casperinous](https://github.com/Casperinous)
|
||||||
* [Debora Grosse](https://github.com/DeboraG)
|
* [Debora Grosse](https://github.com/DeboraG)
|
||||||
* [dieyushi](https://github.com/dieyushi)
|
* [dieyushi](https://github.com/dieyushi)
|
||||||
* [Dōngwén Huáng (黄东文)](https://github.com/DongwenHuang)
|
* [Dōngwén Huáng (黄东文)](https://github.com/DongwenHuang)
|
||||||
|
* [Donough Liu](https://github.com/ldm0)
|
||||||
* Eswar Yaganti
|
* Eswar Yaganti
|
||||||
* [Evan Todd](https://github.com/etodd)
|
* [Evan Todd](https://github.com/etodd)
|
||||||
* [Fabrice Fontaine](https://github.com/ffontaine)
|
* [Fabrice Fontaine](https://github.com/ffontaine)
|
||||||
@@ -33,14 +35,18 @@ Current Maintainer: [Max Bruckner](https://github.com/FSMaxB)
|
|||||||
* [Pawel Winogrodzki](https://github.com/PawelWMS)
|
* [Pawel Winogrodzki](https://github.com/PawelWMS)
|
||||||
* [prefetchnta](https://github.com/prefetchnta)
|
* [prefetchnta](https://github.com/prefetchnta)
|
||||||
* [Rafael Leal Dias](https://github.com/rafaeldias)
|
* [Rafael Leal Dias](https://github.com/rafaeldias)
|
||||||
|
* [raiden00pl](https://github.com/raiden00pl)
|
||||||
* [Robin Mallinson](https://github.com/rmallins)
|
* [Robin Mallinson](https://github.com/rmallins)
|
||||||
* [Rod Vagg](https://github.com/rvagg)
|
* [Rod Vagg](https://github.com/rvagg)
|
||||||
* [Roland Meertens](https://github.com/rmeertens)
|
* [Roland Meertens](https://github.com/rmeertens)
|
||||||
* [Romain Porte](https://github.com/MicroJoe)
|
* [Romain Porte](https://github.com/MicroJoe)
|
||||||
* [Simon Ricaldone](https://github.com/simon-p-r)
|
* [Simon Ricaldone](https://github.com/simon-p-r)
|
||||||
* [Stephan Gatzka](https://github.com/gatzka)
|
* [Stephan Gatzka](https://github.com/gatzka)
|
||||||
|
* [tan-wei](https://github.com/tan-wei)
|
||||||
* [Weston Schmidt](https://github.com/schmidtw)
|
* [Weston Schmidt](https://github.com/schmidtw)
|
||||||
* [yangfl](https://github.com/yangfl)
|
* [yangfl](https://github.com/yangfl)
|
||||||
|
* [yuta-oxo](https://github.com/yuta-oxo)
|
||||||
|
* [Zach Hindes](https://github.com/zhindes)
|
||||||
* [Zhao Zhixu](https://github.com/zhaozhixu)
|
* [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)
|
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)
|
||||||
|
|||||||
4
Makefile
4
Makefile
@@ -8,7 +8,7 @@ CJSON_TEST_SRC = cJSON.c test.c
|
|||||||
|
|
||||||
LDLIBS = -lm
|
LDLIBS = -lm
|
||||||
|
|
||||||
LIBVERSION = 1.7.7
|
LIBVERSION = 1.7.12
|
||||||
CJSON_SOVERSION = 1
|
CJSON_SOVERSION = 1
|
||||||
UTILS_SOVERSION = 1
|
UTILS_SOVERSION = 1
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ STATIC = a
|
|||||||
ifeq (Darwin, $(uname))
|
ifeq (Darwin, $(uname))
|
||||||
SHARED = dylib
|
SHARED = dylib
|
||||||
CJSON_SO_LDFLAG = ""
|
CJSON_SO_LDFLAG = ""
|
||||||
UTILS_SO_LDFLAG = ""
|
UTILS_SO_LDFLAG = ""
|
||||||
endif
|
endif
|
||||||
|
|
||||||
#cJSON library names
|
#cJSON library names
|
||||||
|
|||||||
@@ -298,6 +298,7 @@ In this example we want to build and parse the following JSON:
|
|||||||
Let's build the above JSON and print it to a string:
|
Let's build the above JSON and print it to a string:
|
||||||
```c
|
```c
|
||||||
//create a monitor with a list of supported resolutions
|
//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)
|
char* create_monitor(void)
|
||||||
{
|
{
|
||||||
const unsigned int resolution_numbers[3][2] = {
|
const unsigned int resolution_numbers[3][2] = {
|
||||||
@@ -373,6 +374,7 @@ end:
|
|||||||
|
|
||||||
Alternatively we can use the `cJSON_Add...ToObject` helper functions to make our lifes a little easier:
|
Alternatively we can use the `cJSON_Add...ToObject` helper functions to make our lifes a little easier:
|
||||||
```c
|
```c
|
||||||
|
//NOTE: Returns a heap allocated string, you are required to free it after use.
|
||||||
char *create_monitor_with_helpers(void)
|
char *create_monitor_with_helpers(void)
|
||||||
{
|
{
|
||||||
const unsigned int resolution_numbers[3][2] = {
|
const unsigned int resolution_numbers[3][2] = {
|
||||||
|
|||||||
169
cJSON.c
169
cJSON.c
@@ -58,7 +58,14 @@
|
|||||||
#include "cJSON.h"
|
#include "cJSON.h"
|
||||||
|
|
||||||
/* define our own boolean type */
|
/* define our own boolean type */
|
||||||
|
#ifdef true
|
||||||
|
#undef true
|
||||||
|
#endif
|
||||||
#define true ((cJSON_bool)1)
|
#define true ((cJSON_bool)1)
|
||||||
|
|
||||||
|
#ifdef false
|
||||||
|
#undef false
|
||||||
|
#endif
|
||||||
#define false ((cJSON_bool)0)
|
#define false ((cJSON_bool)0)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -81,7 +88,7 @@ CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *item) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* This is a safeguard to prevent copy-pasters from using incompatible C and header files */
|
/* This is a safeguard to prevent copy-pasters from using incompatible C and header files */
|
||||||
#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 7)
|
#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 12)
|
||||||
#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
|
||||||
|
|
||||||
@@ -119,22 +126,22 @@ static int case_insensitive_strcmp(const unsigned char *string1, const unsigned
|
|||||||
|
|
||||||
typedef struct internal_hooks
|
typedef struct internal_hooks
|
||||||
{
|
{
|
||||||
void *(*allocate)(size_t size);
|
void *(CJSON_CDECL *allocate)(size_t size);
|
||||||
void (*deallocate)(void *pointer);
|
void (CJSON_CDECL *deallocate)(void *pointer);
|
||||||
void *(*reallocate)(void *pointer, size_t size);
|
void *(CJSON_CDECL *reallocate)(void *pointer, size_t size);
|
||||||
} internal_hooks;
|
} internal_hooks;
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
/* work around MSVC error C2322: '...' address of dillimport '...' is not static */
|
/* work around MSVC error C2322: '...' address of dillimport '...' is not static */
|
||||||
static void *internal_malloc(size_t size)
|
static void * CJSON_CDECL internal_malloc(size_t size)
|
||||||
{
|
{
|
||||||
return malloc(size);
|
return malloc(size);
|
||||||
}
|
}
|
||||||
static void internal_free(void *pointer)
|
static void CJSON_CDECL internal_free(void *pointer)
|
||||||
{
|
{
|
||||||
free(pointer);
|
free(pointer);
|
||||||
}
|
}
|
||||||
static void *internal_realloc(void *pointer, size_t size)
|
static void * CJSON_CDECL internal_realloc(void *pointer, size_t size)
|
||||||
{
|
{
|
||||||
return realloc(pointer, size);
|
return realloc(pointer, size);
|
||||||
}
|
}
|
||||||
@@ -144,6 +151,9 @@ static void *internal_realloc(void *pointer, size_t size)
|
|||||||
#define internal_realloc realloc
|
#define internal_realloc realloc
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* strlen of character literals resolved at compile time */
|
||||||
|
#define static_strlen(string_literal) (sizeof(string_literal) - sizeof(""))
|
||||||
|
|
||||||
static internal_hooks global_hooks = { internal_malloc, internal_free, internal_realloc };
|
static internal_hooks global_hooks = { internal_malloc, internal_free, internal_realloc };
|
||||||
|
|
||||||
static unsigned char* cJSON_strdup(const unsigned char* string, const internal_hooks * const hooks)
|
static unsigned char* cJSON_strdup(const unsigned char* string, const internal_hooks * const hooks)
|
||||||
@@ -324,7 +334,7 @@ loop_end:
|
|||||||
{
|
{
|
||||||
item->valueint = INT_MAX;
|
item->valueint = INT_MAX;
|
||||||
}
|
}
|
||||||
else if (number <= INT_MIN)
|
else if (number <= (double)INT_MIN)
|
||||||
{
|
{
|
||||||
item->valueint = INT_MIN;
|
item->valueint = INT_MIN;
|
||||||
}
|
}
|
||||||
@@ -346,7 +356,7 @@ CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number)
|
|||||||
{
|
{
|
||||||
object->valueint = INT_MAX;
|
object->valueint = INT_MAX;
|
||||||
}
|
}
|
||||||
else if (number <= INT_MIN)
|
else if (number <= (double)INT_MIN)
|
||||||
{
|
{
|
||||||
object->valueint = INT_MIN;
|
object->valueint = INT_MIN;
|
||||||
}
|
}
|
||||||
@@ -504,7 +514,7 @@ static cJSON_bool print_number(const cJSON * const item, printbuffer * const out
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sprintf failed or buffer overrun occured */
|
/* sprintf failed or buffer overrun occurred */
|
||||||
if ((length < 0) || (length > (int)(sizeof(number_buffer) - 1)))
|
if ((length < 0) || (length > (int)(sizeof(number_buffer) - 1)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -1555,7 +1565,7 @@ static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_bu
|
|||||||
buffer_skip_whitespace(input_buffer);
|
buffer_skip_whitespace(input_buffer);
|
||||||
if (!parse_string(current_item, input_buffer))
|
if (!parse_string(current_item, input_buffer))
|
||||||
{
|
{
|
||||||
goto fail; /* faile to parse name */
|
goto fail; /* failed to parse name */
|
||||||
}
|
}
|
||||||
buffer_skip_whitespace(input_buffer);
|
buffer_skip_whitespace(input_buffer);
|
||||||
|
|
||||||
@@ -1675,7 +1685,7 @@ static cJSON_bool print_object(const cJSON * const item, printbuffer * const out
|
|||||||
update_offset(output_buffer);
|
update_offset(output_buffer);
|
||||||
|
|
||||||
/* print comma if not last */
|
/* print comma if not last */
|
||||||
length = (size_t) ((output_buffer->format ? 1 : 0) + (current_item->next ? 1 : 0));
|
length = ((size_t)(output_buffer->format ? 1 : 0) + (size_t)(current_item->next ? 1 : 0));
|
||||||
output_pointer = ensure(output_buffer, length + 1);
|
output_pointer = ensure(output_buffer, length + 1);
|
||||||
if (output_pointer == NULL)
|
if (output_pointer == NULL)
|
||||||
{
|
{
|
||||||
@@ -1781,7 +1791,7 @@ static cJSON *get_object_item(const cJSON * const object, const char * const nam
|
|||||||
current_element = object->child;
|
current_element = object->child;
|
||||||
if (case_sensitive)
|
if (case_sensitive)
|
||||||
{
|
{
|
||||||
while ((current_element != NULL) && (strcmp(name, current_element->string) != 0))
|
while ((current_element != NULL) && (current_element->string != NULL) && (strcmp(name, current_element->string) != 0))
|
||||||
{
|
{
|
||||||
current_element = current_element->next;
|
current_element = current_element->next;
|
||||||
}
|
}
|
||||||
@@ -1794,6 +1804,10 @@ static cJSON *get_object_item(const cJSON * const object, const char * const nam
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((current_element == NULL) || (current_element->string == NULL)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return current_element;
|
return current_element;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2300,7 +2314,7 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num)
|
|||||||
{
|
{
|
||||||
item->valueint = INT_MAX;
|
item->valueint = INT_MAX;
|
||||||
}
|
}
|
||||||
else if (num <= INT_MIN)
|
else if (num <= (double)INT_MIN)
|
||||||
{
|
{
|
||||||
item->valueint = INT_MIN;
|
item->valueint = INT_MIN;
|
||||||
}
|
}
|
||||||
@@ -2626,69 +2640,96 @@ fail:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void skip_oneline_comment(char **input)
|
||||||
|
{
|
||||||
|
*input += static_strlen("//");
|
||||||
|
|
||||||
|
for (; (*input)[0] != '\0'; ++(*input))
|
||||||
|
{
|
||||||
|
if ((*input)[0] == '\n') {
|
||||||
|
*input += static_strlen("\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void skip_multiline_comment(char **input)
|
||||||
|
{
|
||||||
|
*input += static_strlen("/*");
|
||||||
|
|
||||||
|
for (; (*input)[0] != '\0'; ++(*input))
|
||||||
|
{
|
||||||
|
if (((*input)[0] == '*') && ((*input)[1] == '/'))
|
||||||
|
{
|
||||||
|
*input += static_strlen("*/");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void minify_string(char **input, char **output) {
|
||||||
|
(*output)[0] = (*input)[0];
|
||||||
|
*input += static_strlen("\"");
|
||||||
|
*output += static_strlen("\"");
|
||||||
|
|
||||||
|
|
||||||
|
for (; (*input)[0] != '\0'; (void)++(*input), ++(*output)) {
|
||||||
|
(*output)[0] = (*input)[0];
|
||||||
|
|
||||||
|
if ((*input)[0] == '\"') {
|
||||||
|
(*output)[0] = '\"';
|
||||||
|
*input += static_strlen("\"");
|
||||||
|
*output += static_strlen("\"");
|
||||||
|
return;
|
||||||
|
} else if (((*input)[0] == '\\') && ((*input)[1] == '\"')) {
|
||||||
|
(*output)[1] = (*input)[1];
|
||||||
|
*input += static_strlen("\"");
|
||||||
|
*output += static_strlen("\"");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CJSON_PUBLIC(void) cJSON_Minify(char *json)
|
CJSON_PUBLIC(void) cJSON_Minify(char *json)
|
||||||
{
|
{
|
||||||
unsigned char *into = (unsigned char*)json;
|
char *into = json;
|
||||||
|
|
||||||
if (json == NULL)
|
if (json == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (*json)
|
while (json[0] != '\0')
|
||||||
{
|
{
|
||||||
if (*json == ' ')
|
switch (json[0])
|
||||||
{
|
{
|
||||||
json++;
|
case ' ':
|
||||||
}
|
case '\t':
|
||||||
else if (*json == '\t')
|
case '\r':
|
||||||
{
|
case '\n':
|
||||||
/* Whitespace characters. */
|
|
||||||
json++;
|
|
||||||
}
|
|
||||||
else if (*json == '\r')
|
|
||||||
{
|
|
||||||
json++;
|
|
||||||
}
|
|
||||||
else if (*json=='\n')
|
|
||||||
{
|
|
||||||
json++;
|
|
||||||
}
|
|
||||||
else if ((*json == '/') && (json[1] == '/'))
|
|
||||||
{
|
|
||||||
/* double-slash comments, to end of line. */
|
|
||||||
while (*json && (*json != '\n'))
|
|
||||||
{
|
|
||||||
json++;
|
json++;
|
||||||
}
|
break;
|
||||||
}
|
|
||||||
else if ((*json == '/') && (json[1] == '*'))
|
case '/':
|
||||||
{
|
if (json[1] == '/')
|
||||||
/* multiline comments. */
|
|
||||||
while (*json && !((*json == '*') && (json[1] == '/')))
|
|
||||||
{
|
|
||||||
json++;
|
|
||||||
}
|
|
||||||
json += 2;
|
|
||||||
}
|
|
||||||
else if (*json == '\"')
|
|
||||||
{
|
|
||||||
/* string literals, which are \" sensitive. */
|
|
||||||
*into++ = (unsigned char)*json++;
|
|
||||||
while (*json && (*json != '\"'))
|
|
||||||
{
|
|
||||||
if (*json == '\\')
|
|
||||||
{
|
{
|
||||||
*into++ = (unsigned char)*json++;
|
skip_oneline_comment(&json);
|
||||||
}
|
}
|
||||||
*into++ = (unsigned char)*json++;
|
else if (json[1] == '*')
|
||||||
}
|
{
|
||||||
*into++ = (unsigned char)*json++;
|
skip_multiline_comment(&json);
|
||||||
}
|
} else {
|
||||||
else
|
json++;
|
||||||
{
|
}
|
||||||
/* All other characters. */
|
break;
|
||||||
*into++ = (unsigned char)*json++;
|
|
||||||
|
case '\"':
|
||||||
|
minify_string(&json, (char**)&into);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
into[0] = json[0];
|
||||||
|
json++;
|
||||||
|
into++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
100
cJSON.h
100
cJSON.h
@@ -28,10 +28,60 @@ extern "C"
|
|||||||
{
|
{
|
||||||
#endif
|
#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 */
|
/* project version */
|
||||||
#define CJSON_VERSION_MAJOR 1
|
#define CJSON_VERSION_MAJOR 1
|
||||||
#define CJSON_VERSION_MINOR 7
|
#define CJSON_VERSION_MINOR 7
|
||||||
#define CJSON_VERSION_PATCH 7
|
#define CJSON_VERSION_PATCH 12
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
@@ -74,55 +124,13 @@ typedef struct cJSON
|
|||||||
|
|
||||||
typedef struct cJSON_Hooks
|
typedef struct cJSON_Hooks
|
||||||
{
|
{
|
||||||
void *(*malloc_fn)(size_t sz);
|
/* 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 (*free_fn)(void *ptr);
|
void *(CJSON_CDECL *malloc_fn)(size_t sz);
|
||||||
|
void (CJSON_CDECL *free_fn)(void *ptr);
|
||||||
} cJSON_Hooks;
|
} cJSON_Hooks;
|
||||||
|
|
||||||
typedef int cJSON_bool;
|
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.
|
/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them.
|
||||||
* This is to prevent stack overflows. */
|
* This is to prevent stack overflows. */
|
||||||
#ifndef CJSON_NESTING_LIMIT
|
#ifndef CJSON_NESTING_LIMIT
|
||||||
|
|||||||
@@ -50,7 +50,14 @@
|
|||||||
#include "cJSON_Utils.h"
|
#include "cJSON_Utils.h"
|
||||||
|
|
||||||
/* define our own boolean type */
|
/* define our own boolean type */
|
||||||
|
#ifdef true
|
||||||
|
#undef true
|
||||||
|
#endif
|
||||||
#define true ((cJSON_bool)1)
|
#define true ((cJSON_bool)1)
|
||||||
|
|
||||||
|
#ifdef false
|
||||||
|
#undef false
|
||||||
|
#endif
|
||||||
#define false ((cJSON_bool)0)
|
#define false ((cJSON_bool)0)
|
||||||
|
|
||||||
static unsigned char* cJSONUtils_strdup(const unsigned char* const string)
|
static unsigned char* cJSONUtils_strdup(const unsigned char* const string)
|
||||||
@@ -499,6 +506,7 @@ static cJSON *sort_list(cJSON *list, const cJSON_bool case_sensitive)
|
|||||||
{
|
{
|
||||||
/* Split the lists */
|
/* Split the lists */
|
||||||
second->prev->next = NULL;
|
second->prev->next = NULL;
|
||||||
|
second->prev = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Recursively sort the sub-lists. */
|
/* Recursively sort the sub-lists. */
|
||||||
@@ -510,7 +518,7 @@ static cJSON *sort_list(cJSON *list, const cJSON_bool case_sensitive)
|
|||||||
while ((first != NULL) && (second != NULL))
|
while ((first != NULL) && (second != NULL))
|
||||||
{
|
{
|
||||||
cJSON *smaller = NULL;
|
cJSON *smaller = NULL;
|
||||||
if (compare_strings((unsigned char*)first->string, (unsigned char*)second->string, false) < 0)
|
if (compare_strings((unsigned char*)first->string, (unsigned char*)second->string, case_sensitive) < 0)
|
||||||
{
|
{
|
||||||
smaller = first;
|
smaller = first;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,5 +6,5 @@ Version: @PROJECT_VERSION@
|
|||||||
Description: Ultralightweight JSON parser in ANSI C
|
Description: Ultralightweight JSON parser in ANSI C
|
||||||
URL: https://github.com/DaveGamble/cJSON
|
URL: https://github.com/DaveGamble/cJSON
|
||||||
Libs: -L${libdir} -lcjson
|
Libs: -L${libdir} -lcjson
|
||||||
Libs.Private: -lm
|
Libs.private: -lm
|
||||||
Cflags: -I${includedir}
|
Cflags: -I${includedir}
|
||||||
|
|||||||
2
test.c
2
test.c
@@ -256,7 +256,7 @@ static void create_objects(void)
|
|||||||
cJSON_Delete(root);
|
cJSON_Delete(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void)
|
int CJSON_CDECL main(void)
|
||||||
{
|
{
|
||||||
/* print the version */
|
/* print the version */
|
||||||
printf("Version: %s\n", cJSON_Version());
|
printf("Version: %s\n", cJSON_Version());
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
if(ENABLE_CJSON_TEST)
|
if(ENABLE_CJSON_TEST)
|
||||||
add_library(unity "${CJSON_LIBRARY_TYPE}" unity/src/unity.c)
|
add_library(unity STATIC unity/src/unity.c)
|
||||||
|
|
||||||
# Disable -Werror for Unity
|
# Disable -Werror for Unity
|
||||||
if (FLAG_SUPPORTED_Werror)
|
if (FLAG_SUPPORTED_Werror)
|
||||||
@@ -57,6 +57,7 @@ if(ENABLE_CJSON_TEST)
|
|||||||
compare_tests
|
compare_tests
|
||||||
cjson_add
|
cjson_add
|
||||||
readme_examples
|
readme_examples
|
||||||
|
minify_tests
|
||||||
)
|
)
|
||||||
|
|
||||||
option(ENABLE_VALGRIND OFF "Enable the valgrind memory checker for the tests.")
|
option(ENABLE_VALGRIND OFF "Enable the valgrind memory checker for the tests.")
|
||||||
@@ -72,6 +73,9 @@ if(ENABLE_CJSON_TEST)
|
|||||||
|
|
||||||
foreach(unity_test ${unity_tests})
|
foreach(unity_test ${unity_tests})
|
||||||
add_executable("${unity_test}" "${unity_test}.c")
|
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)
|
target_link_libraries("${unity_test}" "${CJSON_LIB}" unity)
|
||||||
if(MEMORYCHECK_COMMAND)
|
if(MEMORYCHECK_COMMAND)
|
||||||
add_test(NAME "${unity_test}"
|
add_test(NAME "${unity_test}"
|
||||||
@@ -98,6 +102,9 @@ if(ENABLE_CJSON_TEST)
|
|||||||
foreach (cjson_utils_test ${cjson_utils_tests})
|
foreach (cjson_utils_test ${cjson_utils_tests})
|
||||||
add_executable("${cjson_utils_test}" "${cjson_utils_test}.c")
|
add_executable("${cjson_utils_test}" "${cjson_utils_test}.c")
|
||||||
target_link_libraries("${cjson_utils_test}" "${CJSON_LIB}" "${CJSON_UTILS_LIB}" unity)
|
target_link_libraries("${cjson_utils_test}" "${CJSON_LIB}" "${CJSON_UTILS_LIB}" unity)
|
||||||
|
if("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
|
||||||
|
target_sources(${cjson_utils_test} PRIVATE unity_setup.c)
|
||||||
|
endif()
|
||||||
if(MEMORYCHECK_COMMAND)
|
if(MEMORYCHECK_COMMAND)
|
||||||
add_test(NAME "${cjson_utils_test}"
|
add_test(NAME "${cjson_utils_test}"
|
||||||
COMMAND "${MEMORYCHECK_COMMAND}" ${MEMORYCHECK_COMMAND_OPTIONS} "${CMAKE_CURRENT_BINARY_DIR}/${cjson_utils_test}")
|
COMMAND "${MEMORYCHECK_COMMAND}" ${MEMORYCHECK_COMMAND_OPTIONS} "${CMAKE_CURRENT_BINARY_DIR}/${cjson_utils_test}")
|
||||||
|
|||||||
@@ -28,15 +28,21 @@
|
|||||||
#include "unity/src/unity.h"
|
#include "unity/src/unity.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
static void *failing_malloc(size_t size)
|
static void * CJSON_CDECL failing_malloc(size_t size)
|
||||||
{
|
{
|
||||||
(void)size;
|
(void)size;
|
||||||
return NULL;
|
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 = {
|
static cJSON_Hooks failing_hooks = {
|
||||||
failing_malloc,
|
failing_malloc,
|
||||||
free
|
normal_free
|
||||||
};
|
};
|
||||||
|
|
||||||
static void cjson_add_null_should_add_null(void)
|
static void cjson_add_null_should_add_null(void)
|
||||||
@@ -372,7 +378,7 @@ static void cjson_add_array_should_fail_on_allocation_failure(void)
|
|||||||
cJSON_Delete(root);
|
cJSON_Delete(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void)
|
int CJSON_CDECL main(void)
|
||||||
{
|
{
|
||||||
UNITY_BEGIN();
|
UNITY_BEGIN();
|
||||||
|
|
||||||
|
|||||||
@@ -186,7 +186,7 @@ static void cjson_compare_should_compare_objects(void)
|
|||||||
false))
|
false))
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void)
|
int CJSON_CDECL main(void)
|
||||||
{
|
{
|
||||||
UNITY_BEGIN();
|
UNITY_BEGIN();
|
||||||
|
|
||||||
|
|||||||
@@ -214,6 +214,7 @@
|
|||||||
|
|
||||||
{ "doc": {"foo": null},
|
{ "doc": {"foo": null},
|
||||||
"patch": [{"op": "test", "path": "/foo", "value": null}],
|
"patch": [{"op": "test", "path": "/foo", "value": null}],
|
||||||
|
"expected": {"foo": null},
|
||||||
"comment": "null value should be valid obj property" },
|
"comment": "null value should be valid obj property" },
|
||||||
|
|
||||||
{ "doc": {"foo": null},
|
{ "doc": {"foo": null},
|
||||||
@@ -243,14 +244,17 @@
|
|||||||
|
|
||||||
{ "doc": {"foo": {"foo": 1, "bar": 2}},
|
{ "doc": {"foo": {"foo": 1, "bar": 2}},
|
||||||
"patch": [{"op": "test", "path": "/foo", "value": {"bar": 2, "foo": 1}}],
|
"patch": [{"op": "test", "path": "/foo", "value": {"bar": 2, "foo": 1}}],
|
||||||
|
"expected": {"foo": {"foo": 1, "bar": 2}},
|
||||||
"comment": "test should pass despite rearrangement" },
|
"comment": "test should pass despite rearrangement" },
|
||||||
|
|
||||||
{ "doc": {"foo": [{"foo": 1, "bar": 2}]},
|
{ "doc": {"foo": [{"foo": 1, "bar": 2}]},
|
||||||
"patch": [{"op": "test", "path": "/foo", "value": [{"bar": 2, "foo": 1}]}],
|
"patch": [{"op": "test", "path": "/foo", "value": [{"bar": 2, "foo": 1}]}],
|
||||||
|
"expected": {"foo": [{"foo": 1, "bar": 2}]},
|
||||||
"comment": "test should pass despite (nested) rearrangement" },
|
"comment": "test should pass despite (nested) rearrangement" },
|
||||||
|
|
||||||
{ "doc": {"foo": {"bar": [1, 2, 5, 4]}},
|
{ "doc": {"foo": {"bar": [1, 2, 5, 4]}},
|
||||||
"patch": [{"op": "test", "path": "/foo", "value": {"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" },
|
"comment": "test should pass - no error" },
|
||||||
|
|
||||||
{ "doc": {"foo": {"bar": [1, 2, 5, 4]}},
|
{ "doc": {"foo": {"bar": [1, 2, 5, 4]}},
|
||||||
@@ -264,7 +268,8 @@
|
|||||||
|
|
||||||
{ "comment": "Empty-string element",
|
{ "comment": "Empty-string element",
|
||||||
"doc": { "": 1 },
|
"doc": { "": 1 },
|
||||||
"patch": [{"op": "test", "path": "/", "value": 1}] },
|
"patch": [{"op": "test", "path": "/", "value": 1}],
|
||||||
|
"expected": { "": 1 } },
|
||||||
|
|
||||||
{ "doc": {
|
{ "doc": {
|
||||||
"foo": ["bar", "baz"],
|
"foo": ["bar", "baz"],
|
||||||
@@ -288,8 +293,23 @@
|
|||||||
{"op": "test", "path": "/i\\j", "value": 5},
|
{"op": "test", "path": "/i\\j", "value": 5},
|
||||||
{"op": "test", "path": "/k\"l", "value": 6},
|
{"op": "test", "path": "/k\"l", "value": 6},
|
||||||
{"op": "test", "path": "/ ", "value": 7},
|
{"op": "test", "path": "/ ", "value": 7},
|
||||||
{"op": "test", "path": "/m~0n", "value": 8}] },
|
{"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
|
||||||
|
}
|
||||||
|
},
|
||||||
{ "comment": "Move to same location has no effect",
|
{ "comment": "Move to same location has no effect",
|
||||||
"doc": {"foo": 1},
|
"doc": {"foo": 1},
|
||||||
"patch": [{"op": "move", "from": "/foo", "path": "/foo"}],
|
"patch": [{"op": "move", "from": "/foo", "path": "/foo"}],
|
||||||
@@ -388,11 +408,21 @@
|
|||||||
"patch": [ { "op": "copy", "path": "/-" } ],
|
"patch": [ { "op": "copy", "path": "/-" } ],
|
||||||
"error": "missing 'from' parameter" },
|
"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",
|
{ "comment": "missing from parameter to move",
|
||||||
"doc": { "foo": 1 },
|
"doc": { "foo": 1 },
|
||||||
"patch": [ { "op": "move", "path": "" } ],
|
"patch": [ { "op": "move", "path": "" } ],
|
||||||
"error": "missing 'from' parameter" },
|
"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",
|
{ "comment": "duplicate ops",
|
||||||
"doc": { "foo": "bar" },
|
"doc": { "foo": "bar" },
|
||||||
"patch": [ { "op": "add", "path": "/baz", "value": "qux",
|
"patch": [ { "op": "add", "path": "/baz", "value": "qux",
|
||||||
|
|||||||
174
tests/minify_tests.c
Normal file
174
tests/minify_tests.c
Normal file
@@ -0,0 +1,174 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2009-2019 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 cjson_minify_should_not_overflow_buffer(void)
|
||||||
|
{
|
||||||
|
char unclosed_multiline_comment[] = "/* bla";
|
||||||
|
char pending_escape[] = "\"\\";
|
||||||
|
|
||||||
|
cJSON_Minify(unclosed_multiline_comment);
|
||||||
|
TEST_ASSERT_EQUAL_STRING("", unclosed_multiline_comment);
|
||||||
|
|
||||||
|
cJSON_Minify(pending_escape);
|
||||||
|
TEST_ASSERT_EQUAL_STRING("\"\\", pending_escape);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cjson_minify_should_remove_single_line_comments(void)
|
||||||
|
{
|
||||||
|
const char to_minify[] = "{// this is {} \"some kind\" of [] comment /*, don't you see\n}";
|
||||||
|
|
||||||
|
char* minified = (char*) malloc(sizeof(to_minify));
|
||||||
|
TEST_ASSERT_NOT_NULL(minified);
|
||||||
|
strcpy(minified, to_minify);
|
||||||
|
|
||||||
|
cJSON_Minify(minified);
|
||||||
|
TEST_ASSERT_EQUAL_STRING("{}", minified);
|
||||||
|
|
||||||
|
free(minified);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cjson_minify_should_remove_spaces(void)
|
||||||
|
{
|
||||||
|
const char to_minify[] = "{ \"key\":\ttrue\r\n }";
|
||||||
|
|
||||||
|
char* minified = (char*) malloc(sizeof(to_minify));
|
||||||
|
TEST_ASSERT_NOT_NULL(minified);
|
||||||
|
strcpy(minified, to_minify);
|
||||||
|
|
||||||
|
cJSON_Minify(minified);
|
||||||
|
TEST_ASSERT_EQUAL_STRING("{\"key\":true}", minified);
|
||||||
|
|
||||||
|
free(minified);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cjson_minify_should_remove_multiline_comments(void)
|
||||||
|
{
|
||||||
|
const char to_minify[] = "{/* this is\n a /* multi\n //line \n {comment \"\\\" */}";
|
||||||
|
|
||||||
|
char* minified = (char*) malloc(sizeof(to_minify));
|
||||||
|
TEST_ASSERT_NOT_NULL(minified);
|
||||||
|
strcpy(minified, to_minify);
|
||||||
|
|
||||||
|
cJSON_Minify(minified);
|
||||||
|
TEST_ASSERT_EQUAL_STRING("{}", minified);
|
||||||
|
|
||||||
|
free(minified);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cjson_minify_should_not_modify_strings(void)
|
||||||
|
{
|
||||||
|
const char to_minify[] = "\"this is a string \\\" \\t bla\"";
|
||||||
|
|
||||||
|
char* minified = (char*) malloc(sizeof(to_minify));
|
||||||
|
TEST_ASSERT_NOT_NULL(minified);
|
||||||
|
strcpy(minified, to_minify);
|
||||||
|
|
||||||
|
cJSON_Minify(minified);
|
||||||
|
TEST_ASSERT_EQUAL_STRING(to_minify, minified);
|
||||||
|
|
||||||
|
free(minified);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cjson_minify_should_minify_json(void) {
|
||||||
|
const char to_minify[] =
|
||||||
|
"{\n"
|
||||||
|
" \"glossary\": { // comment\n"
|
||||||
|
" \"title\": \"example glossary\",\n"
|
||||||
|
" /* multi\n"
|
||||||
|
" line */\n"
|
||||||
|
" \"GlossDiv\": {\n"
|
||||||
|
" \"title\": \"S\",\n"
|
||||||
|
" \"GlossList\": {\n"
|
||||||
|
" \"GlossEntry\": {\n"
|
||||||
|
" \"ID\": \"SGML\",\n"
|
||||||
|
" \"SortAs\": \"SGML\",\n"
|
||||||
|
" \"Acronym\": \"SGML\",\n"
|
||||||
|
" \"Abbrev\": \"ISO 8879:1986\",\n"
|
||||||
|
" \"GlossDef\": {\n"
|
||||||
|
" \"GlossSeeAlso\": [\"GML\", \"XML\"]\n"
|
||||||
|
" },\n"
|
||||||
|
" \"GlossSee\": \"markup\"\n"
|
||||||
|
" }\n"
|
||||||
|
" }\n"
|
||||||
|
" }\n"
|
||||||
|
" }\n"
|
||||||
|
"}";
|
||||||
|
const char* minified =
|
||||||
|
"{"
|
||||||
|
"\"glossary\":{"
|
||||||
|
"\"title\":\"example glossary\","
|
||||||
|
"\"GlossDiv\":{"
|
||||||
|
"\"title\":\"S\","
|
||||||
|
"\"GlossList\":{"
|
||||||
|
"\"GlossEntry\":{"
|
||||||
|
"\"ID\":\"SGML\","
|
||||||
|
"\"SortAs\":\"SGML\","
|
||||||
|
"\"Acronym\":\"SGML\","
|
||||||
|
"\"Abbrev\":\"ISO 8879:1986\","
|
||||||
|
"\"GlossDef\":{"
|
||||||
|
"\"GlossSeeAlso\":[\"GML\",\"XML\"]"
|
||||||
|
"},"
|
||||||
|
"\"GlossSee\":\"markup\""
|
||||||
|
"}"
|
||||||
|
"}"
|
||||||
|
"}"
|
||||||
|
"}"
|
||||||
|
"}";
|
||||||
|
|
||||||
|
char *buffer = (char*) malloc(sizeof(to_minify));
|
||||||
|
strcpy(buffer, to_minify);
|
||||||
|
|
||||||
|
cJSON_Minify(buffer);
|
||||||
|
TEST_ASSERT_EQUAL_STRING(minified, buffer);
|
||||||
|
|
||||||
|
free(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cjson_minify_should_not_loop_infinitely(void) {
|
||||||
|
char string[] = { '8', ' ', '/', ' ', '5', '\n', '\0' };
|
||||||
|
/* this should not be an infinite loop */
|
||||||
|
cJSON_Minify(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
int CJSON_CDECL main(void)
|
||||||
|
{
|
||||||
|
UNITY_BEGIN();
|
||||||
|
|
||||||
|
RUN_TEST(cjson_minify_should_not_overflow_buffer);
|
||||||
|
RUN_TEST(cjson_minify_should_minify_json);
|
||||||
|
RUN_TEST(cjson_minify_should_remove_single_line_comments);
|
||||||
|
RUN_TEST(cjson_minify_should_remove_multiline_comments);
|
||||||
|
RUN_TEST(cjson_minify_should_remove_spaces);
|
||||||
|
RUN_TEST(cjson_minify_should_not_modify_strings);
|
||||||
|
RUN_TEST(cjson_minify_should_not_loop_infinitely);
|
||||||
|
|
||||||
|
return UNITY_END();
|
||||||
|
}
|
||||||
@@ -127,6 +127,28 @@ static void cjson_get_object_item_case_sensitive_should_get_object_items(void)
|
|||||||
cJSON_Delete(item);
|
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)
|
static void typecheck_functions_should_check_type(void)
|
||||||
{
|
{
|
||||||
cJSON invalid[1];
|
cJSON invalid[1];
|
||||||
@@ -410,7 +432,7 @@ static void cjson_functions_shouldnt_crash_with_null_pointers(void)
|
|||||||
cJSON_Delete(item);
|
cJSON_Delete(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *failing_realloc(void *pointer, size_t size)
|
static void * CJSON_CDECL failing_realloc(void *pointer, size_t size)
|
||||||
{
|
{
|
||||||
(void)size;
|
(void)size;
|
||||||
(void)pointer;
|
(void)pointer;
|
||||||
@@ -527,7 +549,7 @@ static void cjson_add_item_to_object_should_not_use_after_free_when_string_is_al
|
|||||||
cJSON_Delete(object);
|
cJSON_Delete(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void)
|
int CJSON_CDECL main(void)
|
||||||
{
|
{
|
||||||
UNITY_BEGIN();
|
UNITY_BEGIN();
|
||||||
|
|
||||||
@@ -535,6 +557,8 @@ int main(void)
|
|||||||
RUN_TEST(cjson_array_foreach_should_not_dereference_null_pointer);
|
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_should_get_object_items);
|
||||||
RUN_TEST(cjson_get_object_item_case_sensitive_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(typecheck_functions_should_check_type);
|
||||||
RUN_TEST(cjson_should_not_parse_to_deeply_nested_jsons);
|
RUN_TEST(cjson_should_not_parse_to_deeply_nested_jsons);
|
||||||
RUN_TEST(cjson_set_number_value_should_set_numbers);
|
RUN_TEST(cjson_set_number_value_should_set_numbers);
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ static void parse_array_should_not_parse_non_arrays(void)
|
|||||||
assert_not_array("\"[]hello world!\n\"");
|
assert_not_array("\"[]hello world!\n\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void)
|
int CJSON_CDECL main(void)
|
||||||
{
|
{
|
||||||
/* initialize cJSON item */
|
/* initialize cJSON item */
|
||||||
memset(item, 0, sizeof(cJSON));
|
memset(item, 0, sizeof(cJSON));
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ static void test12_should_not_be_parsed(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void)
|
int CJSON_CDECL main(void)
|
||||||
{
|
{
|
||||||
UNITY_BEGIN();
|
UNITY_BEGIN();
|
||||||
RUN_TEST(file_test1_should_be_parsed_and_printed);
|
RUN_TEST(file_test1_should_be_parsed_and_printed);
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ static void parse_hex4_should_parse_mixed_case(void)
|
|||||||
TEST_ASSERT_EQUAL_INT(0xBEEF, parse_hex4((const unsigned char*)"BEEF"));
|
TEST_ASSERT_EQUAL_INT(0xBEEF, parse_hex4((const unsigned char*)"BEEF"));
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void)
|
int CJSON_CDECL main(void)
|
||||||
{
|
{
|
||||||
UNITY_BEGIN();
|
UNITY_BEGIN();
|
||||||
RUN_TEST(parse_hex4_should_parse_all_combinations);
|
RUN_TEST(parse_hex4_should_parse_all_combinations);
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ static void parse_number_should_parse_negative_reals(void)
|
|||||||
assert_parse_number("-123e-128", 0, -123e-128);
|
assert_parse_number("-123e-128", 0, -123e-128);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void)
|
int CJSON_CDECL main(void)
|
||||||
{
|
{
|
||||||
/* initialize cJSON item */
|
/* initialize cJSON item */
|
||||||
memset(item, 0, sizeof(cJSON));
|
memset(item, 0, sizeof(cJSON));
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ static void parse_object_should_not_parse_non_objects(void)
|
|||||||
assert_not_object("\"{}hello world!\n\"");
|
assert_not_object("\"{}hello world!\n\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void)
|
int CJSON_CDECL main(void)
|
||||||
{
|
{
|
||||||
/* initialize cJSON item */
|
/* initialize cJSON item */
|
||||||
memset(item, 0, sizeof(cJSON));
|
memset(item, 0, sizeof(cJSON));
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ static void parse_string_should_parse_bug_94(void)
|
|||||||
reset(item);
|
reset(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void)
|
int CJSON_CDECL main(void)
|
||||||
{
|
{
|
||||||
/* initialize cJSON item and error pointer */
|
/* initialize cJSON item and error pointer */
|
||||||
memset(item, 0, sizeof(cJSON));
|
memset(item, 0, sizeof(cJSON));
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ static void parse_value_should_parse_object(void)
|
|||||||
reset(item);
|
reset(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void)
|
int CJSON_CDECL main(void)
|
||||||
{
|
{
|
||||||
/* initialize cJSON item */
|
/* initialize cJSON item */
|
||||||
memset(item, 0, sizeof(cJSON));
|
memset(item, 0, sizeof(cJSON));
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ static void parse_with_opts_should_parse_utf8_bom(void)
|
|||||||
cJSON_Delete(without_bom);
|
cJSON_Delete(without_bom);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void)
|
int CJSON_CDECL main(void)
|
||||||
{
|
{
|
||||||
UNITY_BEGIN();
|
UNITY_BEGIN();
|
||||||
|
|
||||||
|
|||||||
@@ -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\",{}]");
|
assert_print_array("[1, null, true, false, [], \"hello\", {\n\t}]", "[1,null,true,false,[],\"hello\",{}]");
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void)
|
int CJSON_CDECL main(void)
|
||||||
{
|
{
|
||||||
/* initialize cJSON item */
|
/* initialize cJSON item */
|
||||||
UNITY_BEGIN();
|
UNITY_BEGIN();
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ static void print_number_should_print_non_number(void)
|
|||||||
/* assert_print_number("null", -INFTY); */
|
/* assert_print_number("null", -INFTY); */
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void)
|
int CJSON_CDECL main(void)
|
||||||
{
|
{
|
||||||
/* initialize cJSON item */
|
/* initialize cJSON item */
|
||||||
UNITY_BEGIN();
|
UNITY_BEGIN();
|
||||||
|
|||||||
@@ -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\":{}}");
|
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 main(void)
|
int CJSON_CDECL main(void)
|
||||||
{
|
{
|
||||||
/* initialize cJSON item */
|
/* initialize cJSON item */
|
||||||
UNITY_BEGIN();
|
UNITY_BEGIN();
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ static void print_string_should_print_utf8(void)
|
|||||||
assert_print_string("\"ü猫慕\"", "ü猫慕");
|
assert_print_string("\"ü猫慕\"", "ü猫慕");
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void)
|
int CJSON_CDECL main(void)
|
||||||
{
|
{
|
||||||
/* initialize cJSON item */
|
/* initialize cJSON item */
|
||||||
UNITY_BEGIN();
|
UNITY_BEGIN();
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ static void print_value_should_print_object(void)
|
|||||||
assert_print_value("{}");
|
assert_print_value("{}");
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void)
|
int CJSON_CDECL main(void)
|
||||||
{
|
{
|
||||||
/* initialize cJSON item */
|
/* initialize cJSON item */
|
||||||
UNITY_BEGIN();
|
UNITY_BEGIN();
|
||||||
|
|||||||
@@ -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));
|
TEST_ASSERT_FALSE(supports_full_hd(monitor_without_hd));
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void)
|
int CJSON_CDECL main(void)
|
||||||
{
|
{
|
||||||
UNITY_BEGIN();
|
UNITY_BEGIN();
|
||||||
|
|
||||||
|
|||||||
3
tests/unity_setup.c
Normal file
3
tests/unity_setup.c
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
// msvc doesn't support weak-linking, so we need to define these functions.
|
||||||
|
void setUp(void) { }
|
||||||
|
void tearDown(void) { }
|
||||||
Reference in New Issue
Block a user