Compare commits

...

10 Commits

Author SHA1 Message Date
openeuler-ci-bot
77bb97ce3a
!53 [sync] PR-52: round upstream patches
From: @openeuler-sync-bot 
Reviewed-by: @yanan-rock 
Signed-off-by: @yanan-rock
2023-09-05 01:07:32 +00:00
sun_hai_10
4c3b1a5530 round upstream patches
(cherry picked from commit c90fe1b81b387ba3f2cce777ff5c2665cc472e20)
2023-09-04 19:55:29 +08:00
openeuler-ci-bot
2d9749e1c3
!42 [sync] PR-41: backport patch to fix integer overflow
From: @openeuler-sync-bot 
Reviewed-by: @yanan-rock 
Signed-off-by: @yanan-rock
2023-05-04 03:40:03 +00:00
zhangrui
a4bc92ebbf backport patch to fix integer overflow
(cherry picked from commit 48fab61885c850363a66541f85abbbcf89b060e0)
2023-04-21 14:56:26 +08:00
openeuler-ci-bot
7b6bb75baa
!38 [sync] PR-37: 新版本升级,回合0.15版本3个补丁
From: @openeuler-sync-bot 
Reviewed-by: @anonymous_z, @yanan-rock 
Signed-off-by: @yanan-rock
2022-11-15 03:27:36 +00:00
klmengkd
96f547b8d7 add backport patch
(cherry picked from commit cc6ad155fd7b8e1ac7d80731ebde9e86c49ce2af)
2022-11-15 09:09:08 +08:00
openeuler-ci-bot
c15a210cdd
!34 Update json-c to 0.16
From: @anonymous_z 
Reviewed-by: @t_feng, @yanan-rock 
Signed-off-by: @t_feng, @yanan-rock
2022-11-09 09:36:51 +00:00
chenhaixing
68742ceb6a Update json-c to 0.16 2022-11-05 14:57:34 +08:00
openeuler-ci-bot
304aaf6e3b
!27 [sync] PR-26: fix upgrade err
From: @openeuler-sync-bot 
Reviewed-by: @overweight 
Signed-off-by: @overweight
2022-05-30 09:15:34 +00:00
t.feng
ce7b82545f fix upgrade error
(cherry picked from commit db0ed70feaa521f2886146fa31dd6d11829342db)
2022-05-25 14:06:55 +08:00
10 changed files with 1070 additions and 55 deletions

View File

@ -0,0 +1,31 @@
From 16208fc01afcd742fd5e6736f52849ad2ec03e8f Mon Sep 17 00:00:00 2001
From: Eric Haszlakiewicz <erh+git@nimenees.com>
Date: Sun, 24 Jul 2022 18:59:26 +0000
Subject: [PATCH] Add test to check for the memory leak mentioned in issue #781
Conflict:NA
Reference:https://github.com/json-c/json-c/commit/16208fc01afcd742fd5e6736f52849ad2ec03e8f
---
tests/test_set_value.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/tests/test_set_value.c b/tests/test_set_value.c
index f51a2a5b67..a8ebbfec79 100644
--- a/tests/test_set_value.c
+++ b/tests/test_set_value.c
@@ -71,6 +71,14 @@ int main(int argc, char **argv)
json_object_set_string(tmp, SHORT);
assert(strcmp(json_object_get_string(tmp), SHORT) == 0);
assert(strcmp(json_object_to_json_string(tmp), "\"" SHORT "\"") == 0);
+
+ // Set an empty string a couple times to try to trigger
+ // a case that used to leak memory.
+ json_object_set_string(tmp, "");
+ json_object_set_string(tmp, HUGE);
+ json_object_set_string(tmp, "");
+ json_object_set_string(tmp, HUGE);
+
json_object_put(tmp);
printf("STRING PASSED\n");

View File

@ -0,0 +1,52 @@
From d6f46ae104871360f84695737864870c97adfd14 Mon Sep 17 00:00:00 2001
From: Eric Haszlakiewicz <erh+git@nimenees.com>
Date: Sun, 30 Oct 2022 19:29:15 +0000
Subject: [PATCH] Explicitly check for integer overflow/underflow when
parsing integers with JSON_TOKENER_STRICT.
Reference:https://github.com/json-c/json-c/commit/d6f46ae104871360f84695737864870c97adfd14
Conflict:Ignore changes in the ChangeLog and test because the pre-feature patch is not merged
---
json_tokener.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/json_tokener.c b/json_tokener.c
index 0c09b66..1feee65 100644
--- a/json_tokener.c
+++ b/json_tokener.c
@@ -17,6 +17,7 @@
#include "math_compat.h"
#include <assert.h>
+#include <errno.h>
#include <limits.h>
#include <math.h>
#include <stddef.h>
@@ -991,6 +992,11 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
if (!tok->is_double && tok->pb->buf[0] == '-' &&
json_parse_int64(tok->pb->buf, &num64) == 0)
{
+ if (errno == ERANGE && (tok->flags & JSON_TOKENER_STRICT))
+ {
+ tok->err = json_tokener_error_parse_number;
+ goto out;
+ }
current = json_object_new_int64(num64);
if (current == NULL)
goto out;
@@ -998,6 +1004,11 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
else if (!tok->is_double && tok->pb->buf[0] != '-' &&
json_parse_uint64(tok->pb->buf, &numuint64) == 0)
{
+ if(errno==ERANGE&&(tok->flags & JSON_TOKENER_STRICT))
+ {
+ tok->err=json_tokener_error_parse_number;
+ goto out;
+ }
if (numuint64 && tok->pb->buf[0] == '0' &&
(tok->flags & JSON_TOKENER_STRICT))
{
--
2.27.0

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,67 @@
From 213bb5caa11ed2182848d86c86f8e9ab4c75642a Mon Sep 17 00:00:00 2001
From: Daniel Danzberger <daniel@dd-wrt.com>
Date: Sun, 24 Jul 2022 18:46:03 +0200
Subject: [PATCH] Fix memory leak with emtpy strings in json_object_set_string
When a json string object is updated with a bigger string, a new
malloc'ed buffer is used to store the new string and it's size is made
negative to indicate that an external buffer is in use.
When that same json string object get's updated again with an empty
stirng (size = 0), the new external malloc'ed buffer is still used.
But the fact that the new size value is not negative removes the
indicator that the externally malloc'ed buffer is used.
This becomes a problem when the object get's updated again with any
other string, because a new buffer will be malloced and linked to the
object while to old one won't be free'd.
This causes a memory leak when updating a json string with
json_object_set_stirng() which has previously been updated
with an empty string.
Example:
--
obj = json_object_new_string("data");
json_object_set_string(obj, "more data");
json_object_set_string(obj, "");
json_object_set_string(obj, "other data"); /* leaks */
--
This commit fixes the issue by free'ing the external buffer when an
empty string is set and use the internal one again.
Signed-off-by: Daniel Danzberger <daniel@dd-wrt.com>
Conflict:NA
Reference:https://github.com/json-c/json-c/commit/213bb5caa11ed2182848d86c86f8e9ab4c75642a
---
json_object.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/json_object.c b/json_object.c
index e52ca4071a..581b1e2748 100644
--- a/json_object.c
+++ b/json_object.c
@@ -1323,11 +1323,18 @@ static int _json_object_set_string_len(json_object *jso, const char *s, size_t l
// length as int, cap length at INT_MAX.
return 0;
- dstbuf = get_string_component_mutable(jso);
curlen = JC_STRING(jso)->len;
- if (curlen < 0)
- curlen = -curlen;
+ if (curlen < 0) {
+ if (len == 0) {
+ free(JC_STRING(jso)->c_string.pdata);
+ JC_STRING(jso)->len = curlen = 0;
+ } else {
+ curlen = -curlen;
+ }
+ }
+
newlen = len;
+ dstbuf = get_string_component_mutable(jso);
if ((ssize_t)len > curlen)
{

View File

@ -1,48 +0,0 @@
From 296db618e9d1862aea788e90e751b4999db41a2a Mon Sep 17 00:00:00 2001
From: Even Rouault <even.rouault@spatialys.com>
Date: Wed, 12 Jan 2022 23:43:03 +0100
Subject: [PATCH] json_escape_str(): avoid harmless unsigned integer overflow
Current behaviour is perfectly valid, since wrap-over upon overflow is
well defined behaviour for unsigned types, but it is nevertheless nice to be
able to build with -fsanitize=undefined,unsigned-integer-overflow
There is no significant effect on the generated assembly as can be seen
on the diff of objdump -d output on a optimized build (the compiler
just decided to switch the order of a comparison):
@@ -135,8 +135,8 @@
1d0: 0f 84 70 ff ff ff je 146 <json_escape_str+0x146>
1d6: 4c 3b 24 24 cmp (%rsp),%r12
1da: 0f 85 2d ff ff ff jne 10d <json_escape_str+0x10d>
- 1e0: 49 39 f4 cmp %rsi,%r12
- 1e3: 0f 87 b7 00 00 00 ja 2a0 <json_escape_str+0x2a0>
+ 1e0: 4c 39 e6 cmp %r12,%rsi
+ 1e3: 0f 82 b7 00 00 00 jb 2a0 <json_escape_str+0x2a0>
1e9: 48 8b 44 24 18 mov 0x18(%rsp),%rax
1ee: 64 48 33 04 25 28 00 xor %fs:0x28,%rax
1f5: 00 00
Conflict:NA
Reference:https://github.com/json-c/json-c/commit/296db618e9d1862aea788e90e751b4999db41a2a
---
json_object.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/json_object.c b/json_object.c
index 9198257..3216941 100644
--- a/json_object.c
+++ b/json_object.c
@@ -216,8 +216,9 @@ static int json_escape_str(struct printbuf *pb, const char *str, size_t len, int
{
int pos = 0, start_offset = 0;
unsigned char c;
- while (len--)
+ while (len)
{
+ --len;
c = str[pos];
switch (c)
{
--
2.27.0

View File

@ -0,0 +1,111 @@
From 5accae04bbc727fd447c2db4c1c541a4142bd4a0 Mon Sep 17 00:00:00 2001
From: Tobias Stoeckmann <tobias@stoeckmann.org>
Date: Sun, 20 Mar 2022 13:17:37 +0100
Subject: [PATCH] json_object_from_fd_ex: fail if file is too large
If the input file is too large to fit into a printbuf then return an
error value instead of silently truncating the parsed content.
This introduces errno handling into printbuf to distinguish between an
input file being too large and running out of memory.
Conflict:tests/test_util_file.expected,0.16 version has merge.
Reference:https://github.com/json-c/json-c/commit/5accae04bbc727fd447c2db4c1c541a4142bd4a0
---
json_util.c | 13 ++++++++++---
printbuf.c | 14 +++++++++++++-
2 files changed, 23 insertions(+), 4 deletions(-)
diff --git a/json_util.c b/json_util.c
index 3e6a6c681b..e1c05c5cfd 100644
--- a/json_util.c
+++ b/json_util.c
@@ -101,15 +101,22 @@ struct json_object *json_object_from_fd_ex(int fd, int in_depth)
if (!tok)
{
_json_c_set_last_err(
- "json_object_from_fd_ex: unable to allocate json_tokener(depth=%d): %s\n", depth,
- strerror(errno));
+ "json_object_from_fd_ex: unable to allocate json_tokener(depth=%d): %s\n",
+ depth, strerror(errno));
printbuf_free(pb);
return NULL;
}
while ((ret = read(fd, buf, JSON_FILE_BUF_SIZE)) > 0)
{
- printbuf_memappend(pb, buf, ret);
+ if (printbuf_memappend(pb, buf, ret) < 0)
+ {
+ _json_c_set_last_err("json_object_from_fd_ex: error reading fd %d: %s\n",
+ fd, strerror(errno));
+ json_tokener_free(tok);
+ printbuf_free(pb);
+ return NULL;
+ }
}
if (ret < 0)
{
diff --git a/printbuf.c b/printbuf.c
index a08f7b1582..12d3b3319d 100644
--- a/printbuf.c
+++ b/printbuf.c
@@ -15,6 +15,7 @@
#include "config.h"
+#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
@@ -56,6 +57,8 @@ struct printbuf *printbuf_new(void)
*
* If the current size is large enough, nothing is changed.
*
+ * If extension failed, errno is set to indicate the error.
+ *
* Note: this does not check the available space! The caller
* is responsible for performing those calculations.
*/
@@ -68,7 +71,10 @@ static int printbuf_extend(struct printbuf *p, int min_size)
return 0;
/* Prevent signed integer overflows with large buffers. */
if (min_size > INT_MAX - 8)
+ {
+ errno = EFBIG;
return -1;
+ }
if (p->size > INT_MAX / 2)
new_size = min_size + 8;
else {
@@ -77,7 +83,7 @@ static int printbuf_extend(struct printbuf *p, int min_size)
new_size = min_size + 8;
}
#ifdef PRINTBUF_DEBUG
- MC_DEBUG("printbuf_memappend: realloc "
+ MC_DEBUG("printbuf_extend: realloc "
"bpos=%d min_size=%d old_size=%d new_size=%d\n",
p->bpos, min_size, p->size, new_size);
#endif /* PRINTBUF_DEBUG */
@@ -92,7 +98,10 @@ int printbuf_memappend(struct printbuf *p, const char *buf, int size)
{
/* Prevent signed integer overflows with large buffers. */
if (size < 0 || size > INT_MAX - p->bpos - 1)
+ {
+ errno = EFBIG;
return -1;
+ }
if (p->size <= p->bpos + size + 1)
{
if (printbuf_extend(p, p->bpos + size + 1) < 0)
@@ -112,7 +121,10 @@ int printbuf_memset(struct printbuf *pb, int offset, int charvalue, int len)
offset = pb->bpos;
/* Prevent signed integer overflows with large buffers. */
if (len < 0 || offset < -1 || len > INT_MAX - offset)
+ {
+ errno = EFBIG;
return -1;
+ }
size_needed = offset + len;
if (pb->size < size_needed)
{

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

Binary file not shown.

BIN
json-c-0.16-20220414.tar.gz Normal file

Binary file not shown.

View File

@ -1,11 +1,11 @@
%{!?_pkgdocdir:%global _pkgdocdir %{_docdir}/%{name}-%{version}}
%global so_ver 5
%global reldate 20200726
%global reldate 20220414
Name: json-c
Version: 0.15
Version: 0.16
Release: 4
Summary: JSON implementation in C
@ -15,6 +15,14 @@ Source0: %{url}/archive/%{name}-%{version}-%{reldate}.tar.gz
BuildRequires: cmake gcc ninja-build
Patch6001: backport-Add-test-to-check-for-the-memory-leak-mentioned-in-issue-781.patch
Patch6002: backport-Fix-memory-leak-with-emtpy-strings-in-json_object_set_string.patch
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
@ -27,8 +35,6 @@ Summary: Development files for %{name}
Requires: %{name}%{?_isa} == %{version}-%{release}
Patch6001: backport-json-escape-str-avoid-harmless-unsigned-integer-overflow.patch
%description devel
This package contains libraries and header files for
developing applications that use %{name}.
@ -69,19 +75,24 @@ doxygen -s -u doc/Doxyfile.in
%{!?__cmake_in_source_build:-B "%{_vpath_builddir}"} \
%__cmake --build "%{_vpath_builddir}" %{?_smp_mflags} --verbose --target all doc
#%cmake_build
%check
%ninja_test -C %{_vpath_builddir}
%install
#%cmake_install
DESTDIR="%{buildroot}" %__cmake --install "%{_vpath_builddir}"
mkdir -p %{buildroot}%{_pkgdocdir}
hardlink -cfv %{buildroot}%{_pkgdocdir}
%pretrans devel -p <lua>
path = "%{_includedir}/%{name}"
st = posix.stat(path)
if st and st.type == "link" then
os.remove(path)
end
%ldconfig_scriptlets
%files
@ -89,7 +100,7 @@ hardlink -cfv %{buildroot}%{_pkgdocdir}
%{_libdir}/lib%{name}.so.%{so_ver}*
%files devel
%{_includedir}/%{name}/
%{_includedir}/%{name}
%{_libdir}/cmake/%{name}
%{_libdir}/lib%{name}.so
%{_libdir}/pkgconfig/%{name}.pc
@ -98,6 +109,27 @@ hardlink -cfv %{buildroot}%{_pkgdocdir}
%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
* Mon Nov 14 2022 mengkanglai <mengkanglai2@huawei.com> - 0.16-2
- add backport-Add-test-to-check-for-the-memory-leak-mentioned-in-issue-781.patch
- add backport-Fix-memory-leak-with-emtpy-strings-in-json_object_set_string.patch
- add backport-json_object_from_fd_ex-fail-if-file-is-too-large.patch
* Sat Nov 5 2022 zhangrui <zhangrui182@huawei.com> - 0.16-1
- Update to 0.16
* Tue May 24 2022 fengtao <fengtao40@huawei.com> - 0.15-5
- we got upgrade error when upgrade json-c from very low version,
for example json-c-0.11-5. because old version has a softlink:
/usr/include/json-c --> /usr/include/json
and now, softlink has been removed. so, we fix this in pretrans
* Fri May 6 2022 wuchaochao <cyanrose@yeah.net> - 0.15-4
- add backport-json-escape-str-avoid-harmless-unsigned-integer-overflow.patch