// Check for ZIP variants (before getimagesize)
$eocdrPos = strpos( $tail, "PK\x05\x06" );
- if ( $eocdrPos !== false ) {
+ if ( $eocdrPos !== false && $eocdrPos <= strlen( $tail ) - 22 ) {
$this->logger->info( __METHOD__ . ": ZIP signature present in $file\n" );
// Check if it really is a ZIP file, make sure the EOCDR is at the end (T40432)
- $commentLength = unpack( "n", substr( $tail, $eocdrPos + 20 ) )[0];
+ $commentLength = unpack( "n", substr( $tail, $eocdrPos + 20 ) )[1];
if ( $eocdrPos + 22 + $commentLength !== strlen( $tail ) ) {
$this->logger->info( __METHOD__ . ": ZIP EOCDR not at end. Not a ZIP file." );
} else {
];
}
+ function providePngZipConfusion() {
+ return [
+ [
+ 'An invalid ZIP file due to the signature being too close to the ' .
+ 'end to accomodate an EOCDR',
+ 'zip-sig-near-end.png',
+ 'image/png',
+ ],
+ [
+ 'An invalid ZIP file due to the comment length running beyond the ' .
+ 'end of the file',
+ 'zip-comment-overflow.png',
+ 'image/png',
+ ],
+ [
+ 'A ZIP file similar to the above, but without either of those two ' .
+ 'problems. Not a valid ZIP file, but it passes MimeAnalyzer\'s ' .
+ 'definition of a ZIP file. This is mostly a sanity check of the ' .
+ 'above two tests.',
+ 'zip-kind-of-valid.png',
+ 'application/zip',
+ ],
+ [
+ 'As above with non-zero comment length',
+ 'zip-kind-of-valid-2.png',
+ 'application/zip',
+ ],
+ ];
+ }
+
+ /** @dataProvider providePngZipConfusion */
+ function testPngZipConfusion( $description, $fileName, $expectedType ) {
+ $file = __DIR__ . '/../../../data/media/' . $fileName;
+ $actualType = $this->doGuessMimeType( [ $file, 'png' ] );
+ $this->assertEquals( $expectedType, $actualType, $description );
+ }
}