From 24b92291d5233748a73a3278d77497b78c35f061 Mon Sep 17 00:00:00 2001 From: Corey Farrell <git@cfware.com> Date: Fri, 28 Sep 2018 15:45:36 -0400 Subject: [PATCH] jansson-bundled: Add patches to improve json_pack error reporting. Change-Id: I045e420d5e73e60639079246e810da6ae21ae22b --- ...Improve-handling-of-formats-with-and.patch | 217 ++++++++++++++++++ ...re-work-on-json_pack-error-reporting.patch | 100 ++++++++ 2 files changed, 317 insertions(+) create mode 100644 third-party/jansson/patches/0029-json_pack-Improve-handling-of-formats-with-and.patch create mode 100644 third-party/jansson/patches/0030-More-work-on-json_pack-error-reporting.patch diff --git a/third-party/jansson/patches/0029-json_pack-Improve-handling-of-formats-with-and.patch b/third-party/jansson/patches/0029-json_pack-Improve-handling-of-formats-with-and.patch new file mode 100644 index 0000000000..fe86db868f --- /dev/null +++ b/third-party/jansson/patches/0029-json_pack-Improve-handling-of-formats-with-and.patch @@ -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 + diff --git a/third-party/jansson/patches/0030-More-work-on-json_pack-error-reporting.patch b/third-party/jansson/patches/0030-More-work-on-json_pack-error-reporting.patch new file mode 100644 index 0000000000..debb2f5f67 --- /dev/null +++ b/third-party/jansson/patches/0030-More-work-on-json_pack-error-reporting.patch @@ -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 + -- GitLab