From owner-svn-src-head@FreeBSD.ORG Sun Mar 8 06:07:36 2009 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 3034D106564A; Sun, 8 Mar 2009 06:07:36 +0000 (UTC) (envelope-from kientzle@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 1D4EE8FC12; Sun, 8 Mar 2009 06:07:36 +0000 (UTC) (envelope-from kientzle@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n2867aeJ074274; Sun, 8 Mar 2009 06:07:36 GMT (envelope-from kientzle@svn.freebsd.org) Received: (from kientzle@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n2867ZH3074271; Sun, 8 Mar 2009 06:07:35 GMT (envelope-from kientzle@svn.freebsd.org) Message-Id: <200903080607.n2867ZH3074271@svn.freebsd.org> From: Tim Kientzle Date: Sun, 8 Mar 2009 06:07:35 +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: r189523 - in head/usr.bin/tar: . test 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: Sun, 08 Mar 2009 06:07:36 -0000 Author: kientzle Date: Sun Mar 8 06:07:35 2009 New Revision: 189523 URL: http://svn.freebsd.org/changeset/base/189523 Log: Merge r709,r710 from libarchive.googlecode.com: More work on Windows support. Added: head/usr.bin/tar/test/test_patterns_4.tar.uu (contents, props changed) Modified: head/usr.bin/tar/test/test_patterns.c head/usr.bin/tar/util.c Modified: head/usr.bin/tar/test/test_patterns.c ============================================================================== --- head/usr.bin/tar/test/test_patterns.c Sun Mar 8 06:03:28 2009 (r189522) +++ head/usr.bin/tar/test/test_patterns.c Sun Mar 8 06:07:35 2009 (r189523) @@ -1,4 +1,5 @@ /*- + * Copyright (c) 2009 Michihiro NAKAJIMA * Copyright (c) 2003-2007 Tim Kientzle * All rights reserved. * @@ -30,6 +31,7 @@ DEFINE_TEST(test_patterns) int fd, r; const char *reffile2 = "test_patterns_2.tar"; const char *reffile3 = "test_patterns_3.tar"; + const char *reffile4 = "test_patterns_4.tar"; const char *p; /* @@ -101,4 +103,81 @@ DEFINE_TEST(test_patterns) assertEmptyFile("tar3d.out"); assertEmptyFile("tar3d.err"); assertEqualInt(0, access("tmp/foo/baz/bar", F_OK)); + + /* + * Test 4 archive has some entries starting with windows drive letters + * such as 'c:\', '//./c:/' or '//?/c:/'. + */ + extract_reference_file(reffile4); + + r = systemf("%s xf %s -C tmp > tar4.out 2> tar4.err", + testprog, reffile4); + assert(r != 0); + assertEmptyFile("tar4.out"); + assertNonEmptyFile("tar4.err"); + + for (r = 1; r <= 54; r++) { + char file_a[] = "tmp/fileXX"; + char file_b1[] = "tmp/server/share/fileXX"; + char file_b2[] = "tmp/server\\share\\fileXX"; + char file_c[] = "tmp/../fileXX"; + char *filex; + int xsize; + + switch (r) { + case 15: case 18: + /* + * Including server and share names. + * //?/UNC/server/share/file15 + * //?/unc/server/share/file18 + */ + filex = file_b1; + xsize = sizeof(file_b1); + break; + case 35: case 38: case 52: + /* + * Including server and share names. + * \\?\UNC\server\share\file35 + * \\?\unc\server\share\file38 + * \/?/uNc/server\share\file52 + */ + filex = file_b2; + xsize = sizeof(file_b2); + break; + default: + filex = file_a; + xsize = sizeof(file_a); + break; + } + filex[xsize-3] = '0' + r / 10; + filex[xsize-2] = '0' + r % 10; + switch (r) { + case 5: case 6: case 17: case 20: case 25: + case 26: case 37: case 40: case 43: case 54: + /* + * Not extracted patterns. + * D:../file05 + * c:../../file06 + * //?/UNC/../file17 + * //?/unc/../file20 + * z:..\file25 + * c:..\..\file26 + * \\?\UNC\..\file37 + * \\?\unc\..\file40 + * c:../..\file43 + * \/?\UnC\../file54 + */ + assertEqualInt(-1, access(filex, F_OK)); + filex = file_c; + xsize = sizeof(file_c); + filex[xsize-3] = '0' + r / 10; + filex[xsize-2] = '0' + r % 10; + assertEqualInt(-1, access(filex, F_OK)); + break; + default: + /* Extracted patterns. */ + assertEqualInt(0, access(filex, F_OK)); + break; + } + } } Added: head/usr.bin/tar/test/test_patterns_4.tar.uu ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/usr.bin/tar/test/test_patterns_4.tar.uu Sun Mar 8 06:07:35 2009 (r189523) @@ -0,0 +1,642 @@ +$FreeBSD$ +begin 644 test_patterns_4.tar +M+V9I;&4P,0`````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````#`P,#8T-"``,#`Q-S4Q(``P,#$W-3$@`#`P,#`P,#`P,#`P +M(#$Q,34P-CCHN+EQF:6QE,C4````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````#`P,#8T-"``,#`Q-S4Q(``P,#$W-3$@`#`P,#`P,#`P +M,#`P(#$Q,34P-Coption_absolute_paths) { - /* Strip Windows drive letters. */ - if (((name[0] >= 'A' && name[0] <= 'Z') - || (name[0] >= 'a' && name[0] <= 'z')) - && name[1] == ':' - && (name[2] == '/' || name[2] == '\\')) + const char *rp, *p = name; + int slashonly = 1; + + /* Remove leading "//./" or "//?/" or "//?/UNC/" + * (absolute path prefixes used by Windows API) */ + if ((p[0] == '/' || p[0] == '\\') && + (p[1] == '/' || p[1] == '\\') && + (p[2] == '.' || p[2] == '?') && + (p[3] == '/' || p[3] == '\\')) { - /* Generate a warning the first time this happens. */ - if (!bsdtar->warned_lead_slash) { - bsdtar_warnc(bsdtar, 0, - "Removing leading drive letter from member names"); - bsdtar->warned_lead_slash = 1; - } - name += 3; - while (*name == '/' || *name == '\\') - ++name; - /* Special case: Stripping everything yields ".". */ - if (*name == '\0') - name = "."; + 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; + else + p += 4; + slashonly = 0; } + do { + rp = p; + /* Remove leading drive letter from archives created + * on Windows. */ + if (((p[0] >= 'a' && p[0] <= 'z') || + (p[0] >= 'A' && p[0] <= 'Z')) && + p[1] == ':') { + 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 "/". */ + } + } while (rp != p); - /* Strip leading '/'. */ - if (name[0] == '/') { + if (p != name && !bsdtar->warned_lead_slash) { /* Generate a warning the first time this happens. */ - if (!bsdtar->warned_lead_slash) { + if (slashonly) bsdtar_warnc(bsdtar, 0, - "Removing leading '/' from member names"); - bsdtar->warned_lead_slash = 1; - } - name++; - /* Special case: Stripping everything yields ".". */ - if (*name == '\0') - name = "."; + "Removing leading '%c' from member names", + name[0]); + else + bsdtar_warnc(bsdtar, 0, + "Removing leading drive letter from " + "member names"); + bsdtar->warned_lead_slash = 1; } + + /* Special case: Stripping everything yields ".". */ + if (*p == '\0') + name = "."; + else + name = p; + } else { + /* Strip redundant leading '/' characters. */ + while (name[0] == '/' && name[1] == '/') + name++; } /* Safely replace name in archive_entry. */