mirror of https://github.com/DaveGamble/cJSON
Compare commits
5 Commits
14993e0080
...
4ad0d9f5a0
Author | SHA1 | Date |
---|---|---|
Jakub Zwolakowski | 4ad0d9f5a0 | |
Alanscut | 87d8f0961a | |
Lee | f66cbab4bf | |
Lee | 60ff122ef5 | |
guillaumemillot | 11de03fbd2 |
|
@ -1,3 +1,10 @@
|
|||
1.7.17 (Dec 26, 2023)
|
||||
======
|
||||
Fixes:
|
||||
------
|
||||
* Fix null reference in cJSON_SetValuestring(CVE-2023-50472), see #809
|
||||
* Fix null reference in cJSON_InsertItemInArray(CVE-2023-50471), see #809 and #810
|
||||
|
||||
1.7.16 (Jul 5, 2023)
|
||||
======
|
||||
Features:
|
||||
|
|
|
@ -2,7 +2,7 @@ set(CMAKE_LEGACY_CYGWIN_WIN32 0)
|
|||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
project(cJSON
|
||||
VERSION 1.7.16
|
||||
VERSION 1.7.17
|
||||
LANGUAGES C)
|
||||
|
||||
cmake_policy(SET CMP0054 NEW) # set CMP0054 policy
|
||||
|
|
2
Makefile
2
Makefile
|
@ -8,7 +8,7 @@ CJSON_TEST_SRC = cJSON.c test.c
|
|||
|
||||
LDLIBS = -lm
|
||||
|
||||
LIBVERSION = 1.7.16
|
||||
LIBVERSION = 1.7.17
|
||||
CJSON_SOVERSION = 1
|
||||
UTILS_SOVERSION = 1
|
||||
|
||||
|
|
|
@ -555,6 +555,9 @@ cJSON is written in ANSI C (or C89, C90). If your compiler or C library doesn't
|
|||
|
||||
NOTE: ANSI C is not C++ therefore it shouldn't be compiled with a C++ compiler. You can compile it with a C compiler and link it with your C++ code however. Although compiling with a C++ compiler might work, correct behavior is not guaranteed.
|
||||
|
||||
Absence of Undefined Behaviors on the test suite guaranteed by [TrustInSoft CI](https://ci.trust-in-soft.com/projects/DaveGamble/cJSON/latest):
|
||||
[![TrustInSoft CI](https://ci.trust-in-soft.com/projects/DaveGamble/cJSON.svg)](https://ci.trust-in-soft.com/projects/DaveGamble/cJSON)
|
||||
|
||||
#### Floating Point Numbers
|
||||
|
||||
cJSON does not officially support any `double` implementations other than IEEE754 double precision floating point numbers. It might still work with other implementations but bugs with these will be considered invalid.
|
||||
|
|
16
cJSON.c
16
cJSON.c
|
@ -117,7 +117,7 @@ CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item)
|
|||
}
|
||||
|
||||
/* 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 != 16)
|
||||
#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 17)
|
||||
#error cJSON.h and cJSON.c have different versions. Make sure that both have the same.
|
||||
#endif
|
||||
|
||||
|
@ -401,7 +401,12 @@ CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring)
|
|||
{
|
||||
char *copy = NULL;
|
||||
/* if object's type is not cJSON_String or is cJSON_IsReference, it should not set valuestring */
|
||||
if (!(object->type & cJSON_String) || (object->type & cJSON_IsReference))
|
||||
if ((object == NULL) || !(object->type & cJSON_String) || (object->type & cJSON_IsReference))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
/* return NULL if the object is corrupted */
|
||||
if (object->valuestring == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
@ -2264,7 +2269,7 @@ CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON
|
|||
{
|
||||
cJSON *after_inserted = NULL;
|
||||
|
||||
if (which < 0)
|
||||
if (which < 0 || newitem == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -2275,6 +2280,11 @@ CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON
|
|||
return add_item_to_array(array, newitem);
|
||||
}
|
||||
|
||||
if (after_inserted != array->child && after_inserted->prev == NULL) {
|
||||
/* return false if after_inserted is a corrupted array item */
|
||||
return false;
|
||||
}
|
||||
|
||||
newitem->next = after_inserted;
|
||||
newitem->prev = after_inserted->prev;
|
||||
after_inserted->prev = newitem;
|
||||
|
|
2
cJSON.h
2
cJSON.h
|
@ -81,7 +81,7 @@ then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJ
|
|||
/* project version */
|
||||
#define CJSON_VERSION_MAJOR 1
|
||||
#define CJSON_VERSION_MINOR 7
|
||||
#define CJSON_VERSION_PATCH 16
|
||||
#define CJSON_VERSION_PATCH 17
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
|
|
|
@ -352,6 +352,19 @@ static void cjson_functions_should_not_crash_with_null_pointers(void)
|
|||
{
|
||||
char buffer[10];
|
||||
cJSON *item = cJSON_CreateString("item");
|
||||
cJSON *array = cJSON_CreateArray();
|
||||
cJSON *item1 = cJSON_CreateString("item1");
|
||||
cJSON *item2 = cJSON_CreateString("corrupted array item3");
|
||||
cJSON *corruptedString = cJSON_CreateString("corrupted");
|
||||
struct cJSON *originalPrev;
|
||||
|
||||
add_item_to_array(array, item1);
|
||||
add_item_to_array(array, item2);
|
||||
|
||||
originalPrev = item2->prev;
|
||||
item2->prev = NULL;
|
||||
free(corruptedString->valuestring);
|
||||
corruptedString->valuestring = NULL;
|
||||
|
||||
cJSON_InitHooks(NULL);
|
||||
TEST_ASSERT_NULL(cJSON_Parse(NULL));
|
||||
|
@ -411,6 +424,8 @@ static void cjson_functions_should_not_crash_with_null_pointers(void)
|
|||
cJSON_DeleteItemFromObject(item, NULL);
|
||||
cJSON_DeleteItemFromObjectCaseSensitive(NULL, "item");
|
||||
cJSON_DeleteItemFromObjectCaseSensitive(item, NULL);
|
||||
TEST_ASSERT_FALSE(cJSON_InsertItemInArray(array, 0, NULL));
|
||||
TEST_ASSERT_FALSE(cJSON_InsertItemInArray(array, 1, item));
|
||||
TEST_ASSERT_FALSE(cJSON_InsertItemInArray(NULL, 0, item));
|
||||
TEST_ASSERT_FALSE(cJSON_InsertItemInArray(item, 0, NULL));
|
||||
TEST_ASSERT_FALSE(cJSON_ReplaceItemViaPointer(NULL, item, item));
|
||||
|
@ -427,10 +442,16 @@ static void cjson_functions_should_not_crash_with_null_pointers(void)
|
|||
TEST_ASSERT_NULL(cJSON_Duplicate(NULL, true));
|
||||
TEST_ASSERT_FALSE(cJSON_Compare(item, NULL, false));
|
||||
TEST_ASSERT_FALSE(cJSON_Compare(NULL, item, false));
|
||||
TEST_ASSERT_NULL(cJSON_SetValuestring(NULL, "test"));
|
||||
TEST_ASSERT_NULL(cJSON_SetValuestring(corruptedString, "test"));
|
||||
cJSON_Minify(NULL);
|
||||
/* skipped because it is only used via a macro that checks for NULL */
|
||||
/* cJSON_SetNumberHelper(NULL, 0); */
|
||||
|
||||
/* restore corrupted item2 to delete it */
|
||||
item2->prev = originalPrev;
|
||||
cJSON_Delete(corruptedString);
|
||||
cJSON_Delete(array);
|
||||
cJSON_Delete(item);
|
||||
}
|
||||
|
||||
|
@ -642,7 +663,9 @@ static void cjson_set_valuestring_to_object_should_not_leak_memory(void)
|
|||
ptr1 = item1->valuestring;
|
||||
return_value = cJSON_SetValuestring(cJSON_GetObjectItem(root, "one"), long_valuestring);
|
||||
TEST_ASSERT_NOT_NULL(return_value);
|
||||
#ifndef __TRUSTINSOFT_ANALYZER__ /* ptr1 was already freed, comparing it with another pointer is Undefined Behavior */
|
||||
TEST_ASSERT_NOT_EQUAL_MESSAGE(ptr1, return_value, "new valuestring longer than old should reallocate memory")
|
||||
#endif /* __TRUSTINSOFT_ANALYZER__ */
|
||||
TEST_ASSERT_EQUAL_STRING(long_valuestring, cJSON_GetObjectItem(root, "one")->valuestring);
|
||||
|
||||
return_value = cJSON_SetValuestring(cJSON_GetObjectItem(root, "two"), long_valuestring);
|
||||
|
|
|
@ -34,7 +34,12 @@ static void parse_hex4_should_parse_all_combinations(void)
|
|||
unsigned char digits_lower[6];
|
||||
unsigned char digits_upper[6];
|
||||
/* test all combinations */
|
||||
#if defined(__TRUSTINSOFT_ANALYZER__)
|
||||
/* Reduce the test's size for TIS CI. */
|
||||
for (number = 0; number <= 0xFFF; number++)
|
||||
#else
|
||||
for (number = 0; number <= 0xFFFF; number++)
|
||||
#endif
|
||||
{
|
||||
TEST_ASSERT_EQUAL_INT_MESSAGE(4, sprintf((char*)digits_lower, "%.4x", number), "sprintf failed.");
|
||||
TEST_ASSERT_EQUAL_INT_MESSAGE(4, sprintf((char*)digits_upper, "%.4X", number), "sprintf failed.");
|
||||
|
|
|
@ -0,0 +1,233 @@
|
|||
[
|
||||
{
|
||||
"name": "cjson_add.c",
|
||||
"files": [
|
||||
"tests/cjson_add.c"
|
||||
],
|
||||
"include": "trustinsoft/common.config"
|
||||
},
|
||||
{
|
||||
"name": "compare_tests.c",
|
||||
"files": [
|
||||
"tests/compare_tests.c"
|
||||
],
|
||||
"include": "trustinsoft/common.config"
|
||||
},
|
||||
{
|
||||
"name": "json_patch_tests.c",
|
||||
"files": [
|
||||
"tests/json_patch_tests.c"
|
||||
],
|
||||
"include": "trustinsoft/common.config"
|
||||
},
|
||||
{
|
||||
"name": "minify_tests.c",
|
||||
"files": [
|
||||
"tests/minify_tests.c"
|
||||
],
|
||||
"include": "trustinsoft/common.config"
|
||||
},
|
||||
{
|
||||
"name": "misc_tests.c",
|
||||
"files": [
|
||||
"tests/misc_tests.c"
|
||||
],
|
||||
"include": "trustinsoft/common.config"
|
||||
},
|
||||
{
|
||||
"name": "misc_utils_tests.c",
|
||||
"files": [
|
||||
"tests/misc_utils_tests.c"
|
||||
],
|
||||
"include": "trustinsoft/common.config"
|
||||
},
|
||||
{
|
||||
"name": "old_utils_tests.c",
|
||||
"files": [
|
||||
"tests/old_utils_tests.c"
|
||||
],
|
||||
"include": "trustinsoft/common.config"
|
||||
},
|
||||
{
|
||||
"name": "parse_array.c",
|
||||
"files": [
|
||||
"tests/parse_array.c"
|
||||
],
|
||||
"include": "trustinsoft/common.config"
|
||||
},
|
||||
{
|
||||
"name": "parse_examples.c",
|
||||
"files": [
|
||||
"tests/parse_examples.c"
|
||||
],
|
||||
"include": "trustinsoft/common.config"
|
||||
},
|
||||
{
|
||||
"name": "parse_hex4.c",
|
||||
"files": [
|
||||
"tests/parse_hex4.c"
|
||||
],
|
||||
"include": "trustinsoft/common.config"
|
||||
},
|
||||
{
|
||||
"name": "parse_number.c",
|
||||
"files": [
|
||||
"tests/parse_number.c"
|
||||
],
|
||||
"include": "trustinsoft/common.config"
|
||||
},
|
||||
{
|
||||
"name": "parse_object.c",
|
||||
"files": [
|
||||
"tests/parse_object.c"
|
||||
],
|
||||
"include": "trustinsoft/common.config"
|
||||
},
|
||||
{
|
||||
"name": "parse_string.c",
|
||||
"files": [
|
||||
"tests/parse_string.c"
|
||||
],
|
||||
"include": "trustinsoft/common.config"
|
||||
},
|
||||
{
|
||||
"name": "parse_value.c",
|
||||
"files": [
|
||||
"tests/parse_value.c"
|
||||
],
|
||||
"include": "trustinsoft/common.config"
|
||||
},
|
||||
{
|
||||
"name": "parse_with_opts.c",
|
||||
"files": [
|
||||
"tests/parse_with_opts.c"
|
||||
],
|
||||
"include": "trustinsoft/common.config"
|
||||
},
|
||||
{
|
||||
"name": "print_array.c",
|
||||
"files": [
|
||||
"tests/print_array.c"
|
||||
],
|
||||
"include": "trustinsoft/common.config"
|
||||
},
|
||||
{
|
||||
"name": "print_number.c",
|
||||
"files": [
|
||||
"tests/print_number.c"
|
||||
],
|
||||
"include": "trustinsoft/common.config"
|
||||
},
|
||||
{
|
||||
"name": "print_object.c",
|
||||
"files": [
|
||||
"tests/print_object.c"
|
||||
],
|
||||
"include": "trustinsoft/common.config"
|
||||
},
|
||||
{
|
||||
"name": "print_string.c",
|
||||
"files": [
|
||||
"tests/print_string.c"
|
||||
],
|
||||
"include": "trustinsoft/common.config"
|
||||
},
|
||||
{
|
||||
"name": "print_value.c",
|
||||
"files": [
|
||||
"tests/print_value.c"
|
||||
],
|
||||
"include": "trustinsoft/common.config"
|
||||
},
|
||||
{
|
||||
"name": "readme_examples.c",
|
||||
"files": [
|
||||
"tests/readme_examples.c"
|
||||
],
|
||||
"include": "trustinsoft/common.config"
|
||||
},
|
||||
{
|
||||
"name": "afl.c test1",
|
||||
"val-args": " fuzzing/inputs/test1",
|
||||
"include": "trustinsoft/common.config",
|
||||
"include": "trustinsoft/fuzz.config"
|
||||
},
|
||||
{
|
||||
"name": "afl.c test10",
|
||||
"val-args": " fuzzing/inputs/test10",
|
||||
"include": "trustinsoft/common.config",
|
||||
"include": "trustinsoft/fuzz.config"
|
||||
},
|
||||
{
|
||||
"name": "afl.c test11",
|
||||
"val-args": " fuzzing/inputs/test11",
|
||||
"include": "trustinsoft/common.config",
|
||||
"include": "trustinsoft/fuzz.config"
|
||||
},
|
||||
{
|
||||
"name": "afl.c test2",
|
||||
"val-args": " fuzzing/inputs/test2",
|
||||
"include": "trustinsoft/common.config",
|
||||
"include": "trustinsoft/fuzz.config"
|
||||
},
|
||||
{
|
||||
"name": "afl.c test3",
|
||||
"val-args": " fuzzing/inputs/test3",
|
||||
"include": "trustinsoft/common.config",
|
||||
"include": "trustinsoft/fuzz.config"
|
||||
},
|
||||
{
|
||||
"name": "afl.c test3.bu",
|
||||
"val-args": " fuzzing/inputs/test3.bu",
|
||||
"include": "trustinsoft/common.config",
|
||||
"include": "trustinsoft/fuzz.config"
|
||||
},
|
||||
{
|
||||
"name": "afl.c test3.uf",
|
||||
"val-args": " fuzzing/inputs/test3.uf",
|
||||
"include": "trustinsoft/common.config",
|
||||
"include": "trustinsoft/fuzz.config"
|
||||
},
|
||||
{
|
||||
"name": "afl.c test3.uu",
|
||||
"val-args": " fuzzing/inputs/test3.uu",
|
||||
"include": "trustinsoft/common.config",
|
||||
"include": "trustinsoft/fuzz.config"
|
||||
},
|
||||
{
|
||||
"name": "afl.c test4",
|
||||
"val-args": " fuzzing/inputs/test4",
|
||||
"include": "trustinsoft/common.config",
|
||||
"include": "trustinsoft/fuzz.config"
|
||||
},
|
||||
{
|
||||
"name": "afl.c test5",
|
||||
"val-args": " fuzzing/inputs/test5",
|
||||
"include": "trustinsoft/common.config",
|
||||
"include": "trustinsoft/fuzz.config"
|
||||
},
|
||||
{
|
||||
"name": "afl.c test6",
|
||||
"val-args": " fuzzing/inputs/test6",
|
||||
"include": "trustinsoft/common.config",
|
||||
"include": "trustinsoft/fuzz.config"
|
||||
},
|
||||
{
|
||||
"name": "afl.c test7",
|
||||
"val-args": " fuzzing/inputs/test7",
|
||||
"include": "trustinsoft/common.config",
|
||||
"include": "trustinsoft/fuzz.config"
|
||||
},
|
||||
{
|
||||
"name": "afl.c test8",
|
||||
"val-args": " fuzzing/inputs/test8",
|
||||
"include": "trustinsoft/common.config",
|
||||
"include": "trustinsoft/fuzz.config"
|
||||
},
|
||||
{
|
||||
"name": "afl.c test9",
|
||||
"val-args": " fuzzing/inputs/test9",
|
||||
"include": "trustinsoft/common.config",
|
||||
"include": "trustinsoft/fuzz.config"
|
||||
}
|
||||
]
|
|
@ -0,0 +1,112 @@
|
|||
{
|
||||
"files": [
|
||||
"../cJSON_Utils.c",
|
||||
"../tests/unity/src/unity.c"
|
||||
],
|
||||
"compilation_cmd": "-DUNITY_EXCLUDE_SETJMP_H",
|
||||
"val-clone-on-recursive-calls-max-depth": 10000,
|
||||
"filesystem": {
|
||||
"files": [
|
||||
{
|
||||
"name": "json-patch-tests/cjson-utils-tests.json",
|
||||
"from": "../tests/json-patch-tests/cjson-utils-tests.json"
|
||||
},
|
||||
{
|
||||
"name": "json-patch-tests/package.json",
|
||||
"from": "../tests/json-patch-tests/package.json"
|
||||
},
|
||||
{
|
||||
"name": "json-patch-tests/spec_tests.json",
|
||||
"from": "../tests/json-patch-tests/spec_tests.json"
|
||||
},
|
||||
{
|
||||
"name": "json-patch-tests/tests.json",
|
||||
"from": "../tests/json-patch-tests/tests.json"
|
||||
},
|
||||
{
|
||||
"name": "inputs/test1",
|
||||
"from": "../tests/inputs/test1"
|
||||
},
|
||||
{
|
||||
"name": "inputs/test1.expected",
|
||||
"from": "../tests/inputs/test1.expected"
|
||||
},
|
||||
{
|
||||
"name": "inputs/test10",
|
||||
"from": "../tests/inputs/test10"
|
||||
},
|
||||
{
|
||||
"name": "inputs/test10.expected",
|
||||
"from": "../tests/inputs/test10.expected"
|
||||
},
|
||||
{
|
||||
"name": "inputs/test11",
|
||||
"from": "../tests/inputs/test11"
|
||||
},
|
||||
{
|
||||
"name": "inputs/test11.expected",
|
||||
"from": "../tests/inputs/test11.expected"
|
||||
},
|
||||
{
|
||||
"name": "inputs/test2",
|
||||
"from": "../tests/inputs/test2"
|
||||
},
|
||||
{
|
||||
"name": "inputs/test2.expected",
|
||||
"from": "../tests/inputs/test2.expected"
|
||||
},
|
||||
{
|
||||
"name": "inputs/test3",
|
||||
"from": "../tests/inputs/test3"
|
||||
},
|
||||
{
|
||||
"name": "inputs/test3.expected",
|
||||
"from": "../tests/inputs/test3.expected"
|
||||
},
|
||||
{
|
||||
"name": "inputs/test4",
|
||||
"from": "../tests/inputs/test4"
|
||||
},
|
||||
{
|
||||
"name": "inputs/test4.expected",
|
||||
"from": "../tests/inputs/test4.expected"
|
||||
},
|
||||
{
|
||||
"name": "inputs/test5",
|
||||
"from": "../tests/inputs/test5"
|
||||
},
|
||||
{
|
||||
"name": "inputs/test5.expected",
|
||||
"from": "../tests/inputs/test5.expected"
|
||||
},
|
||||
{
|
||||
"name": "inputs/test6",
|
||||
"from": "../tests/inputs/test6"
|
||||
},
|
||||
{
|
||||
"name": "inputs/test7",
|
||||
"from": "../tests/inputs/test7"
|
||||
},
|
||||
{
|
||||
"name": "inputs/test7.expected",
|
||||
"from": "../tests/inputs/test7.expected"
|
||||
},
|
||||
{
|
||||
"name": "inputs/test8",
|
||||
"from": "../tests/inputs/test8"
|
||||
},
|
||||
{
|
||||
"name": "inputs/test8.expected",
|
||||
"from": "../tests/inputs/test8.expected"
|
||||
},
|
||||
{
|
||||
"name": "inputs/test9",
|
||||
"from": "../tests/inputs/test9"
|
||||
},
|
||||
{
|
||||
"name": "inputs/test9.expected",
|
||||
"from": "../tests/inputs/test9.expected"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
{
|
||||
"files": [
|
||||
"../cJSON.c",
|
||||
"../fuzzing/afl.c"
|
||||
],
|
||||
"filesystem": {
|
||||
"files": [
|
||||
{
|
||||
"name": "fuzzing/inputs/test1",
|
||||
"from": "../fuzzing/inputs/test1"
|
||||
},
|
||||
{
|
||||
"name": "fuzzing/inputs/test10",
|
||||
"from": "../fuzzing/inputs/test10"
|
||||
},
|
||||
{
|
||||
"name": "fuzzing/inputs/test11",
|
||||
"from": "../fuzzing/inputs/test11"
|
||||
},
|
||||
{
|
||||
"name": "fuzzing/inputs/test2",
|
||||
"from": "../fuzzing/inputs/test2"
|
||||
},
|
||||
{
|
||||
"name": "fuzzing/inputs/test3",
|
||||
"from": "../fuzzing/inputs/test3"
|
||||
},
|
||||
{
|
||||
"name": "fuzzing/inputs/test3.bu",
|
||||
"from": "../fuzzing/inputs/test3.bu"
|
||||
},
|
||||
{
|
||||
"name": "fuzzing/inputs/test3.uf",
|
||||
"from": "../fuzzing/inputs/test3.uf"
|
||||
},
|
||||
{
|
||||
"name": "fuzzing/inputs/test3.uu",
|
||||
"from": "../fuzzing/inputs/test3.uu"
|
||||
},
|
||||
{
|
||||
"name": "fuzzing/inputs/test4",
|
||||
"from": "../fuzzing/inputs/test4"
|
||||
},
|
||||
{
|
||||
"name": "fuzzing/inputs/test5",
|
||||
"from": "../fuzzing/inputs/test5"
|
||||
},
|
||||
{
|
||||
"name": "fuzzing/inputs/test6",
|
||||
"from": "../fuzzing/inputs/test6"
|
||||
},
|
||||
{
|
||||
"name": "fuzzing/inputs/test7",
|
||||
"from": "../fuzzing/inputs/test7"
|
||||
},
|
||||
{
|
||||
"name": "fuzzing/inputs/test8",
|
||||
"from": "../fuzzing/inputs/test8"
|
||||
},
|
||||
{
|
||||
"name": "fuzzing/inputs/test9",
|
||||
"from": "../fuzzing/inputs/test9"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,198 @@
|
|||
#! /usr/bin/env python3
|
||||
|
||||
# This script regenerates TrustInSoft CI configuration.
|
||||
|
||||
# Run from the root of the cJSON project:
|
||||
# $ python3 trustinsoft/regenerate.py
|
||||
|
||||
import re # sub
|
||||
import json # dumps, load
|
||||
from os import path # basename, isdir, join
|
||||
import glob # iglob
|
||||
|
||||
# Outputting JSON.
|
||||
def string_of_json(obj):
|
||||
# Output standard pretty-printed JSON (RFC 7159) with 4-space indentation.
|
||||
s = json.dumps(obj, indent=4)
|
||||
# Sometimes we need to have multiple "include" fields in the outputted
|
||||
# JSON, which is unfortunately impossible in the internal python
|
||||
# representation (OK, it is technically possible, but too cumbersome to
|
||||
# bother implementing it here), so we can name these fields 'include_',
|
||||
# 'include__', etc, and they are all converted to 'include' before
|
||||
# outputting as JSON.
|
||||
s = re.sub(r'"include_+"', '"include"', s)
|
||||
return s
|
||||
|
||||
# Make a command line from a dictionary of lists.
|
||||
def string_of_options(options):
|
||||
elts = []
|
||||
for opt_prefix in options: # e.g. opt_prefix == "-D"
|
||||
for opt_value in options[opt_prefix]: # e.g. opt_value == "HAVE_OPEN"
|
||||
elts.append(opt_prefix + opt_value) # e.g. "-DHAVE_OPEN"
|
||||
return " ".join(elts)
|
||||
|
||||
|
||||
# Directories.
|
||||
test_files_dir = "tests"
|
||||
fuzz_input_dir = path.join("fuzzing", "inputs")
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# ---------------------------------- CHECKS --------------------------------- #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def check_dir(dir):
|
||||
if path.isdir(dir):
|
||||
print(" > OK! Directory '%s' exists." % dir)
|
||||
else:
|
||||
exit("Directory '%s' not found." % dir)
|
||||
|
||||
# Initial check.
|
||||
print("1. Check if all necessary directories and files exist...")
|
||||
check_dir("trustinsoft")
|
||||
check_dir(test_files_dir)
|
||||
check_dir(fuzz_input_dir)
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# -------------------- GENERATE trustinsoft/common.config ------------------- #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
common_config_path = path.join("trustinsoft", "common.config")
|
||||
|
||||
def make_common_config():
|
||||
# C files.
|
||||
c_files = [
|
||||
"cJSON_Utils.c",
|
||||
path.join("tests", "unity", "src", "unity.c"),
|
||||
]
|
||||
# Compilation options.
|
||||
compilation_cmd = (
|
||||
{
|
||||
"-I": [],
|
||||
"-D": [
|
||||
"UNITY_EXCLUDE_SETJMP_H"
|
||||
],
|
||||
"-U": [],
|
||||
}
|
||||
)
|
||||
# Filesystem.
|
||||
json_patch_tests = list(
|
||||
map(lambda file:
|
||||
{
|
||||
"name": path.join("json-patch-tests", path.basename(file)),
|
||||
"from": path.join("..", file),
|
||||
},
|
||||
sorted(glob.iglob(path.join("tests", "json-patch-tests", "*.json"),
|
||||
recursive=False)))
|
||||
)
|
||||
tests_and_expected = list(
|
||||
map(lambda file:
|
||||
{
|
||||
"name": path.join("inputs", path.basename(file)),
|
||||
"from": path.join("..", file),
|
||||
},
|
||||
sorted(glob.iglob(path.join("tests", "inputs", "test*"),
|
||||
recursive=False)))
|
||||
)
|
||||
# Whole common.config JSON.
|
||||
config = (
|
||||
{
|
||||
"files": list(map(lambda file: path.join("..", file), c_files)),
|
||||
"compilation_cmd": string_of_options(compilation_cmd),
|
||||
"val-clone-on-recursive-calls-max-depth": 10000,
|
||||
"filesystem": { "files": json_patch_tests + tests_and_expected },
|
||||
}
|
||||
)
|
||||
# Done.
|
||||
return config
|
||||
|
||||
common_config = make_common_config()
|
||||
with open(common_config_path, "w") as file:
|
||||
print("2. Generate the '%s' file." % common_config_path)
|
||||
file.write(string_of_json(common_config))
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# -------------------- GENERATE trustinsoft/fuzz.config --------------------- #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
fuzz_config_path = path.join("trustinsoft", "fuzz.config")
|
||||
|
||||
def make_fuzz_config():
|
||||
# C files.
|
||||
c_files = [
|
||||
"cJSON.c",
|
||||
path.join("fuzzing", "afl.c"),
|
||||
]
|
||||
# Filesystem.
|
||||
fuzzing_files = list(
|
||||
map(lambda file:
|
||||
{
|
||||
"name": path.join(fuzz_input_dir, path.basename(file)),
|
||||
"from": path.join("..", file),
|
||||
},
|
||||
sorted(glob.iglob(path.join(fuzz_input_dir, "test*"),
|
||||
recursive=False)))
|
||||
)
|
||||
# Whole fuzz.config JSON.
|
||||
config = (
|
||||
{
|
||||
"files": list(map(lambda file: path.join("..", file), c_files)),
|
||||
"filesystem": { "files": fuzzing_files },
|
||||
}
|
||||
)
|
||||
# Done.
|
||||
return config
|
||||
|
||||
fuzz_config = make_fuzz_config()
|
||||
with open(fuzz_config_path, "w") as file:
|
||||
print("3. Generate the '%s' file." % fuzz_config_path)
|
||||
file.write(string_of_json(fuzz_config))
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# -------------------------------- tis.config ------------------------------- #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
exclude_tests = [
|
||||
"unity_setup.c"
|
||||
]
|
||||
|
||||
def test_files():
|
||||
test_files = sorted(
|
||||
glob.iglob(path.join(test_files_dir, "*.c"), recursive=False)
|
||||
)
|
||||
for exclude_test in exclude_tests:
|
||||
test_files.remove(path.join("tests", exclude_test))
|
||||
return test_files
|
||||
|
||||
def make_test(test_file):
|
||||
basename = path.basename(test_file)
|
||||
return (
|
||||
{
|
||||
"name": basename,
|
||||
"files": [ test_file ],
|
||||
"include": common_config_path,
|
||||
}
|
||||
)
|
||||
|
||||
def fuzz_input_files():
|
||||
return sorted(
|
||||
glob.iglob(path.join(fuzz_input_dir, "test*"), recursive=False)
|
||||
)
|
||||
|
||||
def make_fuzz_test(fuzz_input_file):
|
||||
basename = path.basename(fuzz_input_file)
|
||||
return (
|
||||
{
|
||||
"name": ("afl.c " + basename),
|
||||
"val-args": " " + path.join(fuzz_input_dir, basename),
|
||||
"include": common_config_path,
|
||||
"include_": fuzz_config_path,
|
||||
}
|
||||
)
|
||||
|
||||
tis_config = (
|
||||
list(map(make_test, test_files())) +
|
||||
list(map(make_fuzz_test, fuzz_input_files()))
|
||||
)
|
||||
with open("tis.config", "w") as file:
|
||||
print("4. Generate the 'tis.config' file.")
|
||||
file.write(string_of_json(tis_config))
|
Loading…
Reference in New Issue