MDL-35117 librairies: File Packer can only extract a specific list a files

This commit is contained in:
Frederic Massart 2012-10-11 09:15:04 +08:00
parent ecfe814e0f
commit e462f46b77
3 changed files with 50 additions and 4 deletions

View File

@ -63,9 +63,10 @@ abstract class file_packer {
*
* @param stored_file|string $archivefile full pathname of zip file or stored_file instance
* @param string $pathname target directory
* @param array $onlyfiles only extract files present in the array
* @return array|bool list of processed files; false if error
*/
public abstract function extract_to_pathname($archivefile, $pathname);
public abstract function extract_to_pathname($archivefile, $pathname, array $onlyfiles = NULL);
/**
* Extract file to given file path (real OS filesystem), existing files are overwrited

View File

@ -226,6 +226,46 @@ class zip_packer_testcase extends advanced_testcase {
}
}
/**
* @depends test_archive_to_storage
*/
public function test_extract_to_pathname_onlyfiles() {
global $CFG;
$this->resetAfterTest(false);
$packer = get_file_packer('application/zip');
$fs = get_file_storage();
$context = context_system::instance();
$target = "$CFG->tempdir/onlyfiles/";
$testcontent = file_get_contents($this->testfile);
@mkdir($target, $CFG->directorypermissions);
$this->assertTrue(is_dir($target));
$onlyfiles = array('test', 'test.test', 'Žluťoučký/Koníček.txt', 'Idontexist');
$willbeextracted = array_intersect(array_keys($this->files), $onlyfiles);
$donotextract = array_diff(array_keys($this->files), $onlyfiles);
$archive = "$CFG->tempdir/archive.zip";
$this->assertTrue(file_exists($archive));
$result = $packer->extract_to_pathname($archive, $target, $onlyfiles);
$this->assertTrue(is_array($result));
$this->assertEquals(count($willbeextracted), count($result));
foreach($willbeextracted as $file) {
$this->assertTrue($result[$file]);
$this->assertTrue(file_exists($target.$file));
$this->assertSame($testcontent, file_get_contents($target.$file));
}
foreach($donotextract as $file) {
$this->assertFalse(isset($result[$file]));
$this->assertFalse(file_exists($target.$file));
}
}
/**
* @depends test_archive_to_storage
*/

View File

@ -218,9 +218,11 @@ class zip_packer extends file_packer {
* @todo MDL-31048 localise messages
* @param string|stored_file $archivefile full pathname of zip file or stored_file instance
* @param string $pathname target directory
* @param array $onlyfiles only extract files present in the array. The path to files MUST NOT
* start with a /. Example: array('myfile.txt', 'directory/anotherfile.txt')
* @return bool|array list of processed files; false if error
*/
public function extract_to_pathname($archivefile, $pathname) {
public function extract_to_pathname($archivefile, $pathname, array $onlyfiles = null) {
global $CFG;
if (!is_string($archivefile)) {
@ -233,7 +235,7 @@ class zip_packer extends file_packer {
if (!is_readable($archivefile)) {
return false;
}
$ziparch = new zip_archive();
$ziparch = new zip_archive();
if (!$ziparch->open($archivefile, file_archive::OPEN)) {
return false;
}
@ -243,7 +245,10 @@ class zip_packer extends file_packer {
$name = $info->pathname;
if ($name === '' or array_key_exists($name, $processed)) {
//probably filename collisions caused by filename cleaning/conversion
// Probably filename collisions caused by filename cleaning/conversion.
continue;
} else if (is_array($onlyfiles) && !in_array($name, $onlyfiles)) {
// Skipping files which are not in the list.
continue;
}