]> git.ipfire.org Git - thirdparty/tar.git/commitdiff
Fix pointer bug in drop_volume_label_suffix
authorPaul Eggert <eggert@cs.ucla.edu>
Mon, 11 Sep 2023 06:17:02 +0000 (01:17 -0500)
committerPaul Eggert <eggert@cs.ucla.edu>
Mon, 11 Sep 2023 06:17:29 +0000 (01:17 -0500)
Problem reported by Marc Espie in:
https://lists.gnu.org/r/bug-tar/2023-09/msg00003.html
* src/buffer.c (drop_volume_label_suffix):
Redo to not compute a pointer before the start of a buffer,
as this is not portable.

THANKS
src/buffer.c
src/common.h

diff --git a/THANKS b/THANKS
index b51f169416abdbf2edb8bccb566ee4ecac6f26e1..fb8634e172bd5931c4ba3fd7606f26e697377124 100644 (file)
--- a/THANKS
+++ b/THANKS
@@ -327,6 +327,7 @@ Mads Martin Joergensen      mmj@suse.de
 Manfred Weichel                Manfred.Weichel@mch.sni.de
 Manuel Munier          Manuel.Munier@loria.fr
 Marc Boucher           marc@cam.org
+Marc Espie             marc.espie.openbsd@gmail.com
 Marc Ewing             marc@redhat.com
 Marcin Matuszewski     marcin@frodo.nask.org.pl
 Marcus Daniels         marcus@sysc.pdx.edu
index 8a575f9aa776009e0968c5d0753f2b34ba67cd3f..7f353fa44737744999e35d82d404299870a66e63 100644 (file)
@@ -1565,33 +1565,21 @@ try_new_volume (void)
 }
 
 \f
-#define VOLUME_TEXT " Volume "
-#define VOLUME_TEXT_LEN (sizeof VOLUME_TEXT - 1)
-
 char *
 drop_volume_label_suffix (const char *label)
 {
-  const char *p;
-  size_t len = strlen (label);
-
-  if (len < 1)
-    return NULL;
+  static char const VOLUME_TEXT[] = " Volume ";
+  idx_t VOLUME_TEXT_LEN = sizeof VOLUME_TEXT - 1;
+  idx_t prefix_len = 0;
 
-  for (p = label + len - 1; p > label && isdigit ((unsigned char) *p); p--)
-    ;
-  if (p > label && p - (VOLUME_TEXT_LEN - 1) > label)
-    {
-      p -= VOLUME_TEXT_LEN - 1;
-      if (memcmp (p, VOLUME_TEXT, VOLUME_TEXT_LEN) == 0)
-       {
-         char *s = xmalloc ((len = p - label) + 1);
-         memcpy (s, label, len);
-         s[len] = 0;
-         return s;
-       }
-    }
+  for (idx_t i = 0; label[i]; i++)
+    if (!isdigit ((unsigned char) label[i]))
+      prefix_len = i + 1;
 
-  return NULL;
+  ptrdiff_t len = prefix_len - VOLUME_TEXT_LEN;
+  return (0 <= len && memcmp (label + len, VOLUME_TEXT, VOLUME_TEXT_LEN) == 0
+         ? ximemdup0 (label, len)
+         : NULL);
 }
 
 /* Check LABEL against the volume label, seen as a globbing
index 89912567f441fc27e4bb9a2d7d40e58996befb71..55576ef3e92bb3593cdd8e030dbf59916fd9f6c0 100644 (file)
@@ -460,7 +460,8 @@ extern uintmax_t continued_file_size;
 extern uintmax_t continued_file_offset;
 extern off_t records_written;
 
-char *drop_volume_label_suffix (const char *label);
+char *drop_volume_label_suffix (const char *label)
+  _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE;
 
 size_t available_space_after (union block *pointer);
 off_t current_block_ordinal (void);