Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 20 Dec 2011 20:34:03 +0000 (UTC)
From:      Martin Matuska <mm@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r228748 - head/lib/libarchive
Message-ID:  <201112202034.pBKKY34v033876@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mm
Date: Tue Dec 20 20:34:02 2011
New Revision: 228748
URL: http://svn.freebsd.org/changeset/base/228748

Log:
  Sync libarchive with vendor branch release/2.8:
  
  3730:
  Fix issue 174 (Windows path names, not relevant for FreeBSD)
  
  3734:
  Merge r1989: archive_clear_error should set errno to 0.
  
  3735:
  Merge r3247 from trunk: Clear errors before returning
  from archive_read_support_format_all()
  
  3799:
  Check the position before dereferencing the pointer.
  This avoids dereferencing one byte past the end of a string
  
  3824:
  Merge r3823 from trunk for issue 199 (hang in iso9660 reading)
  
  Obtained from:	http://code.google.com/p/libarchive
  MFC after:	2 weeks

Modified:
  head/lib/libarchive/archive_read_support_format_all.c
  head/lib/libarchive/archive_read_support_format_iso9660.c
  head/lib/libarchive/archive_string.c
  head/lib/libarchive/archive_util.c
  head/lib/libarchive/archive_write_disk.c

Modified: head/lib/libarchive/archive_read_support_format_all.c
==============================================================================
--- head/lib/libarchive/archive_read_support_format_all.c	Tue Dec 20 20:29:45 2011	(r228747)
+++ head/lib/libarchive/archive_read_support_format_all.c	Tue Dec 20 20:34:02 2011	(r228748)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2003-2011 Tim Kientzle
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -39,5 +39,13 @@ archive_read_support_format_all(struct a
 	archive_read_support_format_tar(a);
 	archive_read_support_format_xar(a);
 	archive_read_support_format_zip(a);
+
+	/* Note: We always return ARCHIVE_OK here, even if some of the
+	 * above return ARCHIVE_WARN.  The intent here is to enable
+	 * "as much as possible."  Clients who need specific
+	 * compression should enable those individually so they can
+	 * verify the level of support. */
+	/* Clear any warning messages set by the above functions. */
+	archive_clear_error(a);
 	return (ARCHIVE_OK);
 }

Modified: head/lib/libarchive/archive_read_support_format_iso9660.c
==============================================================================
--- head/lib/libarchive/archive_read_support_format_iso9660.c	Tue Dec 20 20:29:45 2011	(r228747)
+++ head/lib/libarchive/archive_read_support_format_iso9660.c	Tue Dec 20 20:34:02 2011	(r228748)
@@ -302,6 +302,8 @@ struct file_info {
 		struct file_info	*first;
 		struct file_info	**last;
 	} rede_files;
+	/* To check a ininity loop. */
+	struct file_info	*loop_by;
 };
 
 struct heap_queue {
@@ -2699,8 +2701,14 @@ rede_add_entry(struct file_info *file)
 	struct file_info *re;
 
 	re = file->parent;
-	while (re != NULL && !re->re)
+	while (re != NULL && !re->re) {
+		/* Sanity check to prevent a infinity loop
+		 * cause by a currupted iso file. */
+		if (re->loop_by == file)
+			return (-1);
+		re->loop_by = file;
 		re = re->parent;
+	}
 	if (re == NULL)
 		return (-1);
 

Modified: head/lib/libarchive/archive_string.c
==============================================================================
--- head/lib/libarchive/archive_string.c	Tue Dec 20 20:29:45 2011	(r228747)
+++ head/lib/libarchive/archive_string.c	Tue Dec 20 20:34:02 2011	(r228748)
@@ -152,7 +152,7 @@ __archive_strncat(struct archive_string 
 	/* Like strlen(p), except won't examine positions beyond p[n]. */
 	s = 0;
 	pp = p;
-	while (*pp && s < n) {
+	while (s < n && *pp) {
 		pp++;
 		s++;
 	}

Modified: head/lib/libarchive/archive_util.c
==============================================================================
--- head/lib/libarchive/archive_util.c	Tue Dec 20 20:29:45 2011	(r228747)
+++ head/lib/libarchive/archive_util.c	Tue Dec 20 20:34:02 2011	(r228748)
@@ -155,6 +155,7 @@ archive_clear_error(struct archive *a)
 {
 	archive_string_empty(&a->error_string);
 	a->error = NULL;
+	a->archive_error_number = 0;
 }
 
 void

Modified: head/lib/libarchive/archive_write_disk.c
==============================================================================
--- head/lib/libarchive/archive_write_disk.c	Tue Dec 20 20:29:45 2011	(r228747)
+++ head/lib/libarchive/archive_write_disk.c	Tue Dec 20 20:34:02 2011	(r228748)
@@ -1513,6 +1513,22 @@ check_symlinks(struct archive_write_disk
 }
 
 #if defined(_WIN32) || defined(__CYGWIN__)
+static int
+guidword(const char *p, int n)
+{
+	int i;
+
+	for (i = 0; i < n; i++) {
+		if ((*p >= '0' && *p <= '9') ||
+		    (*p >= 'a' && *p <= 'f') ||
+		    (*p >= 'A' && *p <= 'F'))
+			p++;
+		else
+			return (-1);
+	}
+	return (0);
+}
+
 /*
  * 1. Convert a path separator from '\' to '/' .
  *    We shouldn't check multi-byte character directly because some
@@ -1521,26 +1537,92 @@ check_symlinks(struct archive_write_disk
  * 2. Replace unusable characters in Windows with underscore('_').
  * See also : http://msdn.microsoft.com/en-us/library/aa365247.aspx
  */
-static void
+static int
 cleanup_pathname_win(struct archive_write_disk *a)
 {
 	wchar_t wc;
 	char *p;
 	size_t alen, l;
 
-	alen = 0;
-	l = 0;
-	for (p = a->name; *p != '\0'; p++) {
-		++alen;
-		if (*p == '\\')
-			l = 1;
+	p = a->name;
+	/* Skip leading "\\.\" or "\\?\" or "\\?\UNC\" or
+	 * "\\?\Volume{GUID}\"
+	 * (absolute path prefixes used by Windows API) */
+	if ((p[0] == '\\' || p[0] == '/') && (p[1] == '\\' || p[1] == '/' ) &&
+	    (p[2] == '.' || p[2] == '?') && (p[3] ==  '\\' || p[3] == '/'))
+	{
+		/* A path begin with "\\?\UNC\" */
+		if (p[2] == '?' &&
+		    (p[4] == 'U' || p[4] == 'u') &&
+		    (p[5] == 'N' || p[5] == 'n') &&
+		    (p[6] == 'C' || p[6] == 'c') &&
+		    (p[7] == '\\' || p[7] == '/'))
+			p += 8;
+		/* A path begin with "\\?\Volume{GUID}\" */
+		else if (p[2] == '?' &&
+		    (p[4] == 'V' || p[4] == 'v') &&
+		    (p[5] == 'O' || p[5] == 'o') &&
+		    (p[6] == 'L' || p[6] == 'l') &&
+		    (p[7] == 'U' || p[7] == 'u') &&
+		    (p[8] == 'M' || p[8] == 'm') &&
+		    (p[9] == 'E' || p[9] == 'e') &&
+		    p[10] == '{') {
+			if (guidword(p+11, 8) == 0 && p[19] == '-' &&
+			    guidword(p+20, 4) == 0 && p[24] == '-' &&
+			    guidword(p+25, 4) == 0 && p[29] == '-' &&
+			    guidword(p+30, 4) == 0 && p[34] == '-' &&
+			    guidword(p+35, 12) == 0 && p[47] == '}' &&
+			    (p[48] == '\\' || p[48] == '/'))
+				p += 49;
+			else
+				p += 4;
+		/* A path begin with "\\.\PhysicalDriveX" */
+		} else if (p[2] == '.' &&
+		    (p[4] == 'P' || p[4] == 'p') &&
+		    (p[5] == 'H' || p[5] == 'h') &&
+		    (p[6] == 'Y' || p[6] == 'y') &&
+		    (p[7] == 'S' || p[7] == 's') &&
+		    (p[8] == 'I' || p[8] == 'i') &&
+		    (p[9] == 'C' || p[9] == 'c') &&
+		    (p[9] == 'A' || p[9] == 'a') &&
+		    (p[9] == 'L' || p[9] == 'l') &&
+		    (p[9] == 'D' || p[9] == 'd') &&
+		    (p[9] == 'R' || p[9] == 'r') &&
+		    (p[9] == 'I' || p[9] == 'i') &&
+		    (p[9] == 'V' || p[9] == 'v') &&
+		    (p[9] == 'E' || p[9] == 'e') &&
+		    (p[10] >= '0' && p[10] <= '9') &&
+		    p[11] == '\0') {
+			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+			    "Path is a physical drive name");
+			return (ARCHIVE_FAILED);
+		} else
+			p += 4;
+	}
+
+	/* Skip leading drive letter from archives created
+	 * on Windows. */
+	if (((p[0] >= 'a' && p[0] <= 'z') ||
+	     (p[0] >= 'A' && p[0] <= 'Z')) &&
+		 p[1] == ':') {
+		if (p[2] == '\0') {
+			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+			    "Path is a drive name");
+			return (ARCHIVE_FAILED);
+		}
+		if (p[2] == '\\' || p[2] == '/')
+			p += 3;
+	}
+
+	for (; *p != '\0'; p++) {
 		/* Rewrite the path name if its character is a unusable. */
 		if (*p == ':' || *p == '*' || *p == '?' || *p == '"' ||
 		    *p == '<' || *p == '>' || *p == '|')
 			*p = '_';
 	}
-	if (alen == 0 || l == 0)
-		return;
+	alen = p - a->name;
+	if (alen == 0 || strchr(a->name, '\\') == NULL)
+		return (ARCHIVE_OK);
 	/*
 	 * Convert path separator.
 	 */
@@ -1560,6 +1642,7 @@ cleanup_pathname_win(struct archive_writ
 		p += l;
 		alen -= l;
 	}
+	return (ARCHIVE_OK);
 }
 #endif
 
@@ -1583,7 +1666,8 @@ cleanup_pathname(struct archive_write_di
 	}
 
 #if defined(_WIN32) || defined(__CYGWIN__)
-	cleanup_pathname_win(a);
+	if (cleanup_pathname_win(a) != ARCHIVE_OK)
+		return (ARCHIVE_FAILED);
 #endif
 	/* Skip leading '/'. */
 	if (*src == '/')



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201112202034.pBKKY34v033876>