Subject: pax and stripping of leading slashes
To: None <tech-userlevel@netbsd.org>
From: James Chacon <jmc@netbsd.org>
List: tech-userlevel
Date: 01/21/2005 02:08:15
--/04w6evG8XlLl3ft
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Does anyone object to the attached patch? It moves the logic for stripping
leading slashes until after any user applied patterns have been made to the
file name. This means folks expecting POSIX behavior from pax and using
patterns (like one we even have in the man page as an example) with /... in
them won't have to add our non-standard -A to their command line to work.

This was brought up in PR#23776.

James


--/04w6evG8XlLl3ft
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=diff

Index: ar_subs.c
===================================================================
RCS file: /cvsroot/src/bin/pax/ar_subs.c,v
retrieving revision 1.34
diff -u -r1.34 ar_subs.c
--- ar_subs.c	22 Oct 2004 21:00:18 -0000	1.34
+++ ar_subs.c	21 Jan 2005 08:04:13 -0000
@@ -118,9 +118,6 @@
 			continue;
 		}
 
-		if (arcn->name[0] == '/' && !check_Aflag()) {
-			memmove(arcn->name, arcn->name + 1, strlen(arcn->name));
-		}
 		/*
 		 * check for pattern, and user specified options match.
 		 * When all patterns are matched we are done.
@@ -141,8 +138,13 @@
 			 */
 			if ((res = mod_name(arcn)) < 0)
 				break;
-			if (res == 0)
+			if (res == 0) {
+				if (arcn->name[0] == '/' && !check_Aflag()) {
+					memmove(arcn->name, arcn->name + 1, 
+					    strlen(arcn->name));
+				}
 				ls_list(arcn, now, stdout);
+			}
 			/*
 			 * if there's an error writing to stdout then we must
 			 * stop now -- we're probably writing to a pipe that
@@ -229,9 +231,6 @@
 			continue;
 		}
 
-		if (arcn->name[0] == '/' && !check_Aflag()) {
-			memmove(arcn->name, arcn->name + 1, strlen(arcn->name));
-		}
 		/*
 		 * check for pattern, and user specified options match. When
 		 * all the patterns are matched we are done
@@ -291,6 +290,9 @@
 			continue;
 		}
 
+		if (arcn->name[0] == '/' && !check_Aflag()) {
+			memmove(arcn->name, arcn->name + 1, strlen(arcn->name));
+		}
 		/*
 		 * Non standard -Y and -Z flag. When the existing file is
 		 * same age or newer skip; ignore this for GNU long links.
@@ -497,9 +499,6 @@
 			}
 		}
 
-		if (arcn->name[0] == '/' && !check_Aflag()) {
-			memmove(arcn->name, arcn->name + 1, strlen(arcn->name));
-		}
 		/*
 		 * Now modify the name as requested by the user
 		 */
@@ -513,6 +512,10 @@
 			break;
 		}
 
+		if (arcn->name[0] == '/' && !check_Aflag()) {
+			memmove(arcn->name, arcn->name + 1, strlen(arcn->name));
+		}
+
 		if ((res > 0) || (docrc && (set_crc(arcn, fd) < 0))) {
 			/*
 			 * unable to obtain the crc we need, close the file,
Index: pat_rep.c
===================================================================
RCS file: /cvsroot/src/bin/pax/pat_rep.c,v
retrieving revision 1.21
diff -u -r1.21 pat_rep.c
--- pat_rep.c	27 Oct 2003 00:12:41 -0000	1.21
+++ pat_rep.c	21 Jan 2005 08:04:13 -0000
@@ -651,38 +651,6 @@
 {
 	int res = 0;
 
-	/*
-	 * Strip off leading '/' if appropriate.
-	 * Currently, this option is only set for the tar format.
-	 */
-	if (rmleadslash && arcn->name[0] == '/') {
-		if (arcn->name[1] == '\0') {
-			arcn->name[0] = '.';
-		} else {
-			(void)memmove(arcn->name, &arcn->name[1],
-			    strlen(arcn->name));
-			arcn->nlen--;
-		}
-		if (rmleadslash < 2) {
-			rmleadslash = 2;
-			tty_warn(0, "Removing leading / from absolute path names in the archive");
-		}
-	}
-	if (rmleadslash && arcn->ln_name[0] == '/' &&
-	    (arcn->type == PAX_HLK || arcn->type == PAX_HRG)) {
-		if (arcn->ln_name[1] == '\0') {
-			arcn->ln_name[0] = '.';
-		} else {
-			(void)memmove(arcn->ln_name, &arcn->ln_name[1],
-			    strlen(arcn->ln_name));
-			arcn->ln_nlen--;
-		}
-		if (rmleadslash < 2) {
-			rmleadslash = 2;
-			tty_warn(0, "Removing leading / from absolute path names in the archive");
-		}
-	}
-
 	if (secure) {
 		if (checkdotdot(arcn->name)) {
 			tty_warn(0, "Ignoring file containing `..' (%s)",
@@ -743,6 +711,39 @@
 		    (arcn->type == PAX_HRG))
 			sub_name(arcn->ln_name, &(arcn->ln_nlen), sizeof(arcn->ln_name));
 	}
+
+	/*
+	 * Strip off leading '/' if appropriate.
+	 * Currently, this option is only set for the tar format.
+	 */
+	if (rmleadslash && arcn->name[0] == '/') {
+		if (arcn->name[1] == '\0') {
+			arcn->name[0] = '.';
+		} else {
+			(void)memmove(arcn->name, &arcn->name[1],
+			    strlen(arcn->name));
+			arcn->nlen--;
+		}
+		if (rmleadslash < 2) {
+			rmleadslash = 2;
+			tty_warn(0, "Removing leading / from absolute path names in the archive");
+		}
+	}
+	if (rmleadslash && arcn->ln_name[0] == '/' &&
+	    (arcn->type == PAX_HLK || arcn->type == PAX_HRG)) {
+		if (arcn->ln_name[1] == '\0') {
+			arcn->ln_name[0] = '.';
+		} else {
+			(void)memmove(arcn->ln_name, &arcn->ln_name[1],
+			    strlen(arcn->ln_name));
+			arcn->ln_nlen--;
+		}
+		if (rmleadslash < 2) {
+			rmleadslash = 2;
+			tty_warn(0, "Removing leading / from absolute path names in the archive");
+		}
+	}
+
 	return(res);
 }
 

--/04w6evG8XlLl3ft--