Refuse to extract an entry from an archive on top of the archive being read.
(This is the converse of the "don't add an archive to itself".)
This commit is contained in:
parent
da9cbfaa5d
commit
b3f695b45c
@ -27,12 +27,14 @@
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_private.h"
|
||||
|
||||
struct read_fd_data {
|
||||
int fd;
|
||||
@ -63,9 +65,16 @@ archive_read_open_fd(struct archive *a, int fd, size_t block_size)
|
||||
static int
|
||||
file_open(struct archive *a, void *client_data)
|
||||
{
|
||||
(void)client_data; /* UNUSED */
|
||||
(void)a; /* UNUSED */
|
||||
struct read_fd_data *mine = client_data;
|
||||
struct stat st;
|
||||
|
||||
if (fstat(mine->fd, &st) != 0) {
|
||||
archive_set_error(a, errno, "Can't stat fd %d", mine->fd);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
a->skip_file_dev = st.st_dev;
|
||||
a->skip_file_ino = st.st_ino;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
@ -34,6 +35,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <unistd.h>
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_private.h"
|
||||
|
||||
struct read_file_data {
|
||||
int fd;
|
||||
@ -77,6 +79,7 @@ static int
|
||||
file_open(struct archive *a, void *client_data)
|
||||
{
|
||||
struct read_file_data *mine = client_data;
|
||||
struct stat st;
|
||||
|
||||
mine->buffer = malloc(mine->block_size);
|
||||
if (*mine->filename != 0)
|
||||
@ -88,6 +91,14 @@ file_open(struct archive *a, void *client_data)
|
||||
mine->filename);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
if (fstat(mine->fd, &st) == 0) {
|
||||
a->skip_file_dev = st.st_dev;
|
||||
a->skip_file_ino = st.st_ino;
|
||||
} else {
|
||||
archive_set_error(a, errno, "Can't stat '%s'",
|
||||
mine->filename);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
@ -34,6 +35,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <unistd.h>
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_private.h"
|
||||
|
||||
struct read_file_data {
|
||||
int fd;
|
||||
@ -77,6 +79,7 @@ static int
|
||||
file_open(struct archive *a, void *client_data)
|
||||
{
|
||||
struct read_file_data *mine = client_data;
|
||||
struct stat st;
|
||||
|
||||
mine->buffer = malloc(mine->block_size);
|
||||
if (*mine->filename != 0)
|
||||
@ -88,6 +91,14 @@ file_open(struct archive *a, void *client_data)
|
||||
mine->filename);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
if (fstat(mine->fd, &st) == 0) {
|
||||
a->skip_file_dev = st.st_dev;
|
||||
a->skip_file_ino = st.st_ino;
|
||||
} else {
|
||||
archive_set_error(a, errno, "Can't stat '%s'",
|
||||
mine->filename);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -189,7 +189,7 @@ archive_write_header(struct archive *a, struct archive_entry *entry)
|
||||
|
||||
if (archive_entry_dev(entry) == a->skip_file_dev &&
|
||||
archive_entry_ino(entry) == a->skip_file_ino) {
|
||||
archive_set_error(a, 0, "Can't add archive to itself.");
|
||||
archive_set_error(a, 0, "Can't add archive to itself");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user