diff --git a/CMakeLists.txt b/CMakeLists.txt index 58ee9ed..c6695eb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -267,6 +267,7 @@ if (HAVE_SYS_RANDOM_H) endif() if (HAVE_SYS_RESOURCE_H) check_symbol_exists(getrusage "sys/resource.h" HAVE_GETRUSAGE) + check_symbol_exists(setrlimit "sys/resource.h" HAVE_SETRLIMIT) endif() check_symbol_exists(strtoll "stdlib.h" HAVE_STRTOLL) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 46f802d..caff03f 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -21,6 +21,7 @@ set(ALL_TEST_NAMES test_charcase test_compare test_deep_copy + test_deep_nesting test_double_serializer test_float test_int_add diff --git a/tests/test_deep_nesting.c b/tests/test_deep_nesting.c new file mode 100644 index 0000000..90fa196 --- /dev/null +++ b/tests/test_deep_nesting.c @@ -0,0 +1,84 @@ +#ifdef NDEBUG +#undef NDEBUG +#endif +#include +#include +#include +#include +#ifdef HAVE_SYS_RESOURCE_H +#include +#endif + +#include "config.h" + +#include "json.h" + +#define NESTING_DEPTH 100000 + +static char *generate_json_string(void); +static char *generate_json_string() +{ + char *str; + int depth = NESTING_DEPTH; + str = malloc(depth * 2 + 1); + memset(str, '[', depth); + memset(str + depth, ']', depth); + str[depth * 2] = '\0'; + return str; +} + +static void test_deep_nesting_put(const char *str); +static void test_deep_nesting_put(const char *str) +{ + json_object *my_array; + + struct json_tokener *tok = json_tokener_new_ex(NESTING_DEPTH); + my_array = json_tokener_parse_ex(tok, str, strlen(str) + 1); + printf("Parsed depth %d string to json_object: %s\n", NESTING_DEPTH, (my_array == NULL) ? "NO" : "yes"); + + json_object_put(my_array); + printf("Freed json_object\n"); + + json_tokener_free(tok); +} + +static void test_deep_nesting_tostring(const char *str); +static void test_deep_nesting_tostring(const char *str) +{ + json_object *my_array; + + struct json_tokener *tok = json_tokener_new_ex(NESTING_DEPTH); + my_array = json_tokener_parse_ex(tok, str, strlen(str) + 1); + printf("Parsed depth %d string to json_object: %s\n", NESTING_DEPTH, (my_array == NULL) ? "NO" : "yes"); + + const char *res = json_object_to_json_string_ext(my_array, JSON_C_TO_STRING_PLAIN); + printf("Serialized to string of length %ld\n", (long)strlen(res)); + json_object_put(my_array); + printf("Freed json_object\n"); + + json_tokener_free(tok); +} + +int main(int argc, char **argv) +{ + char *str; +#ifdef HAVE_SETRLIMIT + struct rlimit rl; + rl.rlim_cur = 2048; + rl.rlim_max = 2048; + setrlimit(RLIMIT_STACK, &rl); +#endif + + str = generate_json_string(); + + MC_SET_DEBUG(1); + + test_deep_nesting_put(str); + + if (0) // TODO: make json_object_to_json_string non-recursive + test_deep_nesting_tostring(str); + + free(str); + + return EXIT_SUCCESS; +} diff --git a/tests/test_deep_nesting.expected b/tests/test_deep_nesting.expected new file mode 100644 index 0000000..0790ee8 --- /dev/null +++ b/tests/test_deep_nesting.expected @@ -0,0 +1,2 @@ +Parsed depth 1000000 string to json_object: yes +Freed json_object diff --git a/tests/test_deep_nesting.test b/tests/test_deep_nesting.test new file mode 120000 index 0000000..58a13f4 --- /dev/null +++ b/tests/test_deep_nesting.test @@ -0,0 +1 @@ +test_basic.test \ No newline at end of file