• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2   Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
3 
4   Permission is hereby granted, free of charge, to any person obtaining a copy
5   of this software and associated documentation files (the "Software"), to deal
6   in the Software without restriction, including without limitation the rights
7   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8   copies of the Software, and to permit persons to whom the Software is
9   furnished to do so, subject to the following conditions:
10 
11   The above copyright notice and this permission notice shall be included in
12   all copies or substantial portions of the Software.
13 
14   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20   THE SOFTWARE.
21 */
22 
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 
27 #include "unity/examples/unity_config.h"
28 #include "unity/src/unity.h"
29 #include "common.h"
30 
cjson_array_foreach_should_loop_over_arrays(void)31 static void cjson_array_foreach_should_loop_over_arrays(void)
32 {
33     cJSON array[1];
34     cJSON elements[10];
35     cJSON *element_pointer = NULL;
36     size_t i = 0;
37 
38     memset(array, 0, sizeof(array));
39     memset(elements, 0, sizeof(elements));
40 
41     /* create array */
42     array[0].child = &elements[0];
43     elements[0].prev = NULL;
44     elements[9].next = NULL;
45     for (i = 0; i < 9; i++)
46     {
47         elements[i].next = &elements[i + 1];
48         elements[i + 1].prev = &elements[i];
49     }
50 
51     i = 0;
52     cJSON_ArrayForEach(element_pointer, array)
53     {
54         TEST_ASSERT_TRUE_MESSAGE(element_pointer == &elements[i], "Not iterating over array properly");
55         i++;
56     }
57 }
58 
cjson_array_foreach_should_not_dereference_null_pointer(void)59 static void cjson_array_foreach_should_not_dereference_null_pointer(void)
60 {
61     cJSON *array = NULL;
62     cJSON *element = NULL;
63     cJSON_ArrayForEach(element, array);
64 }
65 
cjson_get_object_item_should_get_object_items(void)66 static void cjson_get_object_item_should_get_object_items(void)
67 {
68     cJSON *item = NULL;
69     cJSON *found = NULL;
70 
71     item = cJSON_Parse("{\"one\":1, \"Two\":2, \"tHree\":3}");
72 
73     found = cJSON_GetObjectItem(NULL, "test");
74     TEST_ASSERT_NULL_MESSAGE(found, "Failed to fail on NULL pointer.");
75 
76     found = cJSON_GetObjectItem(item, NULL);
77     TEST_ASSERT_NULL_MESSAGE(found, "Failed to fail on NULL string.");
78 
79     found = cJSON_GetObjectItem(item, "one");
80     TEST_ASSERT_NOT_NULL_MESSAGE(found, "Failed to find first item.");
81     TEST_ASSERT_EQUAL_DOUBLE(found->valuedouble, 1);
82 
83     found = cJSON_GetObjectItem(item, "tWo");
84     TEST_ASSERT_NOT_NULL_MESSAGE(found, "Failed to find first item.");
85     TEST_ASSERT_EQUAL_DOUBLE(found->valuedouble, 2);
86 
87     found = cJSON_GetObjectItem(item, "three");
88     TEST_ASSERT_NOT_NULL_MESSAGE(found, "Failed to find item.");
89     TEST_ASSERT_EQUAL_DOUBLE(found->valuedouble, 3);
90 
91     found = cJSON_GetObjectItem(item, "four");
92     TEST_ASSERT_NULL_MESSAGE(found, "Should not find something that isn't there.");
93 
94     cJSON_Delete(item);
95 }
96 
cjson_get_object_item_case_sensitive_should_get_object_items(void)97 static void cjson_get_object_item_case_sensitive_should_get_object_items(void)
98 {
99     cJSON *item = NULL;
100     cJSON *found = NULL;
101 
102     item = cJSON_Parse("{\"one\":1, \"Two\":2, \"tHree\":3}");
103 
104     found = cJSON_GetObjectItemCaseSensitive(NULL, "test");
105     TEST_ASSERT_NULL_MESSAGE(found, "Failed to fail on NULL pointer.");
106 
107     found = cJSON_GetObjectItemCaseSensitive(item, NULL);
108     TEST_ASSERT_NULL_MESSAGE(found, "Failed to fail on NULL string.");
109 
110     found = cJSON_GetObjectItemCaseSensitive(item, "one");
111     TEST_ASSERT_NOT_NULL_MESSAGE(found, "Failed to find first item.");
112     TEST_ASSERT_EQUAL_DOUBLE(found->valuedouble, 1);
113 
114     found = cJSON_GetObjectItemCaseSensitive(item, "Two");
115     TEST_ASSERT_NOT_NULL_MESSAGE(found, "Failed to find first item.");
116     TEST_ASSERT_EQUAL_DOUBLE(found->valuedouble, 2);
117 
118     found = cJSON_GetObjectItemCaseSensitive(item, "tHree");
119     TEST_ASSERT_NOT_NULL_MESSAGE(found, "Failed to find item.");
120     TEST_ASSERT_EQUAL_DOUBLE(found->valuedouble, 3);
121 
122     found = cJSON_GetObjectItemCaseSensitive(item, "One");
123     TEST_ASSERT_NULL_MESSAGE(found, "Should not find something that isn't there.");
124 
125     cJSON_Delete(item);
126 }
127 
cjson_get_object_item_should_not_crash_with_array(void)128 static void cjson_get_object_item_should_not_crash_with_array(void)
129 {
130     cJSON *array = NULL;
131     cJSON *found = NULL;
132     array = cJSON_Parse("[1]");
133 
134     found = cJSON_GetObjectItem(array, "name");
135     TEST_ASSERT_NULL(found);
136 
137     cJSON_Delete(array);
138 }
139 
cjson_get_object_item_case_sensitive_should_not_crash_with_array(void)140 static void cjson_get_object_item_case_sensitive_should_not_crash_with_array(void)
141 {
142     cJSON *array = NULL;
143     cJSON *found = NULL;
144     array = cJSON_Parse("[1]");
145 
146     found = cJSON_GetObjectItemCaseSensitive(array, "name");
147     TEST_ASSERT_NULL(found);
148 
149     cJSON_Delete(array);
150 }
151 
typecheck_functions_should_check_type(void)152 static void typecheck_functions_should_check_type(void)
153 {
154     cJSON invalid[1];
155     cJSON item[1];
156     invalid->type = cJSON_Invalid;
157     invalid->type |= cJSON_StringIsConst;
158     item->type = cJSON_False;
159     item->type |= cJSON_StringIsConst;
160 
161     TEST_ASSERT_FALSE(cJSON_IsInvalid(NULL));
162     TEST_ASSERT_FALSE(cJSON_IsInvalid(item));
163     TEST_ASSERT_TRUE(cJSON_IsInvalid(invalid));
164 
165     item->type = cJSON_False | cJSON_StringIsConst;
166     TEST_ASSERT_FALSE(cJSON_IsFalse(NULL));
167     TEST_ASSERT_FALSE(cJSON_IsFalse(invalid));
168     TEST_ASSERT_TRUE(cJSON_IsFalse(item));
169     TEST_ASSERT_TRUE(cJSON_IsBool(item));
170 
171     item->type = cJSON_True | cJSON_StringIsConst;
172     TEST_ASSERT_FALSE(cJSON_IsTrue(NULL));
173     TEST_ASSERT_FALSE(cJSON_IsTrue(invalid));
174     TEST_ASSERT_TRUE(cJSON_IsTrue(item));
175     TEST_ASSERT_TRUE(cJSON_IsBool(item));
176 
177     item->type = cJSON_NULL | cJSON_StringIsConst;
178     TEST_ASSERT_FALSE(cJSON_IsNull(NULL));
179     TEST_ASSERT_FALSE(cJSON_IsNull(invalid));
180     TEST_ASSERT_TRUE(cJSON_IsNull(item));
181 
182     item->type = cJSON_Number | cJSON_StringIsConst;
183     TEST_ASSERT_FALSE(cJSON_IsNumber(NULL));
184     TEST_ASSERT_FALSE(cJSON_IsNumber(invalid));
185     TEST_ASSERT_TRUE(cJSON_IsNumber(item));
186 
187     item->type = cJSON_String | cJSON_StringIsConst;
188     TEST_ASSERT_FALSE(cJSON_IsString(NULL));
189     TEST_ASSERT_FALSE(cJSON_IsString(invalid));
190     TEST_ASSERT_TRUE(cJSON_IsString(item));
191 
192     item->type = cJSON_Array | cJSON_StringIsConst;
193     TEST_ASSERT_FALSE(cJSON_IsArray(NULL));
194     TEST_ASSERT_FALSE(cJSON_IsArray(invalid));
195     TEST_ASSERT_TRUE(cJSON_IsArray(item));
196 
197     item->type = cJSON_Object | cJSON_StringIsConst;
198     TEST_ASSERT_FALSE(cJSON_IsObject(NULL));
199     TEST_ASSERT_FALSE(cJSON_IsObject(invalid));
200     TEST_ASSERT_TRUE(cJSON_IsObject(item));
201 
202     item->type = cJSON_Raw | cJSON_StringIsConst;
203     TEST_ASSERT_FALSE(cJSON_IsRaw(NULL));
204     TEST_ASSERT_FALSE(cJSON_IsRaw(invalid));
205     TEST_ASSERT_TRUE(cJSON_IsRaw(item));
206 }
207 
cjson_should_not_parse_to_deeply_nested_jsons(void)208 static void cjson_should_not_parse_to_deeply_nested_jsons(void)
209 {
210     char deep_json[CJSON_NESTING_LIMIT + 1];
211     size_t position = 0;
212 
213     for (position = 0; position < sizeof(deep_json); position++)
214     {
215         deep_json[position] = '[';
216     }
217     deep_json[sizeof(deep_json) - 1] = '\0';
218 
219     TEST_ASSERT_NULL_MESSAGE(cJSON_Parse(deep_json), "To deep JSONs should not be parsed.");
220 }
221 
cjson_should_not_follow_too_deep_circular_references(void)222 static void cjson_should_not_follow_too_deep_circular_references(void)
223 {
224     cJSON *o = cJSON_CreateArray();
225     cJSON *a = cJSON_CreateArray();
226     cJSON *b = cJSON_CreateArray();
227     cJSON *x;
228 
229     cJSON_AddItemToArray(o, a);
230     cJSON_AddItemToArray(a, b);
231     cJSON_AddItemToArray(b, o);
232 
233     x = cJSON_Duplicate(o, 1);
234     TEST_ASSERT_NULL(x);
235     cJSON_DetachItemFromArray(b, 0);
236     cJSON_Delete(o);
237 }
238 
cjson_set_number_value_should_set_numbers(void)239 static void cjson_set_number_value_should_set_numbers(void)
240 {
241     cJSON number[1] = {{NULL, NULL, NULL, cJSON_Number, NULL, 0, 0, NULL}};
242 
243     cJSON_SetNumberValue(number, 1.5);
244     TEST_ASSERT_EQUAL(1, number->valueint);
245     TEST_ASSERT_EQUAL_DOUBLE(1.5, number->valuedouble);
246 
247     cJSON_SetNumberValue(number, -1.5);
248     TEST_ASSERT_EQUAL(-1, number->valueint);
249     TEST_ASSERT_EQUAL_DOUBLE(-1.5, number->valuedouble);
250 
251     cJSON_SetNumberValue(number, 1 + (double)INT_MAX);
252     TEST_ASSERT_EQUAL(INT_MAX, number->valueint);
253     TEST_ASSERT_EQUAL_DOUBLE(1 + (double)INT_MAX, number->valuedouble);
254 
255     cJSON_SetNumberValue(number, -1 + (double)INT_MIN);
256     TEST_ASSERT_EQUAL(INT_MIN, number->valueint);
257     TEST_ASSERT_EQUAL_DOUBLE(-1 + (double)INT_MIN, number->valuedouble);
258 }
259 
cjson_detach_item_via_pointer_should_detach_items(void)260 static void cjson_detach_item_via_pointer_should_detach_items(void)
261 {
262     cJSON list[4];
263     cJSON parent[1];
264 
265     memset(list, '\0', sizeof(list));
266 
267     /* link the list */
268     list[0].next = &(list[1]);
269     list[1].next = &(list[2]);
270     list[2].next = &(list[3]);
271 
272     list[3].prev = &(list[2]);
273     list[2].prev = &(list[1]);
274     list[1].prev = &(list[0]);
275     list[0].prev = &(list[3]);
276 
277     parent->child = &list[0];
278 
279     /* detach in the middle (list[1]) */
280     TEST_ASSERT_TRUE_MESSAGE(cJSON_DetachItemViaPointer(parent, &(list[1])) == &(list[1]), "Failed to detach in the middle.");
281     TEST_ASSERT_TRUE_MESSAGE((list[1].prev == NULL) && (list[1].next == NULL), "Didn't set pointers of detached item to NULL.");
282     TEST_ASSERT_TRUE((list[0].next == &(list[2])) && (list[2].prev == &(list[0])));
283 
284     /* detach beginning (list[0]) */
285     TEST_ASSERT_TRUE_MESSAGE(cJSON_DetachItemViaPointer(parent, &(list[0])) == &(list[0]), "Failed to detach beginning.");
286     TEST_ASSERT_TRUE_MESSAGE((list[0].prev == NULL) && (list[0].next == NULL), "Didn't set pointers of detached item to NULL.");
287     TEST_ASSERT_TRUE_MESSAGE((list[2].prev == &(list[3])) && (parent->child == &(list[2])), "Didn't set the new beginning.");
288 
289     /* detach end (list[3])*/
290     TEST_ASSERT_TRUE_MESSAGE(cJSON_DetachItemViaPointer(parent, &(list[3])) == &(list[3]), "Failed to detach end.");
291     TEST_ASSERT_TRUE_MESSAGE((list[3].prev == NULL) && (list[3].next == NULL), "Didn't set pointers of detached item to NULL.");
292     TEST_ASSERT_TRUE_MESSAGE((list[2].next == NULL) && (parent->child == &(list[2])), "Didn't set the new end");
293 
294     /* detach single item (list[2]) */
295     TEST_ASSERT_TRUE_MESSAGE(cJSON_DetachItemViaPointer(parent, &list[2]) == &list[2], "Failed to detach single item.");
296     TEST_ASSERT_TRUE_MESSAGE((list[2].prev == NULL) && (list[2].next == NULL), "Didn't set pointers of detached item to NULL.");
297     TEST_ASSERT_NULL_MESSAGE(parent->child, "Child of the parent wasn't set to NULL.");
298 }
299 
cjson_replace_item_via_pointer_should_replace_items(void)300 static void cjson_replace_item_via_pointer_should_replace_items(void)
301 {
302     cJSON replacements[3];
303     cJSON *beginning = NULL;
304     cJSON *middle = NULL;
305     cJSON *end = NULL;
306     cJSON *array = NULL;
307 
308     beginning = cJSON_CreateNull();
309     TEST_ASSERT_NOT_NULL(beginning);
310     middle = cJSON_CreateNull();
311     TEST_ASSERT_NOT_NULL(middle);
312     end = cJSON_CreateNull();
313     TEST_ASSERT_NOT_NULL(end);
314 
315     array = cJSON_CreateArray();
316     TEST_ASSERT_NOT_NULL(array);
317 
318     cJSON_AddItemToArray(array, beginning);
319     cJSON_AddItemToArray(array, middle);
320     cJSON_AddItemToArray(array, end);
321 
322     memset(replacements, '\0', sizeof(replacements));
323 
324     /* replace beginning */
325     TEST_ASSERT_TRUE(cJSON_ReplaceItemViaPointer(array, beginning, &(replacements[0])));
326     TEST_ASSERT_TRUE(replacements[0].prev == end);
327     TEST_ASSERT_TRUE(replacements[0].next == middle);
328     TEST_ASSERT_TRUE(middle->prev == &(replacements[0]));
329     TEST_ASSERT_TRUE(array->child == &(replacements[0]));
330 
331     /* replace middle */
332     TEST_ASSERT_TRUE(cJSON_ReplaceItemViaPointer(array, middle, &(replacements[1])));
333     TEST_ASSERT_TRUE(replacements[1].prev == &(replacements[0]));
334     TEST_ASSERT_TRUE(replacements[1].next == end);
335     TEST_ASSERT_TRUE(end->prev == &(replacements[1]));
336 
337     /* replace end */
338     TEST_ASSERT_TRUE(cJSON_ReplaceItemViaPointer(array, end, &(replacements[2])));
339     TEST_ASSERT_TRUE(replacements[2].prev == &(replacements[1]));
340     TEST_ASSERT_NULL(replacements[2].next);
341     TEST_ASSERT_TRUE(replacements[1].next == &(replacements[2]));
342 
343     cJSON_free(array);
344 }
345 
cjson_replace_item_in_object_should_preserve_name(void)346 static void cjson_replace_item_in_object_should_preserve_name(void)
347 {
348     cJSON root[1] = {{NULL, NULL, NULL, 0, NULL, 0, 0, NULL}};
349     cJSON *child = NULL;
350     cJSON *replacement = NULL;
351     cJSON_bool flag = false;
352 
353     child = cJSON_CreateNumber(1);
354     TEST_ASSERT_NOT_NULL(child);
355     replacement = cJSON_CreateNumber(2);
356     TEST_ASSERT_NOT_NULL(replacement);
357 
358     flag = cJSON_AddItemToObject(root, "child", child);
359     TEST_ASSERT_TRUE_MESSAGE(flag, "add item to object failed");
360     cJSON_ReplaceItemInObject(root, "child", replacement);
361 
362     TEST_ASSERT_TRUE(root->child == replacement);
363     TEST_ASSERT_EQUAL_STRING("child", replacement->string);
364 
365     cJSON_Delete(replacement);
366 }
367 
cjson_functions_should_not_crash_with_null_pointers(void)368 static void cjson_functions_should_not_crash_with_null_pointers(void)
369 {
370     char buffer[10];
371     cJSON *item = cJSON_CreateString("item");
372     cJSON *array = cJSON_CreateArray();
373     cJSON *item1 = cJSON_CreateString("item1");
374     cJSON *item2 = cJSON_CreateString("corrupted array item3");
375     cJSON *corruptedString = cJSON_CreateString("corrupted");
376     struct cJSON *originalPrev;
377 
378     add_item_to_array(array, item1);
379     add_item_to_array(array, item2);
380 
381     originalPrev = item2->prev;
382     item2->prev = NULL;
383     free(corruptedString->valuestring);
384     corruptedString->valuestring = NULL;
385 
386     cJSON_InitHooks(NULL);
387     TEST_ASSERT_NULL(cJSON_Parse(NULL));
388     TEST_ASSERT_NULL(cJSON_ParseWithOpts(NULL, NULL, true));
389     TEST_ASSERT_NULL(cJSON_Print(NULL));
390     TEST_ASSERT_NULL(cJSON_PrintUnformatted(NULL));
391     TEST_ASSERT_NULL(cJSON_PrintBuffered(NULL, 10, true));
392     TEST_ASSERT_FALSE(cJSON_PrintPreallocated(NULL, buffer, sizeof(buffer), true));
393     TEST_ASSERT_FALSE(cJSON_PrintPreallocated(item, NULL, 1, true));
394     cJSON_Delete(NULL);
395     cJSON_GetArraySize(NULL);
396     TEST_ASSERT_NULL(cJSON_GetArrayItem(NULL, 0));
397     TEST_ASSERT_NULL(cJSON_GetObjectItem(NULL, "item"));
398     TEST_ASSERT_NULL(cJSON_GetObjectItem(item, NULL));
399     TEST_ASSERT_NULL(cJSON_GetObjectItemCaseSensitive(NULL, "item"));
400     TEST_ASSERT_NULL(cJSON_GetObjectItemCaseSensitive(item, NULL));
401     TEST_ASSERT_FALSE(cJSON_HasObjectItem(NULL, "item"));
402     TEST_ASSERT_FALSE(cJSON_HasObjectItem(item, NULL));
403     TEST_ASSERT_FALSE(cJSON_IsInvalid(NULL));
404     TEST_ASSERT_FALSE(cJSON_IsFalse(NULL));
405     TEST_ASSERT_FALSE(cJSON_IsTrue(NULL));
406     TEST_ASSERT_FALSE(cJSON_IsBool(NULL));
407     TEST_ASSERT_FALSE(cJSON_IsNull(NULL));
408     TEST_ASSERT_FALSE(cJSON_IsNumber(NULL));
409     TEST_ASSERT_FALSE(cJSON_IsString(NULL));
410     TEST_ASSERT_FALSE(cJSON_IsArray(NULL));
411     TEST_ASSERT_FALSE(cJSON_IsObject(NULL));
412     TEST_ASSERT_FALSE(cJSON_IsRaw(NULL));
413     TEST_ASSERT_NULL(cJSON_CreateString(NULL));
414     TEST_ASSERT_NULL(cJSON_CreateRaw(NULL));
415     TEST_ASSERT_NULL(cJSON_CreateIntArray(NULL, 10));
416     TEST_ASSERT_NULL(cJSON_CreateFloatArray(NULL, 10));
417     TEST_ASSERT_NULL(cJSON_CreateDoubleArray(NULL, 10));
418     TEST_ASSERT_NULL(cJSON_CreateStringArray(NULL, 10));
419     cJSON_AddItemToArray(NULL, item);
420     cJSON_AddItemToArray(item, NULL);
421     cJSON_AddItemToObject(item, "item", NULL);
422     cJSON_AddItemToObject(item, NULL, item);
423     cJSON_AddItemToObject(NULL, "item", item);
424     cJSON_AddItemToObjectCS(item, "item", NULL);
425     cJSON_AddItemToObjectCS(item, NULL, item);
426     cJSON_AddItemToObjectCS(NULL, "item", item);
427     cJSON_AddItemReferenceToArray(NULL, item);
428     cJSON_AddItemReferenceToArray(item, NULL);
429     cJSON_AddItemReferenceToObject(item, "item", NULL);
430     cJSON_AddItemReferenceToObject(item, NULL, item);
431     cJSON_AddItemReferenceToObject(NULL, "item", item);
432     TEST_ASSERT_NULL(cJSON_DetachItemViaPointer(NULL, item));
433     TEST_ASSERT_NULL(cJSON_DetachItemViaPointer(item, NULL));
434     TEST_ASSERT_NULL(cJSON_DetachItemFromArray(NULL, 0));
435     cJSON_DeleteItemFromArray(NULL, 0);
436     TEST_ASSERT_NULL(cJSON_DetachItemFromObject(NULL, "item"));
437     TEST_ASSERT_NULL(cJSON_DetachItemFromObject(item, NULL));
438     TEST_ASSERT_NULL(cJSON_DetachItemFromObjectCaseSensitive(NULL, "item"));
439     TEST_ASSERT_NULL(cJSON_DetachItemFromObjectCaseSensitive(item, NULL));
440     cJSON_DeleteItemFromObject(NULL, "item");
441     cJSON_DeleteItemFromObject(item, NULL);
442     cJSON_DeleteItemFromObjectCaseSensitive(NULL, "item");
443     cJSON_DeleteItemFromObjectCaseSensitive(item, NULL);
444     TEST_ASSERT_FALSE(cJSON_InsertItemInArray(array, 0, NULL));
445     TEST_ASSERT_FALSE(cJSON_InsertItemInArray(array, 1, item));
446     TEST_ASSERT_FALSE(cJSON_InsertItemInArray(NULL, 0, item));
447     TEST_ASSERT_FALSE(cJSON_InsertItemInArray(item, 0, NULL));
448     TEST_ASSERT_FALSE(cJSON_ReplaceItemViaPointer(NULL, item, item));
449     TEST_ASSERT_FALSE(cJSON_ReplaceItemViaPointer(item, NULL, item));
450     TEST_ASSERT_FALSE(cJSON_ReplaceItemViaPointer(item, item, NULL));
451     TEST_ASSERT_FALSE(cJSON_ReplaceItemInArray(item, 0, NULL));
452     TEST_ASSERT_FALSE(cJSON_ReplaceItemInArray(NULL, 0, item));
453     TEST_ASSERT_FALSE(cJSON_ReplaceItemInObject(NULL, "item", item));
454     TEST_ASSERT_FALSE(cJSON_ReplaceItemInObject(item, NULL, item));
455     TEST_ASSERT_FALSE(cJSON_ReplaceItemInObject(item, "item", NULL));
456     TEST_ASSERT_FALSE(cJSON_ReplaceItemInObjectCaseSensitive(NULL, "item", item));
457     TEST_ASSERT_FALSE(cJSON_ReplaceItemInObjectCaseSensitive(item, NULL, item));
458     TEST_ASSERT_FALSE(cJSON_ReplaceItemInObjectCaseSensitive(item, "item", NULL));
459     TEST_ASSERT_NULL(cJSON_Duplicate(NULL, true));
460     TEST_ASSERT_FALSE(cJSON_Compare(item, NULL, false));
461     TEST_ASSERT_FALSE(cJSON_Compare(NULL, item, false));
462     TEST_ASSERT_NULL(cJSON_SetValuestring(NULL, "test"));
463     TEST_ASSERT_NULL(cJSON_SetValuestring(corruptedString, "test"));
464     cJSON_Minify(NULL);
465     /* skipped because it is only used via a macro that checks for NULL */
466     /* cJSON_SetNumberHelper(NULL, 0); */
467 
468     /* restore corrupted item2 to delete it */
469     item2->prev = originalPrev;
470     cJSON_Delete(corruptedString);
471     cJSON_Delete(array);
472     cJSON_Delete(item);
473 }
474 
failing_realloc(void * pointer,size_t size)475 static void *CJSON_CDECL failing_realloc(void *pointer, size_t size)
476 {
477     (void)size;
478     (void)pointer;
479     return NULL;
480 }
481 
ensure_should_fail_on_failed_realloc(void)482 static void ensure_should_fail_on_failed_realloc(void)
483 {
484     printbuffer buffer = {NULL, 10, 0, 0, false, false, {&malloc, &free, &failing_realloc}};
485     buffer.buffer = (unsigned char *)malloc(100);
486     TEST_ASSERT_NOT_NULL(buffer.buffer);
487 
488     TEST_ASSERT_NULL_MESSAGE(ensure(&buffer, 200), "Ensure didn't fail with failing realloc.");
489 }
490 
skip_utf8_bom_should_skip_bom(void)491 static void skip_utf8_bom_should_skip_bom(void)
492 {
493     const unsigned char string[] = "\xEF\xBB\xBF{}";
494     parse_buffer buffer = {0, 0, 0, 0, {0, 0, 0}};
495     buffer.content = string;
496     buffer.length = sizeof(string);
497     buffer.hooks = global_hooks;
498 
499     TEST_ASSERT_TRUE(skip_utf8_bom(&buffer) == &buffer);
500     TEST_ASSERT_EQUAL_UINT(3U, (unsigned int)buffer.offset);
501 }
502 
skip_utf8_bom_should_not_skip_bom_if_not_at_beginning(void)503 static void skip_utf8_bom_should_not_skip_bom_if_not_at_beginning(void)
504 {
505     const unsigned char string[] = " \xEF\xBB\xBF{}";
506     parse_buffer buffer = {0, 0, 0, 0, {0, 0, 0}};
507     buffer.content = string;
508     buffer.length = sizeof(string);
509     buffer.hooks = global_hooks;
510     buffer.offset = 1;
511 
512     TEST_ASSERT_NULL(skip_utf8_bom(&buffer));
513 }
514 
cjson_get_string_value_should_get_a_string(void)515 static void cjson_get_string_value_should_get_a_string(void)
516 {
517     cJSON *string = cJSON_CreateString("test");
518     cJSON *number = cJSON_CreateNumber(1);
519 
520     TEST_ASSERT_TRUE(cJSON_GetStringValue(string) == string->valuestring);
521     TEST_ASSERT_NULL(cJSON_GetStringValue(number));
522     TEST_ASSERT_NULL(cJSON_GetStringValue(NULL));
523 
524     cJSON_Delete(number);
525     cJSON_Delete(string);
526 }
527 
cjson_get_number_value_should_get_a_number(void)528 static void cjson_get_number_value_should_get_a_number(void)
529 {
530     cJSON *string = cJSON_CreateString("test");
531     cJSON *number = cJSON_CreateNumber(1);
532 
533     TEST_ASSERT_EQUAL_DOUBLE(cJSON_GetNumberValue(number), number->valuedouble);
534     TEST_ASSERT_DOUBLE_IS_NAN(cJSON_GetNumberValue(string));
535     TEST_ASSERT_DOUBLE_IS_NAN(cJSON_GetNumberValue(NULL));
536 
537     cJSON_Delete(number);
538     cJSON_Delete(string);
539 }
540 
cjson_create_string_reference_should_create_a_string_reference(void)541 static void cjson_create_string_reference_should_create_a_string_reference(void)
542 {
543     const char *string = "I am a string!";
544 
545     cJSON *string_reference = cJSON_CreateStringReference(string);
546     TEST_ASSERT_TRUE(string_reference->valuestring == string);
547     TEST_ASSERT_EQUAL_INT(cJSON_IsReference | cJSON_String, string_reference->type);
548 
549     cJSON_Delete(string_reference);
550 }
551 
cjson_create_object_reference_should_create_an_object_reference(void)552 static void cjson_create_object_reference_should_create_an_object_reference(void)
553 {
554     cJSON *number_reference = NULL;
555     cJSON *number_object = cJSON_CreateObject();
556     cJSON *number = cJSON_CreateNumber(42);
557     const char key[] = "number";
558 
559     TEST_ASSERT_TRUE(cJSON_IsNumber(number));
560     TEST_ASSERT_TRUE(cJSON_IsObject(number_object));
561     cJSON_AddItemToObjectCS(number_object, key, number);
562 
563     number_reference = cJSON_CreateObjectReference(number);
564     TEST_ASSERT_TRUE(number_reference->child == number);
565     TEST_ASSERT_EQUAL_INT(cJSON_Object | cJSON_IsReference, number_reference->type);
566 
567     cJSON_Delete(number_object);
568     cJSON_Delete(number_reference);
569 }
570 
cjson_create_array_reference_should_create_an_array_reference(void)571 static void cjson_create_array_reference_should_create_an_array_reference(void)
572 {
573     cJSON *number_reference = NULL;
574     cJSON *number_array = cJSON_CreateArray();
575     cJSON *number = cJSON_CreateNumber(42);
576 
577     TEST_ASSERT_TRUE(cJSON_IsNumber(number));
578     TEST_ASSERT_TRUE(cJSON_IsArray(number_array));
579     cJSON_AddItemToArray(number_array, number);
580 
581     number_reference = cJSON_CreateArrayReference(number);
582     TEST_ASSERT_TRUE(number_reference->child == number);
583     TEST_ASSERT_EQUAL_INT(cJSON_Array | cJSON_IsReference, number_reference->type);
584 
585     cJSON_Delete(number_array);
586     cJSON_Delete(number_reference);
587 }
588 
cjson_add_item_to_object_or_array_should_not_add_itself(void)589 static void cjson_add_item_to_object_or_array_should_not_add_itself(void)
590 {
591     cJSON *object = cJSON_CreateObject();
592     cJSON *array = cJSON_CreateArray();
593     cJSON_bool flag = false;
594 
595     flag = cJSON_AddItemToObject(object, "key", object);
596     TEST_ASSERT_FALSE_MESSAGE(flag, "add an object to itself should fail");
597 
598     flag = cJSON_AddItemToArray(array, array);
599     TEST_ASSERT_FALSE_MESSAGE(flag, "add an array to itself should fail");
600 
601     cJSON_Delete(object);
602     cJSON_Delete(array);
603 }
604 
cjson_add_item_to_object_should_not_use_after_free_when_string_is_aliased(void)605 static void cjson_add_item_to_object_should_not_use_after_free_when_string_is_aliased(void)
606 {
607     cJSON *object = cJSON_CreateObject();
608     cJSON *number = cJSON_CreateNumber(42);
609     char *name = (char *)cJSON_strdup((const unsigned char *)"number", &global_hooks);
610 
611     TEST_ASSERT_NOT_NULL(object);
612     TEST_ASSERT_NOT_NULL(number);
613     TEST_ASSERT_NOT_NULL(name);
614 
615     number->string = name;
616 
617     /* The following should not have a use after free
618      * that would show up in valgrind or with AddressSanitizer */
619     cJSON_AddItemToObject(object, number->string, number);
620 
621     cJSON_Delete(object);
622 }
623 
cjson_delete_item_from_array_should_not_broken_list_structure(void)624 static void cjson_delete_item_from_array_should_not_broken_list_structure(void)
625 {
626     const char expected_json1[] = "{\"rd\":[{\"a\":\"123\"}]}";
627     const char expected_json2[] = "{\"rd\":[{\"a\":\"123\"},{\"b\":\"456\"}]}";
628     const char expected_json3[] = "{\"rd\":[{\"b\":\"456\"}]}";
629     char *str1 = NULL;
630     char *str2 = NULL;
631     char *str3 = NULL;
632 
633     cJSON *root = cJSON_Parse("{}");
634 
635     cJSON *array = cJSON_AddArrayToObject(root, "rd");
636     cJSON *item1 = cJSON_Parse("{\"a\":\"123\"}");
637     cJSON *item2 = cJSON_Parse("{\"b\":\"456\"}");
638 
639     cJSON_AddItemToArray(array, item1);
640     str1 = cJSON_PrintUnformatted(root);
641     TEST_ASSERT_EQUAL_STRING(expected_json1, str1);
642     free(str1);
643 
644     cJSON_AddItemToArray(array, item2);
645     str2 = cJSON_PrintUnformatted(root);
646     TEST_ASSERT_EQUAL_STRING(expected_json2, str2);
647     free(str2);
648 
649     /* this should not broken list structure */
650     cJSON_DeleteItemFromArray(array, 0);
651     str3 = cJSON_PrintUnformatted(root);
652     TEST_ASSERT_EQUAL_STRING(expected_json3, str3);
653     free(str3);
654 
655     cJSON_Delete(root);
656 }
657 
cjson_set_valuestring_to_object_should_not_leak_memory(void)658 static void cjson_set_valuestring_to_object_should_not_leak_memory(void)
659 {
660     cJSON *root = cJSON_Parse("{}");
661     const char *stringvalue = "valuestring could be changed safely";
662     const char *reference_valuestring = "reference item should be freed by yourself";
663     const char *short_valuestring = "shorter valuestring";
664     const char *long_valuestring = "new valuestring which much longer than previous should be changed safely";
665     cJSON *item1 = cJSON_CreateString(stringvalue);
666     cJSON *item2 = cJSON_CreateStringReference(reference_valuestring);
667     char *ptr1 = NULL;
668     char *return_value = NULL;
669 
670     cJSON_AddItemToObject(root, "one", item1);
671     cJSON_AddItemToObject(root, "two", item2);
672 
673     ptr1 = item1->valuestring;
674     return_value = cJSON_SetValuestring(cJSON_GetObjectItem(root, "one"), short_valuestring);
675     TEST_ASSERT_NOT_NULL(return_value);
676     TEST_ASSERT_EQUAL_PTR_MESSAGE(ptr1, return_value, "new valuestring shorter than old should not reallocate memory");
677     TEST_ASSERT_EQUAL_STRING(short_valuestring, cJSON_GetObjectItem(root, "one")->valuestring);
678 
679     /* we needn't to free the original valuestring manually */
680     ptr1 = item1->valuestring;
681     return_value = cJSON_SetValuestring(cJSON_GetObjectItem(root, "one"), long_valuestring);
682     TEST_ASSERT_NOT_NULL(return_value);
683     TEST_ASSERT_NOT_EQUAL_MESSAGE(ptr1, return_value, "new valuestring longer than old should reallocate memory")
684     TEST_ASSERT_EQUAL_STRING(long_valuestring, cJSON_GetObjectItem(root, "one")->valuestring);
685 
686     return_value = cJSON_SetValuestring(cJSON_GetObjectItem(root, "two"), long_valuestring);
687     TEST_ASSERT_NULL_MESSAGE(return_value, "valuestring of reference object should not be changed");
688     TEST_ASSERT_EQUAL_STRING(reference_valuestring, cJSON_GetObjectItem(root, "two")->valuestring);
689 
690     cJSON_Delete(root);
691 }
692 
cjson_set_bool_value_must_not_break_objects(void)693 static void cjson_set_bool_value_must_not_break_objects(void)
694 {
695     cJSON *bobj, *sobj, *oobj, *refobj = NULL;
696 
697     TEST_ASSERT_TRUE((cJSON_SetBoolValue(refobj, 1) == cJSON_Invalid));
698 
699     bobj = cJSON_CreateFalse();
700     TEST_ASSERT_TRUE(cJSON_IsFalse(bobj));
701     TEST_ASSERT_TRUE((cJSON_SetBoolValue(bobj, 1) == cJSON_True));
702     TEST_ASSERT_TRUE(cJSON_IsTrue(bobj));
703     cJSON_SetBoolValue(bobj, 1);
704     TEST_ASSERT_TRUE(cJSON_IsTrue(bobj));
705     TEST_ASSERT_TRUE((cJSON_SetBoolValue(bobj, 0) == cJSON_False));
706     TEST_ASSERT_TRUE(cJSON_IsFalse(bobj));
707     cJSON_SetBoolValue(bobj, 0);
708     TEST_ASSERT_TRUE(cJSON_IsFalse(bobj));
709 
710     sobj = cJSON_CreateString("test");
711     TEST_ASSERT_TRUE(cJSON_IsString(sobj));
712     cJSON_SetBoolValue(sobj, 1);
713     TEST_ASSERT_TRUE(cJSON_IsString(sobj));
714     cJSON_SetBoolValue(sobj, 0);
715     TEST_ASSERT_TRUE(cJSON_IsString(sobj));
716 
717     oobj = cJSON_CreateObject();
718     TEST_ASSERT_TRUE(cJSON_IsObject(oobj));
719     cJSON_SetBoolValue(oobj, 1);
720     TEST_ASSERT_TRUE(cJSON_IsObject(oobj));
721     cJSON_SetBoolValue(oobj, 0);
722     TEST_ASSERT_TRUE(cJSON_IsObject(oobj));
723 
724     refobj = cJSON_CreateStringReference("conststring");
725     TEST_ASSERT_TRUE(cJSON_IsString(refobj));
726     TEST_ASSERT_TRUE(refobj->type & cJSON_IsReference);
727     cJSON_SetBoolValue(refobj, 1);
728     TEST_ASSERT_TRUE(cJSON_IsString(refobj));
729     TEST_ASSERT_TRUE(refobj->type & cJSON_IsReference);
730     cJSON_SetBoolValue(refobj, 0);
731     TEST_ASSERT_TRUE(cJSON_IsString(refobj));
732     TEST_ASSERT_TRUE(refobj->type & cJSON_IsReference);
733     cJSON_Delete(refobj);
734 
735     refobj = cJSON_CreateObjectReference(oobj);
736     TEST_ASSERT_TRUE(cJSON_IsObject(refobj));
737     TEST_ASSERT_TRUE(refobj->type & cJSON_IsReference);
738     cJSON_SetBoolValue(refobj, 1);
739     TEST_ASSERT_TRUE(cJSON_IsObject(refobj));
740     TEST_ASSERT_TRUE(refobj->type & cJSON_IsReference);
741     cJSON_SetBoolValue(refobj, 0);
742     TEST_ASSERT_TRUE(cJSON_IsObject(refobj));
743     TEST_ASSERT_TRUE(refobj->type & cJSON_IsReference);
744     cJSON_Delete(refobj);
745 
746     cJSON_Delete(oobj);
747     cJSON_Delete(bobj);
748     cJSON_Delete(sobj);
749 }
750 
cjson_parse_big_numbers_should_not_report_error(void)751 static void cjson_parse_big_numbers_should_not_report_error(void)
752 {
753     cJSON *valid_big_number_json_object1 = cJSON_Parse("{\"a\": true, \"b\": [ null,9999999999999999999999999999999999999999999999912345678901234567]}");
754     cJSON *valid_big_number_json_object2 = cJSON_Parse("{\"a\": true, \"b\": [ null,999999999999999999999999999999999999999999999991234567890.1234567E3]}");
755     const char *invalid_big_number_json1 = "{\"a\": true, \"b\": [ null,99999999999999999999999999999999999999999999999.1234567890.1234567]}";
756     const char *invalid_big_number_json2 = "{\"a\": true, \"b\": [ null,99999999999999999999999999999999999999999999999E1234567890e1234567]}";
757 
758     TEST_ASSERT_NOT_NULL(valid_big_number_json_object1);
759     TEST_ASSERT_NOT_NULL(valid_big_number_json_object2);
760     TEST_ASSERT_NULL_MESSAGE(cJSON_Parse(invalid_big_number_json1), "Invalid big number JSONs should not be parsed.");
761     TEST_ASSERT_NULL_MESSAGE(cJSON_Parse(invalid_big_number_json2), "Invalid big number JSONs should not be parsed.");
762 
763     cJSON_Delete(valid_big_number_json_object1);
764     cJSON_Delete(valid_big_number_json_object2);
765 }
766 
main(void)767 int CJSON_CDECL main(void)
768 {
769     UNITY_BEGIN();
770 
771     RUN_TEST(cjson_array_foreach_should_loop_over_arrays);
772     RUN_TEST(cjson_array_foreach_should_not_dereference_null_pointer);
773     RUN_TEST(cjson_get_object_item_should_get_object_items);
774     RUN_TEST(cjson_get_object_item_case_sensitive_should_get_object_items);
775     RUN_TEST(cjson_get_object_item_should_not_crash_with_array);
776     RUN_TEST(cjson_get_object_item_case_sensitive_should_not_crash_with_array);
777     RUN_TEST(typecheck_functions_should_check_type);
778     RUN_TEST(cjson_should_not_parse_to_deeply_nested_jsons);
779     RUN_TEST(cjson_should_not_follow_too_deep_circular_references);
780     RUN_TEST(cjson_set_number_value_should_set_numbers);
781     RUN_TEST(cjson_detach_item_via_pointer_should_detach_items);
782     RUN_TEST(cjson_replace_item_via_pointer_should_replace_items);
783     RUN_TEST(cjson_replace_item_in_object_should_preserve_name);
784     RUN_TEST(cjson_functions_should_not_crash_with_null_pointers);
785     RUN_TEST(ensure_should_fail_on_failed_realloc);
786     RUN_TEST(skip_utf8_bom_should_skip_bom);
787     RUN_TEST(skip_utf8_bom_should_not_skip_bom_if_not_at_beginning);
788     RUN_TEST(cjson_get_string_value_should_get_a_string);
789     RUN_TEST(cjson_get_number_value_should_get_a_number);
790     RUN_TEST(cjson_create_string_reference_should_create_a_string_reference);
791     RUN_TEST(cjson_create_object_reference_should_create_an_object_reference);
792     RUN_TEST(cjson_create_array_reference_should_create_an_array_reference);
793     RUN_TEST(cjson_add_item_to_object_or_array_should_not_add_itself);
794     RUN_TEST(cjson_add_item_to_object_should_not_use_after_free_when_string_is_aliased);
795     RUN_TEST(cjson_delete_item_from_array_should_not_broken_list_structure);
796     RUN_TEST(cjson_set_valuestring_to_object_should_not_leak_memory);
797     RUN_TEST(cjson_set_bool_value_must_not_break_objects);
798     RUN_TEST(cjson_parse_big_numbers_should_not_report_error);
799 
800     return UNITY_END();
801 }
802