public function execute()
 {
     // FIXME: This is horrible, no good, very bad hack. Only for testing,
     // and probably should be eventually replaced with something more sane.
     $updaterScript = "extensions/CirrusSearch/maintenance/updateSuggesterIndex.php";
     $this->getResult()->addValue(null, 'result', wfShellExecWithStderr("unset REQUEST_METHOD; /usr/local/bin/mwscript {$updaterScript} --wiki " . wfWikiID()));
 }
Example #2
0
 /**
  * @param File $file
  * @param array $params Rotate parameters.
  *    'rotation' clockwise rotation in degrees, allowed are multiples of 90
  * @since 1.21
  * @return bool
  */
 public function rotate($file, $params)
 {
     global $wgJpegTran;
     $rotation = ($params['rotation'] + $this->getRotation($file)) % 360;
     if ($wgJpegTran && is_file($wgJpegTran)) {
         $cmd = wfEscapeShellArg($wgJpegTran) . " -rotate " . wfEscapeShellArg($rotation) . " -outfile " . wfEscapeShellArg($params['dstPath']) . " " . wfEscapeShellArg($params['srcPath']);
         wfDebug(__METHOD__ . ": running jpgtran: {$cmd}\n");
         wfProfileIn('jpegtran');
         $retval = 0;
         $err = wfShellExecWithStderr($cmd, $retval);
         wfProfileOut('jpegtran');
         if ($retval !== 0) {
             $this->logErrorForExternalProcess($retval, $err, $cmd);
             return new MediaTransformError('thumbnail_error', 0, 0, $err);
         }
         return false;
     } else {
         return parent::rotate($file, $params);
     }
 }
Example #3
0
 /**
  * @param File $file
  * @param array $params Rotate parameters.
  *   'rotation' clockwise rotation in degrees, allowed are multiples of 90
  * @since 1.21
  * @return bool
  */
 public function rotate($file, $params)
 {
     global $wgImageMagickConvertCommand;
     $rotation = ($params['rotation'] + $this->getRotation($file)) % 360;
     $scene = false;
     $scaler = $this->getScalerType(null, false);
     switch ($scaler) {
         case 'im':
             $cmd = wfEscapeShellArg($wgImageMagickConvertCommand) . " " . wfEscapeShellArg($this->escapeMagickInput($params['srcPath'], $scene)) . " -rotate " . wfEscapeShellArg("-{$rotation}") . " " . wfEscapeShellArg($this->escapeMagickOutput($params['dstPath']));
             wfDebug(__METHOD__ . ": running ImageMagick: {$cmd}\n");
             $retval = 0;
             $err = wfShellExecWithStderr($cmd, $retval);
             if ($retval !== 0) {
                 $this->logErrorForExternalProcess($retval, $err, $cmd);
                 return new MediaTransformError('thumbnail_error', 0, 0, $err);
             }
             return false;
         case 'imext':
             $im = new Imagick();
             $im->readImage($params['srcPath']);
             if (!$im->rotateImage(new ImagickPixel('white'), 360 - $rotation)) {
                 return new MediaTransformError('thumbnail_error', 0, 0, "Error rotating {$rotation} degrees");
             }
             $result = $im->writeImage($params['dstPath']);
             if (!$result) {
                 return new MediaTransformError('thumbnail_error', 0, 0, "Unable to write image to {$params['dstPath']}");
             }
             return false;
         default:
             return new MediaTransformError('thumbnail_error', 0, 0, "{$scaler} rotation not implemented");
     }
 }
 /**
  * Generic wrapper function for a virus scanner program.
  * This relies on the $wgAntivirus and $wgAntivirusSetup variables.
  * $wgAntivirusRequired may be used to deny upload if the scan fails.
  *
  * @param string $file pathname to the temporary upload file
  * @return mixed false if not virus is found, NULL if the scan fails or is disabled,
  *         or a string containing feedback from the virus scanner if a virus was found.
  *         If textual feedback is missing but a virus was found, this function returns true.
  */
 public static function detectVirus($file)
 {
     global $wgAntivirus, $wgAntivirusSetup, $wgAntivirusRequired, $wgOut;
     wfProfileIn(__METHOD__);
     if (!$wgAntivirus) {
         wfDebug(__METHOD__ . ": virus scanner disabled\n");
         wfProfileOut(__METHOD__);
         return null;
     }
     if (!$wgAntivirusSetup[$wgAntivirus]) {
         wfDebug(__METHOD__ . ": unknown virus scanner: {$wgAntivirus}\n");
         $wgOut->wrapWikiMsg("<div class=\"error\">\n\$1\n</div>", array('virus-badscanner', $wgAntivirus));
         wfProfileOut(__METHOD__);
         return wfMessage('virus-unknownscanner')->text() . " {$wgAntivirus}";
     }
     # look up scanner configuration
     $command = $wgAntivirusSetup[$wgAntivirus]['command'];
     $exitCodeMap = $wgAntivirusSetup[$wgAntivirus]['codemap'];
     $msgPattern = isset($wgAntivirusSetup[$wgAntivirus]['messagepattern']) ? $wgAntivirusSetup[$wgAntivirus]['messagepattern'] : null;
     if (strpos($command, "%f") === false) {
         # simple pattern: append file to scan
         $command .= " " . wfEscapeShellArg($file);
     } else {
         # complex pattern: replace "%f" with file to scan
         $command = str_replace("%f", wfEscapeShellArg($file), $command);
     }
     wfDebug(__METHOD__ . ": running virus scan: {$command} \n");
     # execute virus scanner
     $exitCode = false;
     # NOTE: there's a 50 line workaround to make stderr redirection work on windows, too.
     #      that does not seem to be worth the pain.
     #      Ask me (Duesentrieb) about it if it's ever needed.
     $output = wfShellExecWithStderr($command, $exitCode);
     # map exit code to AV_xxx constants.
     $mappedCode = $exitCode;
     if ($exitCodeMap) {
         if (isset($exitCodeMap[$exitCode])) {
             $mappedCode = $exitCodeMap[$exitCode];
         } elseif (isset($exitCodeMap["*"])) {
             $mappedCode = $exitCodeMap["*"];
         }
     }
     /* NB: AV_NO_VIRUS is 0 but AV_SCAN_FAILED is false,
      * so we need the strict equalities === and thus can't use a switch here
      */
     if ($mappedCode === AV_SCAN_FAILED) {
         # scan failed (code was mapped to false by $exitCodeMap)
         wfDebug(__METHOD__ . ": failed to scan {$file} (code {$exitCode}).\n");
         $output = $wgAntivirusRequired ? wfMessage('virus-scanfailed', array($exitCode))->text() : null;
     } elseif ($mappedCode === AV_SCAN_ABORTED) {
         # scan failed because filetype is unknown (probably imune)
         wfDebug(__METHOD__ . ": unsupported file type {$file} (code {$exitCode}).\n");
         $output = null;
     } elseif ($mappedCode === AV_NO_VIRUS) {
         # no virus found
         wfDebug(__METHOD__ . ": file passed virus scan.\n");
         $output = false;
     } else {
         $output = trim($output);
         if (!$output) {
             $output = true;
             #if there's no output, return true
         } elseif ($msgPattern) {
             $groups = array();
             if (preg_match($msgPattern, $output, $groups)) {
                 if ($groups[1]) {
                     $output = $groups[1];
                 }
             }
         }
         wfDebug(__METHOD__ . ": FOUND VIRUS! scanner feedback: {$output} \n");
     }
     wfProfileOut(__METHOD__);
     return $output;
 }
Example #5
0
 /**
  * Swaps an embedded ICC profile for another, if found. Depends on exiftool, no-op if not installed.
  * @param string $filepath File to be manipulated (will be overwritten)
  * @param string $oldProfileString Exact name of color profile to look for (the one that will be replaced)
  * @param string $profileFilepath ICC profile file to apply to the file
  * @since 1.26
  * @return bool
  */
 public function swapICCProfile($filepath, $oldProfileString, $profileFilepath)
 {
     global $wgExiftool;
     if (!$wgExiftool || !is_executable($wgExiftool)) {
         return false;
     }
     $cmd = wfEscapeShellArg($wgExiftool, '-DeviceModelDesc', '-S', '-T', $filepath);
     $output = wfShellExecWithStderr($cmd, $retval);
     if ($retval !== 0 || strcasecmp(trim($output), $oldProfileString) !== 0) {
         // We can't establish that this file has the expected ICC profile, don't process it
         return false;
     }
     $cmd = wfEscapeShellArg($wgExiftool, '-overwrite_original', '-icc_profile<=' . $profileFilepath, $filepath);
     $output = wfShellExecWithStderr($cmd, $retval);
     if ($retval !== 0) {
         $this->logErrorForExternalProcess($retval, $output, $cmd);
         return false;
     }
     return true;
 }
Example #6
0
 /**
  * Transform an SVG file to PNG
  * This function can be called outside of thumbnail contexts
  * @param string $srcPath
  * @param string $dstPath
  * @param string $width
  * @param string $height
  * @param bool|string $lang Language code of the language to render the SVG in
  * @throws MWException
  * @return bool|MediaTransformError
  */
 public function rasterize($srcPath, $dstPath, $width, $height, $lang = false)
 {
     global $wgSVGConverters, $wgSVGConverter, $wgSVGConverterPath;
     $err = false;
     $retval = '';
     if (isset($wgSVGConverters[$wgSVGConverter])) {
         if (is_array($wgSVGConverters[$wgSVGConverter])) {
             // This is a PHP callable
             $func = $wgSVGConverters[$wgSVGConverter][0];
             $args = array_merge(array($srcPath, $dstPath, $width, $height, $lang), array_slice($wgSVGConverters[$wgSVGConverter], 1));
             if (!is_callable($func)) {
                 throw new MWException("{$func} is not callable");
             }
             $err = call_user_func_array($func, $args);
             $retval = (bool) $err;
         } else {
             // External command
             $cmd = str_replace(array('$path/', '$width', '$height', '$input', '$output'), array($wgSVGConverterPath ? wfEscapeShellArg("{$wgSVGConverterPath}/") : "", intval($width), intval($height), wfEscapeShellArg($srcPath), wfEscapeShellArg($dstPath)), $wgSVGConverters[$wgSVGConverter]);
             $env = array();
             if ($lang !== false) {
                 $env['LANG'] = $lang;
             }
             wfProfileIn('rsvg');
             wfDebug(__METHOD__ . ": {$cmd}\n");
             $err = wfShellExecWithStderr($cmd, $retval, $env);
             wfProfileOut('rsvg');
         }
     }
     $removed = $this->removeBadFile($dstPath, $retval);
     if ($retval != 0 || $removed) {
         $this->logErrorForExternalProcess($retval, $err, $cmd);
         return new MediaTransformError('thumbnail_error', $width, $height, $err);
     }
     return true;
 }
 /**
  * @param $image File
  * @param $dstPath string
  * @param $dstUrl string
  * @param $params array
  * @param $flags int
  * @return MediaTransformError|MediaTransformOutput|ThumbnailImage|TransformParameterError
  */
 function doTransform($image, $dstPath, $dstUrl, $params, $flags = 0)
 {
     global $wgPdfProcessor, $wgPdfPostProcessor, $wgPdfHandlerDpi, $wgPdfHandlerJpegQuality;
     $metadata = $image->getMetadata();
     if (!$metadata) {
         return $this->doThumbError(isset($params['width']) ? $params['width'] : null, isset($params['height']) ? $params['height'] : null, 'pdf_no_metadata');
     }
     if (!$this->normaliseParams($image, $params)) {
         return new TransformParameterError($params);
     }
     $width = $params['width'];
     $height = $params['height'];
     $page = $params['page'];
     if ($page > $this->pageCount($image)) {
         return $this->doThumbError($width, $height, 'pdf_page_error');
     }
     if ($flags & self::TRANSFORM_LATER) {
         return new ThumbnailImage($image, $dstUrl, $width, $height, false, $page);
     }
     if (!wfMkdirParents(dirname($dstPath), null, __METHOD__)) {
         return $this->doThumbError($width, $height, 'thumbnail_dest_directory');
     }
     // Thumbnail extraction is very inefficient for large files.
     // Provide a way to pool count limit the number of downloaders.
     if ($image->getSize() >= 10000000.0) {
         // 10MB
         $work = new PoolCounterWorkViaCallback('GetLocalFileCopy', sha1($image->getName()), array('doWork' => function () use($image) {
             return $image->getLocalRefPath();
         }));
         $srcPath = $work->execute();
     } else {
         $srcPath = $image->getLocalRefPath();
     }
     if ($srcPath === false) {
         // could not download original
         return $this->doThumbError($width, $height, 'filemissing');
     }
     $cmd = '(' . wfEscapeShellArg($wgPdfProcessor, "-sDEVICE=jpeg", "-sOutputFile=-", "-dFirstPage={$page}", "-dLastPage={$page}", "-r{$wgPdfHandlerDpi}", "-dBATCH", "-dNOPAUSE", "-q", $srcPath);
     $cmd .= " | " . wfEscapeShellArg($wgPdfPostProcessor, "-depth", "8", "-quality", $wgPdfHandlerJpegQuality, "-resize", $width, "-", $dstPath);
     $cmd .= ")";
     wfProfileIn('PdfHandler');
     wfDebug(__METHOD__ . ": {$cmd}\n");
     $retval = '';
     $err = wfShellExecWithStderr($cmd, $retval);
     wfProfileOut('PdfHandler');
     $removed = $this->removeBadFile($dstPath, $retval);
     if ($retval != 0 || $removed) {
         wfDebugLog('thumbnail', sprintf('thumbnail failed on %s: error %d "%s" from "%s"', wfHostname(), $retval, trim($err), $cmd));
         return new MediaTransformError('thumbnail_error', $width, $height, $err);
     } else {
         return new ThumbnailImage($image, $dstUrl, $width, $height, $dstPath, $page);
     }
 }