Fix pointer bug in drop_volume_label_suffix

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.
This commit is contained in:
Paul Eggert
2023-09-11 01:17:02 -05:00
parent 9599d193b8
commit 78d4ccd755
3 changed files with 13 additions and 23 deletions

1
THANKS
View File

@@ -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

View File

@@ -1565,33 +1565,21 @@ try_new_volume (void)
}
#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);
static char const VOLUME_TEXT[] = " Volume ";
idx_t VOLUME_TEXT_LEN = sizeof VOLUME_TEXT - 1;
idx_t prefix_len = 0;
if (len < 1)
return NULL;
for (idx_t i = 0; label[i]; i++)
if (!isdigit ((unsigned char) label[i]))
prefix_len = i + 1;
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;
}
}
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

View 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);