bug-tar
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Bug-tar] file name with backslash is not archived


From: Paul Eggert
Subject: Re: [Bug-tar] file name with backslash is not archived
Date: Tue, 02 Nov 2010 13:13:10 -0700
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.15) Gecko/20101027 Thunderbird/3.0.10

On 11/02/10 10:09, Sergey Poznyakoff wrote:

> It's not a bug.  The section 6.2, "Selecting Archive Members"[1], says:
> 
>     By default GNU `tar' attempts to "unquote" each file or member name,
>     replacing "escape sequences" according to the following table:
>     ...

However, the output of "tar --help" contradicts this, as it says:

      --no-unquote           do not unquote filenames read with -T
      ...
      --unquote              unquote filenames read with -T (default)

which implies that these two options apply only to file names read via
-T, not to command-line arguments.  Also, when other sections of the
tar manual talk about --unquote and --no-unquote, they consistently
say that the options affect the processing of "input file or member
names", implying that the names are input via a -T option, and are not
command-line arguments.

> If you don't want this behavior, use the --no-unquote option.

I'm afraid that isn't an adequate solution.  All other things being
equal, the default should be a behavior that people expect, a behavior
that is compatible with other implementations of 'tar', and a behavior
that is compatible with how other programs such as file-roller expect
'tar' to work.  If there were a good reason for unquoting command-line
arguments being the default, that would override these important
compatibility concerns, but I don't see what that reason would be.

I'd like to push the following patch to fix this.  I haven't done it
yet, since I know Sergey wants to prepare a new release soon.  But
it's pretty small and I hope it can be squeezed in before the release.


>From ffbfcca24da4e6b0195ed97c049cd757a9370b84 Mon Sep 17 00:00:00 2001
From: Paul Eggert <address@hidden>
Date: Tue, 2 Nov 2010 12:43:01 -0700
Subject: [PATCH] tar: do not unquote command-line arguments

This fixes a problem reported by Dinar in
<http://lists.gnu.org/archive/html/bug-tar/2010-10/msg00083.html>.

* NEWS: Document this.
* doc/tar.texi (Selecting Archive Members): Likewise.
* src/misc.c (quote_copy_string): Likewise.
* src/names.c (name_next_elt): Do not unquote file names here.
* src/tar.c (update_argv): Unquote them here instead.
* tests/extrac18.at: New file, to test for odd strings in file names.
* tests/Makefile.am (TESTSUITE_AT): Add it.
* tests/testsuite.at: Likewise.
---
 NEWS               |    9 ++++++++-
 doc/tar.texi       |    9 ++++++++-
 src/misc.c         |    4 ++--
 src/names.c        |    2 --
 src/tar.c          |    7 ++++++-
 tests/Makefile.am  |    1 +
 tests/extrac18.at  |   43 +++++++++++++++++++++++++++++++++++++++++++
 tests/testsuite.at |    1 +
 8 files changed, 69 insertions(+), 7 deletions(-)
 create mode 100644 tests/extrac18.at

diff --git a/NEWS b/NEWS
index 66d9c88..2820d79 100644
--- a/NEWS
+++ b/NEWS
@@ -1,7 +1,14 @@
-GNU tar NEWS - User visible changes. 2010-10-24
+GNU tar NEWS - User visible changes. 2010-11-02
 Please send GNU tar bug reports to <address@hidden>
 
 
+* --unquote and --no-unquote
+
+Command-line arguments are no longer unquoted, and the --quote and
+--no-unquote options now apply only to file names that are read via
+the --files-from (-T) option.  For example, "tar -cf archive.tar *" no
+longer mishandles files whose names contain backslashes.
+
 version 1.24 - Sergey Poznyakoff, 2010-10-24
 
 * The --full-time option.
diff --git a/doc/tar.texi b/doc/tar.texi
index 6d9d9cc..e7379e2 100644
--- a/doc/tar.texi
+++ b/doc/tar.texi
@@ -6834,7 +6834,8 @@ If a file name begins with dash (@samp{-}), precede it 
with
 option.
 
 @anchor{input name quoting}
-By default @GNUTAR{} attempts to @dfn{unquote} each file or member
+By default when reading file or member names from another file,
address@hidden attempts to @dfn{unquote} each file or member
 name, replacing @dfn{escape sequences} according to the following
 table:
 
@@ -6867,6 +6868,12 @@ Enable unquoting input file or member names (default).
 Disable unquoting input file or member names.
 @end table
 
+These options apply only to file or member names that are input from
+another file, via the @address@hidden
+(@option{-T @var{file-of-names}}) option.  File or member names are
+never unquoted if they are given on the command line, or are taken
+from directory entries when operating recursively.
+
 If you specify a directory name as a file name argument, all the files
 in that directory are operated on by @command{tar}.
 
diff --git a/src/misc.c b/src/misc.c
index cb12947..3902f46 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -107,8 +107,8 @@ quote_copy_string (const char *string)
 
    This is used for reading the saved directory file in incremental
    dumps.  It is used for decoding old `N' records (demangling names).
-   But also, it is used for decoding file arguments, would they come
-   from the shell or a -T file, and for decoding the --exclude
+   But also, it is used for decoding file arguments, if they come
+   from a -T (--files-from) file, and for decoding the --exclude
    argument.  */
 int
 unquote_string (char *string)
diff --git a/src/names.c b/src/names.c
index 6e214bf..5197f43 100644
--- a/src/names.c
+++ b/src/names.c
@@ -358,8 +358,6 @@ name_next_elt (int change_dirs)
        }
       else
        {
-         if (unquote_option)
-           unquote_string (name_buffer);
          if (incremental_option)
            register_individual_file (name_buffer);
          entry.type = ep->type;
diff --git a/src/tar.c b/src/tar.c
index 928cfdd..aa31f10 100644
--- a/src/tar.c
+++ b/src/tar.c
@@ -1243,11 +1243,16 @@ update_argv (const char *filename, struct argp_state 
*state)
 
   state->argc = new_argc;
 
-  for (i = state->next, p = start; *p; p += strlen (p) + 1, i++)
+  for (i = state->next, p = start; *p; i++)
     {
+      size_t len;
       if (term == 0 && p[0] == '-')
        state->argv[i++] = "--add-file";
       state->argv[i] = p;
+      len = strlen (p);
+      if (unquote_option)
+       unquote_string (p);
+      p += len + 1;
     }
 }
 
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 12e8c1b..3a50949 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -85,6 +85,7 @@ TESTSUITE_AT = \
  extrac15.at\
  extrac16.at\
  extrac17.at\
+ extrac18.at\
  filerem01.at\
  filerem02.at\
  gzip.at\
diff --git a/tests/extrac18.at b/tests/extrac18.at
new file mode 100644
index 0000000..b9afbff
--- /dev/null
+++ b/tests/extrac18.at
@@ -0,0 +1,43 @@
+# Process this file with autom4te to create testsuite. -*- Autotest -*-
+
+# Test suite for GNU tar.
+# Copyright (C) 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# written by Paul Eggert from a bug report by Dinar
+# <http://lists.gnu.org/archive/html/bug-tar/2010-10/msg00083.html>
+
+# Check creation and extraction of a file with funny characters.
+
+AT_SETUP([create and extract files names with special characters])
+AT_KEYWORDS([extract extrac18])
+
+AT_TAR_CHECK([
+mkdir src dest
+
+for odd_name in '!' '"' '#' '$' '%' '&' "'" '(' ')' '*' '+' ',' '-' \
+  '...' ':' ';' '<' '=' '>' '?' '@' '[' '\0' '\\' '\n' '\r' '\' ']' '^' _ \
+  '`' '{' '|' '}' 'http:ouch' ; do
+  # Don't worry if the file cannot be created due to an oddball file system.
+  touch src/"$odd_name" 2>/dev/null
+done
+
+(cd src && tar -cf ../archive.tar * .??*) &&
+tar -xf archive.tar -C dest &&
+diff -r src dest
+],
+[0],[],[],[],[],[gnu])
+
+AT_CLEANUP
diff --git a/tests/testsuite.at b/tests/testsuite.at
index d18b16e..bbb8369 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -157,6 +157,7 @@ m4_include([extrac14.at])
 m4_include([extrac15.at])
 m4_include([extrac16.at])
 m4_include([extrac17.at])
+m4_include([extrac18.at])
 
 m4_include([label01.at])
 m4_include([label02.at])
-- 
1.7.2





reply via email to

[Prev in Thread] Current Thread [Next in Thread]