function assertMetadata($infile, $expected) { try { $data = SVGMetadataExtractor::getMetadata($infile); $this->assertEquals($expected, $data, 'SVG metadata extraction test'); } catch (MWException $e) { if ($expected === false) { $this->assertTrue(true, 'SVG metadata extracted test (expected failure)'); } else { throw $e; } } }
/** * Convert passed image data, which is assumed to be SVG, to PNG. * * @param string $svg SVG image data * @return string|bool PNG image data, or false on failure */ protected function rasterize($svg) { // This code should be factored out to a separate method on SvgHandler, or perhaps a separate // class, with a separate set of configuration settings. // // This is a distinct use case from regular SVG rasterization: // * We can skip many sanity and security checks (as the images come from a trusted source, // rather than from the user). // * We need to provide extra options to some converters to achieve acceptable quality for very // small images, which might cause performance issues in the general case. // * We want to directly pass image data to the converter, rather than a file path. // // See https://phabricator.wikimedia.org/T76473#801446 for examples of what happens with the // default settings. // // For now, we special-case rsvg (used in WMF production) and do a messy workaround for other // converters. global $wgSVGConverter, $wgSVGConverterPath; $svg = $this->massageSvgPathdata($svg); // Sometimes this might be 'rsvg-secure'. Long as it's rsvg. if (strpos($wgSVGConverter, 'rsvg') === 0) { $command = 'rsvg-convert'; if ($wgSVGConverterPath) { $command = wfEscapeShellArg("{$wgSVGConverterPath}/") . $command; } $process = proc_open($command, array(0 => array('pipe', 'r'), 1 => array('pipe', 'w')), $pipes); if (is_resource($process)) { fwrite($pipes[0], $svg); fclose($pipes[0]); $png = stream_get_contents($pipes[1]); fclose($pipes[1]); proc_close($process); return $png ?: false; } return false; } else { // Write input to and read output from a temporary file $tempFilenameSvg = tempnam(wfTempDir(), 'ResourceLoaderImage'); $tempFilenamePng = tempnam(wfTempDir(), 'ResourceLoaderImage'); file_put_contents($tempFilenameSvg, $svg); $metadata = SVGMetadataExtractor::getMetadata($tempFilenameSvg); if (!isset($metadata['width']) || !isset($metadata['height'])) { unlink($tempFilenameSvg); return false; } $handler = new SvgHandler(); $res = $handler->rasterize($tempFilenameSvg, $tempFilenamePng, $metadata['width'], $metadata['height']); unlink($tempFilenameSvg); $png = null; if ($res === true) { $png = file_get_contents($tempFilenamePng); unlink($tempFilenamePng); } return $png ?: false; } }
/** * @param File $file * @param string $filename * @return string Serialised metadata */ function getMetadata($file, $filename) { $metadata = array('version' => self::SVG_METADATA_VERSION); try { $metadata += SVGMetadataExtractor::getMetadata($filename); } catch (MWException $e) { // @todo SVG specific exceptions // File not found, broken, etc. $metadata['error'] = array('message' => $e->getMessage(), 'code' => $e->getCode()); wfDebug(__METHOD__ . ': ' . $e->getMessage() . "\n"); } return serialize($metadata); }
function getMetadata($file, $filename) { try { $metadata = SVGMetadataExtractor::getMetadata($filename); } catch (Exception $e) { // Broken file? wfDebug(__METHOD__ . ': ' . $e->getMessage() . "\n"); return '0'; } $metadata['version'] = self::SVG_METADATA_VERSION; return serialize($metadata); }