Repository: neovim
Issue: cmdheight=0: NULL dereference in grid_del_lines()
Labels: has:backtrace,bug-crash,startup,messages

### Problem

I'm trying to setup some lua tests for a neovim plugin following [this](https://hiphish.github.io/blog/2024/01/29/testing-neovim-plugins-with-busted/).

This resulted in me running into a NULL pointer deref:

```
(gdb) bt
#0  0x00000000005d3cbb in grid_del_lines ()
#1  0x0000000000671cb0 in msg_scroll_up ()
#2  0x00000000006761ba in msg_start ()
#3  0x0000000000674ef4 in msg_attr_keep ()
#4  0x00000000006754e9 in emsg_multiline ()
#5  0x0000000000676dbd in semsg_multiline ()
#6  0x0000000000623eb0 in nlua_error ()
#7  0x000000000062ddcd in nlua_exec_file ()
#8  0x0000000000459a93 in main ()
(gdb) 
(gdb) x/i $pc
=> 0x5d3cbb <grid_del_lines+587>:       mov    (%rdx),%rdi
(gdb) i r
rax            0x0                 0
rbx            0x1                 1
rcx            0x1                 1
rdx            0x0                 0
rsi            0x0                 0
rdi            0x966a80            9857664
rbp            0x1                 0x1
rsp            0x7ffedab7b660      0x7ffedab7b660
r8             0x0                 0
r9             0x0                 0
r10            0x0                 0
r11            0x1                 1
r12            0x0                 0
r13            0x0                 0
r14            0xffffffff          4294967295
r15            0x966a80            9857664
rip            0x5d3cbb            0x5d3cbb <grid_del_lines+587>
(gdb) x/20i $pc-25
   0x5d3ca2 <grid_del_lines+562>:       pop    %rbp
   0x5d3ca3 <grid_del_lines+563>:       pop    %r14
   0x5d3ca5 <grid_del_lines+565>:       pop    %r15
   0x5d3ca7 <grid_del_lines+567>:       ret
   0x5d3ca8 <grid_del_lines+568>:       nopl   0x0(%rax,%rax,1)
   0x5d3cb0 <grid_del_lines+576>:       mov    0x20(%r15),%rsi
   0x5d3cb4 <grid_del_lines+580>:       movslq %r10d,%rdx
   0x5d3cb7 <grid_del_lines+583>:       lea    (%rsi,%rdx,8),%rdx
=> 0x5d3cbb <grid_del_lines+587>:       mov    (%rdx),%rdi
   0x5d3cbe <grid_del_lines+590>:       cmp    %r11d,%r14d
   0x5d3cc1 <grid_del_lines+593>:       jl     0x5d3ce9 <grid_del_lines+633>
   0x5d3cc3 <grid_del_lines+595>:       cmp    $0x1,%ebp
   0x5d3cc6 <grid_del_lines+598>:       jne    0x5d3fb0 <grid_del_lines+1344>
   0x5d3ccc <grid_del_lines+604>:       nopl   0x0(%rax)
   0x5d3cd0 <grid_del_lines+608>:       movslq %ebx,%rdx
   0x5d3cd3 <grid_del_lines+611>:       lea    (%rsi,%rdx,8),%rdx
   0x5d3cd7 <grid_del_lines+615>:       mov    (%rdx),%rcx
   0x5d3cda <grid_del_lines+618>:       mov    %rcx,(%rsi,%rax,8)
   0x5d3cde <grid_del_lines+622>:       movslq %ebx,%rax
   0x5d3ce1 <grid_del_lines+625>:       add    $0x1,%ebx
```

There has been at least 2 different cases where this function has had crashes in the past maybe #20316 and #10031, but they are both pre 0.10.0.

There is one other open issue #22278 that has `grid_del_lines` in the stacktrace, but is not the same issue as it's not the crashing function.

### Steps to reproduce

I'm running `busted --run unit` with the following setup:

```
❯ bat -p .busted
return {
    _all = {
        lua = './test/nvim-shim.sh'
    },
    unit = {
        ROOT = {'./test/unit/'},
    },
}
```

```
❯ bat -p ./test/nvim-shim.sh
#!/usr/bin/env bash
set -euo pipefail

export XDG_CONFIG_HOME='test/xdg/config/'
export XDG_STATE_HOME='test/xdg/local/state/'
export XDG_DATA_HOME='test/xdg/local/share/'

mkdir -p ${XDG_CONFIG_HOME} ${XDG_STATE_HOME} ${XDG_DATA_HOME}
mkdir -p ${XDG_DATA_HOME}/nvim/site/pack/testing/start || true
# XXX - Expects to be in cursorless.nvim, so we should force cd here
ln -sf "${PWD}" ${XDG_DATA_HOME}/nvim/site/pack/testing/start/cursorless.nvim

NVIM='nvim'
if type -a ${NVIM} | grep 'is an alias'; then
  NVIM=$(type -p nvim)
fi
# shellcheck disable=SC2068
echo $@
${NVIM} --cmd 'set loadplugins' -l $@
exit_code=$?
rm ${XDG_DATA_HOME}/nvim/site/pack/testing/start/cursorless.nvim 2>/dev/null || true

exit $exit_code
```

```
❯ bat -p test/unit/buffer_selection_spec.lua
describe("cursorless buffer selection", function()
  describe("Basic selection", function()
    before_each(function()
      local pos = vim.api.nvim_win_get_cursor(0)[2]
      local line = vim.api.nvim_get_current_line()
      local nline = line:sub(0, pos) .. "hello" .. line:sub(pos + 1)
      vim.api.nvim_set_current_line(nline)
    end)

    it("Can read visible lines", function()
      print("foo")
      assert.is_true(true)
    end)
  end)
end)
```

If I have `print("foo")` in the above `buffer_selection_spec.lua` file:

```
❯ busted --run unit
/nix/store/w1wjplk0znvid1y1kljz1a1nqm2dc24q-luajit2.1-busted-2.2.0-1/busted-2.2.0-1-rocks/busted/2.2.0-1/bin/busted --ignore-lua --run unit
./test/nvim-shim.sh: line 19: 1640715 Segmentation fault      (core dumped) ${NVIM} --cmd 'set loadplugins' -l $@
error: Recipe `test` failed on line 5 with exit code 1
```

If I comment out the print:

```
❯ busted --run unit
/nix/store/w1wjplk0znvid1y1kljz1a1nqm2dc24q-luajit2.1-busted-2.2.0-1/busted-2.2.0-1-rocks/busted/2.2.0-1/bin/busted --ignore-lua --run unit
●
1 success / 0 failures / 0 errors / 0 pending : 0.000675 seconds
```


### Expected behavior

Don't crash.

### Neovim version (nvim -v)

❯ /home/aa/.nix-profile/bin/nvim --version NVIM v0.10.0 Build type: Release LuaJIT 2.1.1693350652

### Vim (not Nvim) behaves the same?

don't know, not sure how to reproduce given my repro relies on lua test

### Operating system/version

nixos 24.05

### Terminal name/version

wezterm

### $TERM environment variable

xterm-256color

### Installation

nixpkgs