bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 2/2] savedir: avoid unlikely undefined behavior


From: Paul Eggert
Subject: [PATCH 2/2] savedir: avoid unlikely undefined behavior
Date: Sat, 3 Apr 2021 20:17:10 -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     |  6 ++++++
 lib/savedir.c | 25 +++++++++----------------
 2 files changed, 15 insertions(+), 16 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index d511911fd..4a665c275 100644
--- 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
diff --git a/lib/savedir.c b/lib/savedir.c
index bcf41700d..1c23d75b6 100644
--- a/lib/savedir.c
+++ b/lib/savedir.c
@@ -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;
-- 
2.30.2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]