diff --git a/lib/filestorage/tests/zip_packer_test.php b/lib/filestorage/tests/zip_packer_test.php index b39bcdfa3e5..8da89dd3d80 100644 --- a/lib/filestorage/tests/zip_packer_test.php +++ b/lib/filestorage/tests/zip_packer_test.php @@ -376,6 +376,73 @@ class core_files_zip_packer_testcase extends advanced_testcase implements file_p unlink($archive); } + public function test_close_archive() { + global $CFG; + + $this->resetAfterTest(true); + + $archive = "$CFG->tempdir/archive.zip"; + $textfile = "$CFG->tempdir/textfile.txt"; + touch($textfile); + + $this->assertFileNotExists($archive); + $this->assertFileExists($textfile); + + // Create archive and close it without files. + // (returns true, without any warning). + $zip_archive = new zip_archive(); + $result = $zip_archive->open($archive, file_archive::CREATE); + $this->assertTrue($result); + $result = $zip_archive->close(); + $this->assertTrue($result); + unlink($archive); + + // Create archive and close it with files. + // (returns true, without any warning). + $zip_archive = new zip_archive(); + $result = $zip_archive->open($archive, file_archive::CREATE); + $this->assertTrue($result); + $result = $zip_archive->add_file_from_string('test.txt', 'test'); + $this->assertTrue($result); + $result = $zip_archive->add_file_from_pathname('test2.txt', $textfile); + $result = $zip_archive->close(); + $this->assertTrue($result); + unlink($archive); + + // Create archive and close if forcing error. + // (returns true for old PHP versions and + // false with warnings for new PHP versions). MDL-51863. + $zip_archive = new zip_archive(); + $result = $zip_archive->open($archive, file_archive::CREATE); + $this->assertTrue($result); + $result = $zip_archive->add_file_from_string('test.txt', 'test'); + $this->assertTrue($result); + $result = $zip_archive->add_file_from_pathname('test2.txt', $textfile); + $this->assertTrue($result); + // Delete the file before closing does force close() to fail. + unlink($textfile); + // Behavior is different between old PHP versions and new ones. Let's detect it. + $result = false; + try { + // Old PHP versions were not printing any warning. + $result = $zip_archive->close(); + } catch (Exception $e) { + // New PHP versions print PHP Warning. + $this->assertInstanceOf('PHPUnit_Framework_Error_Warning', $e); + $this->assertContains('ZipArchive::close', $e->getMessage()); + } + // This is crazy, but it shows how some PHP versions do return true. + try { + // And some PHP versions do return correctly false (5.4.25, 5.6.14...) + $this->assertFalse($result); + } catch (Exception $e) { + // But others do insist into returning true (5.6.13...). Only can accept them. + $this->assertInstanceOf('PHPUnit_Framework_ExpectationFailedException', $e); + $this->assertTrue($result); + } + $this->assertFileNotExists($archive); + } + /** * @depends test_add_files */ diff --git a/lib/filestorage/zip_archive.php b/lib/filestorage/zip_archive.php index f51facd2b3c..70b9d336f5d 100644 --- a/lib/filestorage/zip_archive.php +++ b/lib/filestorage/zip_archive.php @@ -191,7 +191,7 @@ class zip_archive extends file_archive { } if ($this->emptyziphack) { - $this->za->close(); + @$this->za->close(); $this->za = null; $this->mode = null; $this->namelookup = null; @@ -202,7 +202,7 @@ class zip_archive extends file_archive { } else if ($this->za->numFiles == 0) { // PHP can not create empty archives, so let's fake it. - $this->za->close(); + @$this->za->close(); $this->za = null; $this->mode = null; $this->namelookup = null;