diff --git a/src/Console/Command/Extract.php b/src/Console/Command/Extract.php index 9596a0782..4ead856d3 100644 --- a/src/Console/Command/Extract.php +++ b/src/Console/Command/Extract.php @@ -38,6 +38,7 @@ */ final class Extract implements Command { + public const STUB_PATH = '.phar/stub.php'; public const PHAR_META_PATH = '.phar_meta.json'; private const PHAR_ARG = 'phar'; @@ -151,6 +152,7 @@ private static function dumpPhar(string $file, string $tmpDir): string $pubKey = $file.'.pubkey'; $pubKeyContent = null; $tmpPubKey = $tmpFile.'.pubkey'; + $stub = $tmpDir.DIRECTORY_SEPARATOR.self::STUB_PATH; try { FS::copy($file, $tmpFile, true); @@ -164,6 +166,7 @@ private static function dumpPhar(string $file, string $tmpDir): string $pharMeta = PharMeta::fromPhar($phar, $pubKeyContent); $phar->extractTo($tmpDir); + FS::dumpFile($stub, $phar->getStub()); } catch (Throwable $throwable) { FS::remove([$tmpFile, $tmpPubKey]); diff --git a/src/Phar/Differ/ChecksumDiffer.php b/src/Phar/Differ/ChecksumDiffer.php index 87cd060bd..7fdd40fdd 100644 --- a/src/Phar/Differ/ChecksumDiffer.php +++ b/src/Phar/Differ/ChecksumDiffer.php @@ -18,6 +18,7 @@ use KevinGH\Box\Phar\PharInfo; use UnexpectedValueException; use ValueError; +use function hash; use function implode; final class ChecksumDiffer implements Differ @@ -110,6 +111,11 @@ private static function getFileHashesByRelativePathname( $hashFiles = []; try { + $hashFiles[$pharInfo->getStubPath()] = hash( + $algorithm, + $pharInfo->getStubContent(), + ); + foreach ($pharInfo->getFiles() as $file) { $hashFiles[$file->getRelativePathname()] = hash_file( $algorithm, diff --git a/src/Phar/PharInfo.php b/src/Phar/PharInfo.php index 58a7657fa..d3023e75d 100644 --- a/src/Phar/PharInfo.php +++ b/src/Phar/PharInfo.php @@ -247,6 +247,11 @@ public function getSignature(): ?array return $this->meta->signature; } + public function getStubPath(): string + { + return Extract::STUB_PATH; + } + public function getStubContent(): ?string { return $this->meta->stub; @@ -311,6 +316,7 @@ private static function loadDumpedPharFiles(string $tmp): array Finder::create() ->files() ->ignoreDotFiles(false) + ->exclude('.phar') ->in($tmp), ), ); diff --git a/tests/Console/Command/DiffTest.php b/tests/Console/Command/DiffTest.php index c5e759353..89e0ed992 100644 --- a/tests/Console/Command/DiffTest.php +++ b/tests/Console/Command/DiffTest.php @@ -578,7 +578,60 @@ public static function gitDiffPharsProvider(): iterable public static function GNUDiffPharsProvider(): iterable { - yield from self::commonDiffPharsProvider(DiffMode::GNU); + foreach (self::commonDiffPharsProvider(DiffMode::GNU) as $label => $set) { + yield $label => 'different data; same content' === $label + ? [ + self::FIXTURES_DIR.'/simple-phar-bar.phar', + self::FIXTURES_DIR.'/simple-phar-bar-compressed.phar', + sprintf( + <<<'OUTPUT' + + // Comparing the two archives... + + Archive: simple-phar-bar.phar + Archive Compression: None + Files Compression: None + Signature: SHA-1 + Signature Hash: 9ADC09F73909EDF14F8A4ABF9758B6FFAD1BBC51 + Metadata: None + Timestamp: 1552839827 (2019-03-17T16:23:47+00:00) + Contents: 1 file (6.64KB) + + Archive: simple-phar-bar-compressed.phar + Archive Compression: None + Files Compression: GZ + Signature: SHA-1 + Signature Hash: 3A388D86C91C36659A043D52C2DEB64E8848DD1A + Metadata: None + Timestamp: 1552856416 (2019-03-17T21:00:16+00:00) + Contents: 1 file (6.65KB) + + --- PHAR A + +++ PHAR B + @@ @@ + Archive Compression: None + -Files Compression: None + +Files Compression: GZ + Signature: SHA-1 + -Signature Hash: 9ADC09F73909EDF14F8A4ABF9758B6FFAD1BBC51 + +Signature Hash: 3A388D86C91C36659A043D52C2DEB64E8848DD1A + Metadata: None + -Timestamp: 1552839827 (2019-03-17T16:23:47+00:00) + -Contents: 1 file (6.64KB) + +Timestamp: 1552856416 (2019-03-17T21:00:16+00:00) + +Contents: 1 file (6.65KB) + + // Comparing the two archives contents (%s diff)... + + Common subdirectories: simple-phar-bar.phar/.phar and simple-phar-bar-compressed.phar/.phar + + OUTPUT, + DiffMode::GNU->value, + ), + ExitCode::FAILURE, + ] + : $set; + } yield 'different files' => [ self::FIXTURES_DIR.'/simple-phar-foo.phar', @@ -620,6 +673,7 @@ public static function GNUDiffPharsProvider(): iterable // Comparing the two archives contents (gnu diff)... + Common subdirectories: simple-phar-foo.phar/.phar and simple-phar-bar.phar/.phar Only in simple-phar-bar.phar: bar.php Only in simple-phar-foo.phar: foo.php @@ -669,6 +723,7 @@ public static function GNUDiffPharsProvider(): iterable // Comparing the two archives contents (gnu diff)... + Common subdirectories: simple-phar-bar.phar/.phar and simple-phar-baz.phar/.phar diff --exclude=.phar_meta.json simple-phar-bar.phar/bar.php simple-phar-baz.phar/bar.php 3c3 < echo "Hello world!"; @@ -714,6 +769,7 @@ public static function GNUDiffPharsProvider(): iterable // Comparing the two archives contents (gnu diff)... + Common subdirectories: simple-phar-bar.phar/.phar and simple-phar-baz.phar/.phar diff '--exclude=.phar_meta.json' simple-phar-bar.phar/bar.php simple-phar-baz.phar/bar.php 3c3 < echo "Hello world!"; diff --git a/tests/Console/Command/ExtractTest.php b/tests/Console/Command/ExtractTest.php index 484e609ac..d240c2a3e 100644 --- a/tests/Console/Command/ExtractTest.php +++ b/tests/Console/Command/ExtractTest.php @@ -99,6 +99,7 @@ private static function pharProvider(): iterable ); $expectedSimplePharFiles = [ + '.phar/stub.php' => $oldDefaultPharStub, '.hidden' => 'baz', 'foo' => 'bar', '.phar_meta.json' => $pharMeta->toJson(), @@ -118,6 +119,7 @@ private static function pharProvider(): iterable yield 'GZ compressed simple PHAR' => [ self::FIXTURES_DIR.'/gz-compressed-phar.phar', [ + '.phar/stub.php' => $oldDefaultPharStub, '.hidden' => 'baz', 'foo' => 'bar', '.phar_meta.json' => (new PharMeta( @@ -149,6 +151,7 @@ private static function pharProvider(): iterable yield 'sha512 signed PHAR' => [ self::FIXTURES_DIR.'/sha512.phar', [ + '.phar/stub.php' => $sha512Stub, 'index.php' => <<<'PHP' [ self::FIXTURES_DIR.'/openssl.phar', [ + '.phar/stub.php' => $sha512Stub, 'index.php' => <<<'PHP'