diff --git a/orbisrpc/jsonlite.c b/orbisrpc/jsonlite.c index 8fad610..2b1d361 100644 --- a/orbisrpc/jsonlite.c +++ b/orbisrpc/jsonlite.c @@ -152,6 +152,10 @@ static jl_val_t *parse_value(jl_parse_t *p){ return parse_value_depth(p, 0); } jl_val_t *jl_parse(const char *s, size_t len){ if(!s) return NULL; + /* Input cap: no legitimate input here exceeds it (gateway frames, + * manifests, configs are KBs); unbounded input means unbounded + * allocation inside parse_string's doubling buffer. */ + if(len > 4u*1024u*1024u) return NULL; size_t l = len; jl_parse_t p={s,s+l,0}; jl_val_t *v=parse_value(&p); diff --git a/tests/test_utils.c b/tests/test_utils.c index 825a684..cfd5a88 100644 --- a/tests/test_utils.c +++ b/tests/test_utils.c @@ -68,6 +68,8 @@ static void test_json_oom_safe(void) { assert(jl_parse("true", 4) != NULL); /* incomplete pair must fail cleanly, no leak/crash */ assert(jl_parse("{\"a\":", 5) == NULL); assert(jl_parse("{\"a\":1", 6) == NULL); + /* oversize input refused before any allocation */ + assert(jl_parse("[]", 5u*1024u*1024u) == NULL); } static void test_json_hostile(void) { /* 200-deep nesting must be rejected, not stack-smash */ diff --git a/tests/test_utils_asan b/tests/test_utils_asan new file mode 100755 index 0000000..9de8164 Binary files /dev/null and b/tests/test_utils_asan differ