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

(cherry picked from commit a5e5ec8910)
This commit is contained in:
Sean Dewar
2026-01-16 00:53:55 +00:00
committed by github-actions[bot]
parent 92849eacff
commit 1db945b584
3 changed files with 36 additions and 1 deletions

View File

@@ -2408,7 +2408,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);
@@ -2419,6 +2419,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) {

View File

@@ -3245,6 +3245,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)

View File

@@ -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 = {