Compare commits

...

4 Commits

Author SHA1 Message Date
Jakub Zwolakowski ad87960fec
Merge 11de03fbd2 into 66e9dff670 2024-04-26 21:37:51 +08:00
Alan Wang 66e9dff670
Create SECURITY.md 2024-04-26 16:58:00 +08:00
Up-wind 7e4d5dabe7 Add NULL check to cJSON_SetValuestring()
If the valuestring passed to cJSON_SetValuestring is NULL, a null pointer dereference will happen.

This commit adds the NULL check of valuestring before it is dereferenced.
2024-04-26 16:34:05 +08:00
guillaumemillot 11de03fbd2 Initial TrustInSoft CI configuration 2020-11-25 16:40:31 +01:00
9 changed files with 631 additions and 1 deletions

View File

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

11
SECURITY.md Normal file
View File

@ -0,0 +1,11 @@
# Security Policy
## Supported Versions
Security is of the highest importance and all security vulnerabilities or suspected security vulnerabilities should be reported to mavonEditor team privately, to minimize attacks against current users of mavonEditor before they are fixed. Vulnerabilities will be investigated and patched on the next patch (or minor) release as soon as possible. This information could be kept entirely internal to the project.
## Reporting a Vulnerability
If you know of a publicly disclosed security vulnerability for mavonEditor, please IMMEDIATELY contact wp_scut@163.com and peterlee@apache.org to inform the mavonEditor Team.
IMPORTANT: Do not file public issues on GitHub for security vulnerabilities.

View File

@ -406,7 +406,7 @@ CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring)
return NULL;
}
/* return NULL if the object is corrupted */
if (object->valuestring == NULL)
if (object->valuestring == NULL || valuestring == NULL)
{
return NULL;
}

View File

@ -663,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);

View File

@ -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.");

233
tis.config Normal file
View File

@ -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"
}
]

112
trustinsoft/common.config Normal file
View File

@ -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"
}
]
}
}

66
trustinsoft/fuzz.config Normal file
View File

@ -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"
}
]
}
}

198
trustinsoft/regenerate.py Normal file
View File

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