Browse Source

--strip strips file system prefix too, and it counts adjacent
slashes as if they were one slash.

Paul Eggert 21 years ago
parent
commit
07286647fb
4 changed files with 32 additions and 11 deletions
  1. 12 0
      ChangeLog
  2. 1 1
      src/common.h
  3. 3 2
      src/extract.c
  4. 16 8
      src/names.c

+ 12 - 0
ChangeLog

@@ -1,3 +1,15 @@
+2003-09-22  Paul Eggert  <[email protected]>
+
+	* doc/tar.texi (extracting untrusted archives): New section.
+
+	* src/common.h (stripped_path_len): Renamed from cut_path_elements.
+	Return size_t, not pointer, so that we don't have to worry about
+	violating the C standard by converting char const * to char *.
+	All callers changed.
+	* src/names.c (stripped_path_len): Likewise.  Strip file system
+	prefix, too.  Count adjacent slashes as if they were one slash;
+	that is the POSIX standard.
+
 2003-09-17  Paul Eggert  <[email protected]>
 
 	* README-alpha: Document maintainer tool assumptions a bit.  GNU

+ 1 - 1
src/common.h

@@ -567,7 +567,7 @@ char *name_from_list (void);
 void blank_name_list (void);
 char *new_name (const char *, const char *);
 char *safer_name_suffix (char const *, bool);
-char const *cut_path_elements (char const *file_name, size_t num);
+size_t stripped_path_len (char const *file_name, size_t num);
 
 bool excluded_name (char const *);
 

+ 3 - 2
src/extract.c

@@ -719,12 +719,13 @@ extract_archive (void)
   file_name = safer_name_suffix (current_stat_info.file_name, 0);
   if (strip_path_elements)
     {
-      file_name = cut_path_elements (file_name, strip_path_elements);
-      if (!file_name)
+      size_t prefix_len = stripped_prefix_len (file_name, strip_path_elements);
+      if (prefix_len == (size_t) -1)
 	{
 	  skip_member ();
 	  return;
 	}
+      file_name += prefix_len;
     }
   
   apply_nonancestor_delayed_set_stat (file_name, 0);

+ 16 - 8
src/names.c

@@ -1043,21 +1043,29 @@ safer_name_suffix (char const *file_name, bool link_target)
   return (char *) p;
 }
 
-char const *
-cut_path_elements (char const *file_name, size_t num)
+/* Return the size of the prefix of FILE_NAME that is removed after
+   stripping NUM leading path name components.  NUM must be
+   positive.  */
+
+size_t
+stripped_prefix_len (char const *file_name, size_t num)
 {
-  char const *p = file_name;
-  if (ISSLASH (*p))
+  char const *p = file_name + FILESYSTEM_PREFIX_LEN (file_name);
+  while (ISSLASH (*p))
     p++;
-  for (; *p; p++)
+  while (*p)
     {
-      if (ISSLASH (*p))
+      bool slash = ISSLASH (*p);
+      p++;
+      if (slash)
 	{
 	  if (--num == 0)
-	    return p + 1;
+	    return p - file_name;
+	  while (ISSLASH (*p))
+	    p++;
 	}
     }
-  return NULL;
+  return -1;
 }
 
 /* Return nonzero if NAME contains ".." as a path name component.  */