"Seeking $tailLength bytes from EOF failed in " . __METHOD__ );
}
$tail = $tailLength ? fread( $f, $tailLength ) : '';
- fclose( $f );
$this->logger->info( __METHOD__ .
": analyzing head and tail of $file for magic numbers.\n" );
return "image/webp";
}
+ /* Look for MS Compound Binary (OLE) files */
+ if ( strncmp( $head, "\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1", 8 ) == 0 ) {
+ $this->logger->info( __METHOD__ . ': recognized MS CFB (OLE) file' );
+ return $this->detectMicrosoftBinaryType( $f );
+ }
+
/**
* Look for PHP. Check for this before HTML/XML... Warning: this is a
* heuristic, and won't match a file with a lot of non-PHP before. It
}
// Check for ZIP variants (before getimagesize)
- if ( strpos( $tail, "PK\x05\x06" ) !== false ) {
- $this->logger->info( __METHOD__ . ": ZIP header present in $file\n" );
- return $this->detectZipType( $head, $tail, $ext );
+ $eocdrPos = strpos( $tail, "PK\x05\x06" );
+ if ( $eocdrPos !== false ) {
+ $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];
+ if ( $eocdrPos + 22 + $commentLength !== strlen( $tail ) ) {
+ $this->logger->info( __METHOD__ . ": ZIP EOCDR not at end. Not a ZIP file." );
+ } else {
+ return $this->detectZipType( $head, $tail, $ext );
+ }
}
// Check for STL (3D) files
$callback = $this->guessCallback;
if ( $callback ) {
$callback( $this, $head, $tail, $file, $mime /* by reference */ );
- };
+ }
return $mime;
}
return $mime;
}
+ /**
+ * Detect the type of a Microsoft Compound Binary a.k.a. OLE file.
+ * These are old style pre-ODF files such as .doc and .xls
+ *
+ * @param resource $handle An opened seekable file handle
+ * @return string The detected MIME type
+ */
+ function detectMicrosoftBinaryType( $handle ) {
+ $info = MSCompoundFileReader::readHandle( $handle );
+ if ( !$info['valid'] ) {
+ $this->logger->info( __METHOD__ . ': invalid file format' );
+ return 'unknown/unknown';
+ }
+ if ( !$info['mime'] ) {
+ $this->logger->info( __METHOD__ . ": unrecognised document subtype" );
+ return 'unknown/unknown';
+ }
+ return $info['mime'];
+ }
+
/**
* Internal MIME type detection. Detection is done using the fileinfo
* extension if it is available. It can be overriden by callback, which could
* distinguish them from MIME types.
*
* This function relies on the mapping defined by $this->mMediaTypes
- * @access private
+ * @private
* @param string $extMime
* @return int|string
*/