*/
public $rootElement = '';
+ /**
+ * Additional parsing options
+ */
+ private $parserOptions = array(
+ 'processing_instruction_handler' => '',
+ );
+
/**
* @param string $input a filename or string containing the XML element
* @param callable $filterCallback (optional)
* Filter should return 'true' to toggle on $this->filterMatch
* @param boolean $isFile (optional) indicates if the first parameter is a
* filename (default, true) or if it is a string (false)
+ * @param array $options list of additional parsing options:
+ * processing_instruction_handler: Callback for xml_set_processing_instruction_handler
*/
- function __construct( $input, $filterCallback = null, $isFile = true ) {
+ function __construct( $input, $filterCallback = null, $isFile = true, $options = array() ) {
$this->filterCallback = $filterCallback;
+ $this->parserOptions = array_merge( $this->parserOptions, $options );
+
if ( $isFile ) {
$this->validateFromFile( $input );
} else {
// case folding violates XML standard, turn it off
xml_parser_set_option( $parser, XML_OPTION_CASE_FOLDING, false );
xml_set_element_handler( $parser, array( $this, 'rootElementOpen' ), false );
+ if ( $this->parserOptions['processing_instruction_handler'] ) {
+ xml_set_processing_instruction_handler(
+ $parser,
+ array( $this, 'processingInstructionHandler' )
+ );
+ }
return $parser;
}
$this->filterMatch = true;
}
}
+
+ /**
+ * @param $parser
+ * @param $target
+ * @param $data
+ */
+ private function processingInstructionHandler( $parser, $target, $data ) {
+ if ( call_user_func( $this->parserOptions['processing_instruction_handler'], $target, $data ) ) {
+ // Filter hit!
+ $this->filterMatch = true;
+ }
+ }
}
* @return bool
*/
protected function detectScriptInSvg( $filename ) {
- $check = new XmlTypeCheck( $filename, array( $this, 'checkSvgScriptCallback' ) );
+ $check = new XmlTypeCheck(
+ $filename,
+ array( $this, 'checkSvgScriptCallback' ),
+ true,
+ array( 'processing_instruction_handler' => 'UploadBase::checkSvgPICallback' )
+ );
return $check->filterMatch;
}
+ /**
+ * Callback to filter SVG Processing Instructions.
+ * @param $target string processing instruction name
+ * @param $data string processing instruction attribute and value
+ * @return bool (true if the filter identified something bad)
+ */
+ public static function checkSvgPICallback( $target, $data ) {
+ // Don't allow external stylesheets (bug 57550)
+ if ( preg_match( '/xml-stylesheet/i', $target) ) {
+ return true;
+ }
+ return false;
+ }
+
/**
* @todo Replace this with a whitelist filter!
* @param $element string