aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/eval/decode.c30
-rw-r--r--test/functional/eval/json_functions_spec.lua43
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',