Merge "jansson-bundled: Add patches to improve json_pack error reporting." into 16
This commit is contained in:
commit
42b1e197c8
217
third-party/jansson/patches/0029-json_pack-Improve-handling-of-formats-with-and.patch
vendored
Normal file
217
third-party/jansson/patches/0029-json_pack-Improve-handling-of-formats-with-and.patch
vendored
Normal file
|
@ -0,0 +1,217 @@
|
|||
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
|
||||
|
100
third-party/jansson/patches/0030-More-work-on-json_pack-error-reporting.patch
vendored
Normal file
100
third-party/jansson/patches/0030-More-work-on-json_pack-error-reporting.patch
vendored
Normal file
|
@ -0,0 +1,100 @@
|
|||
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
|
||||
|
Loading…
Reference in New Issue