diff -uprk.orig cpio-2.6.orig/src/copyin.c cpio-2.6/src/copyin.c --- cpio-2.6.orig/src/copyin.c 2005-04-26 18:01:02 +0400 +++ cpio-2.6/src/copyin.c 2005-04-26 22:19:07 +0400 @@ -25,6 +25,7 @@ #include "dstring.h" #include "extern.h" #include "defer.h" +#include "dirname.h" #include #ifndef FNM_PATHNAME #include @@ -1335,6 +1336,53 @@ } } +/* Return a safer suffix of FILE_NAME, or "." if it has no safer + suffix. Check for fully specified file names and other atrocities. */ + +static const char * +safer_name_suffix (char const *file_name) +{ + char const *p; + + /* Skip file system prefixes, leading file name components that contain + "..", and leading slashes. */ + + size_t prefix_len = FILE_SYSTEM_PREFIX_LEN (file_name); + + for (p = file_name + prefix_len; *p;) + { + if (p[0] == '.' && p[1] == '.' && (ISSLASH (p[2]) || !p[2])) + prefix_len = p + 2 - file_name; + + do + { + char c = *p++; + if (ISSLASH (c)) + break; + } + while (*p); + } + + for (p = file_name + prefix_len; ISSLASH (*p); p++) + continue; + prefix_len = p - file_name; + + if (prefix_len) + { + char *prefix = alloca (prefix_len + 1); + memcpy (prefix, file_name, prefix_len); + prefix[prefix_len] = '\0'; + + + error (0, 0, _("Removing leading `%s' from member names"), prefix); + } + + if (!*p) + p = "."; + + return p; +} + /* Read the collection from standard input and create files in the file system. */ @@ -1448,18 +1496,11 @@ process_copy_in () /* Do we have to ignore absolute paths, and if so, does the filename have an absolute path? */ - if (no_abs_paths_flag && file_hdr.c_name && file_hdr.c_name [0] == '/') + if (!abs_paths_flag && file_hdr.c_name && file_hdr.c_name [0]) { - char *p; + char *p = safer_name_suffix (file_hdr.c_name); - p = file_hdr.c_name; - while (*p == '/') - ++p; - if (*p == '\0') - { - strcpy (file_hdr.c_name, "."); - } - else + if (p != file_hdr.c_name) { /* Debian hack: file_hrd.c_name is sometimes set to point to static memory by code in tar.c. This diff -uprk.orig cpio-2.6.orig/src/extern.h cpio-2.6/src/extern.h --- cpio-2.6.orig/src/extern.h 2005-04-26 18:01:02 +0400 +++ cpio-2.6/src/extern.h 2005-04-26 22:17:49 +0400 @@ -46,7 +46,7 @@ extern int sparse_flag; extern int quiet_flag; extern int only_verify_crc_flag; -extern int no_abs_paths_flag; +extern int abs_paths_flag; extern unsigned int warn_option; /* Values for warn_option */ diff -uprk.orig cpio-2.6.orig/src/global.c cpio-2.6/src/global.c --- cpio-2.6.orig/src/global.c 2004-09-08 14:23:44 +0400 +++ cpio-2.6/src/global.c 2005-04-26 22:19:27 +0400 @@ -100,7 +100,7 @@ int only_verify_crc_flag = false; /* If true, don't use any absolute paths, prefix them by `./'. */ -int no_abs_paths_flag = false; +int abs_paths_flag = false; #ifdef DEBUG_CPIO /* If true, print debugging information. */ diff -uprk.orig cpio-2.6.orig/src/main.c cpio-2.6/src/main.c --- cpio-2.6.orig/src/main.c 2005-04-26 18:01:02 +0400 +++ cpio-2.6/src/main.c 2005-04-26 22:24:55 +0400 @@ -41,6 +41,7 @@ enum cpio_options { NO_ABSOLUTE_FILENAMES_OPTION=256, + ABSOLUTE_FILENAMES_OPTION, NO_PRESERVE_OWNER_OPTION, ONLY_VERIFY_CRC_OPTION, RENAME_BATCH_FILE_OPTION, @@ -134,6 +135,8 @@ static struct argp_option options[] = { N_("In copy-in mode, read additional patterns specifying filenames to extract or list from FILE"), 210}, {"no-absolute-filenames", NO_ABSOLUTE_FILENAMES_OPTION, 0, 0, N_("Create all files relative to the current directory"), 210}, + {"absolute-filenames", ABSOLUTE_FILENAMES_OPTION, 0, 0, + N_("do not strip leading file name components that contain \"..\" and leading slashes from file names"), 210}, {"only-verify-crc", ONLY_VERIFY_CRC_OPTION, 0, 0, N_("When reading a CRC format archive in copy-in mode, only verify the CRC's of each file in the archive, don't actually extract the files"), 210}, {"rename", 'r', 0, 0, @@ -393,7 +396,11 @@ crc newc odc bin ustar tar (all-caps als break; case NO_ABSOLUTE_FILENAMES_OPTION: /* --no-absolute-filenames */ - no_abs_paths_flag = true; + abs_paths_flag = false; + break; + + case ABSOLUTE_FILENAMES_OPTION: /* --absolute-filenames */ + abs_paths_flag = true; break; case NO_PRESERVE_OWNER_OPTION: /* --no-preserve-owner */ @@ -631,7 +638,7 @@ process_args (int argc, char *argv[]) _("--append is used but no archive file name is given (use -F or -O options"))); CHECK_USAGE(rename_batch_file, "--rename-batch-file", "--create"); - CHECK_USAGE(no_abs_paths_flag, "--no-absolute-pathnames", "--create"); + CHECK_USAGE(abs_paths_flag, "--absolute-pathnames", "--create"); CHECK_USAGE(input_archive_name, "-I", "--create"); if (archive_name && output_archive_name) USAGE_ERROR ((0, 0, _("Both -O and -F are used in copy-out mode"))); @@ -658,7 +665,7 @@ process_args (int argc, char *argv[]) CHECK_USAGE(rename_flag, "--rename", "--pass-through"); CHECK_USAGE(append_flag, "--append", "--pass-through"); CHECK_USAGE(rename_batch_file, "--rename-batch-file", "--pass-through"); - CHECK_USAGE(no_abs_paths_flag, "--no-absolute-pathnames", + CHECK_USAGE(abs_paths_flag, "--absolute-pathnames", "--pass-through"); CHECK_USAGE(to_stdout_option, "--to-stdout", "--pass-through");