Page MenuHomePhabricator

diff.patch

Authored By
bzimport
Nov 21 2014, 10:13 PM
Size
3 KB
Referenced Files
None
Subscribers
None

diff.patch

Index: includes/ImageFunctions.php
===================================================================
--- includes/ImageFunctions.php (revision 36333)
+++ includes/ImageFunctions.php (working copy)
@@ -29,37 +29,90 @@
}
/**
- * Compatible with PHP getimagesize()
+ * Helper class used by wfGetSVGsize
+ *
+ * @ingroup Media
+ */
+class SvgInfo {
+
+ // Class Members
+ public $valid;
+ private $width;
+ private $height;
+
+ private function startElement($parser, $name, $attrs) {
+ if( !$this->valid && $name == 'svg' ) {
+ $this->valid = true;
+
+ foreach ( $attrs as $name => $value ) {
+ if ( $name == 'width' ) {
+ $this->width = wfScaleSVGUnit( $value );
+ } else if ( $name == 'height' ) {
+ $this->height = wfScaleSVGUnit( $value );
+ }
+ }
+ }
+ }
+
+ /**
+ * Constructor - set up the XML parser
+ * @param $filename String: full name of the file (passed to php fopen()).
+ */
+ public function __construct( $filename ) {
+ $this->valid = false;
+ $xml_parser = xml_parser_create( 'UTF-8' );
+ xml_set_object( $xml_parser, $this );
+ xml_parser_set_option( $xml_parser, XML_OPTION_CASE_FOLDING, false );
+ xml_set_element_handler( $xml_parser, 'startElement', '' );
+
+ if( !( $file = fopen( $filename, "r" ) ) ) {
+ wfDebug( "SvgInfo: Couldn't open " . $filename );
+ return;
+ }
+
+ $bytesRead = 0;
+ while ( !$this->valid && $bytesRead < 65536 && $data = fread( $file, 4096 ) ) { // limit amount of data read to prevent DoS attack
+ $bytesRead += 4086;
+ if ( !xml_parse( $xml_parser, $data, feof( $file ) ) ) {
+ wfDebug( sprintf( "SvgInfo XML error: %s at file '%s' line %d\n",
+ $filename,
+ xml_error_string(xml_get_error_code( $xml_parser ) ),
+ xml_get_current_line_number( $xml_parser) ) );
+ xml_parser_free($xml_parser);
+ return;
+ }
+ }
+ xml_parser_free( $xml_parser );
+ }
+
+ /**
+ * Public accessor functions for $width and $height
+ * We return 100% if no detectable width is provided.
+ *
+ * @return string
+ */
+ public function getWidth() {
+ if ( $this->width ) return $this->width;
+ else return '100%';
+ }
+ public function getHeight() {
+ if ( $this->height ) return $this->height;
+ else return '100%';
+ }
+}
+
+/**
* @todo support gzipped SVGZ
- * @todo check XML more carefully
- * @todo sensible defaults
*
- * @param $filename String: full name of the file (passed to php fopen()).
+ * @param $filename String: full name of the file (passed to new SvgInfo()).
* @return array
*/
function wfGetSVGsize( $filename ) {
- $width = 256;
- $height = 256;
+ $svg = new SvgInfo( $filename );
+ if ( !$svg->valid ) return false;
- // Read a chunk of the file
- $f = fopen( $filename, "rt" );
- if( !$f ) return false;
- $chunk = fread( $f, 4096 );
- fclose( $f );
-
- // Uber-crappy hack! Run through a real XML parser.
- $matches = array();
- if( !preg_match( '/<svg\s*([^>]*)\s*>/s', $chunk, $matches ) ) {
- return false;
- }
- $tag = $matches[1];
- if( preg_match( '/(?:^|\s)width\s*=\s*("[^"]+"|\'[^\']+\')/s', $tag, $matches ) ) {
- $width = wfScaleSVGUnit( trim( substr( $matches[1], 1, -1 ) ) );
- }
- if( preg_match( '/(?:^|\s)height\s*=\s*("[^"]+"|\'[^\']+\')/s', $tag, $matches ) ) {
- $height = wfScaleSVGUnit( trim( substr( $matches[1], 1, -1 ) ) );
- }
-
+ $height = $svg->getHeight();
+ $width = $svg->getWidth();
return array( $width, $height, 'SVG',
"width=\"$width\" height=\"$height\"" );
}

File Metadata

Mime Type
text/x-diff
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4516
Default Alt Text
diff.patch (3 KB)

Event Timeline