mirror of
https://github.com/neovim/neovim.git
synced 2025-09-18 17:28:23 +00:00
eval/decode: Do not overflow when parsing -
Also makes if’s less nested.
This commit is contained in:
@@ -503,6 +503,9 @@ static inline int parse_json_number(const char *const buf, const size_t buf_len,
|
|||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
ints = p;
|
ints = p;
|
||||||
|
if (p >= e) {
|
||||||
|
goto parse_json_number_check;
|
||||||
|
}
|
||||||
while (p < e && ascii_isdigit(*p)) {
|
while (p < e && ascii_isdigit(*p)) {
|
||||||
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));
|
emsgf(_("E474: Leading zeroes are not allowed: %.*s"), LENP(s, e));
|
||||||
goto parse_json_number_fail;
|
goto parse_json_number_fail;
|
||||||
}
|
}
|
||||||
if (p < e && p != ints && (*p == '.' || *p == 'e' || *p == 'E')) {
|
if (p >= e || p == ints) {
|
||||||
if (*p == '.') {
|
goto parse_json_number_check;
|
||||||
|
}
|
||||||
|
if (*p == '.') {
|
||||||
|
p++;
|
||||||
|
fracs = p;
|
||||||
|
while (p < e && ascii_isdigit(*p)) {
|
||||||
p++;
|
p++;
|
||||||
fracs = p;
|
|
||||||
while (p < e && ascii_isdigit(*p)) {
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (p < e && (*p == 'e' || *p == 'E')) {
|
if (p >= e || p == fracs) {
|
||||||
p++;
|
goto parse_json_number_check;
|
||||||
exps_s = p;
|
|
||||||
if (p < e && (*p == '-' || *p == '+')) {
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
exps = p;
|
|
||||||
while (p < e && ascii_isdigit(*p)) {
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (*p == 'e' || *p == 'E') {
|
||||||
|
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) {
|
if (p == ints) {
|
||||||
emsgf(_("E474: Missing number after minus sign: %.*s"), LENP(s, e));
|
emsgf(_("E474: Missing number after minus sign: %.*s"), LENP(s, e));
|
||||||
goto parse_json_number_fail;
|
goto parse_json_number_fail;
|
||||||
|
@@ -76,15 +76,15 @@ describe('json_decode_string()', function()
|
|||||||
eq(decode.VAR_UNKNOWN, rettv.v_type)
|
eq(decode.VAR_UNKNOWN, rettv.v_type)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('does not overflow in error messages', function()
|
local check_failure = function(s, len, msg)
|
||||||
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 rettv = ffi.new('typval_T', {v_type=decode.VAR_UNKNOWN})
|
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', 1, 'E474: No container to close: ]')
|
||||||
check_failure('[}test', 2, 'E474: Closing list with curly bracket: }')
|
check_failure('[}test', 2, 'E474: Closing list with curly bracket: }')
|
||||||
check_failure('{]test', 2,
|
check_failure('{]test', 2,
|
||||||
@@ -129,6 +129,10 @@ describe('json_decode_string()', function()
|
|||||||
check_failure('[1test', 2, 'E474: Unexpected end of input: [1')
|
check_failure('[1test', 2, 'E474: Unexpected end of input: [1')
|
||||||
end)
|
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()
|
it('does not overflow and crash when running with `"`', function()
|
||||||
local rettv = ffi.new('typval_T', {v_type=decode.VAR_UNKNOWN})
|
local rettv = ffi.new('typval_T', {v_type=decode.VAR_UNKNOWN})
|
||||||
decode.emsg_silent = 1
|
decode.emsg_silent = 1
|
||||||
|
Reference in New Issue
Block a user