cpio: fix unpacking of names with leading slashes
authorDenys Vlasenko <vda.linux@googlemail.com>
Tue, 5 Jan 2010 03:43:21 +0000 (04:43 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Tue, 5 Jan 2010 03:43:21 +0000 (04:43 +0100)
function                                             old     new   delta
get_header_cpio                                      968     990     +22
cpio_main                                            533     526      -7

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
archival/cpio.c
archival/libunarchive/get_header_cpio.c
testsuite/cpio.tests

index 5c16678e47bebf69e86bb49d7f0dbe8fc0365966..067d6e88d51d4f15578bbae9e4fc28077309af8a 100644 (file)
@@ -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;
 
index 302f122331b4d399f546a3c98a1b699b1d55de97..52854dff9fd953647810b5e09d979722a6ba7496 100644 (file)
@@ -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 */
index f21ba18d1a41a880df5e3f7e0159ad8a37a7cb4e..56f1885ac907feb24b3d2628f64ae0552d792fd5 100755 (executable)
@@ -36,6 +36,7 @@ ls -ln cpio.testdir | $FILTER_LS" \
 "\
 1 blocks
 0
+total 0
 -rw-r--r-- 2 $user $group 0 x
 -rw-r--r-- 2 $user $group 0 y
 " \
@@ -47,10 +48,10 @@ test x"$SKIP_KNOWN_BUGS" = x"" && {
 testing "cpio lists hardlinks" \
 "$ECHO -ne '$hexdump' | bzcat | cpio -t 2>&1; echo \$?" \
 "\
-1 block
 cpio.testdir
 cpio.testdir/x
 cpio.testdir/y
+1 blocks
 0
 " \
        "" ""
@@ -72,6 +73,7 @@ ls -ln cpio.testdir2/cpio.testdir | $FILTER_LS" \
 "\
 2 blocks
 0
+total 8
 -rw-r--r-- 2 $user $group 0 empty
 -rw-r--r-- 2 $user $group 0 empty1
 -rw-r--r-- 2 $user $group 2 nonempty