]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
pwd: prefer xpalloc to xnrealloc
authorPaul Eggert <eggert@cs.ucla.edu>
Fri, 8 Nov 2024 07:24:14 +0000 (23:24 -0800)
committerPaul Eggert <eggert@cs.ucla.edu>
Sat, 9 Nov 2024 07:41:18 +0000 (23:41 -0800)
* src/pwd.c (struct file_name, file_name_prepend):
Prefer idx_t to size_t for sizes related to xpalloc,
(file_name_init): Don’t overflow if PATH_MAX == INT_MAX.
(file_name_prepend): Prefer xpalloc to by-hand resizing.
Simplify by using memcpy return value.

src/pwd.c

index 2add89c8e0f7606d5eb065cb9f32e908f2753e34..ccf3b9bb91909aad6b6d28688a341023f1890496 100644 (file)
--- a/src/pwd.c
+++ b/src/pwd.c
@@ -32,7 +32,7 @@
 struct file_name
 {
   char *buf;
-  size_t n_alloc;
+  idx_t n_alloc;
   char *start;
 };
 
@@ -86,12 +86,13 @@ file_name_init (void)
 {
   struct file_name *p = xmalloc (sizeof *p);
 
-  /* Start with a buffer larger than PATH_MAX, but beware of systems
+  /* Start with a buffer larger than likely file names, but beware of systems
      on which PATH_MAX is very large -- e.g., INT_MAX.  */
-  p->n_alloc = MIN (2 * PATH_MAX, 32 * 1024);
+  int init_alloc = 2 * MIN (PATH_MAX, 16 * 1024);
+  p->n_alloc = init_alloc;
 
-  p->buf = xmalloc (p->n_alloc);
-  p->start = p->buf + (p->n_alloc - 1);
+  p->buf = xmalloc (init_alloc);
+  p->start = p->buf + init_alloc - 1;
   p->start[0] = '\0';
   return p;
 }
@@ -100,21 +101,18 @@ file_name_init (void)
 static void
 file_name_prepend (struct file_name *p, char const *s, size_t s_len)
 {
-  size_t n_free = p->start - p->buf;
+  idx_t n_free = p->start - p->buf;
   if (n_free < 1 + s_len)
     {
-      size_t half = p->n_alloc + 1 + s_len;
-      /* Use xnmalloc+free rather than xnrealloc, since with the latter
+      /* Call xpalloc with nullptr not p->buf, since with the latter
          we'd end up copying the data twice: once via realloc, then again
-         to align it with the end of the new buffer.  With xnmalloc, we
+         to align it with the end of the new buffer.  By passing nullptr we
          copy it only once.  */
-      char *q = xnmalloc (2, half);
-      size_t n_used = p->n_alloc - n_free;
-      p->start = q + 2 * half - n_used;
-      memcpy (p->start, p->buf + n_free, n_used);
+      idx_t n_used = p->n_alloc - n_free;
+      char *buf = xpalloc (nullptr, &p->n_alloc, 1 + s_len - n_free, -1, 1);
+      p->start = memcpy (buf + p->n_alloc - n_free, p->start, n_used);
       free (p->buf);
-      p->buf = q;
-      p->n_alloc = 2 * half;
+      p->buf = buf;
     }
 
   p->start -= 1 + s_len;