Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
12c4bf1986 | ||
|
|
9d1b229086 | ||
|
|
078c4e6c53 | ||
|
|
4f4d7f70c2 | ||
|
|
b47edc4750 | ||
|
|
d6d5449e1f | ||
|
|
a78d975537 | ||
|
|
f28a468e3b | ||
|
|
424ce4ce96 | ||
|
|
324973008c | ||
|
|
8a334b0140 |
35
cJSON.c
35
cJSON.c
@@ -403,6 +403,8 @@ CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number)
|
|||||||
CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring)
|
CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring)
|
||||||
{
|
{
|
||||||
char *copy = NULL;
|
char *copy = NULL;
|
||||||
|
size_t v1_len;
|
||||||
|
size_t v2_len;
|
||||||
/* if object's type is not cJSON_String or is cJSON_IsReference, it should not set valuestring */
|
/* if object's type is not cJSON_String or is cJSON_IsReference, it should not set valuestring */
|
||||||
if ((object == NULL) || !(object->type & cJSON_String) || (object->type & cJSON_IsReference))
|
if ((object == NULL) || !(object->type & cJSON_String) || (object->type & cJSON_IsReference))
|
||||||
{
|
{
|
||||||
@@ -413,8 +415,17 @@ CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring)
|
|||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (strlen(valuestring) <= strlen(object->valuestring))
|
|
||||||
|
v1_len = strlen(valuestring);
|
||||||
|
v2_len = strlen(object->valuestring);
|
||||||
|
|
||||||
|
if (v1_len <= v2_len)
|
||||||
{
|
{
|
||||||
|
/* strcpy does not handle overlapping string: [X1, X2] [Y1, Y2] => X2 < Y1 or Y2 < X1 */
|
||||||
|
if (!( valuestring + v1_len < object->valuestring || object->valuestring + v2_len < valuestring ))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
strcpy(object->valuestring, valuestring);
|
strcpy(object->valuestring, valuestring);
|
||||||
return object->valuestring;
|
return object->valuestring;
|
||||||
}
|
}
|
||||||
@@ -570,10 +581,10 @@ static cJSON_bool print_number(const cJSON * const item, printbuffer * const out
|
|||||||
{
|
{
|
||||||
length = sprintf((char*)number_buffer, "null");
|
length = sprintf((char*)number_buffer, "null");
|
||||||
}
|
}
|
||||||
else if(d == (double)item->valueint)
|
else if(d == (double)item->valueint)
|
||||||
{
|
{
|
||||||
length = sprintf((char*)number_buffer, "%d", item->valueint);
|
length = sprintf((char*)number_buffer, "%d", item->valueint);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */
|
/* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */
|
||||||
@@ -2204,7 +2215,7 @@ CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * c
|
|||||||
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item)
|
CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item)
|
||||||
{
|
{
|
||||||
if ((parent == NULL) || (item == NULL))
|
if ((parent == NULL) || (item == NULL) || (item != parent->child && item->prev == NULL))
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -2726,7 +2737,14 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int co
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Duplication */
|
/* Duplication */
|
||||||
|
cJSON * cJSON_Duplicate_rec(const cJSON *item, size_t depth, cJSON_bool recurse);
|
||||||
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse)
|
CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse)
|
||||||
|
{
|
||||||
|
return cJSON_Duplicate_rec(item, 0, recurse );
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON * cJSON_Duplicate_rec(const cJSON *item, size_t depth, cJSON_bool recurse)
|
||||||
{
|
{
|
||||||
cJSON *newitem = NULL;
|
cJSON *newitem = NULL;
|
||||||
cJSON *child = NULL;
|
cJSON *child = NULL;
|
||||||
@@ -2773,7 +2791,10 @@ CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse)
|
|||||||
child = item->child;
|
child = item->child;
|
||||||
while (child != NULL)
|
while (child != NULL)
|
||||||
{
|
{
|
||||||
newchild = cJSON_Duplicate(child, true); /* Duplicate (with recurse) each item in the ->next chain */
|
if(depth >= CJSON_CIRCULAR_LIMIT) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
newchild = cJSON_Duplicate_rec(child, depth + 1, true); /* Duplicate (with recurse) each item in the ->next chain */
|
||||||
if (!newchild)
|
if (!newchild)
|
||||||
{
|
{
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|||||||
6
cJSON.h
6
cJSON.h
@@ -137,6 +137,12 @@ typedef int cJSON_bool;
|
|||||||
#define CJSON_NESTING_LIMIT 1000
|
#define CJSON_NESTING_LIMIT 1000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Limits the length of circular references can be before cJSON rejects to parse them.
|
||||||
|
* This is to prevent stack overflows. */
|
||||||
|
#ifndef CJSON_CIRCULAR_LIMIT
|
||||||
|
#define CJSON_CIRCULAR_LIMIT 10000
|
||||||
|
#endif
|
||||||
|
|
||||||
/* returns the version of cJSON as a string */
|
/* returns the version of cJSON as a string */
|
||||||
CJSON_PUBLIC(const char*) cJSON_Version(void);
|
CJSON_PUBLIC(const char*) cJSON_Version(void);
|
||||||
|
|
||||||
|
|||||||
@@ -62,7 +62,6 @@ if(ENABLE_CJSON_TEST)
|
|||||||
|
|
||||||
option(ENABLE_VALGRIND OFF "Enable the valgrind memory checker for the tests.")
|
option(ENABLE_VALGRIND OFF "Enable the valgrind memory checker for the tests.")
|
||||||
if (ENABLE_VALGRIND)
|
if (ENABLE_VALGRIND)
|
||||||
add_compile_definitions(ENABLE_VALGRIND)
|
|
||||||
find_program(MEMORYCHECK_COMMAND valgrind)
|
find_program(MEMORYCHECK_COMMAND valgrind)
|
||||||
if ("${MEMORYCHECK_COMMAND}" MATCHES "MEMORYCHECK_COMMAND-NOTFOUND")
|
if ("${MEMORYCHECK_COMMAND}" MATCHES "MEMORYCHECK_COMMAND-NOTFOUND")
|
||||||
message(WARNING "Valgrind couldn't be found.")
|
message(WARNING "Valgrind couldn't be found.")
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ static void * CJSON_CDECL failing_malloc(size_t size)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* work around MSVC error C2322: '...' address of dillimport '...' is not static */
|
/* work around MSVC error C2322: '...' address of dllimport '...' is not static */
|
||||||
static void CJSON_CDECL normal_free(void *pointer)
|
static void CJSON_CDECL normal_free(void *pointer)
|
||||||
{
|
{
|
||||||
free(pointer);
|
free(pointer);
|
||||||
|
|||||||
@@ -219,6 +219,23 @@ static void cjson_should_not_parse_to_deeply_nested_jsons(void)
|
|||||||
TEST_ASSERT_NULL_MESSAGE(cJSON_Parse(deep_json), "To deep JSONs should not be parsed.");
|
TEST_ASSERT_NULL_MESSAGE(cJSON_Parse(deep_json), "To deep JSONs should not be parsed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cjson_should_not_follow_too_deep_circular_references(void)
|
||||||
|
{
|
||||||
|
cJSON *o = cJSON_CreateArray();
|
||||||
|
cJSON *a = cJSON_CreateArray();
|
||||||
|
cJSON *b = cJSON_CreateArray();
|
||||||
|
cJSON *x;
|
||||||
|
|
||||||
|
cJSON_AddItemToArray(o, a);
|
||||||
|
cJSON_AddItemToArray(a, b);
|
||||||
|
cJSON_AddItemToArray(b, o);
|
||||||
|
|
||||||
|
x = cJSON_Duplicate(o, 1);
|
||||||
|
TEST_ASSERT_NULL(x);
|
||||||
|
cJSON_DetachItemFromArray(b, 0);
|
||||||
|
cJSON_Delete(o);
|
||||||
|
}
|
||||||
|
|
||||||
static void cjson_set_number_value_should_set_numbers(void)
|
static void cjson_set_number_value_should_set_numbers(void)
|
||||||
{
|
{
|
||||||
cJSON number[1] = {{NULL, NULL, NULL, cJSON_Number, NULL, 0, 0, NULL}};
|
cJSON number[1] = {{NULL, NULL, NULL, cJSON_Number, NULL, 0, 0, NULL}};
|
||||||
@@ -280,6 +297,21 @@ static void cjson_detach_item_via_pointer_should_detach_items(void)
|
|||||||
TEST_ASSERT_NULL_MESSAGE(parent->child, "Child of the parent wasn't set to NULL.");
|
TEST_ASSERT_NULL_MESSAGE(parent->child, "Child of the parent wasn't set to NULL.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cjson_detach_item_via_pointer_should_return_null_if_item_prev_is_null(void)
|
||||||
|
{
|
||||||
|
cJSON list[2];
|
||||||
|
cJSON parent[1];
|
||||||
|
|
||||||
|
memset(list, '\0', sizeof(list));
|
||||||
|
|
||||||
|
/* link the list */
|
||||||
|
list[0].next = &(list[1]);
|
||||||
|
|
||||||
|
parent->child = &list[0];
|
||||||
|
TEST_ASSERT_NULL_MESSAGE(cJSON_DetachItemViaPointer(parent, &(list[1])), "Failed to detach in the middle.");
|
||||||
|
TEST_ASSERT_TRUE_MESSAGE(cJSON_DetachItemViaPointer(parent, &(list[0])) == &(list[0]), "Failed to detach in the middle.");
|
||||||
|
}
|
||||||
|
|
||||||
static void cjson_replace_item_via_pointer_should_replace_items(void)
|
static void cjson_replace_item_via_pointer_should_replace_items(void)
|
||||||
{
|
{
|
||||||
cJSON replacements[3];
|
cJSON replacements[3];
|
||||||
@@ -456,6 +488,24 @@ static void cjson_functions_should_not_crash_with_null_pointers(void)
|
|||||||
cJSON_Delete(item);
|
cJSON_Delete(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cjson_set_valuestring_should_return_null_if_strings_overlap(void)
|
||||||
|
{
|
||||||
|
cJSON *obj;
|
||||||
|
char* str;
|
||||||
|
char* str2;
|
||||||
|
|
||||||
|
obj = cJSON_Parse("\"foo0z\"");
|
||||||
|
|
||||||
|
str = cJSON_SetValuestring(obj, "abcde");
|
||||||
|
str += 1;
|
||||||
|
/* The string passed to strcpy overlap which is not allowed.*/
|
||||||
|
str2 = cJSON_SetValuestring(obj, str);
|
||||||
|
/* If it overlaps, the string will be messed up.*/
|
||||||
|
TEST_ASSERT_TRUE(strcmp(str, "bcde") == 0);
|
||||||
|
TEST_ASSERT_NULL(str2);
|
||||||
|
cJSON_Delete(obj);
|
||||||
|
}
|
||||||
|
|
||||||
static void *CJSON_CDECL failing_realloc(void *pointer, size_t size)
|
static void *CJSON_CDECL failing_realloc(void *pointer, size_t size)
|
||||||
{
|
{
|
||||||
(void)size;
|
(void)size;
|
||||||
@@ -732,23 +782,6 @@ static void cjson_set_bool_value_must_not_break_objects(void)
|
|||||||
cJSON_Delete(sobj);
|
cJSON_Delete(sobj);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void deallocated_pointers_should_be_set_to_null(void)
|
|
||||||
{
|
|
||||||
/* deallocated pointers should be set to null */
|
|
||||||
/* however, valgrind on linux reports when attempting to access a freed memory, we have to skip it */
|
|
||||||
#ifndef ENABLE_VALGRIND
|
|
||||||
cJSON *string = cJSON_CreateString("item");
|
|
||||||
cJSON *root = cJSON_CreateObject();
|
|
||||||
|
|
||||||
cJSON_Delete(string);
|
|
||||||
free(string->valuestring);
|
|
||||||
|
|
||||||
cJSON_AddObjectToObject(root, "object");
|
|
||||||
cJSON_Delete(root->child);
|
|
||||||
free(root->child->string);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int CJSON_CDECL main(void)
|
int CJSON_CDECL main(void)
|
||||||
{
|
{
|
||||||
UNITY_BEGIN();
|
UNITY_BEGIN();
|
||||||
@@ -761,11 +794,14 @@ int CJSON_CDECL main(void)
|
|||||||
RUN_TEST(cjson_get_object_item_case_sensitive_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_should_not_follow_too_deep_circular_references);
|
||||||
RUN_TEST(cjson_set_number_value_should_set_numbers);
|
RUN_TEST(cjson_set_number_value_should_set_numbers);
|
||||||
RUN_TEST(cjson_detach_item_via_pointer_should_detach_items);
|
RUN_TEST(cjson_detach_item_via_pointer_should_detach_items);
|
||||||
|
RUN_TEST(cjson_detach_item_via_pointer_should_return_null_if_item_prev_is_null);
|
||||||
RUN_TEST(cjson_replace_item_via_pointer_should_replace_items);
|
RUN_TEST(cjson_replace_item_via_pointer_should_replace_items);
|
||||||
RUN_TEST(cjson_replace_item_in_object_should_preserve_name);
|
RUN_TEST(cjson_replace_item_in_object_should_preserve_name);
|
||||||
RUN_TEST(cjson_functions_should_not_crash_with_null_pointers);
|
RUN_TEST(cjson_functions_should_not_crash_with_null_pointers);
|
||||||
|
RUN_TEST(cjson_set_valuestring_should_return_null_if_strings_overlap);
|
||||||
RUN_TEST(ensure_should_fail_on_failed_realloc);
|
RUN_TEST(ensure_should_fail_on_failed_realloc);
|
||||||
RUN_TEST(skip_utf8_bom_should_skip_bom);
|
RUN_TEST(skip_utf8_bom_should_skip_bom);
|
||||||
RUN_TEST(skip_utf8_bom_should_not_skip_bom_if_not_at_beginning);
|
RUN_TEST(skip_utf8_bom_should_not_skip_bom_if_not_at_beginning);
|
||||||
@@ -779,7 +815,6 @@ int CJSON_CDECL main(void)
|
|||||||
RUN_TEST(cjson_delete_item_from_array_should_not_broken_list_structure);
|
RUN_TEST(cjson_delete_item_from_array_should_not_broken_list_structure);
|
||||||
RUN_TEST(cjson_set_valuestring_to_object_should_not_leak_memory);
|
RUN_TEST(cjson_set_valuestring_to_object_should_not_leak_memory);
|
||||||
RUN_TEST(cjson_set_bool_value_must_not_break_objects);
|
RUN_TEST(cjson_set_bool_value_must_not_break_objects);
|
||||||
RUN_TEST(deallocated_pointers_should_be_set_to_null);
|
|
||||||
|
|
||||||
return UNITY_END();
|
return UNITY_END();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ static void assert_print_object(const char * const expected, const char * const
|
|||||||
|
|
||||||
formatted_buffer.format = true;
|
formatted_buffer.format = true;
|
||||||
TEST_ASSERT_TRUE_MESSAGE(print_object(item, &formatted_buffer), "Failed to print formatted string.");
|
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.");
|
TEST_ASSERT_EQUAL_STRING_MESSAGE(expected, printed_formatted, "Formatted object is not correct.");
|
||||||
|
|
||||||
reset(item);
|
reset(item);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ class ParseOutput
|
|||||||
@array_list.push ' <testcase classname="' + test_suite + '" name="' + test_name + '"/>'
|
@array_list.push ' <testcase classname="' + test_suite + '" name="' + test_name + '"/>'
|
||||||
end
|
end
|
||||||
|
|
||||||
# Test was flagged as being ingored so format the output
|
# Test was flagged as being ignored so format the output
|
||||||
def test_ignored(array)
|
def test_ignored(array)
|
||||||
last_item = array.length - 1
|
last_item = array.length - 1
|
||||||
test_name = array[last_item - 2]
|
test_name = array[last_item - 2]
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ header files. These three files _are_ Unity.
|
|||||||
into this folder already. This is where all the handy documentation can be
|
into this folder already. This is where all the handy documentation can be
|
||||||
found.
|
found.
|
||||||
- `examples` - This contains a few examples of using Unity.
|
- `examples` - This contains a few examples of using Unity.
|
||||||
- `extras` - These are optional add ons to Unity that are not part of the core
|
- `extras` - These are optional addons to Unity that are not part of the core
|
||||||
project. If you've reached us through James Grenning's book, you're going to
|
project. If you've reached us through James Grenning's book, you're going to
|
||||||
want to look here.
|
want to look here.
|
||||||
- `test` - This is how Unity and its scripts are all tested. If you're just using
|
- `test` - This is how Unity and its scripts are all tested. If you're just using
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ Eclipse error parsers
|
|||||||
=====================
|
=====================
|
||||||
|
|
||||||
These are a godsend for extracting & quickly navigating to
|
These are a godsend for extracting & quickly navigating to
|
||||||
warnings & error messages from console output. Unforunately
|
warnings & error messages from console output. Unfortunately
|
||||||
I don't know how to write an Eclipse plugin so you'll have
|
I don't know how to write an Eclipse plugin so you'll have
|
||||||
to add them manually.
|
to add them manually.
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
#include "unity.h"
|
#include "unity.h"
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
/* If omitted from header, declare overrideable prototypes here so they're ready for use */
|
/* If omitted from header, declare overridable prototypes here so they're ready for use */
|
||||||
#ifdef UNITY_OMIT_OUTPUT_CHAR_HEADER_DECLARATION
|
#ifdef UNITY_OMIT_OUTPUT_CHAR_HEADER_DECLARATION
|
||||||
void UNITY_OUTPUT_CHAR(int);
|
void UNITY_OUTPUT_CHAR(int);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ task :prepare_for_tests => TEMP_DIRS
|
|||||||
|
|
||||||
include RakefileHelpers
|
include RakefileHelpers
|
||||||
|
|
||||||
# Load proper GCC as defult configuration
|
# Load proper GCC as default configuration
|
||||||
DEFAULT_CONFIG_FILE = 'gcc_auto_stdint.yml'
|
DEFAULT_CONFIG_FILE = 'gcc_auto_stdint.yml'
|
||||||
configure_toolchain(DEFAULT_CONFIG_FILE)
|
configure_toolchain(DEFAULT_CONFIG_FILE)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user