From 60b1ac1dcc697b562ea8acee9d80c7701659cbcb Mon Sep 17 00:00:00 2001 From: Thalia Archibald Date: Thu, 31 Oct 2024 01:36:33 -0700 Subject: [PATCH 1/2] Handle input errors for --indent Handle malformed and overflowing arguments. Also, forbid leading and trailing spaces to match the behavior of tonumber from commit ce0e788 (improve tonumber/0 performance by parsing input as number literal, 2024-03-02). --- src/main.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main.c b/src/main.c index 372342c94c..2a4c32c410 100644 --- a/src/main.c +++ b/src/main.c @@ -431,12 +431,15 @@ int main(int argc, char* argv[]) { fprintf(stderr, "%s: --indent takes one parameter\n", progname); die(); } - dumpopts &= ~(JV_PRINT_TAB | JV_PRINT_INDENT_FLAGS(7)); - int indent = atoi(argv[i+1]); - if (indent < -1 || indent > 7) { + char* end = NULL; + errno = 0; + long indent = strtol(argv[i+1], &end, 10); + if (errno || indent < -1 || indent > 7 || + isspace(*argv[i+1]) || end == NULL || *end) { fprintf(stderr, "%s: --indent takes a number between -1 and 7\n", progname); die(); } + dumpopts &= ~(JV_PRINT_TAB | JV_PRINT_INDENT_FLAGS(7)); dumpopts |= JV_PRINT_INDENT_FLAGS(indent); i++; } else if (isoption(&text, 0, "seq", is_short)) { From f1bfe95f9e21749adafd1c9e8eab6f730746748a Mon Sep 17 00:00:00 2001 From: Thalia Archibald Date: Fri, 1 Nov 2024 18:13:44 -0700 Subject: [PATCH 2/2] Do not skip leading whitespace in jvp_strtod `jvp_strtod` skips leading whitespace, but its decnum counterpart `decNumberFromString` (called within `jv_number_with_literal`) does not. Those two are called interchangeably, so it leads to inconsistent behavior depending on whether the decnum feature is enabled. Additionally, `classify`, used in the token scanner, only considers [ \t\n\r] to be whitespace, but `jvp_strtod` consumes the larger set [ \t\n\v\f\r], so those extra characters are considered literals. Changing this deviates from the behavior of `strdod` from and is technically a breaking API change, since it is a public symbol. --- src/jv_dtoa.c | 14 +++----------- tests/jq.test | 4 ++-- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/src/jv_dtoa.c b/src/jv_dtoa.c index 175e82608f..9f8df4c6be 100644 --- a/src/jv_dtoa.c +++ b/src/jv_dtoa.c @@ -2368,29 +2368,21 @@ jvp_strtod sign = nz0 = nz1 = nz = bc.dplen = bc.uflchk = 0; dval(&rv) = 0.; - for(s = s00;;s++) switch(*s) { + switch(*(s = s00)) { case '-': sign = 1; /* no break */ JQ_FALLTHROUGH; case '+': if (*++s) - goto break2; + break; /* no break */ JQ_FALLTHROUGH; case 0: goto ret0; - case '\t': - case '\n': - case '\v': - case '\f': - case '\r': - case ' ': - continue; default: - goto break2; + break; } - break2: if (*s == '0') { #ifndef NO_HEX_FP /*{*/ switch(s[1]) { diff --git a/tests/jq.test b/tests/jq.test index 404994e268..d129b9a396 100644 --- a/tests/jq.test +++ b/tests/jq.test @@ -2084,8 +2084,8 @@ null 2 .[] |= try tonumber -["1", "2a", "3", " 4 ", "5.67", ".89", "-876", "+5.43", 21] -[1, 3, 5.67, 0.89, -876, 5.43, 21] +["1", "2a", "3", " 4", "5 ", "6.7", ".89", "-876", "+5.43", 21] +[1, 3, 6.7, 0.89, -876, 5.43, 21] # Also 1859, but from 2073 any(keys[]|tostring?;true)