From 3aa3501aa6d93e96653eb8e8c3662f724d3090ce Mon Sep 17 00:00:00 2001 From: Randy Palamar Date: Tue, 16 Dec 2025 10:56:01 -0700 Subject: text-iterator: fix one byte over-read in codepoint iterator Reported by @kyx0r here: https://github.com/kyx0r/nextvi/issues/189#issuecomment-3650406932 The crash is relatively hard to reproduce as it relies on there being no padding after the end of the memory allocation. This can only happen if the text size is an exact multiple of the system page size. In the linked backtrace it->start = 0x7ffff0e00000 and it->end = 0x7ffff7200000 (page size was likely 4K or 0x1000) so it->end, which is one past the last byte of the text, was pointing to an entirely different page. Dereferencing it can cause a segfault. If it doesn't segfault it is still incorrect to read beyond the end of the text even if it happens to work due to padding. The underlying text_iterator_byte_{next,prev}() functions were already handling this correctly. The fix is to not throw away their work. --- text-iterator.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/text-iterator.c b/text-iterator.c index b61c609..e264781 100644 --- a/text-iterator.c +++ b/text-iterator.c @@ -108,10 +108,10 @@ bool text_iterator_byte_find_next(Iterator *it, char b) { } bool text_iterator_codepoint_next(Iterator *it, char *c) { - while (text_iterator_byte_next(it, NULL)) { - if (ISUTF8(*it->text)) { - if (c) - *c = *it->text; + char test_byte; + while (text_iterator_byte_next(it, &test_byte)) { + if (ISUTF8(test_byte)) { + if (c) *c = test_byte; return true; } } @@ -119,10 +119,10 @@ bool text_iterator_codepoint_next(Iterator *it, char *c) { } bool text_iterator_codepoint_prev(Iterator *it, char *c) { - while (text_iterator_byte_prev(it, NULL)) { - if (ISUTF8(*it->text)) { - if (c) - *c = *it->text; + char test_byte; + while (text_iterator_byte_prev(it, &test_byte)) { + if (ISUTF8(test_byte)) { + if (c) *c = test_byte; return true; } } -- cgit v1.2.3