diff options
-rw-r--r-- | src/nvim/eval/decode.c | 30 | ||||
-rw-r--r-- | test/functional/eval/json_functions_spec.lua | 43 |
2 files changed, 46 insertions, 27 deletions
diff --git a/src/nvim/eval/decode.c b/src/nvim/eval/decode.c index 604b758344..75c88e308b 100644 --- a/src/nvim/eval/decode.c +++ b/src/nvim/eval/decode.c @@ -608,11 +608,13 @@ json_decode_string_cycle_start: while (p < e && ascii_isdigit(*p)) { p++; } - if (p < e && *p == '.') { - p++; - fracs = p; - while (p < e && ascii_isdigit(*p)) { + if (p < e && p != ints && (*p == '.' || *p == 'e' || *p == 'E')) { + if (*p == '.') { p++; + fracs = p; + while (p < e && ascii_isdigit(*p)) { + p++; + } } if (p < e && (*p == 'e' || *p == 'E')) { p++; @@ -628,7 +630,7 @@ json_decode_string_cycle_start: if (p == ints) { emsgf(_("E474: Missing number after minus sign: %.*s"), LENP(s, e)); goto json_decode_string_fail; - } else if (p == fracs) { + } else if (p == fracs || exps == fracs + 1) { emsgf(_("E474: Missing number after decimal dot: %.*s"), LENP(s, e)); goto json_decode_string_fail; } else if (p == exps) { @@ -639,14 +641,26 @@ json_decode_string_cycle_start: .v_type = VAR_NUMBER, .v_lock = VAR_UNLOCKED, }; - if (fracs) { + const size_t exp_num_len = (size_t) (p - s); + if (fracs || exps) { // Convert floating-point number - (void) string2float(s, &tv.vval.v_float); + const size_t num_len = string2float(s, &tv.vval.v_float); + if (exp_num_len != num_len) { + emsgf(_("E685: internal error: while converting number \"%.*s\" " + "to float string2float consumed %zu bytes in place of %zu"), + (int) exp_num_len, s, num_len, exp_num_len); + } tv.v_type = VAR_FLOAT; } else { // Convert integer long nr; - vim_str2nr((char_u *) s, NULL, NULL, 0, &nr, NULL, (int) (p - s)); + int num_len; + vim_str2nr((char_u *) s, NULL, &num_len, 0, &nr, NULL, (int) (p - s)); + if ((int) exp_num_len != num_len) { + emsgf(_("E685: internal error: while converting number \"%.*s\" " + "to float vim_str2nr consumed %i bytes in place of %zu"), + (int) exp_num_len, s, num_len, exp_num_len); + } tv.vval.v_number = (varnumber_T) nr; } POP(tv, false); diff --git a/test/functional/eval/json_functions_spec.lua b/test/functional/eval/json_functions_spec.lua index 6379e7fed8..0140ad79aa 100644 --- a/test/functional/eval/json_functions_spec.lua +++ b/test/functional/eval/json_functions_spec.lua @@ -121,19 +121,32 @@ describe('json_decode() function', function() eq(-100000, funcs.json_decode(' -100000 ')) end) - it('fails to parse +numbers', function() + it('fails to parse +numbers and .number', function() eq('Vim(call):E474: Unidentified byte: +1000', exc_exec('call json_decode("+1000")')) + eq('Vim(call):E474: Unidentified byte: .1000', + exc_exec('call json_decode(".1000")')) end) - it('fails to parse negative numbers with space after -', function() - eq('Vim(call):E474: Missing number after minus sign: - 1000', - exc_exec('call json_decode("- 1000")')) - end) - - it('fails to parse -', function() + it('fails to parse incomplete numbers', function() + eq('Vim(call):E474: Missing number after minus sign: -.1', + exc_exec('call json_decode("-.1")')) eq('Vim(call):E474: Missing number after minus sign: -', exc_exec('call json_decode("-")')) + eq('Vim(call):E474: Missing number after decimal dot: -1.', + exc_exec('call json_decode("-1.")')) + eq('Vim(call):E474: Missing number after decimal dot: 0.', + exc_exec('call json_decode("0.")')) + eq('Vim(call):E474: Missing exponent: 0.0e', + exc_exec('call json_decode("0.0e")')) + eq('Vim(call):E474: Missing exponent: 0.0e+', + exc_exec('call json_decode("0.0e+")')) + eq('Vim(call):E474: Missing exponent: 0.0e-', + exc_exec('call json_decode("0.0e-")')) + eq('Vim(call):E474: Missing exponent: 0.0e-', + exc_exec('call json_decode("0.0e-")')) + eq('Vim(call):E474: Missing number after decimal dot: 1.e5', + exc_exec('call json_decode("1.e5")')) end) it('parses floating-point numbers', function() @@ -145,20 +158,12 @@ describe('json_decode() function', function() eq(100000.5e50, funcs.json_decode('100000.5e+50')) eq(-100000.5e-50, funcs.json_decode('-100000.5e-50')) eq(100000.5e-50, funcs.json_decode('100000.5e-50')) + eq(100000e-50, funcs.json_decode('100000e-50')) end) - it('fails to parse incomplete floating-point numbers', function() - eq('Vim(call):E474: Missing number after decimal dot: 0.', - exc_exec('call json_decode("0.")')) - eq('Vim(call):E474: Missing exponent: 0.0e', - exc_exec('call json_decode("0.0e")')) - eq('Vim(call):E474: Missing exponent: 0.0e+', - exc_exec('call json_decode("0.0e+")')) - eq('Vim(call):E474: Missing exponent: 0.0e-', - exc_exec('call json_decode("0.0e-")')) - end) - - it('fails to parse floating-point numbers with spaces inside', function() + it('fails to parse numbers with spaces inside', function() + eq('Vim(call):E474: Missing number after minus sign: - 1000', + exc_exec('call json_decode("- 1000")')) eq('Vim(call):E474: Missing number after decimal dot: 0. ', exc_exec('call json_decode("0. ")')) eq('Vim(call):E474: Missing number after decimal dot: 0. 0', |