/** */ function wfGetType($filename, $safe = true) { global $wgTrivialMimeDetection; $ext = strrchr($filename, '.'); $ext = $ext === false ? '' : strtolower(substr($ext, 1)); # trivial detection by file extension, # used for thumbnails (thumb.php) if ($wgTrivialMimeDetection) { switch ($ext) { case 'gif': return 'image/gif'; case 'png': return 'image/png'; case 'jpg': return 'image/jpeg'; case 'jpeg': return 'image/jpeg'; } return 'unknown/unknown'; } $magic = MimeMagic::singleton(); // Use the extension only, rather than magic numbers, to avoid opening // up vulnerabilities due to uploads of files with allowed extensions // but disallowed types. $type = $magic->guessTypesForExtension($ext); /** * Double-check some security settings that were done on upload but might * have changed since. */ if ($safe) { global $wgFileBlacklist, $wgCheckFileExtensions, $wgStrictFileExtensions, $wgFileExtensions, $wgVerifyMimeType, $wgMimeTypeBlacklist, $wgRequest; list($partName, $extList) = UploadBase::splitExtensions($filename); if (UploadBase::checkFileExtensionList($extList, $wgFileBlacklist)) { return 'unknown/unknown'; } if ($wgCheckFileExtensions && $wgStrictFileExtensions && !UploadBase::checkFileExtensionList($extList, $wgFileExtensions)) { return 'unknown/unknown'; } if ($wgVerifyMimeType && in_array(strtolower($type), $wgMimeTypeBlacklist)) { return 'unknown/unknown'; } } return $type; }
/** * Really do the upload * Checks are made in SpecialUpload::execute() * @access private */ function processUpload() { /** * If there was no filename or a zero size given, give up quick. */ if (trim($this->mOname) == '' || empty($this->mUploadSize)) { return $this->mainUploadForm('<li>' . $this->msg('emptyfile')->plain() . '</li>'); } # Chop off any directories in the given filename if ($this->mDestFile) { $basename = basename($this->mDestFile); } else { $basename = basename($this->mOname); } /** * We'll want to blacklist against *any* 'extension', and use * only the final one for the whitelist. */ list($partname, $ext) = UploadBase::splitExtensions($basename); if (count($ext)) { $finalExt = $ext[count($ext) - 1]; } else { $finalExt = ''; } $fullExt = implode('.', $ext); $this->mUploadSaveName = $basename; $filtered = $basename; /* Don't allow users to override the blacklist (check file extension) */ global $wgStrictFileExtensions, $wgFileBlacklist; if (UploadBase::checkFileExtensionList($ext, $wgFileBlacklist) || $wgStrictFileExtensions && !UploadBase::checkFileExtension($finalExt, $this->fileExtensions)) { return $this->uploadError($this->msg('filetype-banned', htmlspecialchars($fullExt))->escaped()); } /** * Look at the contents of the file; if we can recognize the * type but it's corrupt or data of the wrong type, we should * probably not accept it. */ if (!$this->mStashed) { $veri = $this->verify($this->mUploadTempName, $finalExt); if (!$veri->isGood()) { return $this->uploadError($this->getOutput()->parse($veri->getWikiText())); } } /** * Check for non-fatal conditions */ if (!$this->mIgnoreWarning) { $warning = ''; global $wgCheckFileExtensions; if ($wgCheckFileExtensions) { if (!UploadBase::checkFileExtension($finalExt, $this->fileExtensions)) { $warning .= '<li>' . $this->msg('filetype-banned', htmlspecialchars($fullExt))->escaped() . '</li>'; } } global $wgUploadSizeWarning; if ($wgUploadSizeWarning && $this->mUploadSize > $wgUploadSizeWarning) { $lang = $this->getLanguage(); $wsize = $lang->formatSize($wgUploadSizeWarning); $asize = $lang->formatSize($this->mUploadSize); $warning .= '<li>' . $this->msg('large-file', $wsize, $asize)->escaped() . '</li>'; } if ($this->mUploadSize == 0) { $warning .= '<li>' . $this->msg('emptyfile')->plain() . '</li>'; } if ($warning != '') { /** * Stash the file in a temporary location; the user can choose * to let it through and we'll complete the upload then. */ return $this->uploadWarning($warning); } } /** * Try actually saving the thing... * It will show an error form on failure. */ $status = $this->saveUploadedFile($this->mUploadSaveName, $this->mUploadTempName, strtoupper($fullExt)); if ($status > 0) { $this->showSuccess($status); } }