]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Improve directory traversals on Windows to correctly handle the path which starts...
authorMichihiro NAKAJIMA <ggcueroad@gmail.com>
Thu, 29 Dec 2011 02:19:45 +0000 (21:19 -0500)
committerMichihiro NAKAJIMA <ggcueroad@gmail.com>
Thu, 29 Dec 2011 02:19:45 +0000 (21:19 -0500)
SVN-Revision: 4024

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

index d8a1f5577b1877a5c5d72dcfd9004304bb896803..e5188c994c20ece4f4ac5aaa628c8fe54468001b 100644 (file)
@@ -1277,8 +1277,9 @@ 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); */
-       /* TODO: wildcard detection here screws up on \\?\c:\ UNC names */
-       if (wcschr(base, L'*') || wcschr(base, L'?')) {
+       if (!(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'/');
@@ -1374,7 +1375,9 @@ tree_next(struct tree *t)
                if (t->stack->flags & needsFirstVisit) {
                        wchar_t *d = t->stack->name.s;
                        t->stack->flags &= ~needsFirstVisit;
-                       if (wcschr(d, L'*') || wcschr(d, L'?')) {
+                       if (!(d[0] == L'/' && d[1] == L'/' &&
+                             d[2] == L'?' && d[3] == L'/') &&
+                           (wcschr(d, L'*') || wcschr(d, L'?'))) {
                                r = tree_dir_next_windows(t, d);
                                if (r == 0)
                                        continue;
index a1d6e1ad5e3168a2304ab3e3ef0cdb6e819fcc0f..c3288730c24ffca461326306277a4bdf3b7c464b 100644 (file)
@@ -42,6 +42,9 @@ test_basic(void)
        size_t size;
        int64_t offset;
        int file_count;
+#if defined(_WIN32) && !defined(__CYGWIN__)
+       wchar_t *wcwd, *fullpath;
+#endif
 
        assertMakeDir("dir1", 0755);
        assertMakeFile("dir1/file1", 0644, "0123456789");
@@ -351,6 +354,38 @@ test_basic(void)
 
        /* Close the disk object. */
        assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+
+       /*
+        * Test for a full-path beginning with "//?/"
+        */
+       wcwd = _wgetcwd(NULL, 0);
+       fullpath = malloc(sizeof(wchar_t) * (wcslen(wcwd) + 32));
+       wcscpy(fullpath, L"//?/");
+       wcscat(fullpath, wcwd);
+       wcscat(fullpath, L"/dir1/file1");
+       free(wcwd);
+       assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open_w(a, fullpath));
+       while ((wcwd = wcschr(fullpath, L'\\')) != NULL)
+               *wcwd = L'/';
+
+       /* dir1/file1 */
+       assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
+       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
 
        /*