svn commit: r271016 - stable/8/contrib/libarchive/tar

Andrey V. Elsukov ae at FreeBSD.org
Wed Sep 3 11:17:27 UTC 2014


Author: ae
Date: Wed Sep  3 11:17:27 2014
New Revision: 271016
URL: http://svnweb.freebsd.org/changeset/base/271016

Log:
  MFC r270661:
    Remove leading '/' from hardlink name when removing them from the
    regular file name. This fixes the problem, when bsdtar can not create
    hardlinks to extracted files.

Modified:
  stable/8/contrib/libarchive/tar/util.c
Directory Properties:
  stable/8/contrib/libarchive/tar/   (props changed)

Modified: stable/8/contrib/libarchive/tar/util.c
==============================================================================
--- stable/8/contrib/libarchive/tar/util.c	Wed Sep  3 11:17:11 2014	(r271015)
+++ stable/8/contrib/libarchive/tar/util.c	Wed Sep  3 11:17:27 2014	(r271016)
@@ -349,6 +349,21 @@ strip_components(const char *p, int elem
 	}
 }
 
+static const char*
+strip_leading_slashes(const char *p)
+{
+
+	/* Remove leading "/../", "//", etc. */
+	while (p[0] == '/' || p[0] == '\\') {
+		if (p[1] == '.' && p[2] == '.' && (
+		    p[3] == '/' || p[3] == '\\')) {
+			p += 3; /* Remove "/..", leave "/" for next pass. */
+		} else
+			p += 1; /* Remove "/". */
+	}
+	return (p);
+}
+
 /*
  * Handle --strip-components and any future path-rewriting options.
  * Returns non-zero if the pathname should not be extracted.
@@ -453,16 +468,7 @@ edit_pathname(struct bsdtar *bsdtar, str
 				p += 2;
 				slashonly = 0;
 			}
-			/* Remove leading "/../", "//", etc. */
-			while (p[0] == '/' || p[0] == '\\') {
-				if (p[1] == '.' && p[2] == '.' &&
-					(p[3] == '/' || p[3] == '\\')) {
-					p += 3; /* Remove "/..", leave "/"
-							 * for next pass. */
-					slashonly = 0;
-				} else
-					p += 1; /* Remove "/". */
-			}
+			p = strip_leading_slashes(p);
 		} while (rp != p);
 
 		if (p != name && !bsdtar->warned_lead_slash) {
@@ -483,6 +489,19 @@ edit_pathname(struct bsdtar *bsdtar, str
 			name = ".";
 		else
 			name = p;
+
+		p = archive_entry_hardlink(entry);
+		if (p != NULL) {
+			rp = strip_leading_slashes(p);
+			if (rp == '\0')
+				return (1);
+			if (rp != p) {
+				char *linkname = strdup(rp);
+
+				archive_entry_copy_hardlink(entry, linkname);
+				free(linkname);
+			}
+		}
 	} else {
 		/* Strip redundant leading '/' characters. */
 		while (name[0] == '/' && name[1] == '/')


More information about the svn-src-all mailing list