HipHop fixes:
authorTim Starling <tstarling@users.mediawiki.org>
Tue, 5 Apr 2011 04:43:54 +0000 (04:43 +0000)
committerTim Starling <tstarling@users.mediawiki.org>
Tue, 5 Apr 2011 04:43:54 +0000 (04:43 +0000)
* Fixed preg_replace /e usage in Sanitizer and UserMailer. This was already against policy.
* Removed the __get()-based lazy initialisation of $this->xpath in PPNode_DOM. This caused a notice in HipHop, and is also inefficient due to the need for dynamic properties.
* Fixed the assertion in PPNode_DOM::splitHeading(), flagged by Inez Korczynski. It was obviously completely broken, converting a non-existent property to boolean, and it only appeared to work in Zend by accident.

includes/Sanitizer.php
includes/UserMailer.php
includes/parser/Preprocessor_DOM.php

index 27b17ce..d6abfa2 100644 (file)
@@ -1506,7 +1506,8 @@ class Sanitizer {
                $url = Sanitizer::decodeCharReferences( $url );
 
                # Escape any control characters introduced by the above step
-               $url = preg_replace( '/[\][<>"\\x00-\\x20\\x7F\|]/e', "urlencode('\\0')", $url );
+               $url = preg_replace_callback( '/[\][<>"\\x00-\\x20\\x7F\|]/', 
+                       array( __CLASS__, 'cleanUrlCallback' ), $url );
 
                # Validate hostname portion
                $matches = array();
@@ -1542,4 +1543,7 @@ class Sanitizer {
                }
        }
 
+       static function cleanUrlCallback( $matches ) {
+               return urlencode( $matches[0] );
+       }
 }
index 62ec6dc..14c7d1e 100644 (file)
@@ -290,10 +290,15 @@ class UserMailer {
                        return $string;
                }
                $out = "=?$charset?Q?";
-               $out .= preg_replace( "/([$replace])/e", 'sprintf("=%02X",ord("$1"))', $string );
+               $out .= preg_replace_callback( "/([$replace])/", 
+                       array( __CLASS__, 'quotedPrintableCallback' ), $string );
                $out .= '?=';
                return $out;
        }
+
+       protected static function quotedPrintableCallback( $matches ) {
+               return sprintf( "=%02X", ord( $matches[1] ) );
+       }
 }
 
 /**
index 0ba5805..af16ff4 100644 (file)
@@ -1420,14 +1420,14 @@ class PPCustomFrame_DOM extends PPFrame_DOM {
  * @ingroup Parser
  */
 class PPNode_DOM implements PPNode {
-       var $node;
+       var $node, $xpath;
 
        function __construct( $node, $xpath = false ) {
                $this->node = $node;
        }
 
-       function __get( $name ) {
-               if ( $name == 'xpath' ) {
+       function getXPath() {
+               if ( $this->xpath === null ) {
                        $this->xpath = new DOMXPath( $this->node->ownerDocument );
                }
                return $this->xpath;
@@ -1458,7 +1458,7 @@ class PPNode_DOM implements PPNode {
        }
 
        function getChildrenOfType( $type ) {
-               return new self( $this->xpath->query( $type, $this->node ) );
+               return new self( $this->getXPath()->query( $type, $this->node ) );
        }
 
        function getLength() {
@@ -1489,8 +1489,9 @@ class PPNode_DOM implements PPNode {
         *    value         PPNode value
         */
        function splitArg() {
-               $names = $this->xpath->query( 'name', $this->node );
-               $values = $this->xpath->query( 'value', $this->node );
+               $xpath = $this->getXPath();
+               $names = $xpath->query( 'name', $this->node );
+               $values = $xpath->query( 'value', $this->node );
                if ( !$names->length || !$values->length ) {
                        throw new MWException( 'Invalid brace node passed to ' . __METHOD__ );
                }
@@ -1507,10 +1508,11 @@ class PPNode_DOM implements PPNode {
         * All values in the resulting array are PPNodes. Inner and close are optional.
         */
        function splitExt() {
-               $names = $this->xpath->query( 'name', $this->node );
-               $attrs = $this->xpath->query( 'attr', $this->node );
-               $inners = $this->xpath->query( 'inner', $this->node );
-               $closes = $this->xpath->query( 'close', $this->node );
+               $xpath = $this->getXPath();
+               $names = $xpath->query( 'name', $this->node );
+               $attrs = $xpath->query( 'attr', $this->node );
+               $inners = $xpath->query( 'inner', $this->node );
+               $closes = $xpath->query( 'close', $this->node );
                if ( !$names->length || !$attrs->length ) {
                        throw new MWException( 'Invalid ext node passed to ' . __METHOD__ );
                }
@@ -1530,7 +1532,7 @@ class PPNode_DOM implements PPNode {
         * Split a <h> node
         */
        function splitHeading() {
-               if ( !$this->nodeName == 'h' ) {
+               if ( $this->getName() !== 'h' ) {
                        throw new MWException( 'Invalid h node passed to ' . __METHOD__ );
                }
                return array(