Skip to content

Commit e0c0de0

Browse files
committed
Fix #77978: Dirname ending in colon unzips to wrong dir
When making the relative path, we must not stop on a `:\` sequence in the middle of the filename. This is only significant on Windows as it may indicate an absolute filename, but this is already checked at the beginning of the function. Note that the bug and this patch affects all systems. However, on Windows the file is no longer extracted at all, since Windows NTSF does not allow filenames containing colons. Closes GH-7528.
1 parent 69514e6 commit e0c0de0

File tree

3 files changed

+40
-2
lines changed

3 files changed

+40
-2
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ PHP NEWS
3434

3535
- Zip:
3636
. Fixed bug #81490 (ZipArchive::extractTo() may leak memory). (cmb, Remi)
37+
. Fixed bug #77978 (Dirname ending in colon unzips to wrong dir). (cmb)
3738

3839
23 Sep 2021, PHP 7.4.24
3940

ext/zip/php_zip.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,8 @@ static char * php_zip_make_relative_path(char *path, size_t path_len) /* {{{ */
117117
return path;
118118
}
119119

120-
if (i >= 2 && (path[i -1] == '.' || path[i -1] == ':')) {
121-
/* i is the position of . or :, add 1 for / */
120+
if (i >= 2 && path[i -1] == '.') {
121+
/* i is the position of ., add 1 for / */
122122
path_begin = path + i + 1;
123123
break;
124124
}

ext/zip/tests/bug77978.phpt

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
--TEST--
2+
Bug #77978 (Dirname ending in colon unzips to wrong dir)
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded("zip")) die("skip zip extension not available");
6+
?>
7+
--FILE--
8+
<?php
9+
$file = __DIR__ . "/bug77978.zip";
10+
$target = __DIR__ . "/bug77978";
11+
12+
mkdir($target);
13+
14+
$zip = new ZipArchive();
15+
$zip->open($file, ZipArchive::CREATE|ZipArchive::OVERWRITE);
16+
$zip->addFromString("dir/test:/filename.txt", "contents");
17+
$zip->close();
18+
19+
$zip->open($file);
20+
// Windows won't extract filenames with colons; we suppress the warning
21+
@$zip->extractTo($target, "dir/test:/filename.txt");
22+
$zip->close();
23+
24+
var_dump(!file_exists("$target/filename.txt"));
25+
var_dump(PHP_OS_FAMILY === "Windows" || file_exists("$target/dir/test:/filename.txt"));
26+
?>
27+
--EXPECT--
28+
bool(true)
29+
bool(true)
30+
--CLEAN--
31+
<?php
32+
@unlink(__DIR__ . "/bug77978.zip");
33+
@unlink(__DIR__ . "/bug77978/dir/test:/filename.txt");
34+
@rmdir(__DIR__ . "/bug77978/dir/test:");
35+
@rmdir(__DIR__ . "/bug77978/dir");
36+
@rmdir(__DIR__ . "/bug77978");
37+
?>

0 commit comments

Comments
 (0)