mirror of
https://github.com/neovim/neovim.git
synced 2026-07-12 04:19:45 +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:
|
// Always drop the topmost value:
|
||||||
//
|
//
|
||||||
// 1. When want_node != kENodeValue topmost item on stack is
|
// 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.
|
// needs not be finished again.
|
||||||
// 2. Otherwise it is pointing to NULL what nobody wants.
|
// 2. Otherwise it is pointing to NULL what nobody wants.
|
||||||
kv_drop(ast_stack, 1);
|
kv_drop(ast_stack, 1);
|
||||||
@@ -2417,6 +2417,7 @@ viml_pexpr_parse_valid_colon:
|
|||||||
cur_node->children = *top_node_p;
|
cur_node->children = *top_node_p;
|
||||||
}
|
}
|
||||||
*top_node_p = cur_node;
|
*top_node_p = cur_node;
|
||||||
|
new_top_node_p = top_node_p;
|
||||||
goto viml_pexpr_parse_bracket_closing_error;
|
goto viml_pexpr_parse_bracket_closing_error;
|
||||||
}
|
}
|
||||||
if (want_node == kENodeValue) {
|
if (want_node == kENodeValue) {
|
||||||
|
|||||||
@@ -3242,6 +3242,8 @@ describe('API', function()
|
|||||||
api.nvim_input(':<C-r>=')
|
api.nvim_input(':<C-r>=')
|
||||||
api.nvim_input('1bork/') -- #29648
|
api.nvim_input('1bork/') -- #29648
|
||||||
assert_alive()
|
assert_alive()
|
||||||
|
api.nvim_input('<C-u>];')
|
||||||
|
assert_alive()
|
||||||
api.nvim_parse_expression('a{b}', '', false)
|
api.nvim_parse_expression('a{b}', '', false)
|
||||||
assert_alive()
|
assert_alive()
|
||||||
end)
|
end)
|
||||||
|
|||||||
@@ -4755,6 +4755,38 @@ return function(itp, _check_parsing, hl, fmtn)
|
|||||||
hl('InvalidList', ']'),
|
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('[] []', {
|
check_parsing('[] []', {
|
||||||
-- 01234
|
-- 01234
|
||||||
ast = {
|
ast = {
|
||||||
|
|||||||
Reference in New Issue
Block a user