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

tar -s bug



First of all, I don't want to waste anyone's time that is doing SMP
work.  Please ignore this if that is the case.

tar(1) does regular expression substitution incorrectly:

jaredy% touch abcde
jaredy% tar cf foo.tar abcde 
jaredy% tar tf foo.tar 
abcde
jaredy% tar tfs foo.tar '/b/z/'
azcde
jaredy% tar tfs foo.tar '/b/&/'
accde
jaredy% tar tfs foo.tar '/\(b\)/\1/'
accde

As you can see, tar replaced 'b' with 'c,' not 'b.'  Further
examples wil reveal it has a simple offset problem.

There are a few other issues whose reports are forthcoming.

Here is a suggested fix for this problem.

Index: pat_rep.c
===================================================================
RCS file: /cvs/src/bin/pax/pat_rep.c,v
retrieving revision 1.26
diff -u -r1.26 pat_rep.c
--- pat_rep.c	16 Apr 2004 22:50:23 -0000	1.26
+++ pat_rep.c	10 Jun 2004 16:27:23 -0000
@@ -863,7 +863,7 @@
 	char *endpt;
 	char *rpt;
 	int found = 0;
-	int res;
+	int res, i;
 	regmatch_t pm[MAXSUBEXP];
 	char nname[PAXPATHLEN+1];	/* final result of all replacements */
 	char buf1[PAXPATHLEN+1];	/* where we work on the name */
@@ -903,6 +903,16 @@
 			 */
 			found = 1;
 			rpt = inpt + pm[0].rm_so;
+
+			/*
+			 * Since `inpt' is being advanced next, the offsets
+			 * need to be adjusted to point to the correct
+			 * characters.
+			 */
+			for (i = 0; i <= pt->rcmp.re_nsub; i++) {
+				pm[i].rm_so -= rpt - inpt;
+				pm[i].rm_eo -= rpt - inpt;
+			}
 
 			while ((inpt < rpt) && (outpt < endpt))
 				*outpt++ = *inpt++;