mirror of https://github.com/asterisk/asterisk
This brings in jansson-2.12, removes all patches that were merged upstream. README is created in third-party/jansson/patches to explain how to add patches but also because the patches folder must exist for the build process to succeed. Change-Id: If0f2d541c50997690660c21fb7b03d625a5cdaddpull/12/head
parent
b7af9c8b19
commit
8e1ab4f11c
@ -1 +0,0 @@
|
|||||||
289ca8cbd2df31de9bda7e5220754d25 jansson-2.11.tar.bz2
|
|
@ -0,0 +1 @@
|
|||||||
|
317dbaf90a9f85ea0ec7b12d080d173d jansson-2.12.tar.bz2
|
@ -1,128 +0,0 @@
|
|||||||
From 73c22de51672cb40fdc29c95331923d4dcebb6fa Mon Sep 17 00:00:00 2001
|
|
||||||
From: Corey Farrell <git@cfware.com>
|
|
||||||
Date: Tue, 13 Feb 2018 04:35:37 -0500
|
|
||||||
Subject: [PATCH 01/22] Improve test coverage.
|
|
||||||
|
|
||||||
Changes to test/ removed for bundled use in Asterisk.
|
|
||||||
|
|
||||||
* Test equality of different length strings.
|
|
||||||
* Add tab to json_pack whitespace test.
|
|
||||||
* Test json_sprintf with empty result and invalid UTF.
|
|
||||||
* Test json_get_alloc_funcs with NULL arguments.
|
|
||||||
* Test invalid arguments.
|
|
||||||
* Add test_chaos to test allocation failure code paths.
|
|
||||||
* Remove redundant json_is_string checks from json_string_equal and
|
|
||||||
json_string_copy. Both functions are static and can only be called
|
|
||||||
with a json string.
|
|
||||||
|
|
||||||
Fixes to issues found by test_chaos:
|
|
||||||
* Fix crash on OOM in pack_unpack.c:read_string().
|
|
||||||
* Unconditionally free string in string_create upon allocation failure.
|
|
||||||
Update load.c:parse_value() to reflect this. This resolves a leak on
|
|
||||||
allocation failure for pack_unpack.c:pack_string() and
|
|
||||||
value.c:json_sprintf().
|
|
||||||
|
|
||||||
Although not visible from CodeCoverage these changes significantly
|
|
||||||
increase branch coverage. Especially in src/value.c where we previously
|
|
||||||
covered 67.4% of branches and now cover 96.3% of branches.
|
|
||||||
---
|
|
||||||
CMakeLists.txt | 1 +
|
|
||||||
src/load.c | 6 +-
|
|
||||||
src/pack_unpack.c | 5 +-
|
|
||||||
src/value.c | 9 +-
|
|
||||||
test/.gitignore | 1 +
|
|
||||||
test/suites/api/Makefile.am | 2 +
|
|
||||||
test/suites/api/test_array.c | 73 +++++++++++++++++
|
|
||||||
test/suites/api/test_chaos.c | 115 ++++++++++++++++++++++++++
|
|
||||||
test/suites/api/test_equal.c | 7 ++
|
|
||||||
test/suites/api/test_memory_funcs.c | 7 ++
|
|
||||||
test/suites/api/test_number.c | 36 ++++++++
|
|
||||||
test/suites/api/test_object.c | 122 ++++++++++++++++++++++++++++
|
|
||||||
test/suites/api/test_pack.c | 10 ++-
|
|
||||||
test/suites/api/test_simple.c | 52 ++++++++++++
|
|
||||||
test/suites/api/test_sprintf.c | 12 +++
|
|
||||||
15 files changed, 444 insertions(+), 14 deletions(-)
|
|
||||||
create mode 100644 test/suites/api/test_chaos.c
|
|
||||||
|
|
||||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
|
||||||
index 16cf552..2f6cfec 100644
|
|
||||||
--- a/CMakeLists.txt
|
|
||||||
+++ b/CMakeLists.txt
|
|
||||||
@@ -487,6 +487,7 @@ if (NOT JANSSON_WITHOUT_TESTS)
|
|
||||||
set(api_tests
|
|
||||||
test_array
|
|
||||||
test_copy
|
|
||||||
+ test_chaos
|
|
||||||
test_dump
|
|
||||||
test_dump_callback
|
|
||||||
test_equal
|
|
||||||
diff --git a/src/load.c b/src/load.c
|
|
||||||
index deb36f3..25efe2e 100644
|
|
||||||
--- a/src/load.c
|
|
||||||
+++ b/src/load.c
|
|
||||||
@@ -829,10 +829,8 @@ static json_t *parse_value(lex_t *lex, size_t flags, json_error_t *error)
|
|
||||||
}
|
|
||||||
|
|
||||||
json = jsonp_stringn_nocheck_own(value, len);
|
|
||||||
- if(json) {
|
|
||||||
- lex->value.string.val = NULL;
|
|
||||||
- lex->value.string.len = 0;
|
|
||||||
- }
|
|
||||||
+ lex->value.string.val = NULL;
|
|
||||||
+ lex->value.string.len = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/src/pack_unpack.c b/src/pack_unpack.c
|
|
||||||
index 153f64d..19dbf93 100644
|
|
||||||
--- a/src/pack_unpack.c
|
|
||||||
+++ b/src/pack_unpack.c
|
|
||||||
@@ -159,7 +159,10 @@ static char *read_string(scanner_t *s, va_list *ap,
|
|
||||||
return (char *)str;
|
|
||||||
}
|
|
||||||
|
|
||||||
- strbuffer_init(&strbuff);
|
|
||||||
+ if(strbuffer_init(&strbuff)) {
|
|
||||||
+ set_error(s, "<internal>", json_error_out_of_memory, "Out of memory");
|
|
||||||
+ s->has_error = 1;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
while(1) {
|
|
||||||
str = va_arg(*ap, const char *);
|
|
||||||
diff --git a/src/value.c b/src/value.c
|
|
||||||
index b3b3141..29a978c 100644
|
|
||||||
--- a/src/value.c
|
|
||||||
+++ b/src/value.c
|
|
||||||
@@ -652,8 +652,7 @@ static json_t *string_create(const char *value, size_t len, int own)
|
|
||||||
|
|
||||||
string = jsonp_malloc(sizeof(json_string_t));
|
|
||||||
if(!string) {
|
|
||||||
- if(!own)
|
|
||||||
- jsonp_free(v);
|
|
||||||
+ jsonp_free(v);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
json_init(&string->json, JSON_STRING);
|
|
||||||
@@ -768,9 +767,6 @@ static int json_string_equal(const json_t *string1, const json_t *string2)
|
|
||||||
{
|
|
||||||
json_string_t *s1, *s2;
|
|
||||||
|
|
||||||
- if(!json_is_string(string1) || !json_is_string(string2))
|
|
||||||
- return 0;
|
|
||||||
-
|
|
||||||
s1 = json_to_string(string1);
|
|
||||||
s2 = json_to_string(string2);
|
|
||||||
return s1->length == s2->length && !memcmp(s1->value, s2->value, s1->length);
|
|
||||||
@@ -780,9 +776,6 @@ static json_t *json_string_copy(const json_t *string)
|
|
||||||
{
|
|
||||||
json_string_t *s;
|
|
||||||
|
|
||||||
- if(!json_is_string(string))
|
|
||||||
- return NULL;
|
|
||||||
-
|
|
||||||
s = json_to_string(string);
|
|
||||||
return json_stringn_nocheck(s->value, s->length);
|
|
||||||
}
|
|
||||||
--
|
|
||||||
2.17.1
|
|
||||||
|
|
@ -1,103 +0,0 @@
|
|||||||
From 15105b66b4df387037b670ac713584194ea10c2f Mon Sep 17 00:00:00 2001
|
|
||||||
From: Maxim Zhukov <mussitantesmortem@gmail.com>
|
|
||||||
Date: Mon, 12 Mar 2018 17:39:04 +0300
|
|
||||||
Subject: [PATCH 17/22] Fix error handling in json_pack
|
|
||||||
|
|
||||||
Changes to test/ removed.
|
|
||||||
|
|
||||||
Fixed a bug where the error message was not filled if an empty object
|
|
||||||
was passed to the json_pack.
|
|
||||||
|
|
||||||
Fixes #271
|
|
||||||
---
|
|
||||||
src/pack_unpack.c | 64 ++++++++++++++++++-------------------
|
|
||||||
test/suites/api/test_pack.c | 8 +++++
|
|
||||||
2 files changed, 40 insertions(+), 32 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/pack_unpack.c b/src/pack_unpack.c
|
|
||||||
index 4026fd9..6461c06 100644
|
|
||||||
--- a/src/pack_unpack.c
|
|
||||||
+++ b/src/pack_unpack.c
|
|
||||||
@@ -348,6 +348,36 @@ static json_t *pack_string(scanner_t *s, va_list *ap)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+static json_t *pack_object_inter(scanner_t *s, va_list *ap, int need_incref)
|
|
||||||
+{
|
|
||||||
+ json_t *json;
|
|
||||||
+ char ntoken;
|
|
||||||
+
|
|
||||||
+ next_token(s);
|
|
||||||
+ ntoken = token(s);
|
|
||||||
+
|
|
||||||
+ if (ntoken != '?')
|
|
||||||
+ prev_token(s);
|
|
||||||
+
|
|
||||||
+ json = va_arg(*ap, json_t *);
|
|
||||||
+
|
|
||||||
+ if (json)
|
|
||||||
+ return need_incref ? json_incref(json) : json;
|
|
||||||
+
|
|
||||||
+ switch (ntoken) {
|
|
||||||
+ case '?':
|
|
||||||
+ return json_null();
|
|
||||||
+ case '*':
|
|
||||||
+ return NULL;
|
|
||||||
+ default:
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ set_error(s, "<args>", json_error_null_value, "NULL object key");
|
|
||||||
+ s->has_error = 1;
|
|
||||||
+ return NULL;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static json_t *pack(scanner_t *s, va_list *ap)
|
|
||||||
{
|
|
||||||
switch(token(s)) {
|
|
||||||
@@ -376,40 +406,10 @@ static json_t *pack(scanner_t *s, va_list *ap)
|
|
||||||
return json_real(va_arg(*ap, double));
|
|
||||||
|
|
||||||
case 'O': /* a json_t object; increments refcount */
|
|
||||||
- {
|
|
||||||
- int nullable;
|
|
||||||
- json_t *json;
|
|
||||||
-
|
|
||||||
- next_token(s);
|
|
||||||
- nullable = token(s) == '?';
|
|
||||||
- if (!nullable)
|
|
||||||
- prev_token(s);
|
|
||||||
-
|
|
||||||
- json = va_arg(*ap, json_t *);
|
|
||||||
- if (!json && nullable) {
|
|
||||||
- return json_null();
|
|
||||||
- } else {
|
|
||||||
- return json_incref(json);
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
+ return pack_object_inter(s, ap, 1);
|
|
||||||
|
|
||||||
case 'o': /* a json_t object; doesn't increment refcount */
|
|
||||||
- {
|
|
||||||
- int nullable;
|
|
||||||
- json_t *json;
|
|
||||||
-
|
|
||||||
- next_token(s);
|
|
||||||
- nullable = token(s) == '?';
|
|
||||||
- if (!nullable)
|
|
||||||
- prev_token(s);
|
|
||||||
-
|
|
||||||
- json = va_arg(*ap, json_t *);
|
|
||||||
- if (!json && nullable) {
|
|
||||||
- return json_null();
|
|
||||||
- } else {
|
|
||||||
- return json;
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
+ return pack_object_inter(s, ap, 0);
|
|
||||||
|
|
||||||
default:
|
|
||||||
set_error(s, "<format>", json_error_invalid_format, "Unexpected format character '%c'",
|
|
||||||
--
|
|
||||||
2.17.1
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
|||||||
From aed855e6920923898b94a1b922fbace27a34ddf2 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Petri Lehtinen <petri@digip.org>
|
|
||||||
Date: Mon, 9 Jul 2018 22:26:35 +0300
|
|
||||||
Subject: [PATCH 22/29] Avoid invalid memory read in json_pack()
|
|
||||||
|
|
||||||
Initial patch by @bharjoc-bitdefender
|
|
||||||
|
|
||||||
Fixes #421
|
|
||||||
---
|
|
||||||
src/pack_unpack.c | 5 ++++-
|
|
||||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/pack_unpack.c b/src/pack_unpack.c
|
|
||||||
index 6461c06..b842772 100644
|
|
||||||
--- a/src/pack_unpack.c
|
|
||||||
+++ b/src/pack_unpack.c
|
|
||||||
@@ -75,6 +75,9 @@ static void next_token(scanner_t *s)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ if (!token(s) && !*s->fmt)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
t = s->fmt;
|
|
||||||
s->column++;
|
|
||||||
s->pos++;
|
|
||||||
@@ -97,7 +100,7 @@ static void next_token(scanner_t *s)
|
|
||||||
s->token.column = s->column;
|
|
||||||
s->token.pos = s->pos;
|
|
||||||
|
|
||||||
- t++;
|
|
||||||
+ if (*t) t++;
|
|
||||||
s->fmt = t;
|
|
||||||
}
|
|
||||||
|
|
||||||
--
|
|
||||||
2.17.1
|
|
||||||
|
|
@ -1,64 +0,0 @@
|
|||||||
From 66e4ee795d21a30118f8503c966e9f9ae87db315 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Xin Long <lucien.xin@gmail.com>
|
|
||||||
Date: Wed, 25 Jul 2018 17:39:33 +0800
|
|
||||||
Subject: [PATCH 25/29] Call va_end after va_copy in json_vsprintf
|
|
||||||
|
|
||||||
As said in man doc:
|
|
||||||
"Each invocation of va_copy() must be matched by a corresponding
|
|
||||||
invocation of va_end() in the same function."
|
|
||||||
|
|
||||||
va_copy may alloc memory in some system, it's necessay to free it by
|
|
||||||
va_end.
|
|
||||||
|
|
||||||
Fixes: efe6c7b3f2b3 ("Add json_sprintf and json_vsprintf")
|
|
||||||
Signed-off-by: Xin Long <lucien.xin@gmail.com>
|
|
||||||
---
|
|
||||||
src/value.c | 17 ++++++++++++-----
|
|
||||||
1 file changed, 12 insertions(+), 5 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/value.c b/src/value.c
|
|
||||||
index 29a978c..861dce8 100644
|
|
||||||
--- a/src/value.c
|
|
||||||
+++ b/src/value.c
|
|
||||||
@@ -781,26 +781,33 @@ static json_t *json_string_copy(const json_t *string)
|
|
||||||
}
|
|
||||||
|
|
||||||
json_t *json_vsprintf(const char *fmt, va_list ap) {
|
|
||||||
+ json_t *json = NULL;
|
|
||||||
int length;
|
|
||||||
char *buf;
|
|
||||||
va_list aq;
|
|
||||||
va_copy(aq, ap);
|
|
||||||
|
|
||||||
length = vsnprintf(NULL, 0, fmt, ap);
|
|
||||||
- if (length == 0)
|
|
||||||
- return json_string("");
|
|
||||||
+ if (length == 0) {
|
|
||||||
+ json = json_string("");
|
|
||||||
+ goto out;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
buf = jsonp_malloc(length + 1);
|
|
||||||
if (!buf)
|
|
||||||
- return NULL;
|
|
||||||
+ goto out;
|
|
||||||
|
|
||||||
vsnprintf(buf, length + 1, fmt, aq);
|
|
||||||
if (!utf8_check_string(buf, length)) {
|
|
||||||
jsonp_free(buf);
|
|
||||||
- return NULL;
|
|
||||||
+ goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
- return jsonp_stringn_nocheck_own(buf, length);
|
|
||||||
+ json = jsonp_stringn_nocheck_own(buf, length);
|
|
||||||
+
|
|
||||||
+out:
|
|
||||||
+ va_end(aq);
|
|
||||||
+ return json;
|
|
||||||
}
|
|
||||||
|
|
||||||
json_t *json_sprintf(const char *fmt, ...) {
|
|
||||||
--
|
|
||||||
2.17.1
|
|
||||||
|
|
@ -1,56 +0,0 @@
|
|||||||
From 020cc26b5cb147ae3569a3f7d314d3900b4bbc0b Mon Sep 17 00:00:00 2001
|
|
||||||
From: Petri Lehtinen <petri@digip.org>
|
|
||||||
Date: Sun, 12 Aug 2018 18:25:51 +0300
|
|
||||||
Subject: [PATCH 27/29] Rename a varialble that shadows another one
|
|
||||||
|
|
||||||
configure.ac changes are removed for bundled jansson.
|
|
||||||
|
|
||||||
Fixes #430
|
|
||||||
---
|
|
||||||
configure.ac | 2 +-
|
|
||||||
src/dump.c | 8 ++++----
|
|
||||||
2 files changed, 5 insertions(+), 5 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/dump.c b/src/dump.c
|
|
||||||
index 8e725c9..4a64aa4 100644
|
|
||||||
--- a/src/dump.c
|
|
||||||
+++ b/src/dump.c
|
|
||||||
@@ -306,7 +306,7 @@ static int do_dump(const json_t *json, size_t flags, int depth,
|
|
||||||
const char *separator;
|
|
||||||
int separator_length;
|
|
||||||
/* Space for "0x", double the sizeof a pointer for the hex and a terminator. */
|
|
||||||
- char key[2 + (sizeof(json) * 2) + 1];
|
|
||||||
+ char loop_key[2 + (sizeof(json) * 2) + 1];
|
|
||||||
|
|
||||||
if(flags & JSON_COMPACT) {
|
|
||||||
separator = ":";
|
|
||||||
@@ -318,7 +318,7 @@ static int do_dump(const json_t *json, size_t flags, int depth,
|
|
||||||
}
|
|
||||||
|
|
||||||
/* detect circular references */
|
|
||||||
- if (loop_check(parents, json, key, sizeof(key)))
|
|
||||||
+ if (loop_check(parents, json, loop_key, sizeof(loop_key)))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
iter = json_object_iter((json_t *)json);
|
|
||||||
@@ -326,7 +326,7 @@ static int do_dump(const json_t *json, size_t flags, int depth,
|
|
||||||
if(!embed && dump("{", 1, data))
|
|
||||||
return -1;
|
|
||||||
if(!iter) {
|
|
||||||
- hashtable_del(parents, key);
|
|
||||||
+ hashtable_del(parents, loop_key);
|
|
||||||
return embed ? 0 : dump("}", 1, data);
|
|
||||||
}
|
|
||||||
if(dump_indent(flags, depth + 1, 0, dump, data))
|
|
||||||
@@ -422,7 +422,7 @@ static int do_dump(const json_t *json, size_t flags, int depth,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- hashtable_del(parents, key);
|
|
||||||
+ hashtable_del(parents, loop_key);
|
|
||||||
return embed ? 0 : dump("}", 1, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
--
|
|
||||||
2.17.1
|
|
||||||
|
|
@ -1,217 +0,0 @@
|
|||||||
From 5df5fc5b13cac5212482d36e7f3a78951782cfb5 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Corey Farrell <git@cfware.com>
|
|
||||||
Date: Tue, 25 Sep 2018 14:31:56 -0400
|
|
||||||
Subject: [PATCH 29/30] json_pack: Improve handling of formats with '?' and
|
|
||||||
'*'.
|
|
||||||
|
|
||||||
Test updates have been removed for easier merging for bundled build.
|
|
||||||
|
|
||||||
When NULL is received for an optional argument we should not set an
|
|
||||||
error message as this would block later error messages. If NULL is
|
|
||||||
received for a non-optional string we should set has_error. Set
|
|
||||||
has_error for UTF-8 errors to ensure optional strings with UTF-8
|
|
||||||
errors are not replaced with json_null(). Use 'purpose' argument in
|
|
||||||
NULL error messages of read_string.
|
|
||||||
|
|
||||||
Add error handling and tests for invalid formats where '+', '#', or '%'
|
|
||||||
is used on an optional string 's?' or 's*'.
|
|
||||||
|
|
||||||
Fix NULL string error messages to use 'purpose'.
|
|
||||||
|
|
||||||
Refactor skipping of '*' token, this is now handled by read_string and
|
|
||||||
pack_object_inter. This allows invalid format strings such as 's*#' and
|
|
||||||
's*+' to produce error messages.
|
|
||||||
|
|
||||||
Fixes #437
|
|
||||||
---
|
|
||||||
src/pack_unpack.c | 74 +++++++++++++++++++++++--------------
|
|
||||||
test/suites/api/test_pack.c | 49 ++++++++++++++++++++++--
|
|
||||||
2 files changed, 93 insertions(+), 30 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/pack_unpack.c b/src/pack_unpack.c
|
|
||||||
index b842772..fc98df4 100644
|
|
||||||
--- a/src/pack_unpack.c
|
|
||||||
+++ b/src/pack_unpack.c
|
|
||||||
@@ -130,7 +130,7 @@ static json_t *pack(scanner_t *s, va_list *ap);
|
|
||||||
/* ours will be set to 1 if jsonp_free() must be called for the result
|
|
||||||
afterwards */
|
|
||||||
static char *read_string(scanner_t *s, va_list *ap,
|
|
||||||
- const char *purpose, size_t *out_len, int *ours)
|
|
||||||
+ const char *purpose, size_t *out_len, int *ours, int optional)
|
|
||||||
{
|
|
||||||
char t;
|
|
||||||
strbuffer_t strbuff;
|
|
||||||
@@ -147,7 +147,10 @@ static char *read_string(scanner_t *s, va_list *ap,
|
|
||||||
str = va_arg(*ap, const char *);
|
|
||||||
|
|
||||||
if(!str) {
|
|
||||||
- set_error(s, "<args>", json_error_null_value, "NULL string argument");
|
|
||||||
+ if (!optional) {
|
|
||||||
+ set_error(s, "<args>", json_error_null_value, "NULL %s", purpose);
|
|
||||||
+ s->has_error = 1;
|
|
||||||
+ }
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -155,11 +158,17 @@ static char *read_string(scanner_t *s, va_list *ap,
|
|
||||||
|
|
||||||
if(!utf8_check_string(str, length)) {
|
|
||||||
set_error(s, "<args>", json_error_invalid_utf8, "Invalid UTF-8 %s", purpose);
|
|
||||||
+ s->has_error = 1;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
*out_len = length;
|
|
||||||
return (char *)str;
|
|
||||||
+ } else if (optional) {
|
|
||||||
+ set_error(s, "<format>", json_error_invalid_format, "Cannot use '%c' on optional strings", t);
|
|
||||||
+ s->has_error = 1;
|
|
||||||
+
|
|
||||||
+ return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(strbuffer_init(&strbuff)) {
|
|
||||||
@@ -170,7 +179,7 @@ static char *read_string(scanner_t *s, va_list *ap,
|
|
||||||
while(1) {
|
|
||||||
str = va_arg(*ap, const char *);
|
|
||||||
if(!str) {
|
|
||||||
- set_error(s, "<args>", json_error_null_value, "NULL string argument");
|
|
||||||
+ set_error(s, "<args>", json_error_null_value, "NULL %s", purpose);
|
|
||||||
s->has_error = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -226,6 +235,7 @@ static json_t *pack_object(scanner_t *s, va_list *ap)
|
|
||||||
size_t len;
|
|
||||||
int ours;
|
|
||||||
json_t *value;
|
|
||||||
+ char valueOptional;
|
|
||||||
|
|
||||||
if(!token(s)) {
|
|
||||||
set_error(s, "<format>", json_error_invalid_format, "Unexpected end of format string");
|
|
||||||
@@ -237,20 +247,21 @@ static json_t *pack_object(scanner_t *s, va_list *ap)
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
- key = read_string(s, ap, "object key", &len, &ours);
|
|
||||||
- if (!key)
|
|
||||||
- s->has_error = 1;
|
|
||||||
+ key = read_string(s, ap, "object key", &len, &ours, 0);
|
|
||||||
|
|
||||||
next_token(s);
|
|
||||||
|
|
||||||
+ next_token(s);
|
|
||||||
+ valueOptional = token(s);
|
|
||||||
+ prev_token(s);
|
|
||||||
+
|
|
||||||
value = pack(s, ap);
|
|
||||||
if(!value) {
|
|
||||||
if(ours)
|
|
||||||
jsonp_free(key);
|
|
||||||
|
|
||||||
- if(strchr("soO", token(s)) && s->next_token.token == '*') {
|
|
||||||
- next_token(s);
|
|
||||||
- } else {
|
|
||||||
+ if(valueOptional != '*') {
|
|
||||||
+ set_error(s, "<args>", json_error_null_value, "NULL object value\n");
|
|
||||||
s->has_error = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -269,8 +280,6 @@ static json_t *pack_object(scanner_t *s, va_list *ap)
|
|
||||||
if(ours)
|
|
||||||
jsonp_free(key);
|
|
||||||
|
|
||||||
- if(strchr("soO", token(s)) && s->next_token.token == '*')
|
|
||||||
- next_token(s);
|
|
||||||
next_token(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -289,6 +298,7 @@ static json_t *pack_array(scanner_t *s, va_list *ap)
|
|
||||||
|
|
||||||
while(token(s) != ']') {
|
|
||||||
json_t *value;
|
|
||||||
+ char valueOptional;
|
|
||||||
|
|
||||||
if(!token(s)) {
|
|
||||||
set_error(s, "<format>", json_error_invalid_format, "Unexpected end of format string");
|
|
||||||
@@ -296,11 +306,13 @@ static json_t *pack_array(scanner_t *s, va_list *ap)
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ next_token(s);
|
|
||||||
+ valueOptional = token(s);
|
|
||||||
+ prev_token(s);
|
|
||||||
+
|
|
||||||
value = pack(s, ap);
|
|
||||||
if(!value) {
|
|
||||||
- if(strchr("soO", token(s)) && s->next_token.token == '*') {
|
|
||||||
- next_token(s);
|
|
||||||
- } else {
|
|
||||||
+ if(valueOptional != '*') {
|
|
||||||
s->has_error = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -316,8 +328,6 @@ static json_t *pack_array(scanner_t *s, va_list *ap)
|
|
||||||
s->has_error = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
- if(strchr("soO", token(s)) && s->next_token.token == '*')
|
|
||||||
- next_token(s);
|
|
||||||
next_token(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -332,23 +342,33 @@ error:
|
|
||||||
static json_t *pack_string(scanner_t *s, va_list *ap)
|
|
||||||
{
|
|
||||||
char *str;
|
|
||||||
+ char t;
|
|
||||||
size_t len;
|
|
||||||
int ours;
|
|
||||||
- int nullable;
|
|
||||||
+ int optional;
|
|
||||||
|
|
||||||
next_token(s);
|
|
||||||
- nullable = token(s) == '?';
|
|
||||||
- if (!nullable)
|
|
||||||
+ t = token(s);
|
|
||||||
+ optional = t == '?' || t == '*';
|
|
||||||
+ if (!optional)
|
|
||||||
prev_token(s);
|
|
||||||
|
|
||||||
- str = read_string(s, ap, "string", &len, &ours);
|
|
||||||
- if (!str) {
|
|
||||||
- return nullable ? json_null() : NULL;
|
|
||||||
- } else if (ours) {
|
|
||||||
- return jsonp_stringn_nocheck_own(str, len);
|
|
||||||
- } else {
|
|
||||||
- return json_stringn_nocheck(str, len);
|
|
||||||
+ str = read_string(s, ap, "string", &len, &ours, optional);
|
|
||||||
+
|
|
||||||
+ if (!str)
|
|
||||||
+ return t == '?' && !s->has_error ? json_null() : NULL;
|
|
||||||
+
|
|
||||||
+ if (s->has_error) {
|
|
||||||
+ if (!ours)
|
|
||||||
+ jsonp_free(str);
|
|
||||||
+
|
|
||||||
+ return NULL;
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+ if (ours)
|
|
||||||
+ return jsonp_stringn_nocheck_own(str, len);
|
|
||||||
+
|
|
||||||
+ return json_stringn_nocheck(str, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
static json_t *pack_object_inter(scanner_t *s, va_list *ap, int need_incref)
|
|
||||||
@@ -359,7 +379,7 @@ static json_t *pack_object_inter(scanner_t *s, va_list *ap, int need_incref)
|
|
||||||
next_token(s);
|
|
||||||
ntoken = token(s);
|
|
||||||
|
|
||||||
- if (ntoken != '?')
|
|
||||||
+ if (ntoken != '?' && ntoken != '*')
|
|
||||||
prev_token(s);
|
|
||||||
|
|
||||||
json = va_arg(*ap, json_t *);
|
|
||||||
--
|
|
||||||
2.17.1
|
|
||||||
|
|
@ -1,100 +0,0 @@
|
|||||||
From 8d659113d53d7ef60eae6a6e2c5b0ecfc89fc74b Mon Sep 17 00:00:00 2001
|
|
||||||
From: Corey Farrell <git@cfware.com>
|
|
||||||
Date: Tue, 25 Sep 2018 17:34:25 -0400
|
|
||||||
Subject: [PATCH 30/30] More work on json_pack error reporting.
|
|
||||||
|
|
||||||
Test updates have been removed for easier merging for bundled build.
|
|
||||||
|
|
||||||
* Remove errant line-feed from pack_object error message.
|
|
||||||
* Correct error message in pack_object_inter.
|
|
||||||
* Create pack_integer / pack_real to get the correct error messages on
|
|
||||||
failure when packing numeric values.
|
|
||||||
* Add tests for packing NAN and infinity directly, in an array and as
|
|
||||||
an object value.
|
|
||||||
---
|
|
||||||
src/pack_unpack.c | 46 +++++++++++++++++++++++++++----
|
|
||||||
test/suites/api/test_pack.c | 54 +++++++++++++++++++++++++++++++++++--
|
|
||||||
2 files changed, 93 insertions(+), 7 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/pack_unpack.c b/src/pack_unpack.c
|
|
||||||
index fc98df4..ec04bc3 100644
|
|
||||||
--- a/src/pack_unpack.c
|
|
||||||
+++ b/src/pack_unpack.c
|
|
||||||
@@ -261,7 +261,7 @@ static json_t *pack_object(scanner_t *s, va_list *ap)
|
|
||||||
jsonp_free(key);
|
|
||||||
|
|
||||||
if(valueOptional != '*') {
|
|
||||||
- set_error(s, "<args>", json_error_null_value, "NULL object value\n");
|
|
||||||
+ set_error(s, "<args>", json_error_null_value, "NULL object value");
|
|
||||||
s->has_error = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -396,11 +396,47 @@ static json_t *pack_object_inter(scanner_t *s, va_list *ap, int need_incref)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
- set_error(s, "<args>", json_error_null_value, "NULL object key");
|
|
||||||
+ set_error(s, "<args>", json_error_null_value, "NULL object");
|
|
||||||
s->has_error = 1;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static json_t *pack_integer(scanner_t *s, json_int_t value)
|
|
||||||
+{
|
|
||||||
+ json_t *json = json_integer(value);
|
|
||||||
+
|
|
||||||
+ if (!json) {
|
|
||||||
+ set_error(s, "<internal>", json_error_out_of_memory, "Out of memory");
|
|
||||||
+ s->has_error = 1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return json;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static json_t *pack_real(scanner_t *s, double value)
|
|
||||||
+{
|
|
||||||
+ /* Allocate without setting value so we can identify OOM error. */
|
|
||||||
+ json_t *json = json_real(0.0);
|
|
||||||
+
|
|
||||||
+ if (!json) {
|
|
||||||
+ set_error(s, "<internal>", json_error_out_of_memory, "Out of memory");
|
|
||||||
+ s->has_error = 1;
|
|
||||||
+
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (json_real_set(json, value)) {
|
|
||||||
+ json_decref(json);
|
|
||||||
+
|
|
||||||
+ set_error(s, "<args>", json_error_numeric_overflow, "Invalid floating point value");
|
|
||||||
+ s->has_error = 1;
|
|
||||||
+
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return json;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static json_t *pack(scanner_t *s, va_list *ap)
|
|
||||||
{
|
|
||||||
switch(token(s)) {
|
|
||||||
@@ -420,13 +456,13 @@ static json_t *pack(scanner_t *s, va_list *ap)
|
|
||||||
return va_arg(*ap, int) ? json_true() : json_false();
|
|
||||||
|
|
||||||
case 'i': /* integer from int */
|
|
||||||
- return json_integer(va_arg(*ap, int));
|
|
||||||
+ return pack_integer(s, va_arg(*ap, int));
|
|
||||||
|
|
||||||
case 'I': /* integer from json_int_t */
|
|
||||||
- return json_integer(va_arg(*ap, json_int_t));
|
|
||||||
+ return pack_integer(s, va_arg(*ap, json_int_t));
|
|
||||||
|
|
||||||
case 'f': /* real */
|
|
||||||
- return json_real(va_arg(*ap, double));
|
|
||||||
+ return pack_real(s, va_arg(*ap, double));
|
|
||||||
|
|
||||||
case 'O': /* a json_t object; increments refcount */
|
|
||||||
return pack_object_inter(s, ap, 1);
|
|
||||||
--
|
|
||||||
2.17.1
|
|
||||||
|
|
@ -1,58 +0,0 @@
|
|||||||
From e262ea5fcd789d20d5d20d5d6d9c7ec06e3c00fd Mon Sep 17 00:00:00 2001
|
|
||||||
From: Corey Farrell <git@cfware.com>
|
|
||||||
Date: Mon, 5 Nov 2018 16:43:10 -0500
|
|
||||||
Subject: [PATCH 35/35] Remove inappropriate jsonp_free which caused
|
|
||||||
segmentation fault.
|
|
||||||
|
|
||||||
pack_string should never free str on error. This wouldn't be a problem
|
|
||||||
except the check for `ours` was inverted. Just remove the check for
|
|
||||||
ours since the true condition is unreachable.
|
|
||||||
|
|
||||||
json_vpack_ex also had an error check for s.has_error. This can never
|
|
||||||
be true unless value is NULL.
|
|
||||||
|
|
||||||
Test changes removed for merging into Asterisk bundled copy.
|
|
||||||
|
|
||||||
Fixes #444
|
|
||||||
---
|
|
||||||
src/pack_unpack.c | 9 ++-------
|
|
||||||
test/suites/api/test_pack.c | 21 +++++++++++++++++++++
|
|
||||||
2 files changed, 23 insertions(+), 7 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/pack_unpack.c b/src/pack_unpack.c
|
|
||||||
index ec04bc3..3b99776 100644
|
|
||||||
--- a/src/pack_unpack.c
|
|
||||||
+++ b/src/pack_unpack.c
|
|
||||||
@@ -359,9 +359,7 @@ static json_t *pack_string(scanner_t *s, va_list *ap)
|
|
||||||
return t == '?' && !s->has_error ? json_null() : NULL;
|
|
||||||
|
|
||||||
if (s->has_error) {
|
|
||||||
- if (!ours)
|
|
||||||
- jsonp_free(str);
|
|
||||||
-
|
|
||||||
+ /* It's impossible to reach this point if ours != 0, do not free str. */
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -853,6 +851,7 @@ json_t *json_vpack_ex(json_error_t *error, size_t flags,
|
|
||||||
value = pack(&s, &ap_copy);
|
|
||||||
va_end(ap_copy);
|
|
||||||
|
|
||||||
+ /* This will cover all situations where s.has_error is true */
|
|
||||||
if(!value)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
@@ -862,10 +861,6 @@ json_t *json_vpack_ex(json_error_t *error, size_t flags,
|
|
||||||
set_error(&s, "<format>", json_error_invalid_format, "Garbage after format string");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
- if(s.has_error) {
|
|
||||||
- json_decref(value);
|
|
||||||
- return NULL;
|
|
||||||
- }
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
--
|
|
||||||
2.17.2
|
|
||||||
|
|
@ -0,0 +1,10 @@
|
|||||||
|
Patches should be added here once merged to the upstream jansson project at
|
||||||
|
https://github.com/akheron/jansson/. Patch filenames should be generated by
|
||||||
|
running 'git format-patch ${JANSSON_VERSION}' from the jansson repository, then
|
||||||
|
copying the required patches to this folder.
|
||||||
|
|
||||||
|
Any changes to configure.ac or Makefile.am must be stripped from the upstream
|
||||||
|
patches. The upstream project does not commit `autoreconf -i` output files
|
||||||
|
and we must ensure bundled jansson does not require autoconf or automake.
|
||||||
|
Changes to test files can also be stripped as the bundled builds do not run
|
||||||
|
jansson tests.
|
@ -1,2 +1,2 @@
|
|||||||
JANSSON_VERSION = 2.11
|
JANSSON_VERSION = 2.12
|
||||||
PJPROJECT_VERSION = 2.8
|
PJPROJECT_VERSION = 2.8
|
||||||
|
Loading…
Reference in new issue