From f12db3804882272794b4dafc72db1c5d787375bf Mon Sep 17 00:00:00 2001 From: Tim Starling Date: Tue, 15 Jan 2019 14:15:18 +1100 Subject: [PATCH] Better detection for old MS Office files * Introduce MSCompoundFileReader, which reads the CFB directory and detects the file type from well-known names in the root directory * Do not detect a ZIP file if the EOCDR is not at the end. Other containers, especially CFB files, may contain ZIP files embedded within them in the last 64KB, but this is not a security concern unless the EOCDR is exactly at the end of the file. Bug: T40432 Change-Id: Id5b1a258ccf3c3c8951e32f6b7a5b1bafe941082 --- autoload.php | 1 + includes/libs/mime/MSCompoundFileReader.php | 355 ++++++++++++++++++ includes/libs/mime/MimeAnalyzer.php | 40 +- includes/utils/ZipDirectoryReader.php | 4 +- .../data/MSCompoundFileReader/calc.xls | Bin 0 -> 5632 bytes .../MSCompoundFileReader/dir-beyond-end.xls | Bin 0 -> 5632 bytes .../excel2016-compat97.xls | Bin 0 -> 25600 bytes .../data/MSCompoundFileReader/fat-loop.xls | Bin 0 -> 5632 bytes .../data/MSCompoundFileReader/gnumeric.xls | Bin 0 -> 5632 bytes .../data/MSCompoundFileReader/impress.ppt | Bin 0 -> 124928 bytes .../invalid-signature.xls | Bin 0 -> 5632 bytes .../powerpoint2016-compat97.ppt | Bin 0 -> 87552 bytes .../word2016-compat97.doc | Bin 0 -> 22528 bytes .../data/MSCompoundFileReader/writer.doc | Bin 0 -> 9216 bytes tests/phpunit/data/media/zip-in-doc.doc | Bin 0 -> 22016 bytes .../libs/mime/MSCompoundFileReaderTest.php | 60 +++ .../includes/libs/mime/MimeAnalyzerTest.php | 9 + .../includes/utils/ZipDirectoryReaderTest.php | 3 +- 18 files changed, 466 insertions(+), 6 deletions(-) create mode 100644 includes/libs/mime/MSCompoundFileReader.php create mode 100644 tests/phpunit/data/MSCompoundFileReader/calc.xls create mode 100644 tests/phpunit/data/MSCompoundFileReader/dir-beyond-end.xls create mode 100755 tests/phpunit/data/MSCompoundFileReader/excel2016-compat97.xls create mode 100644 tests/phpunit/data/MSCompoundFileReader/fat-loop.xls create mode 100644 tests/phpunit/data/MSCompoundFileReader/gnumeric.xls create mode 100644 tests/phpunit/data/MSCompoundFileReader/impress.ppt create mode 100644 tests/phpunit/data/MSCompoundFileReader/invalid-signature.xls create mode 100755 tests/phpunit/data/MSCompoundFileReader/powerpoint2016-compat97.ppt create mode 100755 tests/phpunit/data/MSCompoundFileReader/word2016-compat97.doc create mode 100644 tests/phpunit/data/MSCompoundFileReader/writer.doc create mode 100644 tests/phpunit/data/media/zip-in-doc.doc create mode 100644 tests/phpunit/includes/libs/mime/MSCompoundFileReaderTest.php diff --git a/autoload.php b/autoload.php index 91be2e71b9..4481cd74ad 100644 --- a/autoload.php +++ b/autoload.php @@ -816,6 +816,7 @@ $wgAutoloadLocalClasses = [ 'LonelyPagesPage' => __DIR__ . '/includes/specials/SpecialLonelypages.php', 'LongPagesPage' => __DIR__ . '/includes/specials/SpecialLongpages.php', 'MIMEsearchPage' => __DIR__ . '/includes/specials/SpecialMIMEsearch.php', + 'MSCompoundFileReader' => __DIR__ . '/includes/libs/mime/MSCompoundFileReader.php', 'MWCallableUpdate' => __DIR__ . '/includes/deferred/MWCallableUpdate.php', 'MWContentSerializationException' => __DIR__ . '/includes/exception/MWContentSerializationException.php', 'MWCryptHKDF' => __DIR__ . '/includes/utils/MWCryptHKDF.php', diff --git a/includes/libs/mime/MSCompoundFileReader.php b/includes/libs/mime/MSCompoundFileReader.php new file mode 100644 index 0000000000..51407a76e0 --- /dev/null +++ b/includes/libs/mime/MSCompoundFileReader.php @@ -0,0 +1,355 @@ + 'application/vnd.ms-excel', + '00020820-0000-0000-C000-000000000046' => 'application/vnd.ms-excel', + '00020906-0000-0000-C000-000000000046' => 'application/msword', + '64818D10-4F9B-11CF-86EA-00AA00B929E8' => 'application/vnd.ms-powerpoint', + ]; + + /** + * Read a file by name + * + * @param string $fileName The full path to the file + * @return array An associative array of information about the file: + * - valid: true if the file is valid, false otherwise + * - error: An error message in English, should be present if valid=false + * - errorCode: One of the self::ERROR_* constants + * - mime: The MIME type detected from the directory contents + * - mimeFromClsid: The MIME type detected from the CLSID on the root + * directory entry + */ + public static function readFile( $fileName ) { + $handle = fopen( $fileName, 'r' ); + if ( $handle === false ) { + return [ + 'valid' => false, + 'error' => 'file does not exist', + 'errorCode' => self::ERROR_FILE_OPEN + ]; + } + return self::readHandle( $handle ); + } + + /** + * Read from an open seekable handle + * + * @param resource $fileHandle The file handle + * @return array An associative array of information about the file: + * - valid: true if the file is valid, false otherwise + * - error: An error message in English, should be present if valid=false + * - errorCode: One of the self::ERROR_* constants + * - mime: The MIME type detected from the directory contents + * - mimeFromClsid: The MIME type detected from the CLSID on the root + * directory entry + */ + public static function readHandle( $fileHandle ) { + $reader = new self( $fileHandle ); + $info = [ + 'valid' => $reader->valid, + 'mime' => $reader->mime, + 'mimeFromClsid' => $reader->mimeFromClsid + ]; + if ( $reader->error ) { + $info['error'] = $reader->error; + $info['errorCode'] = $reader->errorCode; + } + return $info; + } + + private function __construct( $fileHandle ) { + $this->file = $fileHandle; + try { + $this->init(); + } catch ( RuntimeException $e ) { + $this->valid = false; + $this->error = $e->getMessage(); + $this->errorCode = $e->getCode(); + } + } + + private function init() { + $this->header = $this->unpackOffset( 0, [ + 'header_signature' => 8, + 'header_clsid' => 16, + 'minor_version' => 2, + 'major_version' => 2, + 'byte_order' => 2, + 'sector_shift' => 2, + 'mini_sector_shift' => 2, + 'reserved' => 6, + 'num_dir_sectors' => 4, + 'num_fat_sectors' => 4, + 'first_dir_sector' => 4, + 'transaction_signature_number' => 4, + 'mini_stream_cutoff_size' => 4, + 'first_mini_fat_sector' => 4, + 'num_mini_fat_sectors' => 4, + 'first_difat_sector' => 4, + 'num_difat_sectors' => 4, + 'difat' => 436, + ] ); + if ( $this->header['header_signature'] !== "\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1" ) { + $this->error( 'invalid signature: ' . bin2hex( $this->header['header_signature'] ), + self::ERROR_INVALID_SIGNATURE ); + } + $this->sectorLength = 1 << $this->header['sector_shift']; + $this->readDifat(); + $this->readDirectory(); + + $this->valid = true; + } + + private function sectorOffset( $sectorId ) { + return $this->sectorLength * ( $sectorId + 1 ); + } + + private function decodeClsid( $binaryClsid ) { + $parts = unpack( 'Va/vb/vc/C8d', $binaryClsid ); + return sprintf( "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", + $parts['a'], + $parts['b'], + $parts['c'], + $parts['d1'], + $parts['d2'], + $parts['d3'], + $parts['d4'], + $parts['d5'], + $parts['d6'], + $parts['d7'], + $parts['d8'] + ); + } + + private function unpackOffset( $offset, $struct ) { + $block = $this->readOffset( $offset, array_sum( $struct ) ); + return $this->unpack( $block, 0, $struct ); + } + + private function unpackSector( $sectorNumber, $struct ) { + $offset = $this->sectorOffset( $sectorNumber ); + return $this->unpackOffset( $offset, array_sum( $struct ) ); + } + + private function unpack( $block, $offset, $struct ) { + $data = []; + foreach ( $struct as $key => $length ) { + if ( $length > 4 ) { + $data[$key] = substr( $block, $offset, $length ); + } else { + $data[$key] = $this->bin2dec( $block, $offset, $length ); + } + $offset += $length; + } + return $data; + } + + private function bin2dec( $str, $offset, $length ) { + $value = 0; + for ( $i = $length - 1; $i >= 0; $i-- ) { + $value *= 256; + $value += ord( $str[$offset + $i] ); + } + return $value; + } + + private function readOffset( $offset, $length ) { + $this->fseek( $offset ); + Wikimedia\suppressWarnings(); + $block = fread( $this->file, $length ); + Wikimedia\restoreWarnings(); + if ( $block === false ) { + $this->error( 'error reading from file', self::ERROR_READ ); + } + if ( strlen( $block ) !== $length ) { + $this->error( 'unable to read the required number of bytes from the file', + self::ERROR_READ_PAST_END ); + } + return $block; + } + + private function readSector( $sectorId ) { + return $this->readOffset( $this->sectorOffset( $sectorId ), 1 << $this->header['sector_shift'] ); + } + + private function error( $message, $code ) { + throw new RuntimeException( $message, $code ); + } + + private function fseek( $offset ) { + Wikimedia\suppressWarnings(); + $result = fseek( $this->file, $offset ); + Wikimedia\restoreWarnings(); + if ( $result !== 0 ) { + $this->error( "unable to seek to offset $offset", self::ERROR_SEEK ); + } + } + + private function readDifat() { + $binaryDifat = $this->header['difat']; + $nextDifatSector = $this->header['first_difat_sector']; + for ( $i = 0; $i < $this->header['num_difat_sectors']; $i++ ) { + $block = $this->readSector( $nextDifatSector ); + $binaryDifat .= substr( $block, 0, $this->sectorLength - 4 ); + $nextDifatSector = $this->bin2dec( $block, $this->sectorLength - 4, 4 ); + if ( $nextDifatSector == 0xFFFFFFFE ) { + break; + } + } + + $this->difat = []; + for ( $pos = 0; $pos < strlen( $binaryDifat ); $pos += 4 ) { + $fatSector = $this->bin2dec( $binaryDifat, $pos, 4 ); + if ( $fatSector < 0xFFFFFFFC ) { + $this->difat[] = $fatSector; + } else { + break; + } + } + } + + private function getNextSectorIdFromFat( $sectorId ) { + $entriesPerSector = intdiv( $this->sectorLength, 4 ); + $fatSectorId = intdiv( $sectorId, $entriesPerSector ); + $fatSectorArray = $this->getFatSector( $fatSectorId ); + return $fatSectorArray[$sectorId % $entriesPerSector]; + } + + private function getFatSector( $fatSectorId ) { + if ( !isset( $this->fat[$fatSectorId] ) ) { + $fat = []; + if ( !isset( $this->difat[$fatSectorId] ) ) { + $this->error( 'FAT sector requested beyond the end of the DIFAT', self::ERROR_INVALID_FORMAT ); + } + $absoluteSectorId = $this->difat[$fatSectorId]; + $block = $this->readSector( $absoluteSectorId ); + for ( $pos = 0; $pos < strlen( $block ); $pos += 4 ) { + $fat[] = $this->bin2dec( $block, $pos, 4 ); + } + $this->fat[$fatSectorId] = $fat; + } + return $this->fat[$fatSectorId]; + } + + private function readDirectory() { + $dirSectorId = $this->header['first_dir_sector']; + $binaryDir = ''; + $seenSectorIds = []; + while ( $dirSectorId !== 0xFFFFFFFE ) { + if ( isset( $seenSectorIds[$dirSectorId] ) ) { + $this->error( 'FAT loop detected', self::ERROR_INVALID_FORMAT ); + } + $seenSectorIds[$dirSectorId] = true; + + $binaryDir .= $this->readSector( $dirSectorId ); + $dirSectorId = $this->getNextSectorIdFromFat( $dirSectorId ); + } + + $struct = [ + 'name_raw' => 64, + 'name_length' => 2, + 'object_type' => 1, + 'color' => 1, + 'sid_left' => 4, + 'sid_right' => 4, + 'sid_child' => 4, + 'clsid' => 16, + 'state_bits' => 4, + 'create_time_low' => 4, + 'create_time_high' => 4, + 'modify_time_low' => 4, + 'modify_time_high' => 4, + 'first_sector' => 4, + 'size_low' => 4, + 'size_high' => 4, + ]; + $entryLength = array_sum( $struct ); + + for ( $pos = 0; $pos < strlen( $binaryDir ); $pos += $entryLength ) { + $entry = $this->unpack( $binaryDir, $pos, $struct ); + + // According to [MS-CFB] size_high may contain garbage due to a + // bug in a writer, it's best to pretend it is zero + $entry['size_high'] = 0; + + $type = $entry['object_type']; + if ( $type == self::TYPE_UNALLOCATED ) { + continue; + } + + $name = iconv( 'UTF-16', 'UTF-8', substr( $entry['name_raw'], 0, $entry['name_length'] - 2 ) ); + + $clsid = $this->decodeClsid( $entry['clsid'] ); + if ( $type == self::TYPE_ROOT && isset( self::$mimesByClsid[$clsid] ) ) { + $this->mimeFromClsid = self::$mimesByClsid[$clsid]; + } + + if ( $name === 'Workbook' ) { + $this->mime = 'application/vnd.ms-excel'; + } elseif ( $name === 'WordDocument' ) { + $this->mime = 'application/msword'; + } elseif ( $name === 'PowerPoint Document' ) { + $this->mime = 'application/vnd.ms-powerpoint'; + } + } + } +} diff --git a/includes/libs/mime/MimeAnalyzer.php b/includes/libs/mime/MimeAnalyzer.php index b93084ad5c..a2075dc367 100644 --- a/includes/libs/mime/MimeAnalyzer.php +++ b/includes/libs/mime/MimeAnalyzer.php @@ -653,7 +653,6 @@ EOT; "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" ); @@ -724,6 +723,12 @@ EOT; 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 @@ -797,9 +802,16 @@ EOT; } // 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", $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 @@ -945,6 +957,26 @@ EOT; 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 diff --git a/includes/utils/ZipDirectoryReader.php b/includes/utils/ZipDirectoryReader.php index 46f1aaab47..e7846f43e2 100644 --- a/includes/utils/ZipDirectoryReader.php +++ b/includes/utils/ZipDirectoryReader.php @@ -228,7 +228,9 @@ class ZipDirectoryReader { $this->eocdr['EOCDR size'] = $structSize + $this->eocdr['file comment length']; if ( $structSize + $this->eocdr['file comment length'] != strlen( $block ) - $sigPos ) { - $this->error( 'zip-bad', 'trailing bytes after the end of the file comment' ); + // T40432: MS binary documents frequently embed ZIP files + $this->error( 'zip-wrong-format', 'there is a ZIP signature but it is not at ' . + 'the end of the file. It could be an OLE file with a ZIP file embedded.' ); } if ( $this->eocdr['disk'] !== 0 || $this->eocdr['CD start disk'] !== 0 diff --git a/tests/phpunit/data/MSCompoundFileReader/calc.xls b/tests/phpunit/data/MSCompoundFileReader/calc.xls new file mode 100644 index 0000000000000000000000000000000000000000..f15e2c1aed690a4edf527146e2b0c9959a1e2993 GIT binary patch literal 5632 zcmeHLL2Oi26uo~sQ~tE2ot750Nc}WAw6rx;7Gg~8KtW-F)V9XNkjQlS9V*j~8HR`p z<4|Cskp#oSO%p@Xm>3h3m|%=1wmTOXjgbUh6*q?HVlWufL^_^x{~!B1cIZ?a6f<{n z-+TYO`~H3J-uv!*f4=^ze)jyu=4(bKTrQV~(Ja$l zWPw}mTkf^K~mEvY=!6?lHD?nIwh~bl4 zq7?b%WXk#%EU=ud*zdJJ^EdN&1-NkkGuLzfSAna+HQ=@2T5ug0M}X9W8^G(pjo>Em zdhk8qd%@Jz?AB~=M7st2fQxN%>xC7RTX)g|K@(oA49KTzFEiz9?!ShJ_|QM2aq$DN z1M(7Mqc56>S$B$d>Kvj5V{;lo+JlxMlR#_b14Td6vPYv2LJ_gHqvDO^rV-J(pV6{a z%UYC%e5_->SEO5-C~rpe0Y!7I98Y@tdXLwANDc#c;lLDf#~|J_VavT%JpLJ9jvC$QI)5Mexod_?9Ag z@Gtl|ANEv6a;!s{3a#rim0CAs{93QetkJqL6UZIZ*gcK-e};(~J9Y4|ZKu26#NO<| zZ^kgeB12~k`AMEw@G!D8T@nH?M*phAmf|U*g;}Oq~!*4 zJaWE?+;1YMo4+CL$IK>){rMr_va+#sQUfA8{h03 z?(cm;@yx=fg*-&lV3sG)GvnW)BRaI4P}xR#P&SE#`@*e5qht0_>uLLCYalrm9q$~l zq-9dR(&rva6ujUyF^6@IgO11Zl3Iv&TP-i;_jT@i4eBKZbt zw&y;1rzb z=4F1XkpeO($FTk}+yu6~{|rLO;e$X<3|8IWDj5Ysu> e`VYj)=Cl28tlxs}w5xwLs+HQ``~CfI>;D7h`6@L4 literal 0 HcmV?d00001 diff --git a/tests/phpunit/data/MSCompoundFileReader/dir-beyond-end.xls b/tests/phpunit/data/MSCompoundFileReader/dir-beyond-end.xls new file mode 100644 index 0000000000000000000000000000000000000000..b2aebf4427370f477a06f025c9034baab1e4e08e GIT binary patch literal 5632 zcmeHLL2Oi26uo~sQ~tE2ot750Nc}WAw6rx;7Gg~8KtW-F)V9XNkjQlS9V*j~8HR`p z<4|Cskp#oSO%p@Xm>3h3m|%=1wmTOXjgbUh6*q?HVlWufL^_^x{~!B1cIZ?a6f<{n z-+TYO`~H3J-uv!*f4=^ze)jyu=4(bKTrP(ShzOcx zx{EAu%bhEI=!gFTVETLwm{`!Q@1iA@r@8_Q3`i2cv{av|GRrxY#DQURXi7btf$lG~va{fPA|4GE=_h{%eSc5B)P57e4?y zATKdC`l5-Lb*E^j&LL_rHm4D!J!ly+3A9!|Q1mk`do=nW6cKAXD&9zL8WElQ87*72 ztVL+-mi<_-kZ}=j&7UxSfh7W_908 z$*(yJTJkh)5$D7dzgZeiYb_;T4Ch;ylK=nWQ?RMU<++r%bBAMxY$4uW1n(?@Zz+NY z|AL?MVNYcw$2yd$(7HZTsdYoful2gj8m${Mf!slj-P4HwXPBt5QwI;*cDnmb?9Cqh zW(*T7GIYj}pX7OF=79wT8PN3GZlYY@6c2EPYf+KB>}i9K$>P6TSwyq#tt;kLX6e&v{k_XvX2@xW~Eh8P6jM z(Y=La;DoP02W3Jg;|uv(OL=kw>V2cJRPtzYByH_J9XX;-}z;3|KZU4Z<*4u`J?Y>_en4hO7=&<3{?7w z_oRbh+9(0$ed#!uccxQd-kZ*XIoa#CoI4OP#IH4&j;0c$<8eId-H0;O6#?fdl5e19 zd+w7r-u?07x7?@yh>ESBbMRgH^2+4H8$##a#`-(wF6;spD8LQ?V|JlE$c#mfgO3#>iX}8>}B_r0oer&F`a|0 e|3Iv4KHLAs`Yq^AyZTq7TB-fL-{1eX{yzXhXDUSi literal 0 HcmV?d00001 diff --git a/tests/phpunit/data/MSCompoundFileReader/excel2016-compat97.xls b/tests/phpunit/data/MSCompoundFileReader/excel2016-compat97.xls new file mode 100755 index 0000000000000000000000000000000000000000..8895407d50120e60e6737d1f56940175fd802df3 GIT binary patch literal 25600 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 literal 0 HcmV?d00001 diff --git a/tests/phpunit/data/MSCompoundFileReader/fat-loop.xls b/tests/phpunit/data/MSCompoundFileReader/fat-loop.xls new file mode 100644 index 0000000000000000000000000000000000000000..ef8e1adbe223b3aadc503b9892d1a53238aba1dd GIT binary patch literal 5632 zcmeHLO=w(I6h3c$(l<$(Owy!kYU69rY0^xju?s5_Gi_S6i`tk(1S#0b^d*g*WMn$U zx)7&nyHG4tx^NSaLJ&l#7C{jOlbwr-A{MHv)QuEfOr;_LoALY3dt+b5Of%6?t;`wD zz4v|h+;{Fh=iGDeo3FoWm^*i&<%$&1qvDr^d`PN1xPi7=cn*vB&?dH!&*uv;niaZ( zEO5h}D}5M%6N6y-d<~db2sM3v2Q8^G)fHG^KvMW+#FE`IfjTWO!`tQ4dPIy@T{$DY z`Jx>8r(RnUwj%iwYWT&3U=;v?2s$QJ4)cu68M%9 zc<3+qSs(UPR`RUFS-;i|*($9YvjMHwW!Grklnv$&XzZRs{6Eb^jh#Ap$hI@xZ(wis z;5TcSV3DEIhWsSYF+=ADbU9TyW@2t(#sOo>%iE+T#|-{C?s=vhH<0no8SEf2W72w! zIUYIRMD90{)6L(I_7i5aB>wymaB@Dx#K(ieNhsk(38fZ_4`M>xf(<%}FjW2i?zM0B z4)^yyuXt9knS71N12he0c^o~nfh{_sQ_D$}ZIb(ClSrg5(l#_UZXdCpvR|?WQseQ7 z=zu+XG#O8~MY}Zw_i7YGEA0M@?NdE~{a8k<%CbLcHYVT%GyB+NlU6&`jF6VkX zJneJRhLiFjmdD?uM2)CX7+j7;hp|5U!#1aA9FE}=tjQJc~%8zj>65O9_PYm zJdY?u_ZE|Z6W)&w%7jhE7xJ~1^7sbSd&d&#)RELk#@c->VJEFe9_|{758KJ4tw+ty zv5^rcZ98LDTw>ae(iM+%1}tD@#uBffIp$8i{mcBmL*e({G^KO%hu_ieQ(zvH?2myN zsPq%>Ne95RQ4-Ai(lIdaOeev-H=O}yOT#-vumKgzX2$>_U5x8H*gt zHI~BBU7`Po1y=L>PyJt%1D0AQGfvh`G0)=bGcAW@SieILFC~6UtP#=1c;h}SMZea5AZ#1p8>r|u}erU4_8CKquD8! zA0fiL%x^VPPzL2F)<2G0FTefw;9r0d^$C#-Zo?@crK#Q3&oidn_1_EGi|#9fvI`m# hItN?-fmqpmw*QUwThN_x^{+;?Qu}+qzyEFhe*k)oCPDxJ literal 0 HcmV?d00001 diff --git a/tests/phpunit/data/MSCompoundFileReader/gnumeric.xls b/tests/phpunit/data/MSCompoundFileReader/gnumeric.xls new file mode 100644 index 0000000000000000000000000000000000000000..4e4995d4939460232e49abd6696cb26509eb3fbf GIT binary patch literal 5632 zcmeHL-%lJ>6#iz|h28#u1!@-x#VOFTyKE_CO>9!zB}Nl{Fq)!~M9oTtr39e{>4PT5 z@kbLMG*O#iCTU{&sEw_Si9YB9eL|CMG>whXCu;lys?o$6Wc<#Vncaav113C(oaLN* z?sxCG=gzt3-aEs0-`3AxxU%OameFxkVbP7FI)oe4V?jLu)KC{}(RE#c<7BE^^dE{q zJjR8rj^a$$wVH2iswQv~CO(Z^r38K^KaCf#19*IF!Wx(!ntFb0a@5*rx?kroWXK$5 znPkU|YUY~BtUOOyi)Ni&gUUvgm$mO#DvzOocBK1WO&(Fjz@XW${oYa8uCkWWz!z%s zlOl()3t!VBhIb{kNf8VTO}@C%cw1yQqNoQtJF*=ey@mAAl&7WJA}!p7yF)EcofsK@ zrqbNXjhGCYdwN5*tk8TPAEtF_dw2w|(;;N|Lm}0fv4R47fi>vtWLDQXa$-|ZUuZGL0EA`*ZxB*KZ&!-@s-Ci92T#lz#!LzI2nN{%k zinw^w`78u}-?Gk`5hUy?SIT<3TFVAIqGh99qa|!;xyz2a&+=R_@IKE#?+oFw4!!7n zA-A3)RBUnM3!9}a6)Ll{vn*^ljteJO9u0van>y{kkiY{`c5^?qxcF08zUvw}tGXr)&&LNQFAK6hRmUA#SH;1!4 zQ>)}c=UFpwYGh>kupkA!?tP?BkT2zu5BlWZMuZVEaLI`9WHus6Jwuy#`dSRXM9)7& zt6P&zJhKIjSI`~Fz*)t_)FH%2*rbe>P5LS(RrIa2#H5UtO>zsB*B6G=WNjPmyelxV zpueO7>u2?GI$x97)G7y^(qq_YvH3`uRn6~v3x<13?+DMiF{oVJLG*o zQ&5)mHMU%hyrI3`RC%D>>sG!iq^GD~{8;F(d^)6GKs#T&hP}k0K4=b#OVX`;rF?>8 z$MA|=P@&^y13uSxzkb$&2<+uE`=Jh?(O43r<(ERxjUjJ8 zcmV5)?Ksowe-&E^GWy9uAU7_yb4>EB*sd>cWp&m>i#(bm+x#6DvXEspZ(O@^zNaN| z?t>V*v$rqx5^Ew$n=s$Jb<6+a?K#%gPj~V^fA+)QZa;b|aq&I+@A~XV@t-BjY{kFK zMGgduESSurpCy_kXV+S$|Jsi@huc;T2(#BmWTY-DAwn1`JgG^zwF_)`sbH4|EJ@Ttl3KY QU-nhNf6KsIv?(L-52WA{O8@`> literal 0 HcmV?d00001 diff --git a/tests/phpunit/data/MSCompoundFileReader/impress.ppt b/tests/phpunit/data/MSCompoundFileReader/impress.ppt new file mode 100644 index 0000000000000000000000000000000000000000..8e39c4b7581b4e46b0c9192c6aba09bbd3f422e8 GIT binary patch literal 124928 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 literal 0 HcmV?d00001 diff --git a/tests/phpunit/data/MSCompoundFileReader/powerpoint2016-compat97.ppt b/tests/phpunit/data/MSCompoundFileReader/powerpoint2016-compat97.ppt new file mode 100755 index 0000000000000000000000000000000000000000..1fcafbba85e54d563fc7b02875a8f5edf14544af GIT binary patch literal 87552 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 Tk*d;y(2(sf!vG2YR}uIx6oj_5 literal 0 HcmV?d00001 diff --git a/tests/phpunit/data/MSCompoundFileReader/word2016-compat97.doc b/tests/phpunit/data/MSCompoundFileReader/word2016-compat97.doc new file mode 100755 index 0000000000000000000000000000000000000000..edd25e9722b76d43ba5beddcd32e4d014798fea6 GIT binary patch literal 22528 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 YaWx`eO&_(5Ke_PN#xtk%f6oH{0B5;m82|tP literal 0 HcmV?d00001 diff --git a/tests/phpunit/data/MSCompoundFileReader/writer.doc b/tests/phpunit/data/MSCompoundFileReader/writer.doc new file mode 100644 index 0000000000000000000000000000000000000000..b51df91ce96fb07c9e39b9592f7f463de1a07a96 GIT binary patch literal 9216 zcmeI1TWnNC7{}*qx7#k3vTSQbKv_zm$faB=Sj0=|1Loq2YKKPy~m~J5t zTyt&J7zP={QqY)}K{p|DnTW4^HeX0yhxGkIt*J(NB?9NU*3>|NQGe(uCTUuxK{ z37y@lYfB%pk)Uz|2ljkJllgPQ`QsTu6a5o^8Ko07n&4cNsGGr4$bqpZ6Zt#x`)I)W zJ;Z3GnbihN!t^6YYucJRXIY)oXj+z;u6T*r1+DQpW}qWnF$CK>0%m7CXi^=)@?kg_ zFEt6yKi#oGD`ft(*^Df3Ou$k6lo36B=RT0ODIx)&Y zVl`=oxJvGw&GEr_8S!3=+*+rZ+A<jR)C46htgnM4%W6ws8SqzY~? zjh6k}Qgg~{qpG}V58WBSq#@j~gZu?@EpZxtb#fhY{KQ)~ZXPf_T&bXGT;fmrCIT(# z23itLj%LRKNdwh`rGs4O4MvRVL^Vlsn5zr*X@3Y!1+?h2ZiHcwba_KQYGrcUW@}pc z-;LHI<^+9Cpq-D8@onl$aD~#uGlp$a z{LAlw=<59Erg|pl{*U<_q)A)yk{<&{cyng1zpkmm>GEsu{c*MHXyoI!%FXinPcO-W z(@+LF-wcYc4$ynrGoW`hO<8(hI|&u=D(JmU@hVNfUNh!iw{A~zAl5yc80=4`v`E={ zwUMr7@KUo^AXjhZVWxTf}Cbaa+oebi26tv+5kxAp6`;vH9{m*=+1K31FR?1}>A zk7%#a`OM9|=09`XqapZ*=_}++CABja+4{dnj-Kj^>Gt%1;zV(Hvs1uay4fm=`idSX zdf%#(=_&g`vW%hZkr^!KYKU&+6)B+c<3wSxfq` tK;JF=rMXk+e=VZDeWTLrG*8YSO;gZ+0R8@ZSlADC;N8E%t;c`={R{I%)5QP) literal 0 HcmV?d00001 diff --git a/tests/phpunit/data/media/zip-in-doc.doc b/tests/phpunit/data/media/zip-in-doc.doc new file mode 100644 index 0000000000000000000000000000000000000000..0b4c574eb0b543e8b1380430a061e0f12357874f GIT binary patch literal 22016 zcmeHP2|UzW`#;9a*q4NaYC_Uti;$b7xLL9!+82YtXv~OFsg#Nq-rlrtZb{k`_lg#6 zQfQM_)V+nYQ@RzolK=CJ`IS32w|d|IeLwgAf9Lo-zvrCioaZ^`e9xKR?>y&se#)+P zsoL?QZZ(kz!-y>T(566`9po|)H>T3+gqT1aWgptw+ECmF2%^&Pe+YrPT?IroUV%A;=TL1X3k|;ep{B{WtoHq`$i;(6x!RDj{zjWkl3*uKcc`IMLRo_EFqf zoGNfc6j{S)Pb0sj(H{RZu1To_$3ej4Q?cIXxH9Cwg?!{xem)qnfN3q$6}7+2e-@XM zs)UGftJ0QoT{Hncg7{_q0$u2RJt=x*`>x;l7A^* zvi$#6ni{Xp+TEF)YVWu5&g|j6SpjaKTe}cq53`;@G~kL)6lwVTBjCr07MiL2{o5&R z;a`LRtnnD)wch)8e^DJ$vws@|nA%}wBhz4Yp&hn^Q2+~6@z}TiZCWU8$bSd{T%pPg zB9nX|I19C~M`F${nVQ_>hlKz*_a>6U$trURs$at@suY50GFKsa5E zXuvLxl8hRWgFPSoBZQ8(1+ocf+ZV_Noc=G-ESNE0qRwm#1KrN@{tEeC=r3g#y<95Z z89(|JWh8aO;FsqLBq{%IOlQM%!+s9}LPz%uq|1P+fEs{cDiU=d7LWzda3CL`0H8>q zc%T%Z&h*f(3Cy7i!21ah3(Ed0cK+M->;St7K<|L$0Z$#EaX<@zSTIc9?y|%OXbjMF zR~dSQs{)-56b&QHsP8blJ!I*cfD7J%dy~aUC%XOy zF@3-pHh{?FkpjMu!xv8Xi;d(&Pc@qp!8^G6Qh1?-x=T~yhb3is6;a1cc2$(7yUmUp zcwJ4W_D9q3RSDJ#7w*rlJL+>>-c)F)9$310p8ug$57Jb1*1q<8>OU)mR4 z*LQ~5+UO5A^Ha=p%r+i5%zkt_6ZV^7dlx3$@1WXsd(Y!D0Fe#kBJ9(nIJ{_cGrT6O zx(W~}FMFAIa>=#0G1m)q`ph!ll`_(NXB??ESr}%ZcUSNEUGHM1V!nJr#>=LC4j&FB zH&?HF%+lVnpIKNl((zJQ^(=?e3m0EV%-GXMe)62ir90={&7FS2=i1JpS1k2*x#n4{ z*HBwt>3zcY(1_q`7u2u2yWF)7G+MZ4^~~wzy*6#@US%`-##?RQa@&AItM*=K%PF+D zyv@5{Vb;KhE_A-_y3yR)z#V(dAB;VjvX`^}X3w(Rqs_NlKikn6u^Y6PKnIh6^nrw7 zoCuD2hpQ)>&kp58;p9-h?5SADQXgI&w_|onrEO5YiA&&5mk#AOl98#pPQ_{0x8E&) z_+W``>3z*xTRl`J4osC(N#a~FTYjWr{=hwYd+)gFpC8DpF4lVVbdJu2!z;VqcPoh= z6K8lUB{4Ji7uN0E0k?X;9Qez$V@BZ)$)mZx~*zpN*B#fA!>^x@at z;`Hu3h?glm&R(Wf5wVOtd69O-t`_S`dtQ&Stn5*~YtB!Yw#KF+DRY>SM)QM~ww}HA z9VmZMtlUGRcR%kt(^{jhj5K-`JA7?+{VzQm%`;l> zI|nWfh%+dkc{h2Td-=u<8ES;ni(sSs# zDxH#hx~ukim-(!HV-r>5z|2~)X6~8Lz%;k6p@{`dxtNtHV=Fnd9)Y(Ta40z4qMTaekVR z&J6CQ7yT~xPIypsWr1GGdE3VgD@#L;1sqJc)~UMKCXLF#WIr@HFJzi zZYwv~7wqc(UG1e~y{{;_O)vAyJ*hTUxx3}grf1DfS=$_4iq*FDaD4alU3K9DImbyO zO7};kCOq^vKiyh)wYb+#$88H<|9Y+4tvM5m+I}nSd;0zR*um=8Lyb$5&9}dAth04{%>tE|=T8*38r?276Q(A@cH-1gJVzkb#V2cN%bz74D zn=Ac7HqX`{Vt+2Ts)x+Oor-hfqONwCqrPHAx>oA!^a`05QKj}%{3fwSz3#s`*3Rv0 z_@hAIqWYlu6VB%+cP&1B(oHeOO3h=`E55V7Ws{DVrmEWr&Fj(c<5LvtU-&+&h}rnt zVvk|to|w7x7(KvqP=;aOEg{KyT;&Cu$30d4FpHNnPcFvp!1cMw`o~>M6fgHr=%w*! z(<}RJCi>%7>(^{rud+b)z+U%~0>5{hDc=1XgswWHPR6@V%zdV8>=VW_!=A^_PWk&sj98=`f({<`+`ZMl7{2GPrJsm zV(tDx>=x(dsR`dr6y{H%zp2kUHhIpPx-Rmsn^!)bdLeFn)XBE_7pAVe8ftnt=Z+$0 ze3MFEKO57i6WJqsjxAz_Uo27KZV6UsaV}ftbh0#6)oo^=yWyP6&yFuqV%W?`sd{F( zKiw%|Y*_a5ZN?fG{~<#C6Cot^5-+2hJb{IGfQFUv#Re<;lK=|0~sOIKO@b^?>`beA@6 zTH@iFPc*XLes*~?E|SDbWAA--Z?!|GwRKLqA# z9NA#p!u+|kCSy>35pCA7rhDf+V(C{;WV~*4w*M(3HFcoVsEDjvQ}}aBin(|73O8%_ ze4u&4EavL6iSpe>p3<kF%YNFl zf!9(GzQ5#Y@!X|ffMM(4j0qE$1iUNHAm1H7)aQZaEC0&MU0ou+YuU2ici0$b<@74~ zl@-o)L6N6b{mc5MX&f>h?NVkQxoUT2#O|MKQu|D8ZoF7kXBWav$cZ{I*7|C&l5Omi zl7M^eHH-M`f6{wcnw8|%tmL~(zo^a1|IGrLEn~o<#(1^zqcp=GvLaR~Y0ca_g6rIR zD!!=Trs{I-qsfU}`Tj>o+q5x;+-!>|ov3S^S$$?tBX>DHvDMXOaf*Y9hw*P-y~kZ` zH1k-)Nf_!W$aU%x%nG^xX?9d&^^nr{krn@PuI`fQV?;p z?w`YbwY^qUeixh_u=t+>+j_0g)gC6E#zwv-W|o_xRQtNGO)X3EYmPr;w{z9FT7#Xt zol5e{T$^Iz(q3(qnSb8sWT5)ITcrC2pDk@Ut#-OALd|<=PyH~)DY`O|VUk{Sxyo?s z{?YV{laC)icmHG8WoV}Gp0cxbDHQ7vKC?>o@%X&~$<^8??E!#ihqareqU7r5lcFZ9 zk^iuq=m5W@CCR18Crj5pXGyd$k+dN>2|n4_s_^^P{K=H?@nFD;2w$Bs$W-Y427FIU zhC0GRh&78770ng!9SkhZEDTs2evlxT%MW!h@b~-P)XsnvEoAe9**pQC<6scWi8gQ? zrlL5MZ6Cyo@?=M{zyLqmp6y@|CKN{6o0~@m!BUYOZ6=81@F6cm5Ea1|LNY4UJUEIy z8w^MA%m-Om*qBGKxqJgwV5p^o0Z(XYz!J`ZSnv#p1%?hn*&vibEO-XQ*g-+ylRyb^ zgpxphyX0dTD@tNTm9eHI)|6y0B^gXfY$%D10V|Bh<i4t)f%fOM820K(B%m&JiF^a-wkv_Zt43rS@O{1-p*NU_6S^!+HR32MBdWVg11gBJfnyw7MTgxz z4DE4@VO>-Xc91Ih5Hlg51@zJJH30?$3(I4`ytd&aUPfd^1Zl&1QT?JgPEzB@Ds;0MesSbM;pTu)O4~YtC(BZZ=@mW1e2wP%K#Eh`ucZb*U@JryqZy2}hI?ws2ERB2_ zfe&y)g}dG#3gSemO5FZyvv-*Kfz|S4K;N87oTc+20}lF#ZWbxPQF9XzY<7|iARORq zAe_D>KzQ4~350jlDj>WuzX8H0mNMAF0oMVJD<0fq#{FMs;J8uh0~{WFWD0ORIT{RH z9XJm-?u810WBoW)@ySR{F3C9RIGM4=nz6=ndC>yA-~VZOY=ajrjd*6k0%3%x?4Q}N z6x-7Q?#T^`5=09^ge>on5N;5MHC_-E4D#VXR2Ytt1lb%sCD<{J7($msSOODq#1ZAv zAVolmfD{2K0#XE|2uKl-A|ORTihvXWDFRXi{v8DV%>Sp|x^gSkOiz97M)3a!HXpLU zioiid{}}yL+*CxrJQ4`~)OA4U@23Lc9zh0BH=u(+cp&F65c<(4fY5(G2ZU!VF9V^! zkNX5@yBesYUyo;8{DoW|R~XB3ijL+8S?w=%BH*0^WQqJ^%5SFlC%;))R5zBxHeitC zJ)u#kha@_hhLz(c0(QoaE97xLRsjNOkRl*OK#G7A0Vx7f1f&Q^5s)GvML>#x6ags$ z|Mw6;pBLR-e8-IM&(Uv2w-?{nqc4wsKEA_8e_j&^ zbP6fy4JmbSU|mj41f%QjDRq|6{xQ`j%g%m_-hcrLvRAo zmvJs|s746K#$o~auMgUAdW32j&LO4(&L%?6h_3KyU55~0YAyQDNc}(-FP2+&__nS? z(XWoG5}K%foVVDHuTjJ^DAa$?84taWBEj&TpnwFySAuv*kop$zYi#L4{rDTAF!&lB zQ5pR4Kw!YpCae_?A|m!~PassertTrue( $info['valid'] ); + $this->assertSame( $expectedMime, $info['mime'] ); + } + + public static function provideInvalid() { + return [ + [ 'dir-beyond-end.xls', 'ERROR_READ_PAST_END' ], + [ 'fat-loop.xls', 'ERROR_INVALID_FORMAT' ], + [ 'invalid-signature.xls', 'ERROR_INVALID_SIGNATURE' ], + ]; + } + + /** @dataProvider provideInvalid */ + public function testReadFileInvalid( $fileName, $expectedError ) { + global $IP; + + $info = MSCompoundFileReader::readFile( "$IP/tests/phpunit/data/MSCompoundFileReader/$fileName" ); + $this->assertFalse( $info['valid'] ); + $this->assertSame( constant( MSCompoundFileReader::class . '::' . $expectedError ), + $info['errorCode'] ); + } +} diff --git a/tests/phpunit/includes/libs/mime/MimeAnalyzerTest.php b/tests/phpunit/includes/libs/mime/MimeAnalyzerTest.php index fbe5a2bada..194781207e 100644 --- a/tests/phpunit/includes/libs/mime/MimeAnalyzerTest.php +++ b/tests/phpunit/includes/libs/mime/MimeAnalyzerTest.php @@ -128,4 +128,13 @@ class MimeAnalyzerTest extends PHPUnit\Framework\TestCase { $actualType = $this->doGuessMimeType( [ $file, 'mp3' ] ); $this->assertEquals( 'audio/mpeg', $actualType ); } + + /** + * A ZIP file embedded in the middle of a .doc file is still a Word Document. + */ + function testZipInDoc() { + $file = __DIR__ . '/../../../data/media/zip-in-doc.doc'; + $actualType = $this->doGuessMimeType( [ $file, 'doc' ] ); + $this->assertEquals( 'application/msword', $actualType ); + } } diff --git a/tests/phpunit/includes/utils/ZipDirectoryReaderTest.php b/tests/phpunit/includes/utils/ZipDirectoryReaderTest.php index 9f18e5af35..a1a3fd7309 100644 --- a/tests/phpunit/includes/utils/ZipDirectoryReaderTest.php +++ b/tests/phpunit/includes/utils/ZipDirectoryReaderTest.php @@ -61,7 +61,8 @@ class ZipDirectoryReaderTest extends PHPUnit\Framework\TestCase { } public function testTrailingBytes() { - $this->readZipAssertError( 'trail.zip', 'zip-bad', + // Due to T40432 this is now zip-wrong-format instead of zip-bad + $this->readZipAssertError( 'trail.zip', 'zip-wrong-format', 'Trailing bytes error' ); } -- 2.20.1