archive_string_ensure() used to call exit(3) if it

couldn't allocate more memory for a string.  Change
this so it returns NULL in that case, and update
all of its callers to handle the error.  Some of
those callers can now return errors back to the
client instead of calling exit(3).

Approved by: re (bmah)
This commit is contained in:
Tim Kientzle 2007-07-15 19:13:59 +00:00
parent 75d0856ca5
commit d3bb697513
5 changed files with 27 additions and 10 deletions

View File

@ -895,8 +895,14 @@ read_body_to_string(struct archive_read *a, struct tar *tar,
return (ARCHIVE_FATAL);
}
/* Fail if we can't make our buffer big enough. */
if (archive_string_ensure(as, size+1) == NULL) {
archive_set_error(&a->archive, ENOMEM,
"No memory");
return (ARCHIVE_FATAL);
}
/* Read the body into the string. */
archive_string_ensure(as, size+1);
padded_size = (size + 511) & ~ 511;
dest = as->s;
while (padded_size > 0) {
@ -2020,7 +2026,11 @@ readline(struct archive_read *a, struct tar *tar, const char **start)
}
/* Otherwise, we need to accumulate in a line buffer. */
for (;;) {
archive_string_ensure(&tar->line, total_size + bytes_read);
if (archive_string_ensure(&tar->line, total_size + bytes_read) == NULL) {
archive_set_error(&a->archive, ENOMEM,
"Can't allocate working buffer");
return (ARCHIVE_FATAL);
}
memcpy(tar->line.s + total_size, t, bytes_read);
(a->decompressor->consume)(a, bytes_read);
total_size += bytes_read;

View File

@ -302,7 +302,8 @@ zip_read_file_header(struct archive_read *a, struct archive_entry *entry,
"Truncated ZIP file header");
return (ARCHIVE_FATAL);
}
archive_string_ensure(&zip->pathname, zip->filename_length);
if (archive_string_ensure(&zip->pathname, zip->filename_length) == NULL)
__archive_errx(1, "Out of memory");
archive_strncpy(&zip->pathname, (const char *)h, zip->filename_length);
(a->decompressor->consume)(a, zip->filename_length);
archive_entry_set_pathname(entry, zip->pathname.s);

View File

@ -44,7 +44,8 @@ __FBSDID("$FreeBSD$");
struct archive_string *
__archive_string_append(struct archive_string *as, const char *p, size_t s)
{
__archive_string_ensure(as, as->length + s + 1);
if (__archive_string_ensure(as, as->length + s + 1) == NULL)
__archive_errx(1, "Out of memory");
memcpy(as->s + as->length, p, s);
as->s[as->length + s] = 0;
as->length += s;
@ -54,7 +55,8 @@ __archive_string_append(struct archive_string *as, const char *p, size_t s)
void
__archive_string_copy(struct archive_string *dest, struct archive_string *src)
{
__archive_string_ensure(dest, src->length + 1);
if (__archive_string_ensure(dest, src->length + 1) == NULL)
__archive_errx(1, "Out of memory");
memcpy(dest->s, src->s, src->length);
dest->length = src->length;
dest->s[dest->length] = 0;
@ -69,6 +71,7 @@ __archive_string_free(struct archive_string *as)
free(as->s);
}
/* Returns NULL on any allocation failure. */
struct archive_string *
__archive_string_ensure(struct archive_string *as, size_t s)
{
@ -80,10 +83,8 @@ __archive_string_ensure(struct archive_string *as, size_t s)
while (as->buffer_length < s)
as->buffer_length *= 2;
as->s = (char *)realloc(as->s, as->buffer_length);
/* TODO: Return null instead and fix up all of our callers to
* handle this correctly. */
if (as->s == NULL)
__archive_errx(1, "Out of memory");
return (NULL);
return (as);
}

View File

@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
#include <stdio.h>
#include "archive_string.h"
#include "archive_private.h"
/*
* Like 'vsprintf', but ensures the target is big enough, resizing if
@ -56,7 +57,8 @@ __archive_string_vsprintf(struct archive_string *as, const char *fmt,
uintmax_t u; /* Unsigned integer temp. */
const char *p, *p2;
__archive_string_ensure(as, 64);
if (__archive_string_ensure(as, 64) == NULL)
__archive_errx(1, "Out of memory");
if (fmt == NULL) {
as->s[0] = 0;

View File

@ -610,7 +610,10 @@ archive_write_disk_new(void)
a->lookup_uid = trivial_lookup_uid;
a->lookup_gid = trivial_lookup_gid;
a->user_uid = geteuid();
archive_string_ensure(&a->path_safe, 64);
if (archive_string_ensure(&a->path_safe, 512) == NULL) {
free(a);
return (NULL);
}
return (&a->archive);
}