]> git.ipfire.org Git - thirdparty/gnulib.git/commitdiff
savedir: avoid unlikely undefined behavior
authorPaul Eggert <eggert@cs.ucla.edu>
Sun, 4 Apr 2021 03:14:36 +0000 (20:14 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Sun, 4 Apr 2021 03:15:43 +0000 (20:15 -0700)
* lib/savedir.c (streamsavedir): Prefer idx_to size_t where
either will do.  Simplify reallocation of entries.
Use xpalloc to reallocate name_space, to avoid some unlikely
integer overflows.

ChangeLog
lib/savedir.c

index d511911fdfd7dc0f8948b935fb9cb4da268ecf33..4a665c2753f77949d6375fe399eb2893262b1879 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2021-04-03  Paul Eggert  <eggert@cs.ucla.edu>
 
+       savedir: avoid unlikely undefined behavior
+       * lib/savedir.c (streamsavedir): Prefer idx_to size_t where
+       either will do.  Simplify reallocation of entries.
+       Use xpalloc to reallocate name_space, to avoid some unlikely
+       integer overflows.
+
        quotearg: avoid undefined and/or O(N**2)
        Avoid undefined and O(N**2) behavior in some very unlikely cases.
        * lib/quotearg.c (quotearg_n_options): Document that N must
index bcf41700d2c78e92dd51ee1212c92b19dcff9d3a..1c23d75b685bb0a309506ffde8d1e02225d52b75 100644 (file)
@@ -91,11 +91,11 @@ char *
 streamsavedir (DIR *dirp, enum savedir_option option)
 {
   char *name_space = NULL;
-  size_t allocated = 0;
+  idx_t allocated = 0;
   direntry_t *entries = NULL;
   size_t entries_allocated = 0;
-  size_t entries_used = 0;
-  size_t used = 0;
+  idx_t entries_used = 0;
+  idx_t used = 0;
   comparison_function cmp = comparison_function_table[option];
 
   if (dirp == NULL)
@@ -116,15 +116,12 @@ streamsavedir (DIR *dirp, enum savedir_option option)
       entry = dp->d_name;
       if (entry[entry[0] != '.' ? 0 : entry[1] != '.' ? 1 : 2] != '\0')
         {
-          size_t entry_size = _D_EXACT_NAMLEN (dp) + 1;
+          idx_t entry_size = _D_EXACT_NAMLEN (dp) + 1;
           if (cmp)
             {
               if (entries_allocated == entries_used)
-                {
-                  size_t n = entries_allocated;
-                  entries = x2nrealloc (entries, &n, sizeof *entries);
-                  entries_allocated = n;
-                }
+                entries = x2nrealloc (entries, &entries_allocated,
+                                      sizeof *entries);
               entries[entries_used].name = xstrdup (entry);
 #if D_INO_IN_DIRENT
               entries[entries_used].ino = dp->d_ino;
@@ -134,13 +131,9 @@ streamsavedir (DIR *dirp, enum savedir_option option)
           else
             {
               if (allocated - used <= entry_size)
-                {
-                  size_t n = used + entry_size;
-                  if (n < used)
-                    xalloc_die ();
-                  name_space = x2nrealloc (name_space, &n, 1);
-                  allocated = n;
-                }
+                name_space = xpalloc (name_space, &allocated,
+                                      entry_size - (allocated - used),
+                                      IDX_MAX - 1, sizeof *name_space);
               memcpy (name_space + used, entry, entry_size);
             }
           used += entry_size;