Skip to content

Commit

Permalink
Merge branch 'MDL-70864-311-zip_packer_windows' of git://github.com/m…
Browse files Browse the repository at this point in the history
…udrd8mz/moodle into MOODLE_311_STABLE
  • Loading branch information
vmdef committed May 4, 2021
2 parents 896123d + d95c3a0 commit 116621f
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 4 deletions.
28 changes: 26 additions & 2 deletions lib/filestorage/tests/zip_packer_test.php
Expand Up @@ -260,6 +260,8 @@ public function test_extract_to_pathname() {
* @link https://bugs.php.net/bug.php?id=77214
*/
public function test_zip_entry_path_having_folder_ending_with_dot() {
global $CFG;

$this->resetAfterTest(false);

$packer = get_file_packer('application/zip');
Expand All @@ -276,6 +278,28 @@ public function test_zip_entry_path_having_folder_ending_with_dot() {
'Data/sub1./sub2./Příliš žluťoučký kůň úpěl Ďábelské Ódy.txt' => [''],
];

if ($CFG->ostype === 'WINDOWS') {
// File names cannot end with dots on Windows and trailing dots are replaced with underscore.
$filenamemap = [
'HOW.TO' => 'HOW.TO',
'README.' => 'README_',
'./Current time' => 'Current time',
'Data/sub1./sub2/1221' => 'Data/sub1_/sub2/1221',
'Data/sub1./sub2./Příliš žluťoučký kůň úpěl Ďábelské Ódy.txt' =>
'Data/sub1_/sub2_/Příliš žluťoučký kůň úpěl Ďábelské Ódy.txt',
];

} else {
$filenamemap = [
'HOW.TO' => 'HOW.TO',
'README.' => 'README.',
'./Current time' => 'Current time',
'Data/sub1./sub2/1221' => 'Data/sub1./sub2/1221',
'Data/sub1./sub2./Příliš žluťoučký kůň úpěl Ďábelské Ódy.txt' =>
'Data/sub1./sub2./Příliš žluťoučký kůň úpěl Ďábelské Ódy.txt',
];
}

// Check that the archive can be created.
$result = $packer->archive_to_pathname($zipcontents, $zippath, false);
$this->assertTrue($result);
Expand All @@ -298,8 +322,8 @@ public function test_zip_entry_path_having_folder_ending_with_dot() {

foreach ($zipcontents as $filename => $filecontents) {
$filecontents = reset($filecontents);
$this->assertTrue(is_readable($targetpath . '/' . $filename));
$this->assertEquals($filecontents, file_get_contents($targetpath . '/' . $filename));
$this->assertTrue(is_readable($targetpath . '/' . $filenamemap[$filename]));
$this->assertEquals($filecontents, file_get_contents($targetpath . '/' . $filenamemap[$filename]));
}
}

Expand Down
10 changes: 8 additions & 2 deletions lib/filestorage/zip_packer.php
Expand Up @@ -297,11 +297,17 @@ public function extract_to_pathname($archivefile, $pathname,

$size = $info->size;
$name = $info->pathname;
$origname = $name;

// File names cannot end with dots on Windows and trailing dots are replaced with underscore.
if ($CFG->ostype === 'WINDOWS') {
$name = preg_replace('~([^/]+)\.(/|$)~', '\1_\2', $name);
}

if ($name === '' or array_key_exists($name, $processed)) {
// Probably filename collisions caused by filename cleaning/conversion.
continue;
} else if (is_array($onlyfiles) && !in_array($name, $onlyfiles)) {
} else if (is_array($onlyfiles) && !in_array($origname, $onlyfiles)) {
// Skipping files which are not in the list.
continue;
}
Expand Down Expand Up @@ -342,7 +348,7 @@ public function extract_to_pathname($archivefile, $pathname,

$newfile = "$newdir/$filename";

if (strpos($newfile, './') > 1) {
if (strpos($newfile, './') > 1 || $name !== $origname) {
// The path to the entry contains a directory ending with dot. We cannot use extract_to() due to
// upstream PHP bugs #69477, #74619 and #77214. Extract the file from its stream which is slower but
// should work even in this case.
Expand Down

0 comments on commit 116621f

Please sign in to comment.