| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 | 
							- <?php
 
- /**
 
-  * IXR_MESSAGE
 
-  *
 
-  * @package IXR
 
-  * @since 1.5.0
 
-  *
 
-  */
 
- class IXR_Message
 
- {
 
-     var $message     = false;
 
-     var $messageType = false;  // methodCall / methodResponse / fault
 
-     var $faultCode   = false;
 
-     var $faultString = false;
 
-     var $methodName  = '';
 
-     var $params      = array();
 
-     // Current variable stacks
 
-     var $_arraystructs = array();   // The stack used to keep track of the current array/struct
 
-     var $_arraystructstypes = array(); // Stack keeping track of if things are structs or array
 
-     var $_currentStructName = array();  // A stack as well
 
-     var $_param;
 
-     var $_value;
 
-     var $_currentTag;
 
-     var $_currentTagContents;
 
-     // The XML parser
 
-     var $_parser;
 
- 	/**
 
- 	 * PHP5 constructor.
 
- 	 */
 
-     function __construct( $message )
 
-     {
 
-         $this->message =& $message;
 
-     }
 
- 	/**
 
- 	 * PHP4 constructor.
 
- 	 */
 
- 	public function IXR_Message( $message ) {
 
- 		self::__construct( $message );
 
- 	}
 
-     function parse()
 
-     {
 
-         if ( ! function_exists( 'xml_parser_create' ) ) {
 
-             trigger_error( __( "PHP's XML extension is not available. Please contact your hosting provider to enable PHP's XML extension." ) );
 
-             return false;
 
-         }
 
-         // first remove the XML declaration
 
-         // merged from WP #10698 - this method avoids the RAM usage of preg_replace on very large messages
 
-         $header = preg_replace( '/<\?xml.*?\?'.'>/s', '', substr( $this->message, 0, 100 ), 1 );
 
-         $this->message = trim( substr_replace( $this->message, $header, 0, 100 ) );
 
-         if ( '' == $this->message ) {
 
-             return false;
 
-         }
 
-         // Then remove the DOCTYPE
 
-         $header = preg_replace( '/^<!DOCTYPE[^>]*+>/i', '', substr( $this->message, 0, 200 ), 1 );
 
-         $this->message = trim( substr_replace( $this->message, $header, 0, 200 ) );
 
-         if ( '' == $this->message ) {
 
-             return false;
 
-         }
 
-         // Check that the root tag is valid
 
-         $root_tag = substr( $this->message, 0, strcspn( substr( $this->message, 0, 20 ), "> \t\r\n" ) );
 
-         if ( '<!DOCTYPE' === strtoupper( $root_tag ) ) {
 
-             return false;
 
-         }
 
-         if ( ! in_array( $root_tag, array( '<methodCall', '<methodResponse', '<fault' ) ) ) {
 
-             return false;
 
-         }
 
-         // Bail if there are too many elements to parse
 
-         $element_limit = 30000;
 
-         if ( function_exists( 'apply_filters' ) ) {
 
-             /**
 
-              * Filters the number of elements to parse in an XML-RPC response.
 
-              *
 
-              * @since 4.0.0
 
-              *
 
-              * @param int $element_limit Default elements limit.
 
-              */
 
-             $element_limit = apply_filters( 'xmlrpc_element_limit', $element_limit );
 
-         }
 
-         if ( $element_limit && 2 * $element_limit < substr_count( $this->message, '<' ) ) {
 
-             return false;
 
-         }
 
-         $this->_parser = xml_parser_create();
 
-         // Set XML parser to take the case of tags in to account
 
-         xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, false);
 
-         // Set XML parser callback functions
 
-         xml_set_object($this->_parser, $this);
 
-         xml_set_element_handler($this->_parser, 'tag_open', 'tag_close');
 
-         xml_set_character_data_handler($this->_parser, 'cdata');
 
-         // 256Kb, parse in chunks to avoid the RAM usage on very large messages
 
-         $chunk_size = 262144;
 
-         /**
 
-          * Filters the chunk size that can be used to parse an XML-RPC response message.
 
-          *
 
-          * @since 4.4.0
 
-          *
 
-          * @param int $chunk_size Chunk size to parse in bytes.
 
-          */
 
-         $chunk_size = apply_filters( 'xmlrpc_chunk_parsing_size', $chunk_size );
 
-         $final = false;
 
-         do {
 
-             if (strlen($this->message) <= $chunk_size) {
 
-                 $final = true;
 
-             }
 
-             $part = substr($this->message, 0, $chunk_size);
 
-             $this->message = substr($this->message, $chunk_size);
 
-             if (!xml_parse($this->_parser, $part, $final)) {
 
-                 xml_parser_free($this->_parser);
 
-                 unset($this->_parser);
 
-                 return false;
 
-             }
 
-             if ($final) {
 
-                 break;
 
-             }
 
-         } while (true);
 
-         xml_parser_free($this->_parser);
 
-         unset($this->_parser);
 
-         // Grab the error messages, if any
 
-         if ($this->messageType == 'fault') {
 
-             $this->faultCode = $this->params[0]['faultCode'];
 
-             $this->faultString = $this->params[0]['faultString'];
 
-         }
 
-         return true;
 
-     }
 
-     function tag_open($parser, $tag, $attr)
 
-     {
 
-         $this->_currentTagContents = '';
 
-         $this->currentTag = $tag;
 
-         switch($tag) {
 
-             case 'methodCall':
 
-             case 'methodResponse':
 
-             case 'fault':
 
-                 $this->messageType = $tag;
 
-                 break;
 
-                 /* Deal with stacks of arrays and structs */
 
-             case 'data':    // data is to all intents and puposes more interesting than array
 
-                 $this->_arraystructstypes[] = 'array';
 
-                 $this->_arraystructs[] = array();
 
-                 break;
 
-             case 'struct':
 
-                 $this->_arraystructstypes[] = 'struct';
 
-                 $this->_arraystructs[] = array();
 
-                 break;
 
-         }
 
-     }
 
-     function cdata($parser, $cdata)
 
-     {
 
-         $this->_currentTagContents .= $cdata;
 
-     }
 
-     function tag_close($parser, $tag)
 
-     {
 
-         $valueFlag = false;
 
-         switch($tag) {
 
-             case 'int':
 
-             case 'i4':
 
-                 $value = (int)trim($this->_currentTagContents);
 
-                 $valueFlag = true;
 
-                 break;
 
-             case 'double':
 
-                 $value = (double)trim($this->_currentTagContents);
 
-                 $valueFlag = true;
 
-                 break;
 
-             case 'string':
 
-                 $value = (string)trim($this->_currentTagContents);
 
-                 $valueFlag = true;
 
-                 break;
 
-             case 'dateTime.iso8601':
 
-                 $value = new IXR_Date(trim($this->_currentTagContents));
 
-                 $valueFlag = true;
 
-                 break;
 
-             case 'value':
 
-                 // "If no type is indicated, the type is string."
 
-                 if (trim($this->_currentTagContents) != '') {
 
-                     $value = (string)$this->_currentTagContents;
 
-                     $valueFlag = true;
 
-                 }
 
-                 break;
 
-             case 'boolean':
 
-                 $value = (boolean)trim($this->_currentTagContents);
 
-                 $valueFlag = true;
 
-                 break;
 
-             case 'base64':
 
-                 $value = base64_decode($this->_currentTagContents);
 
-                 $valueFlag = true;
 
-                 break;
 
-                 /* Deal with stacks of arrays and structs */
 
-             case 'data':
 
-             case 'struct':
 
-                 $value = array_pop($this->_arraystructs);
 
-                 array_pop($this->_arraystructstypes);
 
-                 $valueFlag = true;
 
-                 break;
 
-             case 'member':
 
-                 array_pop($this->_currentStructName);
 
-                 break;
 
-             case 'name':
 
-                 $this->_currentStructName[] = trim($this->_currentTagContents);
 
-                 break;
 
-             case 'methodName':
 
-                 $this->methodName = trim($this->_currentTagContents);
 
-                 break;
 
-         }
 
-         if ($valueFlag) {
 
-             if (count($this->_arraystructs) > 0) {
 
-                 // Add value to struct or array
 
-                 if ($this->_arraystructstypes[count($this->_arraystructstypes)-1] == 'struct') {
 
-                     // Add to struct
 
-                     $this->_arraystructs[count($this->_arraystructs)-1][$this->_currentStructName[count($this->_currentStructName)-1]] = $value;
 
-                 } else {
 
-                     // Add to array
 
-                     $this->_arraystructs[count($this->_arraystructs)-1][] = $value;
 
-                 }
 
-             } else {
 
-                 // Just add as a parameter
 
-                 $this->params[] = $value;
 
-             }
 
-         }
 
-         $this->_currentTagContents = '';
 
-     }
 
- }
 
 
  |