From owner-svn-src-head@FreeBSD.ORG Tue Dec 20 20:34:03 2011 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 71E95106564A; Tue, 20 Dec 2011 20:34:03 +0000 (UTC) (envelope-from mm@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 5C2BA8FC08; Tue, 20 Dec 2011 20:34:03 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id pBKKY3Jc033882; Tue, 20 Dec 2011 20:34:03 GMT (envelope-from mm@svn.freebsd.org) Received: (from mm@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id pBKKY34v033876; Tue, 20 Dec 2011 20:34:03 GMT (envelope-from mm@svn.freebsd.org) Message-Id: <201112202034.pBKKY34v033876@svn.freebsd.org> From: Martin Matuska Date: Tue, 20 Dec 2011 20:34:03 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r228748 - head/lib/libarchive X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 20 Dec 2011 20:34:03 -0000 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 == '/')