View | Details | Raw Unified
Collapse All | Expand All

(-) lib/libarchive/archive_read_support_format_tar.c (-36 / +97 lines)
 Lines 690-696    Link Here 
		}
		}
	}
	}
	--tar->header_recursion_depth;
	--tar->header_recursion_depth;
	return (err);
	/* We return warnings or success as-is.  Anything else is fatal. */
	if (err == ARCHIVE_WARN || err == ARCHIVE_OK)
		return (err);
	if (err == ARCHIVE_EOF)
		/* EOF when recursively reading a header is bad. */
		archive_set_error(&a->archive, EINVAL, "Damaged tar archive");
	return (ARCHIVE_FATAL);
}
}
/*
/*
 Lines 761-792    Link Here 
header_Solaris_ACL(struct archive_read *a, struct tar *tar,
header_Solaris_ACL(struct archive_read *a, struct tar *tar,
    struct archive_entry *entry, const void *h)
    struct archive_entry *entry, const void *h)
{
{
	int err, err2;
	const struct archive_entry_header_ustar *header;
	char *p;
	size_t size;
	int err;
	char *acl, *p;
	wchar_t *wp;
	wchar_t *wp;
	/*
	 * read_body_to_string adds a NUL terminator, but we need a little
	 * more to make sure that we don't overrun acl_text later.
	 */
	header = (const struct archive_entry_header_ustar *)h;
	size = tar_atol(header->size, sizeof(header->size));
	err = read_body_to_string(a, tar, &(tar->acl_text), h);
	err = read_body_to_string(a, tar, &(tar->acl_text), h);
	err2 = tar_read_header(a, tar, entry);
	if (err != ARCHIVE_OK)
	err = err_combine(err, err2);
		return (err);
	err = tar_read_header(a, tar, entry);
	/* XXX Ensure p doesn't overrun acl_text */
	if ((err != ARCHIVE_OK) && (err != ARCHIVE_WARN))
		return (err);
	/* Skip leading octal number. */
	/* Skip leading octal number. */
	/* XXX TODO: Parse the octal number and sanity-check it. */
	/* XXX TODO: Parse the octal number and sanity-check it. */
	p = tar->acl_text.s;
	p = acl = tar->acl_text.s;
	while (*p != '\0')
	while (*p != '\0' && p < acl + size)
		p++;
		p++;
	p++;
	p++;
	wp = (wchar_t *)malloc((strlen(p) + 1) * sizeof(wchar_t));
	if (p >= acl + size) {
	if (wp != NULL) {
		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
		utf8_decode(wp, p, strlen(p));
		    "Malformed Solaris ACL attribute");
		err2 = __archive_entry_acl_parse_w(entry, wp,
		return(ARCHIVE_WARN);
		    ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
		err = err_combine(err, err2);
		free(wp);
	}
	}
	/* Skip leading octal number. */
	size -= (p - acl);
	acl = p;
	while (*p != '\0' && p < acl + size)
		p++;
	wp = (wchar_t *)malloc((p - acl + 1) * sizeof(wchar_t));
	if (wp == NULL) {
		archive_set_error(&a->archive, ENOMEM,
		    "Can't allocate work buffer for ACL parsing");
		return (ARCHIVE_FATAL);
	}
	utf8_decode(wp, acl, p - acl);
	err = __archive_entry_acl_parse_w(entry, wp,
	    ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
	free(wp);
	return (err);
	return (err);
}
}
 Lines 797-811    Link Here 
header_longlink(struct archive_read *a, struct tar *tar,
header_longlink(struct archive_read *a, struct tar *tar,
    struct archive_entry *entry, const void *h)
    struct archive_entry *entry, const void *h)
{
{
	int err, err2;
	int err;
	err = read_body_to_string(a, tar, &(tar->longlink), h);
	err = read_body_to_string(a, tar, &(tar->longlink), h);
	err2 = tar_read_header(a, tar, entry);
	if (err != ARCHIVE_OK)
	if (err == ARCHIVE_OK && err2 == ARCHIVE_OK) {
		return (err);
		/* Set symlink if symlink already set, else hardlink. */
	err = tar_read_header(a, tar, entry);
		archive_entry_set_link(entry, tar->longlink.s);
	if ((err != ARCHIVE_OK) && (err != ARCHIVE_WARN))
	}
		return (err);
	return (err_combine(err, err2));
	/* Set symlink if symlink already set, else hardlink. */
	archive_entry_set_link(entry, tar->longlink.s);
	return (ARCHIVE_OK);
}
}
/*
/*
 Lines 815-828    Link Here 
header_longname(struct archive_read *a, struct tar *tar,
header_longname(struct archive_read *a, struct tar *tar,
    struct archive_entry *entry, const void *h)
    struct archive_entry *entry, const void *h)
{
{
	int err, err2;
	int err;
	err = read_body_to_string(a, tar, &(tar->longname), h);
	err = read_body_to_string(a, tar, &(tar->longname), h);
	if (err != ARCHIVE_OK)
		return (err);
	/* Read and parse "real" header, then override name. */
	/* Read and parse "real" header, then override name. */
	err2 = tar_read_header(a, tar, entry);
	err = tar_read_header(a, tar, entry);
	if (err == ARCHIVE_OK && err2 == ARCHIVE_OK)
	if ((err != ARCHIVE_OK) && (err != ARCHIVE_WARN))
		archive_entry_set_pathname(entry, tar->longname.s);
		return (err);
	return (err_combine(err, err2));
	archive_entry_set_pathname(entry, tar->longname.s);
	return (ARCHIVE_OK);
}
}
 Lines 855-860    Link Here 
	(void)tar; /* UNUSED */
	(void)tar; /* UNUSED */
	header = (const struct archive_entry_header_ustar *)h;
	header = (const struct archive_entry_header_ustar *)h;
	size  = tar_atol(header->size, sizeof(header->size));
	size  = tar_atol(header->size, sizeof(header->size));
	if ((size > 1048576) || (size < 0)) {
		archive_set_error(&a->archive, EINVAL,
		    "Special header too large");
		return (ARCHIVE_FATAL);
	}
	/* Read the body into the string. */
	/* Read the body into the string. */
	archive_string_ensure(as, size+1);
	archive_string_ensure(as, size+1);
 Lines 862-867    Link Here 
	dest = as->s;
	dest = as->s;
	while (padded_size > 0) {
	while (padded_size > 0) {
		bytes_read = (a->decompressor->read_ahead)(a, &src, padded_size);
		bytes_read = (a->decompressor->read_ahead)(a, &src, padded_size);
		if (bytes_read == 0)
			return (ARCHIVE_EOF);
		if (bytes_read < 0)
		if (bytes_read < 0)
			return (ARCHIVE_FATAL);
			return (ARCHIVE_FATAL);
		if (bytes_read > padded_size)
		if (bytes_read > padded_size)
 Lines 1052-1062    Link Here 
header_pax_global(struct archive_read *a, struct tar *tar,
header_pax_global(struct archive_read *a, struct tar *tar,
    struct archive_entry *entry, const void *h)
    struct archive_entry *entry, const void *h)
{
{
	int err, err2;
	int err;
	err = read_body_to_string(a, tar, &(tar->pax_global), h);
	err = read_body_to_string(a, tar, &(tar->pax_global), h);
	err2 = tar_read_header(a, tar, entry);
	if (err != ARCHIVE_OK)
	return (err_combine(err, err2));
		return (err);
	err = tar_read_header(a, tar, entry);
	return (err);
}
}
static int
static int
 Lines 1065-1074    Link Here 
{
{
	int err, err2;
	int err, err2;
	read_body_to_string(a, tar, &(tar->pax_header), h);
	err = read_body_to_string(a, tar, &(tar->pax_header), h);
	if (err != ARCHIVE_OK)
		return (err);
	/* Parse the next header. */
	/* Parse the next header. */
	err = tar_read_header(a, tar, entry);
	err = tar_read_header(a, tar, entry);
	if ((err != ARCHIVE_OK) && (err != ARCHIVE_WARN))
		return (err);
	/*
	/*
	 * TODO: Parse global/default options into 'entry' struct here
	 * TODO: Parse global/default options into 'entry' struct here
 Lines 1165-1172    Link Here 
				l--;
				l--;
				break;
				break;
			}
			}
			if (*p < '0' || *p > '9')
			if (*p < '0' || *p > '9') {
				return (-1);
				archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
				    "Ignoring malformed pax extended attributes");
				return (ARCHIVE_WARN);
			}
			line_length *= 10;
			line_length *= 10;
			line_length += *p - '0';
			line_length += *p - '0';
			if (line_length > 999999) {
			if (line_length > 999999) {
 Lines 1178-1185    Link Here 
			l--;
			l--;
		}
		}
		if (line_length > attr_length)
		/*
			return (0);
		 * Parsed length must be no bigger than available data,
		 * at least 1, and the last character of the line must
		 * be '\n'.
		 */
		if (line_length > attr_length
		    || line_length < 1
		    || attr[line_length - 1] != '\n')
		{
			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
			    "Ignoring malformed pax extended attribute");
			return (ARCHIVE_WARN);
		}
		/* Ensure pax_entry buffer is big enough. */
		/* Ensure pax_entry buffer is big enough. */
		if (tar->pax_entry_length <= line_length) {
		if (tar->pax_entry_length <= line_length) {