]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
expand: check for colno overflow
authorPaul Eggert <eggert@cs.ucla.edu>
Thu, 7 Nov 2024 20:51:04 +0000 (12:51 -0800)
committerPaul Eggert <eggert@cs.ucla.edu>
Sat, 9 Nov 2024 07:41:18 +0000 (23:41 -0800)
* src/expand-common.c (get_next_tab_column): Check for tab
stop overflow here.  All callers changed to not check.
* src/expand.c (expand): Use colno for column number.

src/expand-common.c
src/expand.c
src/unexpand.c

index 7c0ea2ea7602a3bf70f1d6aa281388e42316b07f..e3f9ea84eccfc0cb4ae622ba02fd392ed4006f76 100644 (file)
@@ -271,44 +271,54 @@ finalize_tab_stops (void)
 }
 
 
+/* Return number of first tab stop after COLUMN.  TAB_INDEX specifies
+   amny multiple tab-sizes.  Set *LAST_TAB depending on whether we are
+   returning COLUMN + 1 merely because we're past the last tab.
+   If the number would overflow, diagnose this and exit.  */
 extern colno
-get_next_tab_column (const colno column, idx_t *tab_index,
-                     bool *last_tab)
+get_next_tab_column (colno column, idx_t *tab_index, bool *last_tab)
 {
   *last_tab = false;
+  colno tab_distance;
 
   /* single tab-size - return multiples of it */
   if (tab_size)
-    return column + (tab_size - column % tab_size);
-
-  /* multiple tab-sizes - iterate them until the tab position is beyond
-     the current input column. */
-  for ( ; *tab_index < first_free_tab ; (*tab_index)++ )
+    tab_distance = tab_size - column % tab_size;
+  else
     {
-        colno tab = tab_list[*tab_index];
-        if (column < tab)
+      /* multiple tab-sizes - iterate them until the tab position is beyond
+         the current input column. */
+      for ( ; *tab_index < first_free_tab ; (*tab_index)++ )
+        {
+          colno tab = tab_list[*tab_index];
+          if (column < tab)
             return tab;
-    }
-
-  /* relative last tab - return multiples of it */
-  if (extend_size)
-    return column + (extend_size - column % extend_size);
-
-  /* incremental last tab - add increment_size to the previous tab stop */
-  if (increment_size)
-    {
-      colno end_tab = tab_list[first_free_tab - 1];
+        }
 
-      return column + (increment_size - ((column - end_tab) % increment_size));
+      /* relative last tab - return multiples of it */
+      if (extend_size)
+        tab_distance = extend_size - column % extend_size;
+      else if (increment_size)
+        {
+          /* incremental last tab - add increment_size to the previous
+             tab stop */
+          colno end_tab = tab_list[first_free_tab - 1];
+          tab_distance = increment_size - ((column - end_tab) % increment_size);
+        }
+      else
+        {
+          *last_tab = true;
+          tab_distance = 1;
+        }
     }
 
-  *last_tab = true;
-  return 0;
+  colno tab_stop;
+  if (ckd_add (&tab_stop, column, tab_distance))
+    error (EXIT_FAILURE, 0, _("input line is too long"));
+  return tab_stop;
 }
 
 
-
-
 /* Sets new file-list */
 extern void
 set_file_list (char **list)
index 419cf19dff7b5dcf4d0b5baba85168ba44fb3ee4..9f950ecd471128381e55aaa9a25be400d9fb05e5 100644 (file)
@@ -113,7 +113,7 @@ expand (void)
          is true:  */
 
       /* Column of next input character.  */
-      uintmax_t column = 0;
+      colno column = 0;
 
       /* Index in TAB_LIST of next tab stop to examine.  */
       idx_t tab_index = 0;
@@ -131,17 +131,9 @@ expand (void)
               if (c == '\t')
                 {
                   /* Column the next input tab stop is on.  */
-                  uintmax_t next_tab_column;
                   bool last_tab;
-
-                  next_tab_column = get_next_tab_column (column, &tab_index,
-                                                         &last_tab);
-
-                  if (last_tab)
-                    next_tab_column = column + 1;
-
-                  if (next_tab_column < column)
-                    error (EXIT_FAILURE, 0, _("input line is too long"));
+                  colno next_tab_column
+                    = get_next_tab_column (column, &tab_index, &last_tab);
 
                   while (++column < next_tab_column)
                     if (putchar (' ') < 0)
@@ -158,8 +150,7 @@ expand (void)
                 }
               else
                 {
-                  column++;
-                  if (!column)
+                  if (ckd_add (&column, column, 1))
                     error (EXIT_FAILURE, 0, _("input line is too long"));
                 }
 
index 9e621929a2ab191be833b9c380a520d6072a8289..0d10ffe393edd142658ae69cac59a11706a79b36 100644 (file)
@@ -175,9 +175,6 @@ unexpand (void)
 
                   if (convert)
                     {
-                      if (next_tab_column < column)
-                        error (EXIT_FAILURE, 0, _("input line is too long"));
-
                       if (c == '\t')
                         {
                           column = next_tab_column;