]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Improve handing a wildcard which has "//?/" prefix.
authorMichihiro NAKAJIMA <ggcueroad@gmail.com>
Wed, 4 Jan 2012 05:39:09 +0000 (00:39 -0500)
committerMichihiro NAKAJIMA <ggcueroad@gmail.com>
Wed, 4 Jan 2012 05:39:09 +0000 (00:39 -0500)
SVN-Revision: 4083

libarchive/archive_read_disk_windows.c
libarchive/test/test_read_disk_directory_traversals.c

index 666fc91367bd3afdaa80454b13a90973742434bb..29ffabc7cf7006a9e375323baf579ae467a376a2 100644 (file)
@@ -1438,9 +1438,12 @@ tree_reopen(struct tree *t, const wchar_t *path, int restore_time)
 
        /* First item is set up a lot like a symlink traversal. */
        /* printf("Looking for wildcard in %s\n", path); */
-       if (!(base[0] == L'/' && base[1] == L'/' &&
-             base[2] == L'?' && base[3] == L'/') &&
-           (wcschr(base, L'*') || wcschr(base, L'?'))) {
+       if ((base[0] == L'/' && base[1] == L'/' &&
+            base[2] == L'?' && base[3] == L'/' &&
+            (wcschr(base+4, L'*') || wcschr(base+4, L'?'))) ||
+           (!(base[0] == L'/' && base[1] == L'/' &&
+              base[2] == L'?' && base[3] == L'/') &&
+              (wcschr(base, L'*') || wcschr(base, L'?')))) {
                // It has a wildcard in it...
                // Separate the last element.
                p = wcsrchr(base, L'/');
index a116b4a5025d2e7368f4590dcd4cdd615f085626..d8f874242eff3540170f2b7780f78b199329cd62 100644 (file)
@@ -43,7 +43,7 @@ test_basic(void)
        int64_t offset;
        int file_count;
 #if defined(_WIN32) && !defined(__CYGWIN__)
-       wchar_t *wcwd, *fullpath;
+       wchar_t *wcwd, *wp, *fullpath;
 #endif
 
        assertMakeDir("dir1", 0755);
@@ -415,6 +415,63 @@ test_basic(void)
        assertEqualInt(ARCHIVE_OK, archive_read_close(a));
        free(fullpath);
 
+       /*
+        * Test for wild card '*' or '?' with "//?/" prefix.
+        */
+       wcwd = _wgetcwd(NULL, 0);
+       fullpath = malloc(sizeof(wchar_t) * (wcslen(wcwd) + 32));
+       wcscpy(fullpath, L"//?/");
+       wcscat(fullpath, wcwd);
+       wcscat(fullpath, L"/dir1/*1");
+       free(wcwd);
+       assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open_w(a, fullpath));
+       while ((wcwd = wcschr(fullpath, L'\\')) != NULL)
+               *wcwd = L'/';
+
+       /* dir1/file1 */
+       wp = wcsrchr(fullpath, L'/');
+       wcscpy(wp+1, L"file1");
+       assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
+       assertEqualInt(0, archive_read_disk_can_descend(a));
+       assertEqualWString(archive_entry_pathname_w(ae), fullpath);
+       assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+       assertEqualInt(archive_entry_size(ae), 10);
+       assertEqualIntA(a, ARCHIVE_OK,
+           archive_read_data_block(a, &p, &size, &offset));
+       assertEqualInt((int)size, 10);
+       assertEqualInt((int)offset, 0);
+       assertEqualMem(p, "0123456789", 10);
+
+       /* dir1/sub1 */
+       wcscpy(wp+1, L"sub1");
+       assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
+       assertEqualInt(1, archive_read_disk_can_descend(a));
+       assertEqualWString(archive_entry_pathname_w(ae), fullpath);
+       assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+
+       /* Descend into the current object */
+       assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_descend(a));
+
+       /* dir1/sub1/file1 */
+       wcscpy(wp+1, L"sub1/file1");
+       assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
+       assertEqualInt(0, archive_read_disk_can_descend(a));
+       assertEqualWString(archive_entry_pathname_w(ae), fullpath);
+       assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+       assertEqualInt(archive_entry_size(ae), 10);
+       assertEqualIntA(a, ARCHIVE_OK,
+           archive_read_data_block(a, &p, &size, &offset));
+       assertEqualInt((int)size, 10);
+       assertEqualInt((int)offset, 0);
+       assertEqualMem(p, "0123456789", 10);
+
+       /* There is no entry. */
+       assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
+
+       /* Close the disk object. */
+       assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+       free(fullpath);
+
 #endif
 
        /*