round upstream patches

(cherry picked from commit c90fe1b81b387ba3f2cce777ff5c2665cc472e20)
This commit is contained in:
sun_hai_10 2023-09-04 19:41:01 +08:00 committed by openeuler-sync-bot
parent 2d9749e1c3
commit 4c3b1a5530
3 changed files with 778 additions and 1 deletions

View File

@ -0,0 +1,206 @@
From 6eca65617aacd19f4928acd5766b8dd20eda0b34 Mon Sep 17 00:00:00 2001
From: Khem Raj <raj.khem@gmail.com>
Date: Sat, 13 Aug 2022 20:37:03 -0700
Subject: [PATCH] Fix build with clang-15+
Fixes
json_util.c:63:35: error: a function declaration without a prototype is deprecated in all versions of C [-We
rror,-Wstrict-prototypes]
const char *json_util_get_last_err()
^
void
Signed-off-by: Khem Raj <raj.khem@gmail.com>
Conflict:NA
Reference:https://github.com/json-c/json-c/commit/6eca65617aacd19f4928acd5766b8dd20eda0b34
---
json_util.c | 2 +-
tests/test1.c | 6 +++---
tests/test4.c | 2 +-
tests/test_cast.c | 2 +-
tests/test_charcase.c | 2 +-
tests/test_parse.c | 8 ++++----
tests/test_printbuf.c | 4 ++--
tests/test_util_file.c | 6 +++---
8 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/json_util.c b/json_util.c
index 952770a..83d9c68 100644
--- a/json_util.c
+++ b/json_util.c
@@ -60,7 +60,7 @@ static int _json_object_to_fd(int fd, struct json_object *obj, int flags, const
static char _last_err[256] = "";
-const char *json_util_get_last_err()
+const char *json_util_get_last_err(void)
{
if (_last_err[0] == '\0')
return NULL;
diff --git a/tests/test1.c b/tests/test1.c
index befd246..d28811b 100644
--- a/tests/test1.c
+++ b/tests/test1.c
@@ -61,7 +61,7 @@ static const char *to_json_string(json_object *obj, int flags)
#endif
json_object *make_array(void);
-json_object *make_array()
+json_object *make_array(void)
{
json_object *my_array;
@@ -77,7 +77,7 @@ json_object *make_array()
}
void test_array_del_idx(void);
-void test_array_del_idx()
+void test_array_del_idx(void)
{
int rc;
size_t ii;
@@ -143,7 +143,7 @@ void test_array_del_idx()
}
void test_array_list_expand_internal(void);
-void test_array_list_expand_internal()
+void test_array_list_expand_internal(void)
{
int rc;
size_t ii;
diff --git a/tests/test4.c b/tests/test4.c
index 749459d..1e136e5 100644
--- a/tests/test4.c
+++ b/tests/test4.c
@@ -31,7 +31,7 @@ void print_hex(const char *s)
}
static void test_lot_of_adds(void);
-static void test_lot_of_adds()
+static void test_lot_of_adds(void)
{
int ii;
char key[50];
diff --git a/tests/test_cast.c b/tests/test_cast.c
index 276b461..02e19ea 100644
--- a/tests/test_cast.c
+++ b/tests/test_cast.c
@@ -97,7 +97,7 @@ static void getit(struct json_object *new_obj, const char *field)
printf("new_obj.%s json_object_get_double()=%f\n", field, json_object_get_double(o));
}
-static void checktype_header()
+static void checktype_header(void)
{
printf("json_object_is_type: %s,%s,%s,%s,%s,%s,%s\n", json_type_to_name(json_type_null),
json_type_to_name(json_type_boolean), json_type_to_name(json_type_double),
diff --git a/tests/test_charcase.c b/tests/test_charcase.c
index c6e783e..8ffcb68 100644
--- a/tests/test_charcase.c
+++ b/tests/test_charcase.c
@@ -22,7 +22,7 @@ int main(int argc, char **argv)
}
/* make sure only lowercase forms are parsed in strict mode */
-static void test_case_parse()
+static void test_case_parse(void)
{
struct json_tokener *tok;
json_object *new_obj;
diff --git a/tests/test_parse.c b/tests/test_parse.c
index cdd2d8a..4a8e3d7 100644
--- a/tests/test_parse.c
+++ b/tests/test_parse.c
@@ -96,7 +96,7 @@ static void single_basic_parse(const char *test_string, int clear_serializer)
if (getenv("TEST_PARSE_CHUNKSIZE") != NULL)
single_incremental_parse(test_string, clear_serializer);
}
-static void test_basic_parse()
+static void test_basic_parse(void)
{
single_basic_parse("\"\003\"", 0);
single_basic_parse("/* hello */\"foo\"", 0);
@@ -199,7 +199,7 @@ static void test_basic_parse()
single_basic_parse("[18446744073709551616]", 1);
}
-static void test_utf8_parse()
+static void test_utf8_parse(void)
{
// json_tokener_parse doesn't support checking for byte order marks.
// It's the responsibility of the caller to detect and skip a BOM.
@@ -226,7 +226,7 @@ static int clear_serializer(json_object *jso, int flags, json_object *parent_jso
return JSON_C_VISIT_RETURN_CONTINUE;
}
-static void test_verbose_parse()
+static void test_verbose_parse(void)
{
json_object *new_obj;
enum json_tokener_error error = json_tokener_success;
@@ -566,7 +566,7 @@ struct incremental_step
{NULL, -1, -1, json_tokener_success, 0},
};
-static void test_incremental_parse()
+static void test_incremental_parse(void)
{
json_object *new_obj;
enum json_tokener_error jerr;
diff --git a/tests/test_printbuf.c b/tests/test_printbuf.c
index 2a2ccc0..3b1540f 100644
--- a/tests/test_printbuf.c
+++ b/tests/test_printbuf.c
@@ -19,7 +19,7 @@ static void test_printbuf_memset_length(void);
#define __func__ __FUNCTION__
#endif
-static void test_basic_printbuf_memset()
+static void test_basic_printbuf_memset(void)
{
struct printbuf *pb;
@@ -32,7 +32,7 @@ static void test_basic_printbuf_memset()
printf("%s: end test\n", __func__);
}
-static void test_printbuf_memset_length()
+static void test_printbuf_memset_length(void)
{
struct printbuf *pb;
diff --git a/tests/test_util_file.c b/tests/test_util_file.c
index f3a022e..27a097e 100644
--- a/tests/test_util_file.c
+++ b/tests/test_util_file.c
@@ -38,7 +38,7 @@ static void test_read_fd_equal(const char *testdir);
#define PATH_MAX 256
#endif
-static void test_write_to_file()
+static void test_write_to_file(void)
{
json_object *jso;
@@ -234,7 +234,7 @@ static void test_read_valid_nested_with_fd(const char *testdir)
close(d);
}
-static void test_read_nonexistant()
+static void test_read_nonexistant(void)
{
const char *filename = "./not_present.json";
@@ -252,7 +252,7 @@ static void test_read_nonexistant()
}
}
-static void test_read_closed()
+static void test_read_closed(void)
{
// Test reading from a closed fd
int d = open("/dev/null", O_RDONLY, 0);
--
2.23.0

View File

@ -0,0 +1,564 @@
From 9e6acc9a4eefe9f092aa3a3890a6e5c6ca2d5ed1 Mon Sep 17 00:00:00 2001
From: Tobias Stoeckmann <tobias@stoeckmann.org>
Date: Sun, 20 Mar 2022 17:22:07 +0100
Subject: [PATCH] json_tokener_parse_ex: handle out of memory errors
Do not silently truncate values or skip entries if out of memory errors
occur.
Proof of Concept:
- Create poc.c, a program which creates an eight megabyte large json
object with key "A" and a lot of "B"s as value, one of them is
UTF-formatted:
```c
#include <err.h>
#include <stdio.h>
#include <string.h>
#include "json.h"
#define STR_LEN (8 * 1024 * 1024)
#define STR_PREFIX "{ \"A\": \""
#define STR_SUFFIX "\\u0042\" }"
int main(void) {
char *str;
struct json_tokener *tok;
struct json_object *obj;
if ((tok = json_tokener_new()) == NULL)
errx(1, "json_tokener_new");
if ((str = malloc(STR_LEN)) == NULL)
err(1, "malloc");
memset(str, 'B', STR_LEN);
memcpy(str, STR_PREFIX, sizeof(STR_PREFIX) - 1);
memcpy(str + STR_LEN - sizeof(STR_SUFFIX), STR_SUFFIX, sizeof(STR_SUFFIX));
obj = json_tokener_parse(str);
free(str);
printf("%p\n", obj);
if (obj != NULL) {
printf("%.*s\n", 50, json_object_to_json_string(obj));
json_object_put(obj);
}
json_tokener_free(tok);
return 0;
}
```
- Compile and run poc, assuming you have enough free heap space:
```
gcc $(pkg-config --cflags --libs) -o poc poc.c
./poc
0x559421e15de0
{ "A": "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
```
- Reduce available heap and run again, which leads to truncation:
```
ulimit -d 10000
./poc
0x555a5b453de0
{ "A": "B" }
```
- Compile json-c with this change and run with reduced heap again:
```
ulimit -d 10000
./poc
(nil)
```
The output is limited to 70 characters, i.e. json-c parses the 8 MB
string correctly but the poc does not print all of them to the screen.
The truncation occurs because the parser tries to add all chars up
to the UTF-8 formatted 'B' at once. Since memory is limited to 10 MB
there is not enough for this operation. The parser does not fail but
continues normally.
Another possibility is to create a json file close to 2 GB and run a
program on a system with limited amount of RAM, i.e. around 3 GB. But
ulimit restrictions are much easier for proof of concepts.
Treat memory errors correctly and abort operations.
Conflict:NA
Reference:https://github.com/json-c/json-c/commit/9e6acc9a4eefe9f092aa3a3890a6e5c6ca2d5ed1
---
json_tokener.c | 145 ++++++++++++++++++++++++++++++++++---------------
json_tokener.h | 1 +
2 files changed, 103 insertions(+), 43 deletions(-)
diff --git a/json_tokener.c b/json_tokener.c
index 0c09b66..af03a85 100644
--- a/json_tokener.c
+++ b/json_tokener.c
@@ -103,6 +103,7 @@ static const char *json_tokener_errors[] = {
"success",
"continue",
"nesting too deep",
+ "out of memory",
"unexpected end of data",
"unexpected character",
"null expected",
@@ -284,11 +285,24 @@ struct json_object *json_tokener_parse_verbose(const char *str, enum json_tokene
/* ADVANCE_CHAR() macro:
* Increments str & tok->char_offset.
- * For convenience of existing conditionals, returns the old value of c (0 on eof)
+ * For convenience of existing conditionals, returns the old value of c (0 on eof).
* Implicit inputs: c var
*/
#define ADVANCE_CHAR(str, tok) (++(str), ((tok)->char_offset)++, c)
+/* printbuf_memappend_checked(p, s, l) macro:
+ * Add string s of length l to printbuffer p.
+ * If operation fails abort parse operation with memory error.
+ */
+#define printbuf_memappend_checked(p, s, l) \
+ do { \
+ if (printbuf_memappend((p), (s), (l)) < 0) \
+ { \
+ tok->err = json_tokener_error_memory; \
+ goto out; \
+ } \
+ } while (0)
+
/* End optimization macro defs */
struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *str, int len)
@@ -336,7 +350,11 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
char *tmplocale;
tmplocale = setlocale(LC_NUMERIC, NULL);
if (tmplocale)
+ {
oldlocale = strdup(tmplocale);
+ if (oldlocale == NULL)
+ return NULL;
+ }
setlocale(LC_NUMERIC, "C");
}
#endif
@@ -358,7 +376,7 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
if (c == '/' && !(tok->flags & JSON_TOKENER_STRICT))
{
printbuf_reset(tok->pb);
- printbuf_memappend_fast(tok->pb, &c, 1);
+ printbuf_memappend_checked(tok->pb, &c, 1);
state = json_tokener_state_comment_start;
}
else
@@ -376,14 +394,20 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
saved_state = json_tokener_state_object_field_start;
current = json_object_new_object();
if (current == NULL)
+ {
+ tok->err = json_tokener_error_memory;
goto out;
+ }
break;
case '[':
state = json_tokener_state_eatws;
saved_state = json_tokener_state_array;
current = json_object_new_array();
if (current == NULL)
+ {
+ tok->err = json_tokener_error_memory;
goto out;
+ }
break;
case 'I':
case 'i':
@@ -486,7 +510,10 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
}
current = json_object_new_double(is_negative ? -INFINITY : INFINITY);
if (current == NULL)
+ {
+ tok->err = json_tokener_error_memory;
goto out;
+ }
saved_state = json_tokener_state_finish;
state = json_tokener_state_eatws;
goto redo_char;
@@ -496,7 +523,7 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
{
int size;
int size_nan;
- printbuf_memappend_fast(tok->pb, &c, 1);
+ printbuf_memappend_checked(tok->pb, &c, 1);
size = json_min(tok->st_pos + 1, json_null_str_len);
size_nan = json_min(tok->st_pos + 1, json_nan_str_len);
if ((!(tok->flags & JSON_TOKENER_STRICT) &&
@@ -519,7 +546,10 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
{
current = json_object_new_double(NAN);
if (current == NULL)
+ {
+ tok->err = json_tokener_error_memory;
goto out;
+ }
saved_state = json_tokener_state_finish;
state = json_tokener_state_eatws;
goto redo_char;
@@ -548,7 +578,7 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
tok->err = json_tokener_error_parse_comment;
goto out;
}
- printbuf_memappend_fast(tok->pb, &c, 1);
+ printbuf_memappend_checked(tok->pb, &c, 1);
break;
case json_tokener_state_comment:
@@ -559,12 +589,12 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
{
if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
{
- printbuf_memappend_fast(tok->pb, case_start,
- str - case_start);
+ printbuf_memappend_checked(tok->pb, case_start,
+ str - case_start);
goto out;
}
}
- printbuf_memappend_fast(tok->pb, case_start, 1 + str - case_start);
+ printbuf_memappend_checked(tok->pb, case_start, 1 + str - case_start);
state = json_tokener_state_comment_end;
}
break;
@@ -577,19 +607,19 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
{
if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
{
- printbuf_memappend_fast(tok->pb, case_start,
- str - case_start);
+ printbuf_memappend_checked(tok->pb, case_start,
+ str - case_start);
goto out;
}
}
- printbuf_memappend_fast(tok->pb, case_start, str - case_start);
+ printbuf_memappend_checked(tok->pb, case_start, str - case_start);
MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
state = json_tokener_state_eatws;
}
break;
case json_tokener_state_comment_end:
- printbuf_memappend_fast(tok->pb, &c, 1);
+ printbuf_memappend_checked(tok->pb, &c, 1);
if (c == '/')
{
MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
@@ -609,28 +639,31 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
{
if (c == tok->quote_char)
{
- printbuf_memappend_fast(tok->pb, case_start,
- str - case_start);
+ printbuf_memappend_checked(tok->pb, case_start,
+ str - case_start);
current =
json_object_new_string_len(tok->pb->buf, tok->pb->bpos);
if (current == NULL)
+ {
+ tok->err = json_tokener_error_memory;
goto out;
+ }
saved_state = json_tokener_state_finish;
state = json_tokener_state_eatws;
break;
}
else if (c == '\\')
{
- printbuf_memappend_fast(tok->pb, case_start,
- str - case_start);
+ printbuf_memappend_checked(tok->pb, case_start,
+ str - case_start);
saved_state = json_tokener_state_string;
state = json_tokener_state_string_escape;
break;
}
if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
{
- printbuf_memappend_fast(tok->pb, case_start,
- str - case_start);
+ printbuf_memappend_checked(tok->pb, case_start,
+ str - case_start);
goto out;
}
}
@@ -643,7 +676,7 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
case '"':
case '\\':
case '/':
- printbuf_memappend_fast(tok->pb, &c, 1);
+ printbuf_memappend_checked(tok->pb, &c, 1);
state = saved_state;
break;
case 'b':
@@ -652,15 +685,15 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
case 't':
case 'f':
if (c == 'b')
- printbuf_memappend_fast(tok->pb, "\b", 1);
+ printbuf_memappend_checked(tok->pb, "\b", 1);
else if (c == 'n')
- printbuf_memappend_fast(tok->pb, "\n", 1);
+ printbuf_memappend_checked(tok->pb, "\n", 1);
else if (c == 'r')
- printbuf_memappend_fast(tok->pb, "\r", 1);
+ printbuf_memappend_checked(tok->pb, "\r", 1);
else if (c == 't')
- printbuf_memappend_fast(tok->pb, "\t", 1);
+ printbuf_memappend_checked(tok->pb, "\t", 1);
else if (c == 'f')
- printbuf_memappend_fast(tok->pb, "\f", 1);
+ printbuf_memappend_checked(tok->pb, "\f", 1);
state = saved_state;
break;
case 'u':
@@ -720,8 +753,8 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
/* High surrogate was not followed by a low surrogate
* Replace the high and process the rest normally
*/
- printbuf_memappend_fast(tok->pb,
- (char *)utf8_replacement_char, 3);
+ printbuf_memappend_checked(tok->pb,
+ (char *)utf8_replacement_char, 3);
}
tok->high_surrogate = 0;
}
@@ -730,14 +763,14 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
{
unsigned char unescaped_utf[1];
unescaped_utf[0] = tok->ucs_char;
- printbuf_memappend_fast(tok->pb, (char *)unescaped_utf, 1);
+ printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 1);
}
else if (tok->ucs_char < 0x800)
{
unsigned char unescaped_utf[2];
unescaped_utf[0] = 0xc0 | (tok->ucs_char >> 6);
unescaped_utf[1] = 0x80 | (tok->ucs_char & 0x3f);
- printbuf_memappend_fast(tok->pb, (char *)unescaped_utf, 2);
+ printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 2);
}
else if (IS_HIGH_SURROGATE(tok->ucs_char))
{
@@ -763,7 +796,7 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
else if (IS_LOW_SURROGATE(tok->ucs_char))
{
/* Got a low surrogate not preceded by a high */
- printbuf_memappend_fast(tok->pb, (char *)utf8_replacement_char, 3);
+ printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
}
else if (tok->ucs_char < 0x10000)
{
@@ -771,7 +804,7 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
unescaped_utf[0] = 0xe0 | (tok->ucs_char >> 12);
unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
unescaped_utf[2] = 0x80 | (tok->ucs_char & 0x3f);
- printbuf_memappend_fast(tok->pb, (char *)unescaped_utf, 3);
+ printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 3);
}
else if (tok->ucs_char < 0x110000)
{
@@ -780,12 +813,12 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 12) & 0x3f);
unescaped_utf[2] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
unescaped_utf[3] = 0x80 | (tok->ucs_char & 0x3f);
- printbuf_memappend_fast(tok->pb, (char *)unescaped_utf, 4);
+ printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 4);
}
else
{
/* Don't know what we got--insert the replacement char */
- printbuf_memappend_fast(tok->pb, (char *)utf8_replacement_char, 3);
+ printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
}
state = saved_state; // i.e. _state_string or _state_object_field
}
@@ -800,7 +833,7 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
* it. Put a replacement char in for the high surrogate
* and pop back up to _state_string or _state_object_field.
*/
- printbuf_memappend_fast(tok->pb, (char *)utf8_replacement_char, 3);
+ printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
tok->high_surrogate = 0;
tok->ucs_char = 0;
tok->st_pos = 0;
@@ -819,7 +852,7 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
* Put a replacement char in for the high surrogate
* and handle the escape sequence normally.
*/
- printbuf_memappend_fast(tok->pb, (char *)utf8_replacement_char, 3);
+ printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
tok->high_surrogate = 0;
tok->ucs_char = 0;
tok->st_pos = 0;
@@ -834,7 +867,7 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
case json_tokener_state_boolean:
{
int size1, size2;
- printbuf_memappend_fast(tok->pb, &c, 1);
+ printbuf_memappend_checked(tok->pb, &c, 1);
size1 = json_min(tok->st_pos + 1, json_true_str_len);
size2 = json_min(tok->st_pos + 1, json_false_str_len);
if ((!(tok->flags & JSON_TOKENER_STRICT) &&
@@ -845,7 +878,10 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
{
current = json_object_new_boolean(1);
if (current == NULL)
+ {
+ tok->err = json_tokener_error_memory;
goto out;
+ }
saved_state = json_tokener_state_finish;
state = json_tokener_state_eatws;
goto redo_char;
@@ -859,7 +895,10 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
{
current = json_object_new_boolean(0);
if (current == NULL)
+ {
+ tok->err = json_tokener_error_memory;
goto out;
+ }
saved_state = json_tokener_state_finish;
state = json_tokener_state_eatws;
goto redo_char;
@@ -939,7 +978,7 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
{
- printbuf_memappend_fast(tok->pb, case_start, case_len);
+ printbuf_memappend_checked(tok->pb, case_start, case_len);
goto out;
}
}
@@ -948,7 +987,7 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
it might have been intended to be, and return a potentially
more understandable error right away.
However, if we're at the top-level, use the number as-is
- because c can be part of a new object to parse on the
+ because c can be part of a new object to parse on the
next call to json_tokener_parse().
*/
if (tok->depth > 0 && c != ',' && c != ']' && c != '}' && c != '/' &&
@@ -958,7 +997,7 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
goto out;
}
if (case_len > 0)
- printbuf_memappend_fast(tok->pb, case_start, case_len);
+ printbuf_memappend_checked(tok->pb, case_start, case_len);
// Check for -Infinity
if (tok->pb->buf[0] == '-' && case_len <= 1 && (c == 'i' || c == 'I'))
@@ -993,7 +1032,10 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
}
current = json_object_new_int64(num64);
if (current == NULL)
+ {
+ tok->err = json_tokener_error_memory;
goto out;
+ }
}
else if (!tok->is_double && tok->pb->buf[0] != '-' &&
json_parse_uint64(tok->pb->buf, &numuint64) == 0)
@@ -1009,13 +1051,19 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
num64 = (uint64_t)numuint64;
current = json_object_new_int64(num64);
if (current == NULL)
+ {
+ tok->err = json_tokener_error_memory;
goto out;
+ }
}
else
{
current = json_object_new_uint64(numuint64);
if (current == NULL)
+ {
+ tok->err = json_tokener_error_memory;
goto out;
+ }
}
}
else if (tok->is_double &&
@@ -1024,7 +1072,10 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
{
current = json_object_new_double_s(numd, tok->pb->buf);
if (current == NULL)
+ {
+ tok->err = json_tokener_error_memory;
goto out;
+ }
}
else
{
@@ -1069,7 +1120,10 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
case json_tokener_state_array_add:
if (json_object_array_add(current, obj) != 0)
+ {
+ tok->err = json_tokener_error_memory;
goto out;
+ }
saved_state = json_tokener_state_array_sep;
state = json_tokener_state_eatws;
goto redo_char;
@@ -1129,25 +1183,30 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
{
if (c == tok->quote_char)
{
- printbuf_memappend_fast(tok->pb, case_start,
- str - case_start);
+ printbuf_memappend_checked(tok->pb, case_start,
+ str - case_start);
obj_field_name = strdup(tok->pb->buf);
+ if (obj_field_name == NULL)
+ {
+ tok->err = json_tokener_error_memory;
+ goto out;
+ }
saved_state = json_tokener_state_object_field_end;
state = json_tokener_state_eatws;
break;
}
else if (c == '\\')
{
- printbuf_memappend_fast(tok->pb, case_start,
- str - case_start);
+ printbuf_memappend_checked(tok->pb, case_start,
+ str - case_start);
saved_state = json_tokener_state_object_field;
state = json_tokener_state_string_escape;
break;
}
if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
{
- printbuf_memappend_fast(tok->pb, case_start,
- str - case_start);
+ printbuf_memappend_checked(tok->pb, case_start,
+ str - case_start);
goto out;
}
}
diff --git a/json_tokener.h b/json_tokener.h
index a07e12c..c1502e8 100644
--- a/json_tokener.h
+++ b/json_tokener.h
@@ -28,6 +28,7 @@ enum json_tokener_error
json_tokener_success,
json_tokener_continue,
json_tokener_error_depth,
+ json_tokener_error_memory,
json_tokener_error_parse_eof,
json_tokener_error_parse_unexpected,
json_tokener_error_parse_null,
--
2.23.0

View File

@ -6,7 +6,7 @@
Name: json-c
Version: 0.16
Release: 3
Release: 4
Summary: JSON implementation in C
License: MIT
@ -20,6 +20,9 @@ Patch6002: backport-Fix-memory-leak-with-emtpy-strings-in-json_object_set_s
Patch6003: backport-json_object_from_fd_ex-fail-if-file-is-too-large.patch
Patch6004: backport-Explicitly-check-for-integer-overflow-when-parsing.patch
Patch6005: backport-Fix-build-with-clang-15.patch
Patch6006: backport-json_tokener_parse_ex-handle-out-of-memory-errors.patch
%description
JSON-C implements a reference counting object model that allows you
to easily construct JSON objects in C, output them as JSON formatted
@ -106,6 +109,10 @@ end
%doc %{_pkgdocdir}
%changelog
* Mon Sep 04 2023 sunhai <sunhai10@huawei.com> - 0.16-4
- backport patch to Fix build with clang-15+
- backport patch to Fix json_tokener_parse_ex: handle out of memory errors
* Fri Apr 21 2023 zhangrui <zhangrui182@huawei.com> - 0.16-3
- backport patch to fix integer overflow