Quellcode durchsuchen

Accept only position-sensitive (file-selection) options in file list files.

Using such options as -f, -z, etc. is senseless in the file list file
and bypasses the option consistency checks in decode_options.  Therefore,
only options related to file selection (a.k.a position-sensitive options)
are allowed in files.

* doc/tar.texi: Document changes.
* src/common.h (tar_args): Move from tar.c
(TAR_ARGS_INITIALIZER): New macro.
* src/names.c: Declare option group identifiers as an enum.
(names_parse_opt): Special handling for ARGP_KEY_ERROR.
(names_argp): Remove static qualifier.
(names_argp_children): Remove.
* src/tar.c: Declare option group identifiers as an enum.
(parse_opt): Special handling for ARGP_KEY_INIT.
(argp_children): New static variable.
(args): Remove static variable.
(more_options): Allow only options from names_argp.
(parse_default_options): Take a pointer to struct tar_args as argument.
Replace the loc member during the call to argp_parse and restore it
afterwards.
(decode_options): Use automatic variable for args.
Sergey Poznyakoff vor 4 Jahren
Ursprung
Commit
1ff0b63f48
4 geänderte Dateien mit 443 neuen und 368 gelöschten Zeilen
  1. 6 3
      doc/tar.texi
  2. 18 0
      src/common.h
  3. 56 43
      src/names.c
  4. 363 322
      src/tar.c

+ 6 - 3
doc/tar.texi

@@ -7730,9 +7730,12 @@ any leading and trailing whitespace.  If the resulting string begins
 with @samp{-} character, it is considered a @command{tar} option and is
 processed accordingly@footnote{Versions of @GNUTAR{} up to 1.15.1
 recognized only @option{-C} option in file lists, and only if the
-option and its argument occupied two consecutive lines.}. For example,
-the common use of this feature is to change to another directory by
-specifying @option{-C} option:
+option and its argument occupied two consecutive lines.}.  Only a
+subset of @GNUTAR{} options is allowed for use in file lists.  For
+a list of such options, @ref{Position-Sensitive Options}.
+
+For example, the common use of this feature is to change to another
+directory by specifying @option{-C} option:
 
 @smallexample
 @group

+ 18 - 0
src/common.h

@@ -834,6 +834,24 @@ struct option_locus
 				 class */
 };
 
+struct tar_args        /* Variables used during option parsing */
+{
+  struct option_locus *loc;
+
+  struct textual_date *textual_date; /* Keeps the arguments to --newer-mtime
+					and/or --date option if they are
+					textual dates */
+  bool o_option;                   /* True if -o option was given */
+  bool pax_option;                 /* True if --pax-option was given */
+  bool compress_autodetect;        /* True if compression autodetection should
+				      be attempted when creating archives */
+  char const *backup_suffix_string;   /* --suffix option argument */
+  char const *version_control_string; /* --backup option argument */
+};
+
+#define TAR_ARGS_INITIALIZER(loc)              \
+  { loc, NULL, false, false, false, NULL, NULL }
+
 void more_options (int argc, char **argv, struct option_locus *loc);
 
 /* Module update.c.  */

+ 56 - 43
src/names.c

@@ -62,89 +62,93 @@ enum
     WILDCARDS_OPTION
   };
 
+enum
+  {
+    GRH_LOCAL,
+    GRID_LOCAL,
+    GRH_MATCH,
+    GRID_MATCH,
+  };
+
 static struct argp_option names_options[] = {
-#define GRID 100
   {NULL, 0, NULL, 0,
-   N_("Local file name selection:"), GRID },
+   N_("Local file name selection:"), GRH_LOCAL },
 
   {"add-file", ADD_FILE_OPTION, N_("FILE"), 0,
-   N_("add given FILE to the archive (useful if its name starts with a dash)"), GRID+1 },
+   N_("add given FILE to the archive (useful if its name starts with a dash)"), GRID_LOCAL },
   {"directory", 'C', N_("DIR"), 0,
-   N_("change to directory DIR"), GRID+1 },
+   N_("change to directory DIR"), GRID_LOCAL },
   {"files-from", 'T', N_("FILE"), 0,
-   N_("get names to extract or create from FILE"), GRID+1 },
+   N_("get names to extract or create from FILE"), GRID_LOCAL },
   {"null", NULL_OPTION, 0, 0,
    N_("-T reads null-terminated names; implies --verbatim-files-from"),
-      GRID+1 },
+      GRID_LOCAL },
   {"no-null", NO_NULL_OPTION, 0, 0,
-   N_("disable the effect of the previous --null option"), GRID+1 },
+   N_("disable the effect of the previous --null option"), GRID_LOCAL },
   {"unquote", UNQUOTE_OPTION, 0, 0,
-   N_("unquote input file or member names (default)"), GRID+1 },
+   N_("unquote input file or member names (default)"), GRID_LOCAL },
   {"no-unquote", NO_UNQUOTE_OPTION, 0, 0,
-   N_("do not unquote input file or member names"), GRID+1 },
+   N_("do not unquote input file or member names"), GRID_LOCAL },
   {"verbatim-files-from", VERBATIM_FILES_FROM_OPTION, 0, 0,
-   N_("-T reads file names verbatim (no escape or option handling)"), GRID+1 },
+   N_("-T reads file names verbatim (no escape or option handling)"), GRID_LOCAL },
   {"no-verbatim-files-from", NO_VERBATIM_FILES_FROM_OPTION, 0, 0,
    N_("-T treats file names starting with dash as options (default)"),
-      GRID+1 },
+      GRID_LOCAL },
   {"exclude", EXCLUDE_OPTION, N_("PATTERN"), 0,
-   N_("exclude files, given as a PATTERN"), GRID+1 },
+   N_("exclude files, given as a PATTERN"), GRID_LOCAL },
   {"exclude-from", 'X', N_("FILE"), 0,
-   N_("exclude patterns listed in FILE"), GRID+1 },
+   N_("exclude patterns listed in FILE"), GRID_LOCAL },
   {"exclude-caches", EXCLUDE_CACHES_OPTION, 0, 0,
    N_("exclude contents of directories containing CACHEDIR.TAG, "
-      "except for the tag file itself"), GRID+1 },
+      "except for the tag file itself"), GRID_LOCAL },
   {"exclude-caches-under", EXCLUDE_CACHES_UNDER_OPTION, 0, 0,
    N_("exclude everything under directories containing CACHEDIR.TAG"),
-   GRID+1 },
+   GRID_LOCAL },
   {"exclude-caches-all", EXCLUDE_CACHES_ALL_OPTION, 0, 0,
-   N_("exclude directories containing CACHEDIR.TAG"), GRID+1 },
+   N_("exclude directories containing CACHEDIR.TAG"), GRID_LOCAL },
   {"exclude-tag", EXCLUDE_TAG_OPTION, N_("FILE"), 0,
    N_("exclude contents of directories containing FILE, except"
-      " for FILE itself"), GRID+1 },
+      " for FILE itself"), GRID_LOCAL },
   {"exclude-ignore", EXCLUDE_IGNORE_OPTION, N_("FILE"), 0,
     N_("read exclude patterns for each directory from FILE, if it exists"),
-   GRID+1 },
+   GRID_LOCAL },
   {"exclude-ignore-recursive", EXCLUDE_IGNORE_RECURSIVE_OPTION, N_("FILE"), 0,
     N_("read exclude patterns for each directory and its subdirectories "
-       "from FILE, if it exists"), GRID+1 },
+       "from FILE, if it exists"), GRID_LOCAL },
   {"exclude-tag-under", EXCLUDE_TAG_UNDER_OPTION, N_("FILE"), 0,
-   N_("exclude everything under directories containing FILE"), GRID+1 },
+   N_("exclude everything under directories containing FILE"), GRID_LOCAL },
   {"exclude-tag-all", EXCLUDE_TAG_ALL_OPTION, N_("FILE"), 0,
-   N_("exclude directories containing FILE"), GRID+1 },
+   N_("exclude directories containing FILE"), GRID_LOCAL },
   {"exclude-vcs", EXCLUDE_VCS_OPTION, NULL, 0,
-   N_("exclude version control system directories"), GRID+1 },
+   N_("exclude version control system directories"), GRID_LOCAL },
   {"exclude-vcs-ignores", EXCLUDE_VCS_IGNORES_OPTION, NULL, 0,
-   N_("read exclude patterns from the VCS ignore files"), GRID+1 },
+   N_("read exclude patterns from the VCS ignore files"), GRID_LOCAL },
   {"exclude-backups", EXCLUDE_BACKUPS_OPTION, NULL, 0,
-   N_("exclude backup and lock files"), GRID+1 },
+   N_("exclude backup and lock files"), GRID_LOCAL },
   {"recursion", RECURSION_OPTION, 0, 0,
-   N_("recurse into directories (default)"), GRID+1 },
+   N_("recurse into directories (default)"), GRID_LOCAL },
   {"no-recursion", NO_RECURSION_OPTION, 0, 0,
-   N_("avoid descending automatically in directories"), GRID+1 },
-#undef GRID
+   N_("avoid descending automatically in directories"), GRID_LOCAL },
 
-#define GRID 120
   {NULL, 0, NULL, 0,
    N_("File name matching options (affect both exclude and include patterns):"),
-   GRID },
+   GRH_MATCH },
   {"anchored", ANCHORED_OPTION, 0, 0,
-   N_("patterns match file name start"), GRID+1 },
+   N_("patterns match file name start"), GRID_MATCH },
   {"no-anchored", NO_ANCHORED_OPTION, 0, 0,
-   N_("patterns match after any '/' (default for exclusion)"), GRID+1 },
+   N_("patterns match after any '/' (default for exclusion)"), GRID_MATCH },
   {"ignore-case", IGNORE_CASE_OPTION, 0, 0,
-   N_("ignore case"), GRID+1 },
+   N_("ignore case"), GRID_MATCH },
   {"no-ignore-case", NO_IGNORE_CASE_OPTION, 0, 0,
-   N_("case sensitive matching (default)"), GRID+1 },
+   N_("case sensitive matching (default)"), GRID_MATCH },
   {"wildcards", WILDCARDS_OPTION, 0, 0,
-   N_("use wildcards (default for exclusion)"), GRID+1 },
+   N_("use wildcards (default for exclusion)"), GRID_MATCH },
   {"no-wildcards", NO_WILDCARDS_OPTION, 0, 0,
-   N_("verbatim string matching"), GRID+1 },
+   N_("verbatim string matching"), GRID_MATCH },
   {"wildcards-match-slash", WILDCARDS_MATCH_SLASH_OPTION, 0, 0,
-   N_("wildcards match '/' (default for exclusion)"), GRID+1 },
+   N_("wildcards match '/' (default for exclusion)"), GRID_MATCH },
   {"no-wildcards-match-slash", NO_WILDCARDS_MATCH_SLASH_OPTION, 0, 0,
-   N_("wildcards do not match '/'"), GRID+1 },
-#undef GRID
+   N_("wildcards do not match '/'"), GRID_MATCH },
 
   {NULL}
 };
@@ -195,12 +199,25 @@ names_parse_opt (int key, char *arg, struct argp_state *state)
     case ADD_FILE_OPTION:
       name_add_name (arg);
       break;
+      
+    case ARGP_KEY_ERROR:
+      {
+	struct tar_args *args = state->input;
+	if (args->loc->source == OPTS_FILE)
+	  {
+	    error (0, 0, _("%s:%lu: unrecognized option"), args->loc->name,
+		   (unsigned long) args->loc->line);
+	    set_exit_status (TAREXIT_FAILURE);
+	  }
+	return ARGP_ERR_UNKNOWN;
+      }
 
     default:
       if (is_file_selection_option (key))
 	name_add_option (key, arg);
       else
 	return ARGP_ERR_UNKNOWN;
+      
     }
   return 0;
 }
@@ -419,7 +436,7 @@ handle_file_selection_option (int key, const char *arg)
     }
 }
 
-static struct argp names_argp = {
+struct argp names_argp = {
   names_options,
   names_parse_opt,
   NULL,
@@ -429,10 +446,6 @@ static struct argp names_argp = {
   NULL
 };
 
-struct argp_child names_argp_children[] = {
-  { &names_argp, 0, "", 0 },
-  { NULL }
-};
 
 /* User and group names.  */
 

Datei-Diff unterdrückt, da er zu groß ist
+ 363 - 322
src/tar.c


Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.