diff options
| author | Johannes Altmanninger <aclopte@gmail.com> | 2024-02-17 22:32:05 +0100 |
|---|---|---|
| committer | Maxime Coste <mawww@kakoune.org> | 2024-02-18 10:14:17 +1100 |
| commit | 22b1d4ec4a3d2ae6a31f2395b43a209fc4d54653 (patch) | |
| tree | 0f80d3cfe024d52675d9fe9f8dbfe0d090b37cd8 /src/buffer_utils.cc | |
| parent | a85b81e08ad1b442119b94238e172a7c1b7ffae4 (diff) | |
Try to fix crash due to fifo read regression
I saw a crash when running
git log --oneline %arg{@}
hook -once buffer NormalIdle .* %{
execute-keys -draft \
%{gk!} \
%{git diff --quiet || echo "Unstaged changes";} \
%{git diff --quiet --cached || echo "Staged changes";} \
<ret>
}
Backtrace (I still have GDB attached):
#4 0x00006502c740b13f in Kakoune::operator- (rhs=..., lhs=...) at /home/johannes/git/kakoune/src/units.hh:33
33 { return RealType(lhs.m_value - rhs.m_value); }
(gdb) up
#5 Kakoune::Buffer::next (coord=..., this=0x6502c90d7ff0) at /home/johannes/git/kakoune/src/buffer.inl.hh:18
18 if (coord.column < m_lines[coord.line].length() - 1)
(gdb) up
#6 FifoWatcher::read_fifo (this=0x6502c90d9e48) at buffer_utils.cc:252
252 m_buffer.erase(pos, m_buffer.next(pos));
This was introduced in 582c3c56b (Do not add trailing newline to
non-scrolling fifo buffers, 2024-01-28).
The problem seems to be that we call "m_buffer.next()" on a position
that is past-end the buffer, so m_lines[coord.line] is out-of-bounds.
Fix it.
For some reason I have not managed to reproduce the crash, not even
with sanitize=address.
There might be another problem: m_had_trailing_newline is intentionally
uninitialized because it is supposed to be read only on the second
read() with a positive return value. Unfortunately I think it's
possible that e.g. a NormalIdle hook inserts some text before the
first positive read(). Then, this line
const bool is_first = pos == BufferCoord{0,0};
if (not m_scroll and (is_first or m_had_trailing_newline))
pos = m_buffer.next(pos);
will read uninitialized "m_had_trailing_newline". Fix that too, to
be on the safe side. Sadly I don't have a test for this one either
so I'm not sure.
Diffstat (limited to 'src/buffer_utils.cc')
| -rw-r--r-- | src/buffer_utils.cc | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/src/buffer_utils.cc b/src/buffer_utils.cc index be255e4a..996f6be5 100644 --- a/src/buffer_utils.cc +++ b/src/buffer_utils.cc @@ -246,7 +246,7 @@ Buffer* create_fifo_buffer(String name, int fd, Buffer::Flags flags, bool scroll if (is_first) m_buffer.erase({0,0}, m_buffer.next({0,0})); else if (not m_had_trailing_newline and have_trailing_newline) - m_buffer.erase(pos, m_buffer.next(pos)); + m_buffer.erase(m_buffer.prev(pos), pos); } m_had_trailing_newline = have_trailing_newline; } @@ -264,7 +264,7 @@ Buffer* create_fifo_buffer(String name, int fd, Buffer::Flags flags, bool scroll Buffer& m_buffer; bool m_scroll; - bool m_had_trailing_newline; + bool m_had_trailing_newline = false; }; buffer->values()[fifo_watcher_id] = Value(Meta::Type<FifoWatcher>{}, fd, *buffer, scroll); |
