mirror of
https://git.savannah.gnu.org/git/tar.git
synced 2026-08-01 15:06:02 +00:00
(name_gather, addname): Use offsetof when computing sizes for
struct hack; this avoids wasted space in some cases. (name_gather): Use strcpy, not memcpy. for consistency with other code that does similar things. (read_name_from_file, name_next, name_gather, add_hierarchy_to_namelist): Avoid quadratic behavior when reallocating buffers. Check for buffer size overflow. (addname): Avoid unnecessary clearing of memory.
This commit is contained in:
+57
-26
@@ -270,7 +270,9 @@ read_name_from_file (void)
|
||||
{
|
||||
if (counter == name_buffer_length)
|
||||
{
|
||||
name_buffer_length += NAME_FIELD_SIZE;
|
||||
if (name_buffer_length * 2 < name_buffer_length)
|
||||
xalloc_die ();
|
||||
name_buffer_length *= 2;
|
||||
name_buffer = xrealloc (name_buffer, name_buffer_length + 2);
|
||||
}
|
||||
name_buffer[counter++] = character;
|
||||
@@ -281,7 +283,9 @@ read_name_from_file (void)
|
||||
|
||||
if (counter == name_buffer_length)
|
||||
{
|
||||
name_buffer_length += NAME_FIELD_SIZE;
|
||||
if (name_buffer_length * 2 < name_buffer_length)
|
||||
xalloc_die ();
|
||||
name_buffer_length *= 2;
|
||||
name_buffer = xrealloc (name_buffer, name_buffer_length + 2);
|
||||
}
|
||||
name_buffer[counter] = '\0';
|
||||
@@ -319,11 +323,20 @@ name_next (int change_dirs)
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t source_len;
|
||||
source = name_array[name_index++];
|
||||
if (strlen (source) > name_buffer_length)
|
||||
source_len = strlen (source);
|
||||
if (name_buffer_length < source_len)
|
||||
{
|
||||
do
|
||||
{
|
||||
name_buffer_length *= 2;
|
||||
if (! name_buffer_length)
|
||||
xalloc_die ();
|
||||
}
|
||||
while (name_buffer_length < source_len);
|
||||
|
||||
free (name_buffer);
|
||||
name_buffer_length = strlen (source);
|
||||
name_buffer = xmalloc (name_buffer_length + 2);
|
||||
}
|
||||
strcpy (name_buffer, source);
|
||||
@@ -382,7 +395,7 @@ name_gather (void)
|
||||
{
|
||||
/* Buffer able to hold a single name. */
|
||||
static struct name *buffer;
|
||||
static size_t allocated_length;
|
||||
static size_t allocated_size;
|
||||
|
||||
char const *name;
|
||||
|
||||
@@ -390,12 +403,12 @@ name_gather (void)
|
||||
{
|
||||
static int change_dir;
|
||||
|
||||
if (allocated_length == 0)
|
||||
if (allocated_size == 0)
|
||||
{
|
||||
allocated_length = sizeof (struct name) + NAME_FIELD_SIZE;
|
||||
buffer = xmalloc (allocated_length);
|
||||
allocated_size = offsetof (struct name, name) + NAME_FIELD_SIZE + 1;
|
||||
buffer = xmalloc (allocated_size);
|
||||
/* FIXME: This memset is overkill, and ugly... */
|
||||
memset (buffer, 0, allocated_length);
|
||||
memset (buffer, 0, allocated_size);
|
||||
}
|
||||
|
||||
while ((name = name_next (0)) && strcmp (name, "-C") == 0)
|
||||
@@ -408,14 +421,23 @@ name_gather (void)
|
||||
|
||||
if (name)
|
||||
{
|
||||
size_t needed_size;
|
||||
buffer->length = strlen (name);
|
||||
if (sizeof (struct name) + buffer->length >= allocated_length)
|
||||
needed_size = offsetof (struct name, name) + buffer->length + 1;
|
||||
if (allocated_size < needed_size)
|
||||
{
|
||||
allocated_length = sizeof (struct name) + buffer->length;
|
||||
buffer = xrealloc (buffer, allocated_length);
|
||||
do
|
||||
{
|
||||
allocated_size *= 2;
|
||||
if (! allocated_size)
|
||||
xalloc_die ();
|
||||
}
|
||||
while (allocated_size < needed_size);
|
||||
|
||||
buffer = xrealloc (buffer, allocated_size);
|
||||
}
|
||||
buffer->change_dir = change_dir;
|
||||
memcpy (buffer->name, name, buffer->length + 1);
|
||||
strcpy (buffer->name, name);
|
||||
buffer->next = 0;
|
||||
buffer->found = 0;
|
||||
|
||||
@@ -454,23 +476,26 @@ name_gather (void)
|
||||
struct name *
|
||||
addname (char const *string, int change_dir)
|
||||
{
|
||||
struct name *name;
|
||||
size_t length;
|
||||
|
||||
length = string ? strlen (string) : 0;
|
||||
name = xmalloc (sizeof (struct name) + length);
|
||||
memset (name, 0, sizeof (struct name) + length);
|
||||
name->next = 0;
|
||||
size_t length = string ? strlen (string) : 0;
|
||||
struct name *name = xmalloc (offsetof (struct name, name) + length + 1);
|
||||
|
||||
if (string)
|
||||
{
|
||||
name->fake = 0;
|
||||
name->length = length;
|
||||
memcpy (name->name, string, length + 1);
|
||||
strcpy (name->name, string);
|
||||
}
|
||||
else
|
||||
name->fake = 1;
|
||||
{
|
||||
name->fake = 1;
|
||||
|
||||
/* FIXME: This initialization (and the byte of memory that it
|
||||
initializes) is probably not needed, but we are currently in
|
||||
bug-fix mode so we'll leave it in for now. */
|
||||
name->name[0] = 0;
|
||||
}
|
||||
|
||||
name->next = 0;
|
||||
name->length = length;
|
||||
name->found = 0;
|
||||
name->regexp = 0; /* assume not a regular expression */
|
||||
name->firstch = 1; /* assume first char is literal */
|
||||
@@ -717,10 +742,16 @@ add_hierarchy_to_namelist (struct name *name, dev_t device)
|
||||
string_length = strlen (string);
|
||||
if (*string == 'D')
|
||||
{
|
||||
if (name_length + string_length >= allocated_length)
|
||||
if (allocated_length <= name_length + string_length)
|
||||
{
|
||||
while (name_length + string_length >= allocated_length)
|
||||
allocated_length += NAME_FIELD_SIZE;
|
||||
do
|
||||
{
|
||||
allocated_length *= 2;
|
||||
if (! allocated_length)
|
||||
xalloc_die ();
|
||||
}
|
||||
while (allocated_length <= name_length + string_length);
|
||||
|
||||
name_buffer = xrealloc (name_buffer, allocated_length + 1);
|
||||
}
|
||||
strcpy (name_buffer + name_length, string + 1);
|
||||
|
||||
Reference in New Issue
Block a user