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:
parent
75d0856ca5
commit
d3bb697513
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user