WordPress.org

Make WordPress Core

Ticket #10698: wp-includes--class-IXR.php.diff

File wp-includes--class-IXR.php.diff, 2.8 KB (added by josephscott, 6 years ago)
  • wp-includes/class-IXR.php

     
    153153    var $_currentTagContents; 
    154154    // The XML parser 
    155155    var $_parser; 
    156     function IXR_Message ($message) { 
    157         $this->message = $message; 
     156    function IXR_Message (&$message) { 
     157        $this->message = &$message; 
    158158    } 
    159159    function parse() { 
    160         // first remove the XML declaration 
    161         $this->message = preg_replace('/<\?xml.*?\?'.'>/', '', $this->message); 
     160                // first remove the XML declaration 
     161                // this method avoids the RAM usage of preg_replace on very large messages 
     162                $header = preg_replace( '/<\?xml.*?\?'.'>/', '', substr( $this->message, 0, 100 ), 1 ); 
     163                $this->message = substr_replace($this->message, $header, 0, 100); 
    162164        if (trim($this->message) == '') { 
    163165            return false; 
    164         } 
     166                } 
    165167        $this->_parser = xml_parser_create(); 
    166168        // Set XML parser to take the case of tags in to account 
    167169        xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, false); 
    168170        // Set XML parser callback functions 
    169171        xml_set_object($this->_parser, $this); 
    170172        xml_set_element_handler($this->_parser, 'tag_open', 'tag_close'); 
    171         xml_set_character_data_handler($this->_parser, 'cdata'); 
    172         if (!xml_parse($this->_parser, $this->message)) { 
    173             /* die(sprintf('XML error: %s at line %d', 
    174                 xml_error_string(xml_get_error_code($this->_parser)), 
    175                 xml_get_current_line_number($this->_parser))); */ 
    176             return false; 
    177         } 
    178         xml_parser_free($this->_parser); 
     173                xml_set_character_data_handler($this->_parser, 'cdata'); 
     174                $chunk_size = 262144; // 256Kb, parse in chunks to avoid the RAM usage on very large messages 
     175                do { 
     176                        if ( strlen($this->message) <= $chunk_size ) 
     177                                $final=true; 
     178                        $part = substr( $this->message, 0, $chunk_size ); 
     179                        $this->message = substr( $this->message, $chunk_size ); 
     180                        if ( !xml_parse( $this->_parser, $part, $final ) ) 
     181                                return false; 
     182                        if ( $final ) 
     183                                break; 
     184                } while ( true ); 
     185                xml_parser_free($this->_parser); 
    179186        // Grab the error messages, if any 
    180187        if ($this->messageType == 'fault') { 
    181188            $this->faultCode = $this->params[0]['faultCode']; 
    182189            $this->faultString = $this->params[0]['faultString']; 
    183         } 
     190                } 
    184191        return true; 
    185192    } 
    186193    function tag_open($parser, $tag, $attr) { 
     
    304311               header( 'Content-Type: text/plain' ); 
    305312               die('XML-RPC server accepts POST requests only.'); 
    306313            } 
    307             $data = $HTTP_RAW_POST_DATA; 
     314            $data = &$HTTP_RAW_POST_DATA; 
    308315        } 
    309316        $this->message = new IXR_Message($data); 
    310317        if (!$this->message->parse()) {