]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
pg: fix out-of-bounds access past wbuf on a trailing tab
authorlogical-misha <220645577+logical-misha@users.noreply.github.com>
Tue, 21 Jul 2026 04:55:43 +0000 (04:55 +0000)
committerlogical-misha <220645577+logical-misha@users.noreply.github.com>
Tue, 21 Jul 2026 04:55:43 +0000 (04:55 +0000)
endline_for_mb() and its single-byte twin endline() advance the scan
pointer twice when the last character of a buffer-filling line is a tab
(once in the tab branch, once via the shared *++p) with no terminator
re-check in between. A full line (wl == READBUF-1) ending in a tab makes
*++p read wbuf[READBUF] and the following *end = L'\0' write it -- one
element past the wbuf[READBUF] array.

Re-check for the terminator before the second advance.

Closes #4495

Signed-off-by: logical-misha <220645577+logical-misha@users.noreply.github.com>
text-utils/pg.c

index 2e3a03981c0385379cebc45eefc62e7cc7181dbb..29a2bb9830edfbf62b4e0fdc9e1036c3805791b6 100644 (file)
@@ -444,7 +444,7 @@ static char *endline_for_mb(unsigned col, char *s)
                                 * Assume the terminal will print the
                                 * entire character onto the next row. */
                                p--;
-                       if (*++p == L'\n')
+                       if (*p != L'\0' && *++p == L'\n')
                                p++;
                        end = p;
                        goto ended;
@@ -499,7 +499,7 @@ static char *endline(unsigned col, char *s)
                if (pos > col) {
                        if (*s == '\t')
                                s++;
-                       if (*++s == '\n')
+                       if (*s != '\0' && *++s == '\n')
                                s++;
                        t = s;
                        goto cend;