mirror of
https://github.com/neovim/neovim.git
synced 2026-03-31 21:02:11 +00:00
fix(api): parse_expression crash with unopened ] and node
Problem: nvim_parse_expression null pointer dereference with unmatched ] followed by a node. Solution: if ast_stack was empty, set new_top_node_p to top of the stack after pushing the list literal node; similar to what's done for curlies. This bug was originally found by a Matrix user, but I couldn't remember how to trigger it... Ran into the other crash while finding a repro. :P
This commit is contained in:
@@ -2406,7 +2406,7 @@ viml_pexpr_parse_valid_colon:
|
||||
// Always drop the topmost value:
|
||||
//
|
||||
// 1. When want_node != kENodeValue topmost item on stack is
|
||||
// a *finished* left operand, which may as well be "{@a}" which
|
||||
// a *finished* left operand, which may as well be "[@a]" which
|
||||
// needs not be finished again.
|
||||
// 2. Otherwise it is pointing to NULL what nobody wants.
|
||||
kv_drop(ast_stack, 1);
|
||||
@@ -2417,6 +2417,7 @@ viml_pexpr_parse_valid_colon:
|
||||
cur_node->children = *top_node_p;
|
||||
}
|
||||
*top_node_p = cur_node;
|
||||
new_top_node_p = top_node_p;
|
||||
goto viml_pexpr_parse_bracket_closing_error;
|
||||
}
|
||||
if (want_node == kENodeValue) {
|
||||
|
||||
@@ -3242,6 +3242,8 @@ describe('API', function()
|
||||
api.nvim_input(':<C-r>=')
|
||||
api.nvim_input('1bork/') -- #29648
|
||||
assert_alive()
|
||||
api.nvim_input('<C-u>];')
|
||||
assert_alive()
|
||||
api.nvim_parse_expression('a{b}', '', false)
|
||||
assert_alive()
|
||||
end)
|
||||
|
||||
@@ -4755,6 +4755,38 @@ return function(itp, _check_parsing, hl, fmtn)
|
||||
hl('InvalidList', ']'),
|
||||
})
|
||||
|
||||
check_parsing(']a', {
|
||||
-- 01
|
||||
ast = {
|
||||
{
|
||||
'OpMissing:0:1:',
|
||||
children = {
|
||||
'ListLiteral:0:0:',
|
||||
'PlainIdentifier(scope=0,ident=a):0:1:a',
|
||||
},
|
||||
},
|
||||
},
|
||||
err = {
|
||||
arg = ']a',
|
||||
msg = 'E15: Unexpected closing figure brace: %.*s',
|
||||
},
|
||||
}, {
|
||||
hl('InvalidList', ']'),
|
||||
hl('InvalidIdentifierName', 'a'),
|
||||
}, {
|
||||
[1] = {
|
||||
ast = {
|
||||
len = 1,
|
||||
ast = {
|
||||
'ListLiteral:0:0:',
|
||||
},
|
||||
},
|
||||
hl_fs = {
|
||||
[2] = REMOVE_THIS,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
check_parsing('[] []', {
|
||||
-- 01234
|
||||
ast = {
|
||||
|
||||
Reference in New Issue
Block a user