From 583911a66c5b1103e7c98e59ef165631c0cbf290 Mon Sep 17 00:00:00 2001 From: Tobias Stoeckmann Date: Sat, 22 Aug 2020 13:07:45 +0200 Subject: [PATCH 1/2] Aligned comment in _json_object_new_string The comment only aligns correctly if tab size is 4. Replaced spaces with tabs to stay in sync with style of other lines. --- json_object.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/json_object.c b/json_object.c index 6c572a8..f8d14d5 100644 --- a/json_object.c +++ b/json_object.c @@ -1254,17 +1254,17 @@ static struct json_object *_json_object_new_string(const char *s, const size_t l struct json_object_string *jso; /* - * Structures Actual memory layout - * ------------------- -------------------- + * Structures Actual memory layout + * ------------------- -------------------- * [json_object_string [json_object_string * [json_object] [json_object] - * ...other fields... ...other fields... + * ...other fields... ...other fields... * c_string] len - * bytes + * bytes * of * string * data - * \0] + * \0] */ if (len > (SSIZE_T_MAX - (sizeof(*jso) - sizeof(jso->c_string)) - 1)) return NULL; From e50154f615cbd2a14857a6f68462e3a699be42d8 Mon Sep 17 00:00:00 2001 From: Tobias Stoeckmann Date: Sat, 22 Aug 2020 13:09:11 +0200 Subject: [PATCH 2/2] Cap string length at INT_MAX. Several issues occur if a string is longer than INT_MAX: - The function json_object_get_string_len returns the length of a string as int. If the string is longer than INT_MAX, the result would be negative. - That in turn would lead to possible out of boundary access when comparing these strings with memcmp and the returned length as done in json_object_equal. - If json_escape_str is called with such strings, out of boundary accesses can occur due to internal int handling (also fixed). - The string cannot be printed out due to printbuffer limits at INT_MAX (which is still true after this commit). Such huge strings can only be inserted through API calls at this point because input files are capped at INT_MAX anyway. Due to huge amount of RAM needed to reproduce these issues I have not added test cases. --- json_object.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/json_object.c b/json_object.c index f8d14d5..b42026b 100644 --- a/json_object.c +++ b/json_object.c @@ -214,7 +214,7 @@ static inline const char *get_string_component(const struct json_object *jso) static int json_escape_str(struct printbuf *pb, const char *str, size_t len, int flags) { - int pos = 0, start_offset = 0; + size_t pos = 0, start_offset = 0; unsigned char c; while (len--) { @@ -1329,9 +1329,10 @@ static int _json_object_set_string_len(json_object *jso, const char *s, size_t l if (jso == NULL || jso->o_type != json_type_string) return 0; - if (len >= SSIZE_T_MAX - 1) + if (len >= INT_MAX - 1) // jso->len is a signed ssize_t, so it can't hold the - // full size_t range. + // full size_t range. json_object_get_string_len returns + // length as int, cap length at INT_MAX. return 0; dstbuf = get_string_component_mutable(jso);