diff options
author | ZyX <kp-pav@yandex.ru> | 2016-03-10 01:06:43 +0300 |
---|---|---|
committer | ZyX <kp-pav@yandex.ru> | 2016-04-18 02:48:20 +0300 |
commit | d06c2a1b1846a96a45625ad5472a235b2d249933 (patch) | |
tree | 963e2c8fc0186f15127be9f55310a2120f1226ff | |
parent | 2b0d46195be0792791171aa23d04ee7ba31c54c9 (diff) | |
download | rneovim-d06c2a1b1846a96a45625ad5472a235b2d249933.tar.gz rneovim-d06c2a1b1846a96a45625ad5472a235b2d249933.tar.bz2 rneovim-d06c2a1b1846a96a45625ad5472a235b2d249933.zip |
eval/decode: Do not overflow when parsing `-`
Also makes if’s less nested.
-rw-r--r-- | src/nvim/eval/decode.c | 38 | ||||
-rw-r--r-- | test/unit/eval/decode_spec.lua | 20 |
2 files changed, 35 insertions, 23 deletions
diff --git a/src/nvim/eval/decode.c b/src/nvim/eval/decode.c index 1303e288c3..2e9bf8fbac 100644 --- a/src/nvim/eval/decode.c +++ b/src/nvim/eval/decode.c @@ -503,6 +503,9 @@ static inline int parse_json_number(const char *const buf, const size_t buf_len, p++; } ints = p; + if (p >= e) { + goto parse_json_number_check; + } while (p < e && ascii_isdigit(*p)) { p++; } @@ -510,26 +513,31 @@ static inline int parse_json_number(const char *const buf, const size_t buf_len, emsgf(_("E474: Leading zeroes are not allowed: %.*s"), LENP(s, e)); goto parse_json_number_fail; } - if (p < e && p != ints && (*p == '.' || *p == 'e' || *p == 'E')) { - if (*p == '.') { + if (p >= e || p == ints) { + goto parse_json_number_check; + } + if (*p == '.') { + p++; + fracs = p; + while (p < e && ascii_isdigit(*p)) { p++; - fracs = p; - while (p < e && ascii_isdigit(*p)) { - p++; - } } - if (p < e && (*p == 'e' || *p == 'E')) { + if (p >= e || p == fracs) { + goto parse_json_number_check; + } + } + if (*p == 'e' || *p == 'E') { + p++; + exps_s = p; + if (p < e && (*p == '-' || *p == '+')) { + p++; + } + exps = p; + while (p < e && ascii_isdigit(*p)) { p++; - exps_s = p; - if (p < e && (*p == '-' || *p == '+')) { - p++; - } - exps = p; - while (p < e && ascii_isdigit(*p)) { - p++; - } } } +parse_json_number_check: if (p == ints) { emsgf(_("E474: Missing number after minus sign: %.*s"), LENP(s, e)); goto parse_json_number_fail; diff --git a/test/unit/eval/decode_spec.lua b/test/unit/eval/decode_spec.lua index 57fc5f7b94..44471c1877 100644 --- a/test/unit/eval/decode_spec.lua +++ b/test/unit/eval/decode_spec.lua @@ -76,15 +76,15 @@ describe('json_decode_string()', function() eq(decode.VAR_UNKNOWN, rettv.v_type) end) - it('does not overflow in error messages', function() - local check_failure = function(s, len, msg) - local rettv = ffi.new('typval_T', {v_type=decode.VAR_UNKNOWN}) - eq(0, decode.json_decode_string(s, len, rettv)) - eq(decode.VAR_UNKNOWN, rettv.v_type) - neq(nil, decode.last_msg_hist) - eq(msg, ffi.string(decode.last_msg_hist.msg)) - end + local check_failure = function(s, len, msg) local rettv = ffi.new('typval_T', {v_type=decode.VAR_UNKNOWN}) + eq(0, decode.json_decode_string(s, len, rettv)) + eq(decode.VAR_UNKNOWN, rettv.v_type) + neq(nil, decode.last_msg_hist) + eq(msg, ffi.string(decode.last_msg_hist.msg)) + end + + it('does not overflow in error messages', function() check_failure(']test', 1, 'E474: No container to close: ]') check_failure('[}test', 2, 'E474: Closing list with curly bracket: }') check_failure('{]test', 2, @@ -129,6 +129,10 @@ describe('json_decode_string()', function() check_failure('[1test', 2, 'E474: Unexpected end of input: [1') end) + it('does not overflow with `-`', function() + check_failure('-0', 1, 'E474: Missing number after minus sign: -') + end) + it('does not overflow and crash when running with `"`', function() local rettv = ffi.new('typval_T', {v_type=decode.VAR_UNKNOWN}) decode.emsg_silent = 1 |