/** * Get an associative array containing information about * a file with the given storage path. * * Resulting array fields include: * - fileExists * - size (filesize in bytes) * - mime (as major/minor) * - media_type (value to be used with the MEDIATYPE_xxx constants) * - metadata (handler specific) * - sha1 (in base 36) * - width * - height * - bits (bitrate) * - file-mime * - major_mime * - minor_mime * * @param string $path Filesystem path to a file * @param string|bool $ext The file extension, or true to extract it from the filename. * Set it to false to ignore the extension. * @return array * @since 1.28 */ public function getPropsFromPath($path, $ext) { $fsFile = new FSFile($path); $info = $this->newPlaceholderProps(); $info['fileExists'] = $fsFile->exists(); if ($info['fileExists']) { $info['size'] = $fsFile->getSize(); // bytes $info['sha1'] = $fsFile->getSha1Base36(); # MIME type according to file contents $info['file-mime'] = $this->magic->guessMimeType($path, false); # Logical MIME type $ext = $ext === true ? FileBackend::extensionFromPath($path) : $ext; $info['mime'] = $this->magic->improveTypeFromExtension($info['file-mime'], $ext); list($info['major_mime'], $info['minor_mime']) = File::splitMime($info['mime']); $info['media_type'] = $this->magic->getMediaType($path, $info['mime']); # Height, width and metadata $handler = MediaHandler::getHandler($info['mime']); if ($handler) { $info['metadata'] = $handler->getMetadata($fsFile, $path); /** @noinspection PhpMethodParametersCountMismatchInspection */ $gis = $handler->getImageSize($fsFile, $path, $info['metadata']); if (is_array($gis)) { $info = $this->extractImageSizeInfo($gis) + $info; } } } return $info; }
/** * @covers MediaHandler::fitBoxWidth * * @dataProvider provideTestFitBoxWidth */ public function testFitBoxWidth($width, $height, $max, $expected) { $y = round($expected * $height / $width); $result = MediaHandler::fitBoxWidth($width, $height, $max); $y2 = round($result * $height / $width); $this->assertEquals($expected, $result, "({$width}, {$height}, {$max}) wanted: {$expected}x{$y}, got: {z{$result}}x{$y2}"); }
/** * @param $title Title * @param $repo ForeignApiRepo * @return ForeignAPIFile|null */ static function newFromTitle( Title $title, $repo ) { $data = $repo->fetchImageQuery( array( 'titles' => 'File:' . $title->getDBkey(), 'iiprop' => self::getProps(), 'prop' => 'imageinfo', 'iimetadataversion' => MediaHandler::getMetadataVersion() ) ); $info = $repo->getImageInfo( $data ); if ( $info ) { $lastRedirect = isset( $data['query']['redirects'] ) ? count( $data['query']['redirects'] ) - 1 : -1; if ( $lastRedirect >= 0 ) { $newtitle = Title::newFromText( $data['query']['redirects'][$lastRedirect]['to'] ); $img = new self( $newtitle, $repo, $info, true ); if ( $img ) { $img->redirectedFrom( $title->getDBkey() ); } } else { $img = new self( $title, $repo, $info, true ); } return $img; } else { return null; } }
/** * Returns the number of pages of a multipage document, or false for * documents which aren't multipage documents */ function pageCount() { if ( !isset( $this->pageCount ) ) { if ( $this->getHandler() && $this->handler->isMultiPage( $this ) ) { $this->pageCount = $this->handler->pageCount( $this ); } else { $this->pageCount = false; } } return $this->pageCount; }
/** * @return bool */ function getMetadata() { if (!isset($this->metadata)) { if (!$this->getHandler()) { $this->metadata = false; } else { $this->metadata = $this->handler->getMetadata($this, $this->getLocalRefPath()); } } return $this->metadata; }
/** * Returns the number of pages of a multipage document, or false for * documents which aren't multipage documents * @return bool|int */ function pageCount() { if (!isset($this->pageCount)) { // @FIXME: callers expect File objects if ($this->getHandler() && $this->handler->isMultiPage($this)) { $this->pageCount = $this->handler->pageCount($this); } else { $this->pageCount = false; } } return $this->pageCount; }
/** * @covers MediaHandler::fitBoxWidth * @todo split into a dataprovider and test method */ public function testFitBoxWidth() { $vals = array(array('width' => 50, 'height' => 50, 'tests' => array(50 => 50, 17 => 17, 18 => 18)), array('width' => 366, 'height' => 300, 'tests' => array(50 => 61, 17 => 21, 18 => 22)), array('width' => 300, 'height' => 366, 'tests' => array(50 => 41, 17 => 14, 18 => 15)), array('width' => 100, 'height' => 400, 'tests' => array(50 => 12, 17 => 4, 18 => 4))); foreach ($vals as $row) { $tests = $row['tests']; $height = $row['height']; $width = $row['width']; foreach ($tests as $max => $expected) { $y = round($expected * $height / $width); $result = MediaHandler::fitBoxWidth($width, $height, $max); $y2 = round($result * $height / $width); $this->assertEquals($expected, $result, "({$width}, {$height}, {$max}) wanted: {$expected}x{$y}, got: {$result}x{$y2}"); } } }
/** * Upload a file and record it in the DB * @param string $srcPath Source storage path, virtual URL, or filesystem path * @param string $comment Upload description * @param string $pageText Text to use for the new description page, * if a new description page is created * @param int|bool $flags Flags for publish() * @param array|bool $props File properties, if known. This can be used to * reduce the upload time when uploading virtual URLs for which the file * info is already known * @param string|bool $timestamp Timestamp for img_timestamp, or false to use the * current time * @param User|null $user User object or null to use $wgUser * @param string[] $tags Change tags to add to the log entry and page revision. * (This doesn't check $user's permissions.) * @return FileRepoStatus On success, the value member contains the * archive name, or an empty string if it was a new file. */ function upload($srcPath, $comment, $pageText, $flags = 0, $props = false, $timestamp = false, $user = null, $tags = array()) { global $wgContLang; if ($this->getRepo()->getReadOnlyReason() !== false) { return $this->readOnlyFatalStatus(); } if (!$props) { if ($this->repo->isVirtualUrl($srcPath) || FileBackend::isStoragePath($srcPath)) { $props = $this->repo->getFileProps($srcPath); } else { $props = FSFile::getPropsFromPath($srcPath); } } $options = array(); $handler = MediaHandler::getHandler($props['mime']); if ($handler) { $options['headers'] = $handler->getStreamHeaders($props['metadata']); } else { $options['headers'] = array(); } // Trim spaces on user supplied text $comment = trim($comment); // Truncate nicely or the DB will do it for us // non-nicely (dangling multi-byte chars, non-truncated version in cache). $comment = $wgContLang->truncate($comment, 255); $this->lock(); // begin $status = $this->publish($srcPath, $flags, $options); if ($status->successCount >= 2) { // There will be a copy+(one of move,copy,store). // The first succeeding does not commit us to updating the DB // since it simply copied the current version to a timestamped file name. // It is only *preferable* to avoid leaving such files orphaned. // Once the second operation goes through, then the current version was // updated and we must therefore update the DB too. $oldver = $status->value; if (!$this->recordUpload2($oldver, $comment, $pageText, $props, $timestamp, $user, $tags)) { $status->fatal('filenotfound', $srcPath); } } $this->unlock(); // done return $status; }
protected function tearDown() { wfProfileIn(__METHOD__); // Cleaning up temporary files foreach ($this->tmpFiles as $fileName) { if (is_file($fileName) || is_link($fileName)) { unlink($fileName); } elseif (is_dir($fileName)) { wfRecursiveRemoveDir($fileName); } } if ($this->needsDB() && $this->db) { // Clean up open transactions while ($this->db->trxLevel() > 0) { $this->db->rollback(); } // don't ignore DB errors $this->db->ignoreErrors(false); } // Restore mw globals foreach ($this->mwGlobals as $key => $value) { $GLOBALS[$key] = $value; } $this->mwGlobals = array(); RequestContext::resetMain(); MediaHandler::resetCache(); $phpErrorLevel = intval(ini_get('error_reporting')); if ($phpErrorLevel !== $this->phpErrorLevel) { ini_set('error_reporting', $this->phpErrorLevel); $oldHex = strtoupper(dechex($this->phpErrorLevel)); $newHex = strtoupper(dechex($phpErrorLevel)); $message = "PHP error_reporting setting was left dirty: " . "was 0x{$oldHex} before test, 0x{$newHex} after test!"; $this->fail($message); } parent::tearDown(); wfProfileOut(__METHOD__); }
echo " Failed to load comment file {$f}, using default comment. "; } } } if (!$commentText) { $commentText = $comment; } } # Import the file if (isset($options['dry'])) { echo " publishing {$file} by '" . $wgUser->getName() . "', comment '{$commentText}'... "; } else { $props = FSFile::getPropsFromPath($file); $flags = 0; $publishOptions = array(); $handler = MediaHandler::getHandler($props['mime']); if ($handler) { $publishOptions['headers'] = $handler->getStreamHeaders($props['metadata']); } else { $publishOptions['headers'] = array(); } $archive = $image->publish($file, $flags, $publishOptions); if (!$archive->isGood()) { echo "failed. (" . $archive->getWikiText() . ")\n"; $failed++; continue; } } $commentText = SpecialUpload::getInitialPageText($commentText, $license); if (!isset($options['summary'])) { $summary = $commentText;
/** * Get the thumbnail extension and MIME type for a given source MIME type * @return array thumbnail extension and MIME type */ static function getThumbType($ext, $mime) { $handler = MediaHandler::getHandler($mime); if ($handler) { return $handler->getThumbType($ext, $mime); } else { return array($ext, $mime); } }
public function sanitizeParamsForBucketing($params) { $params = parent::sanitizeParamsForBucketing($params); // We unset the height parameters in order to let normaliseParams recalculate them // Otherwise there might be a height discrepancy if (isset($params['height'])) { unset($params['height']); } if (isset($params['physicalHeight'])) { unset($params['physicalHeight']); } return $params; }
function execute() { global $wgUploadBaseUrl, $wgUploadPath, $wgScriptPath, $wgServer; // Determine URI if ( $_SERVER['REQUEST_URI'][0] == '/' ) { $url = ( !empty( $_SERVER['HTTPS'] ) ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; } else { $url = $_SERVER['REQUEST_URI']; } if ( $wgUploadBaseUrl ) { $thumbBase = $wgUploadBaseUrl . $wgUploadPath . '/thumb'; } else { $thumbBase = $wgServer . $wgUploadPath . '/thumb'; } if ( substr( $url, 0, strlen( $thumbBase ) ) != $thumbBase ) { // Not a thumbnail URL header( 'X-Debug: not thumb' ); $this->real404(); return true; } $rel = substr( $url, strlen( $thumbBase ) + 1 ); // plus one for slash // Check for path traversal if ( !$this->validateFilename( $rel ) ) { header( 'X-Debug: invalid path traversal' ); $this->real404(); return false; } if ( !preg_match( '!^(\w)/(\w\w)/([^/]*)/([^/]*)$!', $rel, $parts ) ) { header( 'X-Debug: regex mismatch' ); $this->real404(); return false; } list( $all, $hash1, $hash2, $filename, $thumbName ) = $parts; $srcNamePos = strrpos( $thumbName, $filename ); if ( $srcNamePos === false ) { header( 'X-Debug: filename/fn2 mismatch' ); $this->real404(); return false; } $extraExt = substr( $thumbName, $srcNamePos + strlen( $filename ) ); if ( $extraExt != '' && $extraExt[0] != '.' ) { header( "X-Debug: invalid trailing characters in filename: $extraExt" ); $this->real404(); return false; } // Determine MIME type $extPos = strrpos( $filename, '.' ); $srcExt = $extPos === false ? '' : substr( $filename, $extPos + 1 ); $magic = MimeMagic::singleton(); $mime = $magic->guessTypesForExtension( $srcExt ); $handler = MediaHandler::getHandler( $mime ); if ( !$handler ) { header( 'X-Debug: no handler' ); $this->real404(); return false; } // Parse parameter string $paramString = substr( $thumbName, 0, $srcNamePos - 1 ); $params = $handler->parseParamString( $paramString ); if ( !$params ) { header( "X-Debug: handler for $mime says param string is invalid" ); $this->real404(); return false; } // Open the destination temporary file $dstPath = "{$this->publicDir}/thumb/$rel"; $tmpPath = "$dstPath.temp.MW_WebStore"; $tmpFile = @fopen( $tmpPath, 'a+' ); if ( !$tmpFile ) { $this->htmlError( 500, 'webstore_temp_open', $tmpPath ); return false; } // Get an exclusive lock if ( !flock( $tmpFile, LOCK_EX | LOCK_NB ) ) { wfDebug( "Waiting for shared lock..." ); if ( !flock( $tmpFile, LOCK_SH ) ) { wfDebug( "failed\n" ); $this->htmlError( 500, 'webstore_temp_lock' ); return false; } wfDebug( "OK\n" ); // Close it and see if it appears at $dstPath fclose( $tmpFile ); if ( $this->windows ) { // Rename happens after unlock on windows, so we have to wait for it usleep( 200000 ); } if ( file_exists( $dstPath ) ) { // Stream it out $magic = MimeMagic::singleton(); $type = $magic->guessMimeType( $dstPath ); $dstFile = fopen( $dstPath, 'r' ); if ( !$dstFile ) { $this->htmlError( 500, 'webstore_dest_open' ); return false; } $this->streamFile( $dstFile, $type ); fclose( $dstFile ); return true; } else { // Something went wrong, only the forwarding process knows what $this->real404(); return true; } } // Send an image scaling request to a host in the scaling cluster $error = false; $errno = false; $tmpUnlinkDone = false; do { $scalerUrl = "$wgServer$wgScriptPath/extensions/WebStore/inplace-scaler.php"; // Pick a server $servers = $this->scalerServers; shuffle( $servers ); foreach( $servers as $server ) { if ( strpos( $server, ':' ) === false ) { $server .= ':80'; } $post = WebStorePostFile::post( $scalerUrl, 'data', "{$this->publicDir}/$hash1/$hash2/$filename", $params, $server, $tmpFile, $this->httpConnectTimeout, $this->httpOverallTimeout ); // Try next server unless that one was successful if ( !$post->errno ) { break; } } if ( $post->errno ) { break; } if ( $post->responseCode != 200 ) { # Pass through image scaler errors (but don't keep the file) $info = self::$httpErrors[$post->responseCode]; header( "HTTP/1.1 {$post->responseCode} $info" ); $this->streamFile( $tmpFile ); break; } fseek( $tmpFile, 0, SEEK_END ); if ( ftell( $tmpFile ) == 0 ) { $this->htmlError( 500, 'webstore_scaler_empty_response' ); break; } // Report PHP errors if ( count( $this->phpErrors ) ) { $errors = '<ul>'; foreach ( $this->phpErrors as $error ) { $errors .= "<li>$error</li>"; } $errors .= '</ul>'; $info = self::$httpErrors[500]; header( "HTTP/1.1 500 $info" ); echo $this->dtd(); $msg = wfMsgHtml( 'webstore_php_error' ); echo <<<EOT <html><head><title>500 $info</title></head> <body> <h1>500 $info</h1> <p>$msg</p> $errors </body> </html> EOT; restore_error_handler(); break; } // Request completed successfully. // Move the file to its destination if ( $this->windows ) { fclose( $tmpFile ); // Wait for other processes to close the file if rename fails for ( $i = 0; $i < 10; $i++ ) { if ( !rename( $tmpPath, $dstPath ) ) { usleep( 50000 ); } else { break; } } $tmpFile = fopen( $dstPath, 'r' ); if ( !$tmpFile ) { $this->htmlError( 500, 'webstore_dest_open' ); } $tmpUnlinkDone = true; } else { rename( $tmpPath, $dstPath ); // Unlock so that other processes can start streaming the file out flock( $tmpFile, LOCK_UN ); $tmpUnlinkDone = true; } header( "HTTP/1.1 200 OK" ); // Stream it ourselves $this->streamFile( $tmpFile, $post->contentType ); } while (false); if ( $tmpFile ) { if ( !$tmpUnlinkDone ) { $this->closeAndDelete( $tmpFile, $tmpPath ); } else { fclose( $tmpFile ); } } if ( $post->errno ) { $this->htmlError( 500, 'webstore_curl', $post->error ); return false; } return true; }
/** * Upload a file and record it in the DB * @param string $srcPath Source storage path, virtual URL, or filesystem path * @param string $comment Upload description * @param string $pageText Text to use for the new description page, * if a new description page is created * @param int|bool $flags Flags for publish() * @param array|bool $props File properties, if known. This can be used to * reduce the upload time when uploading virtual URLs for which the file * info is already known * @param string|bool $timestamp Timestamp for img_timestamp, or false to use the * current time * @param User|null $user User object or null to use $wgUser * * @return FileRepoStatus object. On success, the value member contains the * archive name, or an empty string if it was a new file. */ function upload($srcPath, $comment, $pageText, $flags = 0, $props = false, $timestamp = false, $user = null) { global $wgContLang; if ($this->getRepo()->getReadOnlyReason() !== false) { return $this->readOnlyFatalStatus(); } if (!$props) { wfProfileIn(__METHOD__ . '-getProps'); if ($this->repo->isVirtualUrl($srcPath) || FileBackend::isStoragePath($srcPath)) { $props = $this->repo->getFileProps($srcPath); } else { $props = FSFile::getPropsFromPath($srcPath); } wfProfileOut(__METHOD__ . '-getProps'); } $options = array(); $handler = MediaHandler::getHandler($props['mime']); if ($handler) { $options['headers'] = $handler->getStreamHeaders($props['metadata']); } else { $options['headers'] = array(); } // Trim spaces on user supplied text $comment = trim($comment); // truncate nicely or the DB will do it for us // non-nicely (dangling multi-byte chars, non-truncated version in cache). $comment = $wgContLang->truncate($comment, 255); $this->lock(); // begin $status = $this->publish($srcPath, $flags, $options); if ($status->successCount > 0) { # Essentially we are displacing any existing current file and saving # a new current file at the old location. If just the first succeeded, # we still need to displace the current DB entry and put in a new one. if (!$this->recordUpload2($status->value, $comment, $pageText, $props, $timestamp, $user)) { $status->fatal('filenotfound', $srcPath); } } $this->unlock(); // done return $status; }
/** * @return string */ function getShortDesc() { $handler = $this->getHandler(); if ($handler) { return $handler->getShortDesc($this); } else { return MediaHandler::getGeneralShortDesc($this); } }
/** * Verifies that it's ok to include the uploaded file * * @return mixed True of the file is verified, array otherwise. */ protected function verifyFile() { global $wgVerifyMimeType, $wgDisableUploadScriptChecks; $status = $this->verifyPartialFile(); if ($status !== true) { return $status; } $mwProps = new MWFileProps(MimeMagic::singleton()); $this->mFileProps = $mwProps->getPropsFromPath($this->mTempPath, $this->mFinalExtension); $mime = $this->mFileProps['mime']; if ($wgVerifyMimeType) { # XXX: Missing extension will be caught by validateName() via getTitle() if ($this->mFinalExtension != '' && !$this->verifyExtension($mime, $this->mFinalExtension)) { return ['filetype-mime-mismatch', $this->mFinalExtension, $mime]; } } # check for htmlish code and javascript if (!$wgDisableUploadScriptChecks) { if ($this->mFinalExtension == 'svg' || $mime == 'image/svg+xml') { $svgStatus = $this->detectScriptInSvg($this->mTempPath, false); if ($svgStatus !== false) { return $svgStatus; } } } $handler = MediaHandler::getHandler($mime); if ($handler) { $handlerStatus = $handler->verifyUpload($this->mTempPath); if (!$handlerStatus->isOK()) { $errors = $handlerStatus->getErrorsArray(); return reset($errors); } } $error = true; Hooks::run('UploadVerifyFile', [$this, $mime, &$error]); if ($error !== true) { if (!is_array($error)) { $error = [$error]; } return $error; } wfDebug(__METHOD__ . ": all clear; passing.\n"); return true; }
/** * Get an associative array containing information about * a file with the given storage path. * * @param $ext Mixed: the file extension, or true to extract it from the filename. * Set it to false to ignore the extension. * * @return array */ public function getProps($ext = true) { wfProfileIn(__METHOD__); wfDebug(__METHOD__ . ": Getting file info for {$this->path}\n"); $info = self::placeholderProps(); $info['fileExists'] = $this->exists(); if ($info['fileExists']) { $magic = MimeMagic::singleton(); # get the file extension if ($ext === true) { $ext = self::extensionFromPath($this->path); } # mime type according to file contents $info['file-mime'] = $this->getMimeType(); # logical mime type $info['mime'] = $magic->improveTypeFromExtension($info['file-mime'], $ext); list($info['major_mime'], $info['minor_mime']) = File::splitMime($info['mime']); $info['media_type'] = $magic->getMediaType($this->path, $info['mime']); # Get size in bytes $info['size'] = $this->getSize(); # Height, width and metadata $handler = MediaHandler::getHandler($info['mime']); if ($handler) { $tempImage = (object) array(); $info['metadata'] = $handler->getMetadata($tempImage, $this->path); $gis = $handler->getImageSize($tempImage, $this->path, $info['metadata']); if (is_array($gis)) { $info = $this->extractImageSizeInfo($gis) + $info; } } $info['sha1'] = $this->getSha1Base36(); wfDebug(__METHOD__ . ": {$this->path} loaded, {$info['size']} bytes, {$info['mime']}.\n"); } else { wfDebug(__METHOD__ . ": {$this->path} NOT FOUND!\n"); } wfProfileOut(__METHOD__); return $info; }
function getShortDesc( $file ) { global $wgLang; $metadata = $this->unpackMetadata( $file->getMetadata() ); $streamTypes = $this->getStreamTypes( $file ); if ( !$streamTypes ) { return parent::getShortDesc( $file ); } if ( isset( $metadata['video'] ) && $metadata['video'] ) { // Count multiplexed audio/video as video for short descriptions $msg = 'wah-short-video'; } elseif ( isset( $metadata['audio'] ) && $metadata['audio'] ) { $msg = 'wah-short-audio'; } else { $msg = 'wah-short-general'; } return wfMsg( $msg, implode( '/', $streamTypes ), $wgLang->formatTimePeriod( $this->getLength( $file ) ) ); }
static function outputHook($outputPage, $parserOutput, $data) { $instance = MediaHandler::getHandler('application/ogg'); if ($instance) { $instance->setHeaders($outputPage); } }
/** * Verifies that it's ok to include the uploaded file * * @return mixed true of the file is verified, array otherwise. */ protected function verifyFile() { global $wgVerifyMimeType; wfProfileIn(__METHOD__); $status = $this->verifyPartialFile(); if ($status !== true) { wfProfileOut(__METHOD__); return $status; } $this->mFileProps = FSFile::getPropsFromPath($this->mTempPath, $this->mFinalExtension); $mime = $this->mFileProps['file-mime']; if ($wgVerifyMimeType) { # XXX: Missing extension will be caught by validateName() via getTitle() if ($this->mFinalExtension != '' && !$this->verifyExtension($mime, $this->mFinalExtension)) { wfProfileOut(__METHOD__); return array('filetype-mime-mismatch', $this->mFinalExtension, $mime); } } $handler = MediaHandler::getHandler($mime); if ($handler) { $handlerStatus = $handler->verifyUpload($this->mTempPath); if (!$handlerStatus->isOK()) { $errors = $handlerStatus->getErrorsArray(); wfProfileOut(__METHOD__); return reset($errors); } } wfRunHooks('UploadVerifyFile', array($this, $mime, &$status)); if ($status !== true) { wfProfileOut(__METHOD__); return $status; } wfDebug(__METHOD__ . ": all clear; passing.\n"); wfProfileOut(__METHOD__); return true; }
protected function tearDown() { global $wgRequest; $status = ob_get_status(); if (isset($status['name']) && $status['name'] === 'MediaWikiTestCase::wfResetOutputBuffersBarrier') { ob_end_flush(); } $this->called['tearDown'] = true; // Cleaning up temporary files foreach ($this->tmpFiles as $fileName) { if (is_file($fileName) || is_link($fileName)) { unlink($fileName); } elseif (is_dir($fileName)) { wfRecursiveRemoveDir($fileName); } } if ($this->needsDB() && $this->db) { // Clean up open transactions while ($this->db->trxLevel() > 0) { $this->db->rollback(__METHOD__, 'flush'); } } // Restore mw globals foreach ($this->mwGlobals as $key => $value) { $GLOBALS[$key] = $value; } $this->mwGlobals = array(); RequestContext::resetMain(); MediaHandler::resetCache(); if (session_id() !== '') { session_write_close(); session_id(''); } $wgRequest = new FauxRequest(); MediaWiki\Session\SessionManager::resetCache(); $phpErrorLevel = intval(ini_get('error_reporting')); if ($phpErrorLevel !== $this->phpErrorLevel) { ini_set('error_reporting', $this->phpErrorLevel); $oldHex = strtoupper(dechex($this->phpErrorLevel)); $newHex = strtoupper(dechex($phpErrorLevel)); $message = "PHP error_reporting setting was left dirty: " . "was 0x{$oldHex} before test, 0x{$newHex} after test!"; $this->fail($message); } parent::tearDown(); }
/** * Verifies that it's ok to include the uploaded file * * @return mixed true of the file is verified, array otherwise. */ protected function verifyFile() { global $wgAllowJavaUploads, $wgDisableUploadScriptChecks; # get the title, even though we are doing nothing with it, because # we need to populate mFinalExtension $this->getTitle(); $this->mFileProps = FSFile::getPropsFromPath($this->mTempPath, $this->mFinalExtension); # check mime type, if desired $mime = $this->mFileProps['file-mime']; $status = $this->verifyMimeType($mime); if ($status !== true) { return $status; } # check for htmlish code and javascript if (!$wgDisableUploadScriptChecks) { if (self::detectScript($this->mTempPath, $mime, $this->mFinalExtension)) { return array('uploadscripted'); } if ($this->mFinalExtension == 'svg' || $mime == 'image/svg+xml') { if ($this->detectScriptInSvg($this->mTempPath)) { return array('uploadscripted'); } } } # Check for Java applets, which if uploaded can bypass cross-site # restrictions. if (!$wgAllowJavaUploads) { $this->mJavaDetected = false; $zipStatus = ZipDirectoryReader::read($this->mTempPath, array($this, 'zipEntryCallback')); if (!$zipStatus->isOK()) { $errors = $zipStatus->getErrorsArray(); $error = reset($errors); if ($error[0] !== 'zip-wrong-format') { return $error; } } if ($this->mJavaDetected) { return array('uploadjava'); } } # Scan the uploaded file for viruses $virus = $this->detectVirus($this->mTempPath); if ($virus) { return array('uploadvirus', $virus); } $handler = MediaHandler::getHandler($mime); if ($handler) { $handlerStatus = $handler->verifyUpload($this->mTempPath); if (!$handlerStatus->isOK()) { $errors = $handlerStatus->getErrorsArray(); return reset($errors); } } wfRunHooks('UploadVerifyFile', array($this, $mime, &$status)); if ($status !== true) { return $status; } wfDebug(__METHOD__ . ": all clear; passing.\n"); return true; }
/** * Resets all static caches */ public static function resetCache() { self::$handlers = array(); }
/** * Verifies that it's ok to include the uploaded file * * @return mixed true of the file is verified, array otherwise. */ protected function verifyFile() { # get the title, even though we are doing nothing with it, because # we need to populate mFinalExtension $this->getTitle(); $this->mFileProps = File::getPropsFromPath($this->mTempPath, $this->mFinalExtension); $this->checkMacBinary(); # check mime type, if desired $mime = $this->mFileProps['file-mime']; $status = $this->verifyMimeType($mime); if ($status !== true) { return $status; } # check for htmlish code and javascript if (self::detectScript($this->mTempPath, $mime, $this->mFinalExtension)) { return array('uploadscripted'); } if ($this->mFinalExtension == 'svg' || $mime == 'image/svg+xml') { if ($this->detectScriptInSvg($this->mTempPath)) { return array('uploadscripted'); } } /** * Scan the uploaded file for viruses */ $virus = $this->detectVirus($this->mTempPath); if ($virus) { return array('uploadvirus', $virus); } $handler = MediaHandler::getHandler($mime); if ($handler) { $handlerStatus = $handler->verifyUpload($this->mTempPath); if (!$handlerStatus->isOK()) { $errors = $handlerStatus->getErrorsArray(); return reset($errors); } } wfRunHooks('UploadVerifyFile', array($this, $mime, &$status)); if ($status !== true) { return $status; } wfDebug(__METHOD__ . ": all clear; passing.\n"); return true; }
/** * Resets all static caches */ public static function resetCache() { self::$handlers = []; }
/** * Shown in file history box on image description page. * * @access public * @param File $file * @return string Dimensions */ public function getDimensionsString($file) { global $wgLang; $probe = new FFProbe($file->getLocalRefPath()); $format = $probe->getFormat(); $stream = $probe->getStream("a:0"); if ($format === false || $stream === false) { return parent::getDimensionsString($file); } return wfMessage('ev_audio_short_desc', $wgLang->formatTimePeriod($format->getDuration()))->text(); }