From: Christian Brabandt Date: Tue, 16 Jun 2026 19:26:00 +0000 (+0000) Subject: patch 9.2.0658: xxd: signed integer overflow in huntype() X-Git-Tag: v9.2.0658^0 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=24bf0b60e901b11a37d877cd5947849c18e1a602;p=thirdparty%2Fvim.git patch 9.2.0658: xxd: signed integer overflow in huntype() Problem: malformed revert input with an overlong address column causes signed integer overflow (UB) in huntype(). Solution: perform the offset/bit shifts through unsigned types related: neovim/neovim#40246 Supported by AI Co-Authored-by: Justin M. Keyes Signed-off-by: Christian Brabandt --- diff --git a/src/testdir/test_xxd.vim b/src/testdir/test_xxd.vim index fd23d38e1a..aca1c4f2fe 100644 --- a/src/testdir/test_xxd.vim +++ b/src/testdir/test_xxd.vim @@ -838,4 +838,17 @@ func Test_xxd_color_term_unset() call delete(outfile) endfunc +func Test_xxd_reverse_long_input() + " triggered UB in huntype() + let input = 'Xxd_reverse_input' + call writefile([repeat('1', 515)], input, 'D') + + " When this triggers undefined behaviour, there will be a warning output + " from the system() command + let out = system(s:xxd_cmd . ' -r ' . input) + call assert_equal('', out) + let out = system(s:xxd_cmd . ' -b -r ' . input) + call assert_equal('', out) +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/version.c b/src/version.c index fef84f283e..1dc1267b27 100644 --- a/src/version.c +++ b/src/version.c @@ -759,6 +759,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 658, /**/ 657, /**/ diff --git a/src/xxd/xxd.c b/src/xxd/xxd.c index 323d5a3982..9b1ca6ea55 100644 --- a/src/xxd/xxd.c +++ b/src/xxd/xxd.c @@ -76,6 +76,7 @@ * 25.03.2026 Fix color output issues * 26.04.2026 Use unsigned long for printing offsets * 31.05.2026 Colorize binary output + * 15.06.2026 Fix UB in huntype() * * (c) 1990-1998 by Juergen Weigert (jnweiger@gmail.com) * @@ -156,7 +157,7 @@ extern void perror __P((char *)); # endif #endif -char version[] = "xxd 2026-05-31 by Juergen Weigert et al."; +char version[] = "xxd 2026-06-16 by Juergen Weigert et al."; #ifdef WIN32 char osver[] = " (Win32)"; #else @@ -445,7 +446,8 @@ huntype( bt = parse_bin_digit(c); if (bt != -1) { - b = ((b << 1) | bt); + /* shift via unsigned to avoid signed overflow on bad input */ + b = (int)(((unsigned)b << 1) | (unsigned)bt); ++bcnt; } } @@ -461,7 +463,7 @@ huntype( p = 0; continue; } - want_off = (want_off << 4) | n1; + want_off = (long)(((unsigned long)want_off << 4) | (unsigned)n1); } else /* HEX_BITS */ { @@ -471,7 +473,7 @@ huntype( bcnt = 0; continue; } - want_off = (want_off << 4) | n1; + want_off = (long)(((unsigned long)want_off << 4) | (unsigned)n1); } continue; } @@ -607,9 +609,7 @@ xxdline(FILE *fp, char *l, char *colors, int nz) { strcpy(z, l); if (colors) - { memcpy(z_colors, colors, strlen(z)); - } } if (nz || !zero_seen++)