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', | 
