Skip to content

Commit 6313fca

Browse files
committed
Bug #69477 ext/zip: Do not extract files that can't be opened on Windows
There are known issues with folder and files ending with dot on Windows. Similarly to how 7-zip deals with the situation, replace the trailing dot with underscore for such files.
1 parent 5dcb855 commit 6313fca

File tree

2 files changed

+55
-18
lines changed

2 files changed

+55
-18
lines changed

ext/zip/php_zip.c

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,8 @@ static char * php_zip_make_relative_path(char *path, size_t path_len) /* {{{ */
102102
return NULL;
103103
}
104104

105-
if (IS_SLASH(path[0])) {
106-
return path + 1;
105+
if (path_len == 1 && (path[0] == '.' || IS_SLASH(path[0]))) {
106+
return NULL;
107107
}
108108

109109
i = path_len;
@@ -114,7 +114,12 @@ static char * php_zip_make_relative_path(char *path, size_t path_len) /* {{{ */
114114
}
115115

116116
if (!i) {
117-
return path;
117+
if (IS_SLASH(path[0])) {
118+
path_begin = path + 1;
119+
} else {
120+
path_begin = path;
121+
}
122+
break;
118123
}
119124

120125
if (i >= 1 && path[i - 1] == ':') {
@@ -135,6 +140,18 @@ static char * php_zip_make_relative_path(char *path, size_t path_len) /* {{{ */
135140
i--;
136141
}
137142

143+
#ifdef PHP_WIN32
144+
if (path[path_len - 1] == '.') {
145+
path[path_len - 1] = '_';
146+
}
147+
148+
for (i = 1; i < path_len; i++) {
149+
if (IS_SLASH(path[i]) && path[i - 1] == '.') {
150+
path[i - 1] = '_';
151+
}
152+
}
153+
#endif
154+
138155
return path_begin;
139156
}
140157
/* }}} */

ext/zip/tests/bug69477.phpt

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,41 @@ if (!$archive->open($zipfile, ZipArchive::CREATE)) {
1919
}
2020

2121
// (string) Entry path in the ZIP => (string) Expected actual target path
22-
$paths = [
23-
'.a/b/c/file01.txt' => '.a/b/c/file01.txt',
24-
'a./b/c/file02.txt' => 'a./b/c/file02.txt',
25-
'a/.b/c/file03.txt' => 'a/.b/c/file03.txt',
26-
'a/b./c/file04.txt' => 'a/b./c/file04.txt',
27-
'a/b../c/file05.txt' => 'a/b../c/file05.txt',
28-
'a/b.../c/file06.txt' => 'a/b.../c/file06.txt',
29-
'a/..b/c/file07.txt' => 'a/..b/c/file07.txt',
30-
'a/...b/c/file08.txt' => 'a/...b/c/file08.txt',
31-
'a/../b./c./file09.txt' => 'b./c./file09.txt',
32-
'//../b./c./file10.txt' => 'b./c./file10.txt',
33-
'/../b./c./file11.txt' => 'b./c./file11.txt',
34-
'C:/a./b./file12.txt' => 'a./b./file12.txt',
35-
'a/b:/c/file13.txt' => 'c/file13.txt',
36-
];
22+
if (PHP_OS_FAMILY === 'Windows') {
23+
$paths = [
24+
'.a/b/c/file01.txt' => '.a/b/c/file01.txt',
25+
'a./b/c/file02.txt' => 'a_/b/c/file02.txt',
26+
'a/.b/c/file03.txt' => 'a/.b/c/file03.txt',
27+
'a/b./c/file04.txt' => 'a/b_/c/file04.txt',
28+
'a/b../c/file05.txt' => 'a/b._/c/file05.txt',
29+
'a/b.../c/file06.txt' => 'a/b.._/c/file06.txt',
30+
'a/..b/c/file07.txt' => 'a/..b/c/file07.txt',
31+
'a/...b/c/file08.txt' => 'a/...b/c/file08.txt',
32+
'a/../b./c./file09.txt' => 'b_/c_/file09.txt',
33+
'//../b./c./file10.txt' => 'b_/c_/file10.txt',
34+
'/../b./c./file11.txt' => 'b_/c_/file11.txt',
35+
'C:/a./b./file12.txt' => 'a_/b_/file12.txt',
36+
'a/b:/c/file13.txt' => 'c/file13.txt',
37+
'a/b/c/file14.' => 'a/b/c/file14_',
38+
];
39+
} else {
40+
$paths = [
41+
'.a/b/c/file01.txt' => '.a/b/c/file01.txt',
42+
'a./b/c/file02.txt' => 'a./b/c/file02.txt',
43+
'a/.b/c/file03.txt' => 'a/.b/c/file03.txt',
44+
'a/b./c/file04.txt' => 'a/b./c/file04.txt',
45+
'a/b../c/file05.txt' => 'a/b../c/file05.txt',
46+
'a/b.../c/file06.txt' => 'a/b.../c/file06.txt',
47+
'a/..b/c/file07.txt' => 'a/..b/c/file07.txt',
48+
'a/...b/c/file08.txt' => 'a/...b/c/file08.txt',
49+
'a/../b./c./file09.txt' => 'b./c./file09.txt',
50+
'//../b./c./file10.txt' => 'b./c./file10.txt',
51+
'/../b./c./file11.txt' => 'b./c./file11.txt',
52+
'C:/a./b./file12.txt' => 'a./b./file12.txt',
53+
'a/b:/c/file13.txt' => 'c/file13.txt',
54+
'a/b/c/file14.' => 'a/b/c/file14.',
55+
];
56+
}
3757

3858
foreach ($paths as $zippath => $realpath) {
3959
$archive->addFromString($zippath, $zippath . ' => ' . $realpath);

0 commit comments

Comments
 (0)