ZipTestCase.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. <?php
  2. namespace PhpZip;
  3. use PHPUnit\Framework\TestCase;
  4. use PhpZip\Model\EndOfCentralDirectory;
  5. use PhpZip\Util\FilesUtil;
  6. /**
  7. * PHPUnit test case and helper methods.
  8. */
  9. abstract class ZipTestCase extends TestCase
  10. {
  11. /** @var string */
  12. protected $outputFilename;
  13. /** @var string */
  14. protected $outputDirname;
  15. /**
  16. * Before test.
  17. */
  18. protected function setUp()
  19. {
  20. $id = uniqid('phpzip', true);
  21. $tempDir = sys_get_temp_dir() . '/phpunit-phpzip';
  22. if (!is_dir($tempDir) && !mkdir($tempDir, 0755, true) && !is_dir($tempDir)) {
  23. throw new \RuntimeException('Dir ' . $tempDir . " can't created");
  24. }
  25. $this->outputFilename = $tempDir . '/' . $id . '.zip';
  26. $this->outputDirname = $tempDir . '/' . $id;
  27. }
  28. /**
  29. * After test.
  30. */
  31. protected function tearDown()
  32. {
  33. parent::tearDown();
  34. if ($this->outputFilename !== null && file_exists($this->outputFilename)) {
  35. unlink($this->outputFilename);
  36. }
  37. if ($this->outputDirname !== null && is_dir($this->outputDirname)) {
  38. FilesUtil::removeDir($this->outputDirname);
  39. }
  40. }
  41. /**
  42. * Assert correct zip archive.
  43. *
  44. * @param string $filename
  45. * @param string|null $password
  46. */
  47. public static function assertCorrectZipArchive($filename, $password = null)
  48. {
  49. if (self::existsProgram('unzip')) {
  50. $command = 'unzip';
  51. if ($password !== null) {
  52. $command .= ' -P ' . escapeshellarg($password);
  53. }
  54. $command .= ' -t ' . escapeshellarg($filename);
  55. $command .= ' 2>&1';
  56. exec($command, $output, $returnCode);
  57. $output = implode(\PHP_EOL, $output);
  58. if ($password !== null && $returnCode === 81) {
  59. if (self::existsProgram('7z')) {
  60. /**
  61. * WinZip 99-character limit.
  62. *
  63. * @see https://sourceforge.net/p/p7zip/discussion/383044/thread/c859a2f0/
  64. */
  65. $password = substr($password, 0, 99);
  66. $command = '7z t -p' . escapeshellarg($password) . ' ' . escapeshellarg($filename);
  67. exec($command, $output, $returnCode);
  68. /**
  69. * @var array $output
  70. */
  71. $output = implode(\PHP_EOL, $output);
  72. static::assertSame($returnCode, 0);
  73. static::assertNotContains(' Errors', $output);
  74. static::assertContains(' Ok', $output);
  75. } else {
  76. fwrite(\STDERR, 'Program unzip cannot support this function.' . \PHP_EOL);
  77. fwrite(\STDERR, 'Please install 7z. For Ubuntu-like: sudo apt-get install p7zip-full' . \PHP_EOL);
  78. }
  79. } else {
  80. static::assertSame($returnCode, 0, $output);
  81. static::assertNotContains('incorrect password', $output);
  82. static::assertContains(' OK', $output);
  83. static::assertContains('No errors', $output);
  84. }
  85. }
  86. }
  87. /**
  88. * @param string $program
  89. *
  90. * @return bool
  91. */
  92. private static function existsProgram($program)
  93. {
  94. if (\DIRECTORY_SEPARATOR !== '\\') {
  95. exec('which ' . escapeshellarg($program), $output, $returnCode);
  96. return $returnCode === 0;
  97. }
  98. // false for Windows
  99. return false;
  100. }
  101. /**
  102. * Assert correct empty zip archive.
  103. *
  104. * @param $filename
  105. */
  106. public static function assertCorrectEmptyZip($filename)
  107. {
  108. if (self::existsProgram('zipinfo')) {
  109. exec('zipinfo ' . escapeshellarg($filename), $output, $returnCode);
  110. $output = implode(\PHP_EOL, $output);
  111. static::assertContains('Empty zipfile', $output);
  112. }
  113. $actualEmptyZipData = pack('VVVVVv', EndOfCentralDirectory::END_OF_CD_SIG, 0, 0, 0, 0, 0);
  114. static::assertStringEqualsFile($filename, $actualEmptyZipData);
  115. }
  116. /**
  117. * @param string $filename
  118. * @param bool $showErrors
  119. *
  120. * @return bool|null If null returned, then the zipalign program is not installed
  121. */
  122. public static function assertVerifyZipAlign($filename, $showErrors = false)
  123. {
  124. if (self::existsProgram('zipalign')) {
  125. exec('zipalign -c -v 4 ' . escapeshellarg($filename), $output, $returnCode);
  126. if ($showErrors && $returnCode !== 0) {
  127. fwrite(\STDERR, implode(\PHP_EOL, $output));
  128. }
  129. return $returnCode === 0;
  130. }
  131. fwrite(\STDERR, "Cannot find the program 'zipalign' for the test" . \PHP_EOL);
  132. return null;
  133. }
  134. }