]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.2.0658: xxd: signed integer overflow in huntype() v9.2.0658
authorChristian Brabandt <cb@256bit.org>
Tue, 16 Jun 2026 19:26:00 +0000 (19:26 +0000)
committerChristian Brabandt <cb@256bit.org>
Tue, 16 Jun 2026 19:29:37 +0000 (19:29 +0000)
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 <justinkz@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/testdir/test_xxd.vim
src/version.c
src/xxd/xxd.c

index fd23d38e1a3dc21a158eb9013b5e0b1acea2d7fd..aca1c4f2feed66a23d14aacb50b67c2ec5b2dacd 100644 (file)
@@ -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
index fef84f283ed20a1489657f12207d19a884f298a8..1dc1267b27e3ce1e728eea433389e1e243faec9a 100644 (file)
@@ -759,6 +759,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    658,
 /**/
     657,
 /**/
index 323d5a3982efe7bde9b44ca3a554c4bd21ba312e..9b1ca6ea5555df413546e48126d75ab91e1c8393 100644 (file)
@@ -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++)