This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: Add ar --output
Hi Fangrui,
> I believe users need the resolved path (/tmp/c + ../file => /tmp/file;
> /tmp/c + /tmp/file => /tmp/file). The traditional behavior is to
> extract the file under the current working directory. Users can easily
> predict the output filename. With --output, users need a second to
> think about the resolved path. A resolved path will be more useful, I
> think.
Agreed.
I have checked in the attached patch.
Cheers
Nick
binutils/ChangeLog
2019-11-07 Nick Clifton <nickc@redhat.com>
* ar.c (open_output_file): Check for filename validity before
prefixing with output directory.
Display the constructed output filename if in verbose mode.
(extract_file): Let open_output_file display the filename.
diff --git a/binutils/ar.c b/binutils/ar.c
index 0af7954a47..b8342ce65a 100644
--- a/binutils/ar.c
+++ b/binutils/ar.c
@@ -1070,6 +1070,18 @@ open_output_file (bfd * abfd)
{
output_filename = bfd_get_filename (abfd);
+ /* PR binutils/17533: Do not allow directory traversal
+ outside of the current directory tree - unless the
+ user has explicitly specified an output directory. */
+ if (! is_valid_archive_path (output_filename))
+ {
+ char * base = (char *) lbasename (output_filename);
+
+ non_fatal (_("illegal output pathname for archive member: %s, using '%s' instead"),
+ output_filename, base);
+ output_filename = base;
+ }
+
if (output_dir)
{
size_t len = strlen (output_dir);
@@ -1083,18 +1095,10 @@ open_output_file (bfd * abfd)
output_filename = concat (output_dir, "/", output_filename, NULL);
}
}
-
- /* PR binutils/17533: Do not allow directory traversal
- outside of the current directory tree. */
- if (! is_valid_archive_path (output_filename))
- {
- char * base = (char *) lbasename (output_filename);
-
- non_fatal (_("illegal output pathname for archive member: %s, using '%s' instead"),
- output_filename, base);
- output_filename = base;
- }
+ if (verbose)
+ printf ("x - %s\n", output_filename);
+
FILE * ostream = fopen (output_filename, FOPEN_WB);
if (ostream == NULL)
{
@@ -1126,9 +1130,6 @@ extract_file (bfd *abfd)
fatal (_("internal stat error on %s"), bfd_get_filename (abfd));
size = buf.st_size;
- if (verbose)
- printf ("x - %s\n", bfd_get_filename (abfd));
-
bfd_seek (abfd, (file_ptr) 0, SEEK_SET);
output_file = NULL;
diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi
index 2a86b92033..11de2d3deb 100644
--- a/binutils/doc/binutils.texi
+++ b/binutils/doc/binutils.texi
@@ -390,7 +390,9 @@ are extracted.
Files cannot be extracted from a thin archive, and there are
restrictions on extracting from archives created with @option{P}: The
paths must not be absolute, may not contain @code{..}, and any
-subdirectories in the paths must exist.
+subdirectories in the paths must exist. If it is desired to avoid
+these restrictions then used the @option{--output} option to specify
+an output directory.
@end table
A number of modifiers (@var{mod}) may immediately follow the @var{p}
@@ -589,11 +591,6 @@ Note - although the presence of this option does imply a @option{x}
extraction operation that option must still be included on the command
line.
-Note - using this option does not allow archive members to be
-extracted to locations outside of the current directory, or one of its
-sub-directories. This is a security feature to prevent archives
-created with the @option{P} option from maliciously overwriting user
-files.
@end table
@c man end