fix(eval): crash on some NULL ptr deref #39182

Crash on
```
let busy=$FOO
call prompt_setcallback(bufnr('%'), $FOO)
call chanclose(1, $FOO)
```

Co-authored-by: zeertzjq <zeertzjq@outlook.com>
(cherry picked from commit f0329092f7)
This commit is contained in:
phanium
2026-04-19 02:08:10 +08:00
committed by github-actions[bot]
parent 20c6edbc12
commit 1ebb9b16d2
3 changed files with 9 additions and 12 deletions
+4 -8
View File
@@ -795,10 +795,8 @@ void f_prompt_setcallback(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
return;
}
if (argvars[1].v_type != VAR_STRING || *argvars[1].vval.v_string != NUL) {
if (!callback_from_typval(&prompt_callback, &argvars[1])) {
return;
}
if (!callback_from_typval(&prompt_callback, &argvars[1])) {
return;
}
callback_free(&buf->b_prompt_callback);
@@ -818,10 +816,8 @@ void f_prompt_setinterrupt(typval_T *argvars, typval_T *rettv, EvalFuncData fptr
return;
}
if (argvars[1].v_type != VAR_STRING || *argvars[1].vval.v_string != NUL) {
if (!callback_from_typval(&interrupt_callback, &argvars[1])) {
return;
}
if (!callback_from_typval(&interrupt_callback, &argvars[1])) {
return;
}
callback_free(&buf->b_prompt_interrupt);
+1 -1
View File
@@ -578,7 +578,7 @@ static void f_chanclose(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
ChannelPart part = kChannelPartAll;
if (argvars[1].v_type == VAR_STRING) {
char *stream = argvars[1].vval.v_string;
const char *stream = tv_get_string(&argvars[1]);
if (!strcmp(stream, "stdin")) {
part = kChannelPartStdin;
} else if (!strcmp(stream, "stdout")) {
+4 -3
View File
@@ -3204,12 +3204,13 @@ static OptVal tv_to_optval(typval_T *tv, OptIndex opt_idx, const char *option, b
// So we need to check if it's actually a number.
if (!err && tv->v_type == VAR_STRING && n == 0) {
unsigned idx;
for (idx = 0; tv->vval.v_string[idx] == '0'; idx++) {}
if (tv->vval.v_string[idx] != NUL || idx == 0) {
for (idx = 0; tv->vval.v_string != NULL && tv->vval.v_string[idx] == '0'; idx++) {}
if (idx == 0 || tv->vval.v_string[idx] != NUL) {
// There's another character after zeros or the string is empty.
// In both cases, we are trying to set a num option using a string.
err = true;
semsg(_("E521: Number required: &%s = '%s'"), option, tv->vval.v_string);
semsg(_("E521: Number required: &%s = '%s'"), option,
tv->vval.v_string == NULL ? "" : tv->vval.v_string);
}
}
value = option_has_num ? NUMBER_OPTVAL((OptInt)n) : BOOLEAN_OPTVAL(TRISTATE_FROM_INT(n));