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

File wp-includes--class-IXR.php.diff, 2.8 KB (added by josephscott, 4 years ago)
Line 
1Index: wp-includes/class-IXR.php
2===================================================================
3--- wp-includes/class-IXR.php   (revision 11893)
4+++ wp-includes/class-IXR.php   (working copy)
5@@ -153,34 +153,41 @@
6     var $_currentTagContents;
7     // The XML parser
8     var $_parser;
9-    function IXR_Message ($message) {
10-        $this->message = $message;
11+    function IXR_Message (&$message) {
12+        $this->message = &$message;
13     }
14     function parse() {
15-        // first remove the XML declaration
16-        $this->message = preg_replace('/<\?xml.*?\?'.'>/', '', $this->message);
17+               // first remove the XML declaration
18+               // this method avoids the RAM usage of preg_replace on very large messages
19+               $header = preg_replace( '/<\?xml.*?\?'.'>/', '', substr( $this->message, 0, 100 ), 1 );
20+               $this->message = substr_replace($this->message, $header, 0, 100);
21         if (trim($this->message) == '') {
22             return false;
23-        }
24+               }
25         $this->_parser = xml_parser_create();
26         // Set XML parser to take the case of tags in to account
27         xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, false);
28         // Set XML parser callback functions
29         xml_set_object($this->_parser, $this);
30         xml_set_element_handler($this->_parser, 'tag_open', 'tag_close');
31-        xml_set_character_data_handler($this->_parser, 'cdata');
32-        if (!xml_parse($this->_parser, $this->message)) {
33-            /* die(sprintf('XML error: %s at line %d',
34-                xml_error_string(xml_get_error_code($this->_parser)),
35-                xml_get_current_line_number($this->_parser))); */
36-            return false;
37-        }
38-        xml_parser_free($this->_parser);
39+               xml_set_character_data_handler($this->_parser, 'cdata');
40+               $chunk_size = 262144; // 256Kb, parse in chunks to avoid the RAM usage on very large messages
41+               do {
42+                       if ( strlen($this->message) <= $chunk_size )
43+                               $final=true;
44+                       $part = substr( $this->message, 0, $chunk_size );
45+                       $this->message = substr( $this->message, $chunk_size );
46+                       if ( !xml_parse( $this->_parser, $part, $final ) )
47+                               return false;
48+                       if ( $final )
49+                               break;
50+               } while ( true );
51+               xml_parser_free($this->_parser);
52         // Grab the error messages, if any
53         if ($this->messageType == 'fault') {
54             $this->faultCode = $this->params[0]['faultCode'];
55             $this->faultString = $this->params[0]['faultString'];
56-        }
57+               }
58         return true;
59     }
60     function tag_open($parser, $tag, $attr) {
61@@ -304,7 +311,7 @@
62                header( 'Content-Type: text/plain' );
63                die('XML-RPC server accepts POST requests only.');
64             }
65-            $data = $HTTP_RAW_POST_DATA;
66+            $data = &$HTTP_RAW_POST_DATA;
67         }
68         $this->message = new IXR_Message($data);
69         if (!$this->message->parse()) {