function testBasename() { $sets = array('' => '', '/' => '', '\\' => '', '//' => '', '\\\\' => '', 'a' => 'a', 'aaaa' => 'aaaa', '/a' => 'a', '\\a' => 'a', '/aaaa' => 'aaaa', '\\aaaa' => 'aaaa', '/aaaa/' => 'aaaa', '\\aaaa\\' => 'aaaa', '\\aaaa\\' => 'aaaa', '/mnt/upload3/wikipedia/en/thumb/8/8b/Zork_Grand_Inquisitor_box_cover.jpg/93px-Zork_Grand_Inquisitor_box_cover.jpg' => '93px-Zork_Grand_Inquisitor_box_cover.jpg', 'C:\\Progra~1\\Wikime~1\\Wikipe~1\\VIEWER.EXE' => 'VIEWER.EXE', 'Östergötland_coat_of_arms.png' => 'Östergötland_coat_of_arms.png'); foreach ($sets as $from => $to) { $this->assertEquals($to, wfBaseName($from), "wfBaseName('{$from}') => '{$to}'"); } }
/** * Replace all invalid characters with '-'. * Additional characters can be defined in $wgIllegalFileChars (see T22489). * By default, $wgIllegalFileChars includes ':', '/', '\'. * * @param string $name Filename to process * @return string */ function wfStripIllegalFilenameChars($name) { global $wgIllegalFileChars; $illegalFileChars = $wgIllegalFileChars ? "|[" . $wgIllegalFileChars . "]" : ''; $name = preg_replace("/[^" . Title::legalChars() . "]" . $illegalFileChars . "/", '-', $name); // $wgIllegalFileChars may not include '/' and '\', so we still need to do this $name = wfBaseName($name); return $name; }
private static function makeThumbs($local_file, $sample) { global $wgImageMagickConvertCommand, $wgUseOptiPng, $wgOptiPngCommand; $comment = 'Auto-uploaded for the Samples page.'; $license = 'cc-by-sa-nc-2.5-self'; //PNG the file name $img_file = preg_replace('@.pdf@', '.png', $local_file); //make an image out of a pdf (add an [0] so we only get the first page) $cmd = $wgImageMagickConvertCommand . ' ' . escapeshellarg($local_file) . '[0] ' . escapeshellarg($img_file); exec($cmd); //optimize that bad boy if ($wgUseOptiPng) { $cmd = $wgOptiPngCommand . ' ' . escapeshellarg($img_file); exec($cmd); } //put the new image into the system $title = Title::makeTitleSafe(NS_IMAGE, wfBaseName($img_file)); if (!is_object($title)) { self::error_log($sample, 'Image could not be imported; a valid title cannot be produced.'); return false; } $image = wfLocalFile($title); $archive = $image->publish($img_file); //remove the temp image file @unlink($img_file); if (WikiError::isError($archive) || !$archive->isGood()) { self::error_log($sample, 'Image archive publish failed.'); return false; } if ($image->recordUpload($archive->value, $comment, $license)) { //yay! return true; } else { self::error_log($sample, 'Image record upload failed.'); return false; } }
if (isset($options['comment-file'])) { $comment = file_get_contents($options['comment-file']); if ($comment === false || $comment === null) { die("failed to read comment file: {$options['comment-file']}\n"); } } elseif (isset($options['comment'])) { $comment = $options['comment']; } $commentExt = isset($options['comment-ext']) ? $options['comment-ext'] : false; # Get the license specifier $license = isset($options['license']) ? $options['license'] : ''; # Batch "upload" operation $count = count($files); if ($count > 0) { foreach ($files as $file) { $base = wfBaseName($file); # Validate a title $title = Title::makeTitleSafe(NS_FILE, $base); if (!is_object($title)) { echo "{$base} could not be imported; a valid title cannot be produced\n"; continue; } if ($from) { if ($from == $title->getDBkey()) { $from = null; } else { $ignored++; continue; } } if ($checkUserBlock && $processed % $checkUserBlock == 0) {
/** * @see FileBackendStore::getLocalCopy() */ public function getLocalCopy(array $params) { list($srcCont, $srcRel) = $this->resolveStoragePathReal($params['src']); if ($srcRel === null) { return null; } /*if ( !$this->fileExists( $params ) ) { return null; }*/ $tmpFile = null; try { $sContObj = $this->getContainer($srcCont); $obj = new CF_Object($sContObj, $srcRel, false, false); // skip HEAD // Get source file extension $ext = FileBackend::extensionFromPath($srcRel); // Create a new temporary file... $tmpFile = TempFSFile::factory(wfBaseName($srcRel) . '_', $ext); if ($tmpFile) { $handle = fopen($tmpFile->getPath(), 'wb'); if ($handle) { $obj->stream($handle, $this->headersFromParams($params)); fclose($handle); } else { $tmpFile = null; // couldn't open temp file } } } catch (NoSuchContainerException $e) { $tmpFile = null; $this->logException($e, __METHOD__, $params); } catch (NoSuchObjectException $e) { $tmpFile = null; $this->logException($e, __METHOD__, $params); } catch (InvalidResponseException $e) { $tmpFile = null; $this->logException($e, __METHOD__, $params); } catch (Exception $e) { // some other exception? $tmpFile = null; $this->logException($e, __METHOD__, $params); } return $tmpFile; }
/** * Replace all invalid characters with - * Additional characters can be defined in $wgIllegalFileChars (see bug 20489) * By default, $wgIllegalFileChars = ':' * * @param string $name Filename to process * @return string */ function wfStripIllegalFilenameChars($name) { global $wgIllegalFileChars; $illegalFileChars = $wgIllegalFileChars ? "|[" . $wgIllegalFileChars . "]" : ''; $name = wfBaseName($name); $name = preg_replace("/[^" . Title::legalChars() . "]" . $illegalFileChars . "/", '-', $name); return $name; }
function wfImageAuthMain() { global $wgImgAuthPublicTest, $wgRequest; // See if this is a public Wiki (no protections). if ($wgImgAuthPublicTest && in_array('read', User::getGroupPermissions(array('*')), true)) { // This is a public wiki, so disable this script (for private wikis only) wfForbidden('img-auth-accessdenied', 'img-auth-public'); return; } // Get the requested file path (source file or thumbnail) $matches = WebRequest::getPathInfo(); if (!isset($matches['title'])) { wfForbidden('img-auth-accessdenied', 'img-auth-nopathinfo'); return; } $path = $matches['title']; if ($path && $path[0] !== '/') { // Make sure $path has a leading / $path = "/" . $path; } // Check for bug 28235: QUERY_STRING overriding the correct extension $whitelist = array(); $dotPos = strrpos($path, '.'); if ($dotPos !== false) { $whitelist[] = substr($path, $dotPos + 1); } if (!$wgRequest->checkUrlExtension($whitelist)) { return; } // Get the local file repository $repo = RepoGroup::singleton()->getRepo('local'); // Get the full file storage path and extract the source file name. // (e.g. 120px-Foo.png => Foo.png or page2-120px-Foo.png => Foo.png). // This only applies to thumbnails, and all thumbnails should // be under a folder that has the source file name. if (strpos($path, '/thumb/') === 0) { $name = wfBaseName(dirname($path)); // file is a thumbnail $filename = $repo->getZonePath('thumb') . substr($path, 6); // strip "/thumb" } else { $name = wfBaseName($path); // file is a source file $filename = $repo->getZonePath('public') . $path; } // Check to see if the file exists if (!$repo->fileExists($filename)) { wfForbidden('img-auth-accessdenied', 'img-auth-nofile', $filename); return; } $title = Title::makeTitleSafe(NS_FILE, $name); if (!$title instanceof Title) { // files have valid titles wfForbidden('img-auth-accessdenied', 'img-auth-badtitle', $name); return; } // Run hook for extension authorization plugins /** @var $result array */ $result = null; if (!wfRunHooks('ImgAuthBeforeStream', array(&$title, &$path, &$name, &$result))) { wfForbidden($result[0], $result[1], array_slice($result, 2)); return; } // Check user authorization for this title // Checks Whitelist too if (!$title->userCan('read')) { wfForbidden('img-auth-accessdenied', 'img-auth-noread', $name); return; } // Stream the requested file wfDebugLog('img_auth', "Streaming `" . $filename . "`."); $repo->streamFile($filename, array('Cache-Control: private', 'Vary: Cookie')); }
$comment = file_get_contents($options['comment-file']); if ($comment === false || $comment === null) { die("failed to read comment file: {$options['comment-file']}\n"); } } elseif (isset($options['comment'])) { $comment = $options['comment']; } $commentExt = isset($options['comment-ext']) ? $options['comment-ext'] : false; $summary = isset($options['summary']) ? $options['summary'] : ''; # Get the license specifier $license = isset($options['license']) ? $options['license'] : ''; # Batch "upload" operation $count = count($files); if ($count > 0) { foreach ($files as $file) { $base = UtfNormal\Validator::cleanUp(wfBaseName($file)); # Validate a title $title = Title::makeTitleSafe(NS_FILE, $base); if (!is_object($title)) { echo "{$base} could not be imported; a valid title cannot be produced\n"; continue; } if ($from) { if ($from == $title->getDBkey()) { $from = null; } else { $ignored++; continue; } } if ($checkUserBlock && $processed % $checkUserBlock == 0) {
function checkMissingImage($fullpath) { $filename = wfBaseName($fullpath); if (is_dir($fullpath)) { return; } if (is_link($fullpath)) { $this->output("skipping symlink at {$fullpath}\n"); return; } $row = $this->dbw->selectRow('image', array('img_name'), array('img_name' => $filename), __METHOD__); if ($row) { // already known, move on return; } else { $this->addMissingImage($filename, $fullpath); } }
/** * Constructor * * @param $file String: filename. */ function __construct($file) { /** * Page numbers here refer to pages in the EXIF 2.2 standard * * @link http://exif.org/Exif2-2.PDF The Exif 2.2 specification */ $this->mExifTags = array('tiff' => array('structure' => array('ImageWidth' => Exif::SHORT . ',' . Exif::LONG, 'ImageLength' => Exif::SHORT . ',' . Exif::LONG, 'BitsPerSample' => Exif::SHORT, 'Compression' => Exif::SHORT, 'PhotometricInterpretation' => Exif::SHORT, 'Orientation' => Exif::SHORT, 'SamplesPerPixel' => Exif::SHORT, 'PlanarConfiguration' => Exif::SHORT, 'YCbCrSubSampling' => Exif::SHORT, 'YCbCrPositioning' => Exif::SHORT, 'XResolution' => Exif::RATIONAL, 'YResolution' => Exif::RATIONAL, 'ResolutionUnit' => Exif::SHORT), 'offset' => array('StripOffsets' => Exif::SHORT . ',' . Exif::LONG, 'RowsPerStrip' => Exif::SHORT . ',' . Exif::LONG, 'StripByteCounts' => Exif::SHORT . ',' . Exif::LONG, 'JPEGInterchangeFormat' => Exif::SHORT . ',' . Exif::LONG, 'JPEGInterchangeFormatLength' => Exif::SHORT . ',' . Exif::LONG), 'characteristics' => array('TransferFunction' => Exif::SHORT, 'WhitePoint' => Exif::RATIONAL, 'PrimaryChromaticities' => Exif::RATIONAL, 'YCbCrCoefficients' => Exif::RATIONAL, 'ReferenceBlackWhite' => Exif::RATIONAL), 'other' => array('DateTime' => Exif::ASCII, 'ImageDescription' => Exif::ASCII, 'Make' => Exif::ASCII, 'Model' => Exif::ASCII, 'Software' => Exif::ASCII, 'Artist' => Exif::ASCII, 'Copyright' => Exif::ASCII)), 'exif' => array('version' => array('ExifVersion' => Exif::UNDEFINED, 'FlashpixVersion' => Exif::UNDEFINED), 'characteristics' => array('ColorSpace' => Exif::SHORT), 'configuration' => array('ComponentsConfiguration' => Exif::UNDEFINED, 'CompressedBitsPerPixel' => Exif::RATIONAL, 'PixelYDimension' => Exif::SHORT . ',' . Exif::LONG, 'PixelXDimension' => Exif::SHORT . ',' . Exif::LONG), 'user' => array('MakerNote' => Exif::UNDEFINED, 'UserComment' => Exif::UNDEFINED), 'related' => array('RelatedSoundFile' => Exif::ASCII), 'dateandtime' => array('DateTimeOriginal' => Exif::ASCII, 'DateTimeDigitized' => Exif::ASCII, 'SubSecTime' => Exif::ASCII, 'SubSecTimeOriginal' => Exif::ASCII, 'SubSecTimeDigitized' => Exif::ASCII), 'conditions' => array('ExposureTime' => Exif::RATIONAL, 'FNumber' => Exif::RATIONAL, 'ExposureProgram' => Exif::SHORT, 'SpectralSensitivity' => Exif::ASCII, 'ISOSpeedRatings' => Exif::SHORT, 'OECF' => Exif::UNDEFINED, 'ShutterSpeedValue' => Exif::SRATIONAL, 'ApertureValue' => Exif::RATIONAL, 'BrightnessValue' => Exif::SRATIONAL, 'ExposureBiasValue' => Exif::SRATIONAL, 'MaxApertureValue' => Exif::RATIONAL, 'SubjectDistance' => Exif::RATIONAL, 'MeteringMode' => Exif::SHORT, 'LightSource' => Exif::SHORT, 'Flash' => Exif::SHORT, 'FocalLength' => Exif::RATIONAL, 'SubjectArea' => Exif::SHORT, 'FlashEnergy' => Exif::RATIONAL, 'SpatialFrequencyResponse' => Exif::UNDEFINED, 'FocalPlaneXResolution' => Exif::RATIONAL, 'FocalPlaneYResolution' => Exif::RATIONAL, 'FocalPlaneResolutionUnit' => Exif::SHORT, 'SubjectLocation' => Exif::SHORT, 'ExposureIndex' => Exif::RATIONAL, 'SensingMethod' => Exif::SHORT, 'FileSource' => Exif::UNDEFINED, 'SceneType' => Exif::UNDEFINED, 'CFAPattern' => Exif::UNDEFINED, 'CustomRendered' => Exif::SHORT, 'ExposureMode' => Exif::SHORT, 'WhiteBalance' => Exif::SHORT, 'DigitalZoomRatio' => Exif::RATIONAL, 'FocalLengthIn35mmFilm' => Exif::SHORT, 'SceneCaptureType' => Exif::SHORT, 'GainControl' => Exif::RATIONAL, 'Contrast' => Exif::SHORT, 'Saturation' => Exif::SHORT, 'Sharpness' => Exif::SHORT, 'DeviceSettingDescription' => Exif::UNDEFINED, 'SubjectDistanceRange' => Exif::SHORT), 'other' => array('ImageUniqueID' => Exif::ASCII)), 'gps' => array('GPSVersionID' => Exif::BYTE, 'GPSLatitudeRef' => Exif::ASCII, 'GPSLatitude' => Exif::RATIONAL, 'GPSLongitudeRef' => Exif::ASCII, 'GPSLongitude' => Exif::RATIONAL, 'GPSAltitudeRef' => Exif::BYTE, 'GPSAltitude' => Exif::RATIONAL, 'GPSTimeStamp' => Exif::RATIONAL, 'GPSSatellites' => Exif::ASCII, 'GPSStatus' => Exif::ASCII, 'GPSMeasureMode' => Exif::ASCII, 'GPSDOP' => Exif::RATIONAL, 'GPSSpeedRef' => Exif::ASCII, 'GPSSpeed' => Exif::RATIONAL, 'GPSTrackRef' => Exif::ASCII, 'GPSTrack' => Exif::RATIONAL, 'GPSImgDirectionRef' => Exif::ASCII, 'GPSImgDirection' => Exif::RATIONAL, 'GPSMapDatum' => Exif::ASCII, 'GPSDestLatitudeRef' => Exif::ASCII, 'GPSDestLatitude' => Exif::RATIONAL, 'GPSDestLongitudeRef' => Exif::ASCII, 'GPSDestLongitude' => Exif::RATIONAL, 'GPSDestBearingRef' => Exif::ASCII, 'GPSDestBearing' => Exif::RATIONAL, 'GPSDestDistanceRef' => Exif::ASCII, 'GPSDestDistance' => Exif::RATIONAL, 'GPSProcessingMethod' => Exif::UNDEFINED, 'GPSAreaInformation' => Exif::UNDEFINED, 'GPSDateStamp' => Exif::ASCII, 'GPSDifferential' => Exif::SHORT)); $this->file = $file; $this->basename = wfBaseName($this->file); $this->makeFlatExifTags(); $this->debugFile($this->basename, __FUNCTION__, true); wfSuppressWarnings(); $data = exif_read_data($this->file); wfRestoreWarnings(); /** * exif_read_data() will return false on invalid input, such as * when somebody uploads a file called something.jpeg * containing random gibberish. */ $this->mRawExifData = $data ? $data : array(); $this->makeFilteredData(); $this->makeFormattedData(); $this->debugFile(__FUNCTION__, false); }
function internalProcessUpload(&$resultDetails) { global $wgUser; /* Check for PHP error if any, requires php 4.2 or newer */ if ($this->mCurlError == 1) { return self::LARGE_FILE_SERVER; } /** * If there was no filename or a zero size given, give up quick. */ if (trim($this->mSrcName) == '' || empty($this->mFileSize)) { return self::EMPTY_FILE; } # Chop off any directories in the given filename if ($this->mDesiredDestName) { $basename = $this->mDesiredDestName . '.' . $this->mParameterExt; $this->mStoredDestName = $this->mDesiredDestName; } else { $basename = $this->mSrcName; } $filtered = wfBaseName($basename); /** * We'll want to blacklist against *any* 'extension', and use * only the final one for the whitelist. */ list($partname, $ext) = $this->splitExtensions($filtered); if (count($ext)) { $finalExt = $ext[count($ext) - 1]; } else { $finalExt = ''; } # If there was more than one "extension", reassemble the base # filename to prevent bogus complaints about length if (count($ext) > 1) { for ($i = 0; $i < count($ext) - 1; $i++) { $partname .= '.' . $ext[$i]; } } if (strlen($partname) < 1) { return self::MIN_LENGTH_PARTNAME; } /** * Filter out illegal characters, and try to make a legible name * out of it. We'll strip some silently that Title would die on. */ $filtered = preg_replace("/[^" . Title::legalChars() . "]|:/", '-', $filtered); $nt = Title::makeTitleSafe(NS_IMAGE, $filtered); if (is_null($nt)) { $resultDetails = array('filtered' => $filtered); return self::ILLEGAL_FILENAME; } $this->mLocalFile = wfLocalFile($nt); $this->mDestName = $this->mLocalFile->getName(); /** * If the image is protected, non-sysop users won't be able * to modify it by uploading a new revision. */ if (!$nt->userCan('edit')) { return self::PROTECTED_PAGE; } /** * In some cases we may forbid overwriting of existing files. */ // here starts the interesting part... // we overwrite mDestName and give it a new twist $timestamp = ''; $img_found = wfFindFile($this->mDestName); if ($img_found) { // ehhh... // we'll do it hard way then... $timestamp = $this->mDestName; } else { // this timestamp should not repeat... $timestamp = 'invalid'; } $tempname = ''; $tmpcount = 0; while ($img_found && $timestamp != $this->mLastTimestamp) { $tmpcount++; $file_ext = explode('.', $this->mDestName); $file_ext = $file_ext[0]; $tmpdestname = $file_ext; $tempname = $tmpdestname . $tmpcount . '.' . $this->mParameterExt; $timestamp = $tempname; $img_found = wfFindFile($tempname); } if ($tmpcount > 0) { wfLocalFile($title); $tempname = preg_replace("/[^" . Title::legalChars() . "]|:/", '-', $tempname); $nt = Title::makeTitleSafe(NS_FILE, $tempname); $this->mLocalFile = wfLocalFile($nt); $this->mDestName = $this->mLocalFile->getName(); $this->mDesiredDestName = $this->mStoredDestName . $tmpcount . '.' . $this->mParameterExt; } else { // append the extension anyway $this->mDesiredDestName = $this->mStoredDestName . '.' . $this->mParameterExt; } $overwrite = $this->checkOverwrite($this->mDestName); if ($overwrite !== true) { $resultDetails = array('overwrite' => $overwrite); return self::OVERWRITE_EXISTING_FILE; } /* Don't allow users to override the blacklist (check file extension) */ global $wgStrictFileExtensions, $wgFileExtensions, $wgFileBlacklist; if ($finalExt == '') { return self::FILETYPE_MISSING; } elseif ($this->checkFileExtensionList($ext, $wgFileBlacklist) || $wgStrictFileExtensions && !$this->checkFileExtension($finalExt, $wgFileExtensions)) { $resultDetails = array('finalExt' => $finalExt); return self::FILETYPE_BADTYPE; } /** * 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) { $this->mFileProps = File::getPropsFromPath($this->mTempPath, $finalExt); $this->checkMacBinary(); $veri = $this->verify($this->mTempPath, $finalExt); if ($veri !== true) { // it's a wiki error... $resultDetails = array('veri' => $veri); return self::VERIFICATION_ERROR; } /** * Provide an opportunity for extensions to add further checks */ $error = ''; } /** * Check for non-fatal conditions */ if (!$this->mIgnoreWarning) { $warning = ''; global $wgCapitalLinks; if ($wgCapitalLinks) { $filtered = ucfirst($filtered); } if ($basename != $filtered) { $warning .= '<li>' . wfMsgHtml('badfilename', htmlspecialchars($this->mDestName)) . '</li>'; } global $wgCheckFileExtensions; if ($wgCheckFileExtensions) { if (!$this->checkFileExtension($finalExt, $wgFileExtensions)) { $warning .= '<li>' . wfMsgExt('filetype-badtype', array('parseinline'), htmlspecialchars($finalExt), implode(', ', $wgFileExtensions)) . '</li>'; } } global $wgUploadSizeWarning; if ($wgUploadSizeWarning && $this->mFileSize > $wgUploadSizeWarning) { $skin = $wgUser->getSkin(); $wsize = $skin->formatSize($wgUploadSizeWarning); $asize = $skin->formatSize($this->mFileSize); $warning .= '<li>' . wfMsgHtml('large-file', $wsize, $asize) . '</li>'; } if ($this->mFileSize == 0) { $warning .= '<li>' . wfMsgHtml('emptyfile') . '</li>'; } if (!$this->mDestWarningAck) { $warning .= self::getExistsWarning($this->mLocalFile); } if ($warning != '') { /** * Stash the file in a temporary location; the user can choose * to let it through and we'll complete the upload then. */ $resultDetails = array('warning' => $warning); return self::UPLOAD_WARNING; } } /** * Try actually saving the thing... * It will show an error form on failure. */ $pageText = self::getInitialPageText($this->mComment, $this->mLicense, $this->mCopyrightStatus, $this->mCopyrightSource); $status = $this->mLocalFile->upload($this->mTempPath, $this->mComment, $pageText, File::DELETE_SOURCE, $this->mFileProps); if (!$status->isGood()) { $this->showError($status->getWikiText()); } else { if ($this->mWatchthis) { global $wgUser; $wgUser->addWatch($this->mLocalFile->getTitle()); } // Success, redirect to description page $this->mReturnedTimestamp = $this->getQuickTimestamp($this->mDestName); $img = null; // @todo: added to avoid passing a ref to null - should this be defined somewhere? return self::SUCCESS; } }
* directory, and $wgUploadPath to point to this file. Also set $wgWhitelistRead * to an array of pages you want everyone to be able to access. Your server must * support PATH_INFO, CGI-based configurations generally don't. */ require_once './includes/WebStart.php'; wfProfileIn('img_auth.php'); require_once './includes/StreamFile.php'; if (!isset($_SERVER['PATH_INFO'])) { wfDebugLog('img_auth', "missing PATH_INFO"); wfForbidden(); } # Get filenames/directories wfDebugLog('img_auth', "PATH_INFO is: " . $_SERVER['PATH_INFO']); $filename = realpath($wgUploadDirectory . $_SERVER['PATH_INFO']); $realUploadDirectory = realpath($wgUploadDirectory); $imageName = $wgContLang->getNsText(NS_IMAGE) . ":" . wfBaseName($_SERVER['PATH_INFO']); # Check if the filename is in the correct directory if (substr($filename, 0, strlen($realUploadDirectory)) != $realUploadDirectory) { wfDebugLog('img_auth', "requested path not in upload dir: {$filename}"); wfForbidden(); } if (is_array($wgWhitelistRead) && !in_array($imageName, $wgWhitelistRead) && !$wgUser->getID()) { wfDebugLog('img_auth', "not logged in and requested file not in whitelist: {$imageName}"); wfForbidden(); } if (!file_exists($filename)) { wfDebugLog('img_auth', "requested file does not exist: {$filename}"); wfForbidden(); } if (is_dir($filename)) { wfDebugLog('img_auth', "requested file is a directory: {$filename}");
/** * This method imports all images given in $images. * A page that reports the results and failures can be created if * you call startReport() before and createReport() after this method. * * @param array(string) $images * Names of the images that will be imported from the source wiki. * If no namespace is given it will be appended automatically. * @param bool $createReport (default: false) * If <true>, a report for this operation is created. * * @throws * IAIException(IAIException::HTTP_ERROR) * if the HTTP request fails * */ public function importImages($images) { // Add namespace if necessary global $wgContLang, $iaigTempDir; $imgNs = $wgContLang->getNsText(NS_IMAGE) . ":"; foreach ($images as $k => $i) { if (strpos($i, $imgNs) === false) { $images[$k] = $imgNs . $i; } } $imageURLs = $this->getImageURLs($images); foreach ($imageURLs as $img) { $base = urldecode(wfBaseName($img)); $title = Title::makeTitleSafe(NS_FILE, $base); if (!is_object($title)) { echo "{$base} could not be imported; a valid title cannot be produced\n"; continue; } # Check existence $image = wfLocalFile($title); //TODO replace $options['overwrite'] with a field in this class if ($image->exists()) { // if( isset( $options['overwrite'] ) ) { // echo( "{$base} exists, overwriting..." ); // } else { echo "{$base} exists, skipping\n"; $this->mSkippedImages[] = $base; continue; // } } else { echo "Importing {$base}..."; } // Read image from source wiki $contents = Http::get($img, self::HTTP_TIMEOUT); if ($contents === false) { // HTTP-Timeout $this->mSkippedImages[] = $base; echo "HTTP timeout for {$base}; skipping\n"; continue; // throw new IAIException(IAIException::HTTP_ERROR, $img); } $handle = fopen($iaigTempDir . $base, "wb"); fwrite($handle, $contents); fclose($handle); $this->mImportedImages[] = $base; $archive = $image->publish($iaigTempDir . $base); if (WikiError::isError($archive) || !$archive->isGood()) { echo "failed.\n"; continue; } else { echo "success.\n"; } $image->recordUpload($archive->value, "Imported with IAI Article Importer", "No license information"); unlink($iaigTempDir . $base); } }
function wfImageAuthMain() { global $wgImgAuthPublicTest, $wgImgAuthUrlPathMap, $wgRequest; // See if this is a public Wiki (no protections). if ($wgImgAuthPublicTest && in_array('read', User::getGroupPermissions(array('*')), true)) { // This is a public wiki, so disable this script (for private wikis only) wfForbidden('img-auth-accessdenied', 'img-auth-public'); return; } // Get the requested file path (source file or thumbnail) $matches = WebRequest::getPathInfo(); if (!isset($matches['title'])) { wfForbidden('img-auth-accessdenied', 'img-auth-nopathinfo'); return; } $path = $matches['title']; if ($path && $path[0] !== '/') { // Make sure $path has a leading / $path = "/" . $path; } // Check for bug 28235: QUERY_STRING overriding the correct extension $whitelist = array(); $extension = FileBackend::extensionFromPath($path, 'rawcase'); if ($extension != '') { $whitelist[] = $extension; } if (!$wgRequest->checkUrlExtension($whitelist)) { return; } // Various extensions may have their own backends that need access. // Check if there is a special backend and storage base path for this file. foreach ($wgImgAuthUrlPathMap as $prefix => $storageDir) { $prefix = rtrim($prefix, '/') . '/'; // implicit trailing slash if (strpos($path, $prefix) === 0) { $be = FileBackendGroup::singleton()->backendFromPath($storageDir); $filename = $storageDir . substr($path, strlen($prefix)); // strip prefix // Check basic user authorization if (!RequestContext::getMain()->getUser()->isAllowed('read')) { wfForbidden('img-auth-accessdenied', 'img-auth-noread', $path); return; } if ($be->fileExists(array('src' => $filename))) { wfDebugLog('img_auth', "Streaming `" . $filename . "`."); $be->streamFile(array('src' => $filename), array('Cache-Control: private', 'Vary: Cookie')); } else { wfForbidden('img-auth-accessdenied', 'img-auth-nofile', $path); } return; } } // Get the local file repository $repo = RepoGroup::singleton()->getRepo('local'); // Get the full file storage path and extract the source file name. // (e.g. 120px-Foo.png => Foo.png or page2-120px-Foo.png => Foo.png). // This only applies to thumbnails, and all thumbnails should // be under a folder that has the source file name. if (strpos($path, '/thumb/') === 0) { $name = wfBaseName(dirname($path)); // file is a thumbnail $filename = $repo->getZonePath('thumb') . substr($path, 6); // strip "/thumb" } else { $name = wfBaseName($path); // file is a source file $filename = $repo->getZonePath('public') . $path; } // Check to see if the file exists if (!$repo->fileExists($filename)) { wfForbidden('img-auth-accessdenied', 'img-auth-nofile', $filename); return; } $title = Title::makeTitleSafe(NS_FILE, $name); if (!$title instanceof Title) { // files have valid titles wfForbidden('img-auth-accessdenied', 'img-auth-badtitle', $name); return; } // Run hook for extension authorization plugins /** @var $result array */ $result = null; if (!wfRunHooks('ImgAuthBeforeStream', array(&$title, &$path, &$name, &$result))) { wfForbidden($result[0], $result[1], array_slice($result, 2)); return; } // Check user authorization for this title // Checks Whitelist too if (!$title->userCan('read')) { wfForbidden('img-auth-accessdenied', 'img-auth-noread', $name); return; } if ($wgRequest->getCheck('download')) { header('Content-Disposition: attachment'); } // Stream the requested file wfDebugLog('img_auth', "Streaming `" . $filename . "`."); $repo->streamFile($filename, array('Cache-Control: private', 'Vary: Cookie')); }
function checkMissingImage($fullpath) { $fname = 'ImageBuilder::checkMissingImage'; $filename = wfBaseName($fullpath); if (is_dir($fullpath)) { return; } if (is_link($fullpath)) { $this->log("skipping symlink at {$fullpath}"); return; } $row = $this->dbw->selectRow('image', array('img_name'), array('img_name' => $filename), $fname); if ($row) { // already known, move on return; } else { $this->addMissingImage($filename, $fullpath); } }
/** * @dataProvider providePaths */ public function testBaseName($fullpath, $basename) { $this->assertEquals($basename, wfBaseName($fullpath), "wfBaseName('{$fullpath}') => '{$basename}'"); }
wfDebugLog('img_auth', 'Missing PATH_INFO'); wfForbidden(); } $path = $_SERVER['PATH_INFO']; $filename = realpath($wgUploadDirectory . $_SERVER['PATH_INFO']); $realUpload = realpath($wgUploadDirectory); wfDebugLog('img_auth', "\$path is {$path}"); wfDebugLog('img_auth', "\$filename is {$filename}"); // Basic directory traversal check if (substr($filename, 0, strlen($realUpload)) != $realUpload) { wfDebugLog('img_auth', 'Requested path not in upload directory'); wfForbidden(); } // Extract the file name and chop off the size specifier // (e.g. 120px-Foo.png => Foo.png) $name = wfBaseName($path); if (preg_match('!\\d+px-(.*)!i', $name, $m)) { $name = $m[1]; } wfDebugLog('img_auth', "\$name is {$name}"); $title = Title::makeTitleSafe(NS_FILE, $name); if (!$title instanceof Title) { wfDebugLog('img_auth', "Unable to construct a valid Title from `{$name}`"); wfForbidden(); } $title = $title->getPrefixedText(); // Check the whitelist if needed if (!$wgUser->getId() && (!is_array($wgWhitelistRead) || !in_array($title, $wgWhitelistRead))) { wfDebugLog('img_auth', "Not logged in and `{$title}` not in whitelist."); wfForbidden(); }
function wfImageAuthMain() { global $wgImgAuthUrlPathMap; $request = RequestContext::getMain()->getRequest(); $publicWiki = in_array('read', User::getGroupPermissions(array('*')), true); // Get the requested file path (source file or thumbnail) $matches = WebRequest::getPathInfo(); if (!isset($matches['title'])) { wfForbidden('img-auth-accessdenied', 'img-auth-nopathinfo'); return; } $path = $matches['title']; if ($path && $path[0] !== '/') { // Make sure $path has a leading / $path = "/" . $path; } // Check for bug 28235: QUERY_STRING overriding the correct extension $whitelist = array(); $extension = FileBackend::extensionFromPath($path, 'rawcase'); if ($extension != '') { $whitelist[] = $extension; } if (!$request->checkUrlExtension($whitelist)) { return; } // Various extensions may have their own backends that need access. // Check if there is a special backend and storage base path for this file. foreach ($wgImgAuthUrlPathMap as $prefix => $storageDir) { $prefix = rtrim($prefix, '/') . '/'; // implicit trailing slash if (strpos($path, $prefix) === 0) { $be = FileBackendGroup::singleton()->backendFromPath($storageDir); $filename = $storageDir . substr($path, strlen($prefix)); // strip prefix // Check basic user authorization if (!RequestContext::getMain()->getUser()->isAllowed('read')) { wfForbidden('img-auth-accessdenied', 'img-auth-noread', $path); return; } if ($be->fileExists(array('src' => $filename))) { wfDebugLog('img_auth', "Streaming `" . $filename . "`."); $be->streamFile(array('src' => $filename), array('Cache-Control: private', 'Vary: Cookie')); } else { wfForbidden('img-auth-accessdenied', 'img-auth-nofile', $path); } return; } } // Get the local file repository $repo = RepoGroup::singleton()->getRepo('local'); $zone = strstr(ltrim($path, '/'), '/', true); // Get the full file storage path and extract the source file name. // (e.g. 120px-Foo.png => Foo.png or page2-120px-Foo.png => Foo.png). // This only applies to thumbnails/transcoded, and each of them should // be under a folder that has the source file name. if ($zone === 'thumb' || $zone === 'transcoded') { $name = wfBaseName(dirname($path)); $filename = $repo->getZonePath($zone) . substr($path, strlen("/" . $zone)); // Check to see if the file exists if (!$repo->fileExists($filename)) { wfForbidden('img-auth-accessdenied', 'img-auth-nofile', $filename); return; } } else { $name = wfBaseName($path); // file is a source file $filename = $repo->getZonePath('public') . $path; // Check to see if the file exists and is not deleted $bits = explode('!', $name, 2); if (substr($path, 0, 9) === '/archive/' && count($bits) == 2) { $file = $repo->newFromArchiveName($bits[1], $name); } else { $file = $repo->newFile($name); } if (!$file->exists() || $file->isDeleted(File::DELETED_FILE)) { wfForbidden('img-auth-accessdenied', 'img-auth-nofile', $filename); return; } } $headers = array(); // extra HTTP headers to send if (!$publicWiki) { // For private wikis, run extra auth checks and set cache control headers $headers[] = 'Cache-Control: private'; $headers[] = 'Vary: Cookie'; $title = Title::makeTitleSafe(NS_FILE, $name); if (!$title instanceof Title) { // files have valid titles wfForbidden('img-auth-accessdenied', 'img-auth-badtitle', $name); return; } // Run hook for extension authorization plugins /** @var $result array */ $result = null; if (!wfRunHooks('ImgAuthBeforeStream', array(&$title, &$path, &$name, &$result))) { wfForbidden($result[0], $result[1], array_slice($result, 2)); return; } // Check user authorization for this title // Checks Whitelist too if (!$title->userCan('read')) { wfForbidden('img-auth-accessdenied', 'img-auth-noread', $name); return; } } if ($request->getCheck('download')) { $headers[] = 'Content-Disposition: attachment'; } // Stream the requested file wfDebugLog('img_auth', "Streaming `" . $filename . "`."); $repo->streamFile($filename, $headers); }
/** * Constructor * * @param string $file filename. * @param string $byteOrder Type of byte ordering either 'BE' (Big Endian) or 'LE' (Little Endian). Default ''. * @throws MWException * @todo FIXME: The following are broke: * SubjectArea. Need to test the more obscure tags. * * DigitalZoomRatio = 0/0 is rejected. need to determine if that's valid. * possibly should treat 0/0 = 0. need to read exif spec on that. */ function __construct($file, $byteOrder = '') { /** * Page numbers here refer to pages in the Exif 2.2 standard * * Note, Exif::UNDEFINED is treated as a string, not as an array of bytes * so don't put a count parameter for any UNDEFINED values. * * @link http://exif.org/Exif2-2.PDF The Exif 2.2 specification */ $this->mExifTags = array('IFD0' => array('ImageWidth' => Exif::SHORT_OR_LONG, 'ImageLength' => Exif::SHORT_OR_LONG, 'BitsPerSample' => array(Exif::SHORT, 3), 'Compression' => Exif::SHORT, 'PhotometricInterpretation' => Exif::SHORT, 'Orientation' => Exif::SHORT, 'SamplesPerPixel' => Exif::SHORT, 'PlanarConfiguration' => Exif::SHORT, 'YCbCrSubSampling' => array(Exif::SHORT, 2), 'YCbCrPositioning' => Exif::SHORT, 'XResolution' => Exif::RATIONAL, 'YResolution' => Exif::RATIONAL, 'ResolutionUnit' => Exif::SHORT, 'StripOffsets' => Exif::SHORT_OR_LONG, 'RowsPerStrip' => Exif::SHORT_OR_LONG, 'StripByteCounts' => Exif::SHORT_OR_LONG, 'JPEGInterchangeFormat' => Exif::SHORT_OR_LONG, 'JPEGInterchangeFormatLength' => Exif::SHORT_OR_LONG, 'TransferFunction' => Exif::IGNORE, 'WhitePoint' => array(Exif::RATIONAL, 2), 'PrimaryChromaticities' => array(Exif::RATIONAL, 6), 'YCbCrCoefficients' => array(Exif::RATIONAL, 3), 'ReferenceBlackWhite' => array(Exif::RATIONAL, 6), 'DateTime' => Exif::ASCII, 'ImageDescription' => Exif::ASCII, 'Make' => Exif::ASCII, 'Model' => Exif::ASCII, 'Software' => Exif::ASCII, 'Artist' => Exif::ASCII, 'Copyright' => Exif::ASCII), 'EXIF' => array('ExifVersion' => Exif::UNDEFINED, 'FlashPixVersion' => Exif::UNDEFINED, 'ColorSpace' => Exif::SHORT, 'ComponentsConfiguration' => Exif::UNDEFINED, 'CompressedBitsPerPixel' => Exif::RATIONAL, 'PixelYDimension' => Exif::SHORT_OR_LONG, 'PixelXDimension' => Exif::SHORT_OR_LONG, 'MakerNote' => Exif::IGNORE, 'UserComment' => Exif::UNDEFINED, 'RelatedSoundFile' => Exif::ASCII, 'DateTimeOriginal' => Exif::ASCII, 'DateTimeDigitized' => Exif::ASCII, 'SubSecTime' => Exif::ASCII, 'SubSecTimeOriginal' => Exif::ASCII, 'SubSecTimeDigitized' => Exif::ASCII, 'ExposureTime' => Exif::RATIONAL, 'FNumber' => Exif::RATIONAL, 'ExposureProgram' => Exif::SHORT, 'SpectralSensitivity' => Exif::ASCII, 'ISOSpeedRatings' => Exif::SHORT, 'OECF' => Exif::IGNORE, 'ShutterSpeedValue' => Exif::SRATIONAL, 'ApertureValue' => Exif::RATIONAL, 'BrightnessValue' => Exif::SRATIONAL, 'ExposureBiasValue' => Exif::SRATIONAL, 'MaxApertureValue' => Exif::RATIONAL, 'SubjectDistance' => Exif::RATIONAL, 'MeteringMode' => Exif::SHORT, 'LightSource' => Exif::SHORT, 'Flash' => Exif::SHORT, 'FocalLength' => Exif::RATIONAL, 'SubjectArea' => array(Exif::SHORT, 4), 'FlashEnergy' => Exif::RATIONAL, 'SpatialFrequencyResponse' => Exif::IGNORE, 'FocalPlaneXResolution' => Exif::RATIONAL, 'FocalPlaneYResolution' => Exif::RATIONAL, 'FocalPlaneResolutionUnit' => Exif::SHORT, 'SubjectLocation' => array(Exif::SHORT, 2), 'ExposureIndex' => Exif::RATIONAL, 'SensingMethod' => Exif::SHORT, 'FileSource' => Exif::UNDEFINED, 'SceneType' => Exif::UNDEFINED, 'CFAPattern' => Exif::IGNORE, 'CustomRendered' => Exif::SHORT, 'ExposureMode' => Exif::SHORT, 'WhiteBalance' => Exif::SHORT, 'DigitalZoomRatio' => Exif::RATIONAL, 'FocalLengthIn35mmFilm' => Exif::SHORT, 'SceneCaptureType' => Exif::SHORT, 'GainControl' => Exif::SHORT, 'Contrast' => Exif::SHORT, 'Saturation' => Exif::SHORT, 'Sharpness' => Exif::SHORT, 'DeviceSettingDescription' => Exif::IGNORE, 'SubjectDistanceRange' => Exif::SHORT, 'ImageUniqueID' => Exif::ASCII), 'GPS' => array('GPSVersion' => Exif::UNDEFINED, 'GPSLatitudeRef' => Exif::ASCII, 'GPSLatitude' => array(Exif::RATIONAL, 3), 'GPSLongitudeRef' => Exif::ASCII, 'GPSLongitude' => array(Exif::RATIONAL, 3), 'GPSAltitudeRef' => Exif::UNDEFINED, 'GPSAltitude' => Exif::RATIONAL, 'GPSTimeStamp' => array(Exif::RATIONAL, 3), 'GPSSatellites' => Exif::ASCII, 'GPSStatus' => Exif::ASCII, 'GPSMeasureMode' => Exif::ASCII, 'GPSDOP' => Exif::RATIONAL, 'GPSSpeedRef' => Exif::ASCII, 'GPSSpeed' => Exif::RATIONAL, 'GPSTrackRef' => Exif::ASCII, 'GPSTrack' => Exif::RATIONAL, 'GPSImgDirectionRef' => Exif::ASCII, 'GPSImgDirection' => Exif::RATIONAL, 'GPSMapDatum' => Exif::ASCII, 'GPSDestLatitudeRef' => Exif::ASCII, 'GPSDestLatitude' => array(Exif::RATIONAL, 3), 'GPSDestLongitudeRef' => Exif::ASCII, 'GPSDestLongitude' => array(Exif::RATIONAL, 3), 'GPSDestBearingRef' => Exif::ASCII, 'GPSDestBearing' => Exif::RATIONAL, 'GPSDestDistanceRef' => Exif::ASCII, 'GPSDestDistance' => Exif::RATIONAL, 'GPSProcessingMethod' => Exif::UNDEFINED, 'GPSAreaInformation' => Exif::UNDEFINED, 'GPSDateStamp' => Exif::ASCII, 'GPSDifferential' => Exif::SHORT)); $this->file = $file; $this->basename = wfBaseName($this->file); if ($byteOrder === 'BE' || $byteOrder === 'LE') { $this->byteOrder = $byteOrder; } else { // Only give a warning for b/c, since originally we didn't // require this. The number of things affected by this is // rather small. wfWarn('Exif class did not have byte order specified. ' . 'Some properties may be decoded incorrectly.'); $this->byteOrder = 'BE'; // BE seems about twice as popular as LE in jpg's. } $this->debugFile($this->basename, __FUNCTION__, true); if (function_exists('exif_read_data')) { wfSuppressWarnings(); $data = exif_read_data($this->file, 0, true); wfRestoreWarnings(); } else { throw new MWException("Internal error: exif_read_data not present. \$wgShowEXIF may be incorrectly set or not checked by an extension."); } /** * exif_read_data() will return false on invalid input, such as * when somebody uploads a file called something.jpeg * containing random gibberish. */ $this->mRawExifData = $data ? $data : array(); $this->makeFilteredData(); $this->collapseData(); $this->debugFile(__FUNCTION__, false); }
/** * @see FileBackend::getLocalCopy() */ function getLocalCopy( array $params ) { list( $srcCont, $srcRel ) = $this->resolveStoragePath( $params['src'] ); if ( $srcRel === null ) { return null; } // Get source file extension $ext = FileBackend::extensionFromPath( $srcRel ); // Create a new temporary file... // TODO: Caution: tempfile should not write a local file. $tmpFile = TempFSFile::factory( wfBaseName( $srcRel ) . '_', $ext ); if ( !$tmpFile ) { return null; } $tmpPath = $tmpFile->getPath(); try { $this->storageClient->getBlob( $srcCont, $srcRel, $tmpPath ); } catch ( Exception $e ) { $tmpFile = null; } return $tmpFile; }
protected function doPerfTest(FileBackend $backend) { $ops1 = array(); $ops2 = array(); $ops3 = array(); $ops4 = array(); $ops5 = array(); $baseDir = 'mwstore://' . $backend->getName() . '/testing-cont1'; $backend->prepare(array('dir' => $baseDir)); $dirname = $this->getOption('srcdir'); $dir = opendir($dirname); if (!$dir) { return; } while ($dir && ($file = readdir($dir)) !== false) { if ($file[0] != '.') { $this->output("Using '{$dirname}/{$file}' in operations.\n"); $dst = $baseDir . '/' . wfBaseName($file); $ops1[] = array('op' => 'store', 'src' => "{$dirname}/{$file}", 'dst' => $dst, 'overwrite' => 1); $ops2[] = array('op' => 'copy', 'src' => "{$dst}", 'dst' => "{$dst}-1", 'overwrite' => 1); $ops3[] = array('op' => 'move', 'src' => $dst, 'dst' => "{$dst}-2", 'overwrite' => 1); $ops4[] = array('op' => 'delete', 'src' => "{$dst}-1"); $ops5[] = array('op' => 'delete', 'src' => "{$dst}-2"); } if (count($ops1) >= $this->getOption('maxfiles', 20)) { break; // enough } } closedir($dir); $this->output("\n"); $method = $this->hasOption('quick') ? 'doQuickOperations' : 'doOperations'; $opts = array('force' => 1); if ($this->hasOption('parallelize')) { $opts['parallelize'] = $this->getOption('parallelize') === 'true'; } $start = microtime(true); $status = $backend->{$method}($ops1, $opts); $e = (microtime(true) - $start) * 1000; if ($status->getErrorsArray()) { print_r($status->getErrorsArray()); exit(0); } $this->output($backend->getName() . ": Stored " . count($ops1) . " files in {$e} ms.\n"); $start = microtime(true); $backend->{$method}($ops2, $opts); $e = (microtime(true) - $start) * 1000; if ($status->getErrorsArray()) { print_r($status->getErrorsArray()); exit(0); } $this->output($backend->getName() . ": Copied " . count($ops2) . " files in {$e} ms.\n"); $start = microtime(true); $backend->{$method}($ops3, $opts); $e = (microtime(true) - $start) * 1000; if ($status->getErrorsArray()) { print_r($status->getErrorsArray()); exit(0); } $this->output($backend->getName() . ": Moved " . count($ops3) . " files in {$e} ms.\n"); $start = microtime(true); $backend->{$method}($ops4, $opts); $e = (microtime(true) - $start) * 1000; if ($status->getErrorsArray()) { print_r($status->getErrorsArray()); exit(0); } $this->output($backend->getName() . ": Deleted " . count($ops4) . " files in {$e} ms.\n"); $start = microtime(true); $backend->{$method}($ops5, $opts); $e = (microtime(true) - $start) * 1000; if ($status->getErrorsArray()) { print_r($status->getErrorsArray()); exit(0); } $this->output($backend->getName() . ": Deleted " . count($ops5) . " files in {$e} ms.\n"); }
/** * Really do the upload * Checks are made in SpecialUpload::execute() * @access private */ function processUpload() { global $wgUser, $wgOut, $wrGedcomUploadDirectory, $wrGrepPath; /* Check for PHP error if any, requires php 4.2 or newer */ // this must appear before the tree name check if ($this->mUploadError == 1) { $this->mainUploadForm(wfMsgHtml('largegedcom')); return; } /** * If there was no filename or a zero size given, give up quick. */ if (trim($this->mOname) == '' || empty($this->mUploadSize)) { $this->mainUploadForm(wfMsgHtml('emptyfile')); return; } if ($this->mUploadError != 0) { $this->mainUploadForm('Error during upload.'); return; } // get tree id if ($this->mTreeName == '[new]') { $treeName = $this->mNewTreeName; } else { $treeName = $this->mTreeName; } $dbr =& wfGetDB(DB_SLAVE); $tree = $dbr->selectRow('familytree', array('ft_tree_id', 'ft_person_count'), array('ft_user' => $wgUser->getName(), 'ft_name' => $treeName)); if ($tree === false) { if (!$treeName) { $this->mainUploadForm('Please enter a name for your new tree'); return; } if (!FamilyTreeUtil::isValidTreeName($treeName)) { $this->mainUploadForm('Sorry, that name contains characters that are not allowed in a tree name'); return; } else { if (FamilyTreeUtil::createFamilyTree($dbr, $wgUser->getName(), $treeName) == FTE_SUCCESS) { $tree = $dbr->selectRow('familytree', array('ft_tree_id', 'ft_person_count'), array('ft_user' => $wgUser->getName(), 'ft_name' => $treeName)); } if ($tree === false) { $this->mainUploadForm('Error creating tree'); return; } } } // else { // $this->mainUploadForm('This tree already exists. You must import your GEDCOM into a new tree.'); // return; // } // check if there are too many people in the file // HACK: set ft_person_count = -1 to allow people to upload GEDCOM's up to UPPER_MAX_PEOPLE // $handle = popen($wrGrepPath.' -c "@ INDI" '.$this->mUploadTempName, 'r'); // use tr to translate from cr to lf so grep works for mac files $handle = popen('cat ' . $this->mUploadTempName . ' | tr \\\\r \\\\n | grep -c "@ INDI"', 'r'); $cnt = fread($handle, 1024); pclose($handle); wfDebug("GEDCOM treeid={$tree->ft_tree_id} count={$cnt} person_count={$tree->ft_person_count}\n"); if ($cnt > self::UPPER_MAX_PEOPLE || $tree->ft_person_count >= 0 && $cnt > self::LOWER_MAX_PEOPLE) { $this->mainUploadForm(wfMsgHtml('largegedcom')); return; } # Chop off any directories in the given filename $basename = wfBaseName($this->mOname); $dbw =& wfGetDB(DB_MASTER); $timestamp = wfTimestampNow(); $record = array('fg_tree_id' => $tree->ft_tree_id, 'fg_gedcom_filename' => $basename, 'fg_status_date' => $timestamp, 'fg_file_size' => $this->mUploadSize, 'fg_default_country' => $this->mDefaultCountry, 'fg_status' => FG_STATUS_UPLOADED); $dbw->insert('familytree_gedcom', $record); $gedcomId = $dbw->selectField('', 'last_insert_id()', null); $destFilename = $wrGedcomUploadDirectory . '/' . $gedcomId . '.ged'; wfSuppressWarnings(); $success = move_uploaded_file($this->mUploadTempName, $destFilename); wfRestoreWarnings(); if (!$success) { wfDebug("wfUploadGedcom error move={$destFilename}\n"); $wgOut->showFileNotFoundError($this->mUploadTempName); return; } chmod($destFilename, 0644); $this->showSuccess($basename, $treeName); }
/** I BORROWED THIS FUNCTION FROM SpecialUpload.php!! CHECK FOR EACH VERSION OF MEDIAWIKI, IF * THIS FUNCTION STILL MAKES SENSE! * */ function processUpload() { global $wgUser, $wgUploadDirectory, $wgRequest; $fname = "AnyWikiDraw_body::processUpload"; // Retrieve form fields $drawingName = $wgRequest->getText('DrawingName'); $drawingWidth = $wgRequest->getText('DrawingWidth'); $drawingHeight = $wgRequest->getText('DrawingHeight'); $drawingTempFile = $wgRequest->getFileTempName('DrawingData'); $drawingFileSize = $wgRequest->getFileSize('DrawingData'); $drawingUploadError = $wgRequest->getUploadError('DrawingData'); $renderedTempFile = $wgRequest->getFileTempName('RenderedImageData'); $renderedFileSize = $wgRequest->getFileSize('RenderedImageData'); $renderedUploadError = $wgRequest->getUploadError('RenderedImageData'); $imageMapTempFile = $wgRequest->getFileTempName('ImageMapData'); $imageMapFileSize = $wgRequest->getFileSize('ImageMapData'); $imageMapUploadError = $wgRequest->getUploadError('ImageMapData'); $uploadSummary = $wgRequest->getText('UploadSummary'); // validate image dimension if (!is_numeric($drawingWidth) || $drawingWidth < 1) { $drawingWidth = null; } if (!is_numeric($drawingHeight) || $drawingHeight < 1) { $drawingHeight = null; } # If there was no filename or no image data, give up quickly. if (strlen($drawingName) == 0 || $drawingFileSize == 0) { wfDebug('[client ' . $_SERVER["REMOTE_ADDR"] . ']' . '[user ' . $wgUser->getName() . '] ' . $fname . ' received bad request [DrawingName=' . $drawingName . ']' . '[fileSize(DrawingData)=' . $drawingFileSize . ']'); header('HTTP/1.0 400 Bad Request'); exit("\n\n" + '<html><body>DrawingName and DrawingData must be supplied.</body></html>'); } // Verify filename # Chop off any directories in the given filename. $drawingName = wfBaseName($drawingName); $imageExtension = substr(strrchr($drawingName, '.'), 1); # Only allow filenames with known extensions $allowedExtensions = array('svg', 'svgz', 'png', 'jpg'); if (!in_array($imageExtension, $allowedExtensions)) { wfDebug('[client ' . $_SERVER["REMOTE_ADDR"] . ']' . '[user ' . $wgUser->getName() . '] ' . $fname . ' Received bad image extension [DrawingName=' . $drawingName . ']'); header('HTTP/1.0 400 Bad Request'); exit("\n\n" + '<html><body>DrawingName must have one of the following extensions: ' . implode(',', $allowedExtensions) . '.</body></html>'); } /** * Filter out illegal characters, and try to make a legible name * out of it. We'll strip some silently that Title would die on. */ $filtered = preg_replace("/[^" . Title::legalChars() . "]|:/", '-', $drawingName); $nt = Title::newFromText($filtered); if (is_null($nt)) { wfDebug('[client ' . $_SERVER["REMOTE_ADDR"] . ']' . '[user ' . $wgUser->getName() . '] ' . $fname . ' Received bad image name [DrawingName=' . $drawingName . ']'); header('HTTP/1.0 400 Bad Request'); exit("\n\n" + '<html><body>DrawingName must contain legible characters only.</body></html>'); } $nt =& Title::makeTitle(NS_IMAGE, $nt->getDBkey()); $uploadSaveName = $nt->getDBkey(); /** * If the image is protected, non-sysop users won't be able * to modify it by uploading a new revision. */ if (!$nt->userCanEdit()) { wfDebug('[client ' . $_SERVER["REMOTE_ADDR"] . ']' . '[user ' . $wgUser->getName() . '] ' . $fname . ' image is protected [DrawingName=' . $drawingName . ']'); header('HTTP/1.0 403 Forbidden'); exit("\n\n" + '<html><body>You are not allowed to edit this image.</body></html>'); } /** * In some cases we may forbid overwriting of existing files. */ if (!$this->userCanOverwrite($uploadSaveName)) { wfDebug('[client ' . $_SERVER["REMOTE_ADDR"] . ']' . '[user ' . $wgUser->getName() . '] ' . $fname . ' image may not be overwritten [DrawingName=' . $drawingName . ']'); header('HTTP/1.0 403 Forbidden'); exit("\n\n" + '<html><body>You are not allowed to overwrite this image.</body></html>'); } /** Check if the image directory is writeable, this is a common mistake */ if (!is_writeable($wgUploadDirectory)) { header('HTTP/1.0 403 Forbidden'); exit("\n\n" + '<html><body>The upload directory on the server is read only.</body></html>'); } /** * Upload the file into the temp directory, so that we can scrutinize its content */ $archive = wfImageArchiveDir($uploadSaveName, 'temp'); /** * 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. */ $veri = $this->verify($drawingTempFile, $imageExtension); if ($veri !== true) { wfDebug('[client ' . $_SERVER["REMOTE_ADDR"] . ']' . '[user ' . $wgUser->getName() . '] ' . $fname . ' image failed verification [DrawingName=' . $drawingName . '][DrawingTempFile=' . $drawingTempFile . ']'); unlink($drawingTempFile); header('HTTP/1.0 400 Bad Request'); exit("\n\n" + '<html><body>The image data is corrupt.</body></html>'); } /** * Provide an opportunity for extensions to add further checks */ $error = ''; if (!wfRunHooks('UploadVerification', array($uploadSaveName, $drawingTempFile, &$error))) { wfDebug('[client ' . $_SERVER["REMOTE_ADDR"] . ']' . '[user ' . $wgUser->getName() . '] ' . $fname . ' image failed extended verification [DrawingName=' . $drawingName . ']'); unlink($drawingTempFile); header('HTTP/1.0 400 Bad Request'); exit("\n\n" + '<html><body>The image data does not match the image name extension.</body></html>'); } /** * Try actually saving the thing... * It will show an error form on failure. */ if ($this->saveUploadedFile($uploadSaveName, $drawingTempFile, true)) { /** * Update the upload log and create the description page * if it's a new file. */ $img = Image::newFromName($uploadSaveName); if ($drawingWidth != null) { $img->width = $drawingWidth; } if ($drawingHeight != null) { $img->height = $drawingHeight; } $this->mUploadDescription = $uploadSummary; $success = $img->recordUpload($this->mUploadOldVersion, $this->mUploadDescription, $this->mLicense, $this->mUploadCopyStatus, $this->mUploadSource, $this->mWatchthis); /** * Save the rendered image, if one was provided */ if ($renderedTempFile != null && $drawingWidth != null) { $thumbName = $img->thumbName($drawingWidth, $img->fromSharedDirectory); $thumbDir = wfImageThumbDir($img->name, $img->fromSharedDirectory); $thumbPath = $thumbDir . '/' . $thumbName; wfDebug("we have a rendered image: " . $renderedTempFile . ' width=' . $drawingWidth . ' height=' . $drawingHeight . ' thumbName=' . $thumbPath); if (!file_exists(dirname($thumbPath))) { mkdir(dirname($thumbPath), 0777, true); } // 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. $veri = $this->verify($renderedTempFile, 'png'); if ($veri !== true) { wfDebug('[client ' . $_SERVER["REMOTE_ADDR"] . ']' . '[user ' . $wgUser->getName() . '] ' . $fname . ' rendered image failed verification [DrawingName=' . $drawingName . '][RenderedTempFile=' . $renderedTempFile . ']'); unlink($renderedTempFile); } else { move_uploaded_file($renderedTempFile, $thumbPath); } } else { if ($renderedTempFile != null) { unlink($renderedTempFile); } } /** * Save the image map, if one was provided */ if ($imageMapTempFile != null && $drawingWidth != null) { $thumbName = $img->thumbName($drawingWidth, $img->fromSharedDirectory); $thumbDir = wfImageThumbDir($img->name, $img->fromSharedDirectory); $imageMapPath = $thumbDir . '/' . $thumbName . '.map'; wfDebug("we have an image map: " . $imageMapTempFile); if (!file_exists(dirname($imageMapPath))) { mkdir(dirname($imageMapPath), 0777, true); } // 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. $hasScript = $this->detectScript($imageMapTempFile, 'text/html', 'html'); if ($hasScript !== false) { wfDebug('[client ' . $_SERVER["REMOTE_ADDR"] . ']' . '[user ' . $wgUser->getName() . '] ' . $fname . ' image map failed verification [DrawingName=' . $drawingName . '][ImageMapTempFile=' . $imageMapTempFile . ']'); unlink($imageMapTempFile); } else { move_uploaded_file($imageMapTempFile, $imageMapPath); } } else { if ($imageMapTempFile != null) { unlink($imageMapTempFile); } } if ($success) { $this->showSuccess(); wfRunHooks('UploadComplete', array(&$img)); } else { // Image::recordUpload() fails if the image went missing, which is // unlikely, hence the lack of a specialised message $wgOut->showFileNotFoundError($this->mUploadSaveName); } } if ($renderedTempFile != null) { unlink($renderedTempFile); } if ($imageMapTempFile != null) { unlink($imageMapTempFile); } }
/** * @see FileBackendStore::getLocalCopy() */ public function getLocalCopy(array $params) { $source = $this->resolveToFSPath($params['src']); if ($source === null) { return null; } // Create a new temporary file with the same extension... $ext = FileBackend::extensionFromPath($params['src']); $tmpFile = TempFSFile::factory(wfBaseName($source) . '_', $ext); if (!$tmpFile) { return null; } $tmpPath = $tmpFile->getPath(); // Copy the source file over the temp file $ok = copy($source, $tmpPath); if (!$ok) { return null; } $this->chmod($tmpPath); return $tmpFile; }
/** * Really do the upload * Checks are made in SpecialUpload::execute() * @access private */ function processUpload() { global $wgUser, $wgOut; /* Check for PHP error if any, requires php 4.2 or newer */ if ($this->mUploadError == 1) { $this->mainUploadForm(wfMsgHtml('largefileserver')); return; } /** * If there was no filename or a zero size given, give up quick. */ if (trim($this->mOname) == '' || empty($this->mUploadSize)) { $this->mainUploadForm(wfMsgHtml('emptyfile')); return; } # Chop off any directories in the given filename if ($this->mDestFile) { $basename = wfBaseName($this->mDestFile); } else { $basename = wfBaseName($this->mOname); } /** * We'll want to blacklist against *any* 'extension', and use * only the final one for the whitelist. */ list($partname, $ext) = $this->splitExtensions($basename); if (count($ext)) { $finalExt = $ext[count($ext) - 1]; } else { $finalExt = ''; } $fullExt = implode('.', $ext); # If there was more than one "extension", reassemble the base # filename to prevent bogus complaints about length if (count($ext) > 1) { for ($i = 0; $i < count($ext) - 1; $i++) { $partname .= '.' . $ext[$i]; } } if (strlen($partname) < 3) { $this->mainUploadForm(wfMsgHtml('minlength')); return; } // WERELATE - added validation tests if (!$this->mLicense && !$this->mReUploading) { $this->uploadError("You must select a license (press the \"back button\" on your browser to correct this)"); return; } /** * Filter out illegal characters, and try to make a legible name * out of it. We'll strip some silently that Title would die on. */ $filtered = preg_replace("/[^" . Title::legalChars() . "]|:/", '-', $basename); $nt = Title::newFromText($filtered); if (is_null($nt)) { $this->uploadError(wfMsgWikiHtml('illegalfilename', htmlspecialchars($filtered))); return; } $nt =& Title::makeTitle(NS_IMAGE, $nt->getDBkey()); $this->mUploadSaveName = $nt->getDBkey(); /** * If the image is protected, non-sysop users won't be able * to modify it by uploading a new revision. */ if (!$nt->userCanEdit()) { return $this->uploadError(wfMsgWikiHtml('protectedpage')); } /** * In some cases we may forbid overwriting of existing files. */ $overwrite = $this->checkOverwrite($this->mUploadSaveName); if (WikiError::isError($overwrite)) { return $this->uploadError($overwrite->toString()); } /* Don't allow users to override the blacklist (check file extension) */ global $wgStrictFileExtensions; global $wgFileExtensions, $wgFileBlacklist; if ($this->checkFileExtensionList($ext, $wgFileBlacklist) || $wgStrictFileExtensions && !$this->checkFileExtension($finalExt, $wgFileExtensions)) { return $this->uploadError(wfMsgHtml('badfiletype', htmlspecialchars($fullExt))); } /** * 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) { $this->checkMacBinary(); $veri = $this->verify($this->mUploadTempName, $finalExt); if ($veri !== true) { //it's a wiki error... return $this->uploadError($veri->toString()); } } /** * Provide an opportunity for extensions to add futher checks */ $error = ''; if (!wfRunHooks('UploadVerification', array($this->mUploadSaveName, $this->mUploadTempName, &$error))) { return $this->uploadError($error); } /** * Check for non-fatal conditions */ if (!$this->mIgnoreWarning) { $warning = ''; global $wgCapitalLinks; if ($wgCapitalLinks) { $filtered = ucfirst($filtered); } if ($this->mUploadSaveName != $filtered) { $warning .= '<li>' . wfMsgHtml('badfilename', htmlspecialchars($this->mUploadSaveName)) . '</li>'; } global $wgCheckFileExtensions; if ($wgCheckFileExtensions) { if (!$this->checkFileExtension($finalExt, $wgFileExtensions)) { $warning .= '<li>' . wfMsgHtml('badfiletype', htmlspecialchars($fullExt)) . '</li>'; } } global $wgUploadSizeWarning; if ($wgUploadSizeWarning && $this->mUploadSize > $wgUploadSizeWarning) { # TODO: Format $wgUploadSizeWarning to something that looks better than the raw byte # value, perhaps add GB,MB and KB suffixes? $warning .= '<li>' . wfMsgHtml('largefile', $wgUploadSizeWarning, $this->mUploadSize) . '</li>'; } if ($this->mUploadSize == 0) { $warning .= '<li>' . wfMsgHtml('emptyfile') . '</li>'; } if ($nt->getArticleID()) { global $wgUser; $sk = $wgUser->getSkin(); $dlink = $sk->makeKnownLinkObj($nt); $warning .= '<li>' . wfMsgHtml('fileexists', $dlink) . '</li>'; // WERELATE: added fileexistsnoreupload warning; assume that if user entered license, then this isn't a case of purposeful re-uploading if ($this->mLicense) { $warning .= '<li>' . wfMsgHtml('fileexistsnoreupload') . '</li>'; } } else { # If the file existed before and was deleted, warn the user of this # Don't bother doing so if the image exists now, however // WERELATE: remove // $image = new Image( $nt ); // if( $image->wasDeleted() ) { // $skin = $wgUser->getSkin(); // $ltitle = Title::makeTitle( NS_SPECIAL, 'Log' ); // $llink = $skin->makeKnownLinkObj( $ltitle, wfMsgHtml( 'deletionlog' ), 'type=delete&page=' . $nt->getPrefixedUrl() ); // $warning .= wfOpenElement( 'li' ) . wfMsgWikiHtml( 'filewasdeleted', $llink ) . wfCloseElement( '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. */ $hasBeenMunged = !empty($this->mSessionKey) || $this->mRemoveTempFile; if ($this->saveUploadedFile($this->mUploadSaveName, $this->mUploadTempName, $hasBeenMunged)) { /** * Update the upload log and create the description page * if it's a new file. */ $img = Image::newFromName($this->mUploadSaveName); // WERELATE - changed - added getMetadata, null out license (because we capture it in metadata), redirect only if target is empty $success = $img->recordUpload($this->mUploadOldVersion, $this->mUploadDescription, '', $this->mUploadCopyStatus, $this->mUploadSource, $this->mWatchthis, $this->getMetadata(), !$this->mTarget); if ($success) { // WERELATE - if we're uploading for a P/F target, showSuccess, else just redirect if ($this->mTarget) { $this->showSuccess(); } else { $article = new Article($img->getTitle()); $article->doRedirect(); } wfRunHooks('UploadComplete', array(&$img)); } else { // Image::recordUpload() fails if the image went missing, which is // unlikely, hence the lack of a specialised message $wgOut->showFileNotFoundError($this->mUploadSaveName); } } }
/** * Replace all invalid characters with - * @param mixed $title Filename to process */ function wfStripIllegalFilenameChars($name) { $name = wfBaseName($name); $name = preg_replace("/[^" . Title::legalChars() . "]|:/", '-', $name); return $name; }
function checkMissingImage($fullpath) { $filename = wfBaseName($fullpath); $row = $this->dbw->selectRow('image', array('img_name'), array('img_name' => $filename), __METHOD__); if (!$row) { // file not registered $this->addMissingImage($filename, $fullpath); } }
/** * Generate a relative path name to the given file. * May explode on non-matching case-insensitive paths, * funky symlinks, etc. * * @param string $path Absolute destination path including target filename * @param string $from Absolute source path, directory only * @return string */ function wfRelativePath($path, $from) { // Normalize mixed input on Windows... $path = str_replace('/', DIRECTORY_SEPARATOR, $path); $from = str_replace('/', DIRECTORY_SEPARATOR, $from); // Trim trailing slashes -- fix for drive root $path = rtrim($path, DIRECTORY_SEPARATOR); $from = rtrim($from, DIRECTORY_SEPARATOR); $pieces = explode(DIRECTORY_SEPARATOR, dirname($path)); $against = explode(DIRECTORY_SEPARATOR, $from); if ($pieces[0] !== $against[0]) { // Non-matching Windows drive letters? // Return a full path. return $path; } // Trim off common prefix while (count($pieces) && count($against) && $pieces[0] == $against[0]) { array_shift($pieces); array_shift($against); } // relative dots to bump us to the parent while (count($against)) { array_unshift($pieces, '..'); array_shift($against); } array_push($pieces, wfBaseName($path)); return implode(DIRECTORY_SEPARATOR, $pieces); }