summaryrefslogtreecommitdiff
path: root/archival
diff options
context:
space:
mode:
authorDenys Vlasenko2010-01-05 04:43:21 +0100
committerDenys Vlasenko2010-01-05 04:43:21 +0100
commitaf1c8e8be070f2121d5d977c5ed7a7f60c03a6dc (patch)
tree7f0bc3627ab6b07baf8d8b835e5d47f5c9cb34c5 /archival
parent074e8dcba76ac2a313d6a14ca2289e648f926b25 (diff)
downloadbusybox-af1c8e8be070f2121d5d977c5ed7a7f60c03a6dc.zip
busybox-af1c8e8be070f2121d5d977c5ed7a7f60c03a6dc.tar.gz
cpio: fix unpacking of names with leading slashes
function old new delta get_header_cpio 968 990 +22 cpio_main 533 526 -7 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'archival')
-rw-r--r--archival/cpio.c2
-rw-r--r--archival/libunarchive/get_header_cpio.c9
2 files changed, 10 insertions, 1 deletions
diff --git a/archival/cpio.c b/archival/cpio.c
index 5c16678..067d6e8 100644
--- a/archival/cpio.c
+++ b/archival/cpio.c
@@ -364,7 +364,7 @@ int cpio_main(int argc UNUSED_PARAM, char **argv)
#endif
archive_handle = init_handle();
- archive_handle->src_fd = STDIN_FILENO;
+ /* archive_handle->src_fd = STDIN_FILENO; - done by init_handle */
archive_handle->seek = seek_by_read;
archive_handle->ah_flags = ARCHIVE_EXTRACT_NEWER;
diff --git a/archival/libunarchive/get_header_cpio.c b/archival/libunarchive/get_header_cpio.c
index 302f122..52854df 100644
--- a/archival/libunarchive/get_header_cpio.c
+++ b/archival/libunarchive/get_header_cpio.c
@@ -70,6 +70,15 @@ char FAST_FUNC get_header_cpio(archive_handle_t *archive_handle)
file_header->name = xzalloc(namesize + 1);
/* Read in filename */
xread(archive_handle->src_fd, file_header->name, namesize);
+ if (file_header->name[0] == '/') {
+ /* Testcase: echo /etc/hosts | cpio -pvd /tmp
+ * Without this code, it tries to unpack /etc/hosts
+ * into "/etc/hosts", not "etc/hosts".
+ */
+ char *p = file_header->name;
+ do p++; while (*p == '/');
+ overlapping_strcpy(file_header->name, p);
+ }
archive_handle->offset += namesize;
/* Update offset amount and skip padding before file contents */