| | <?php |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | class IXR_Message |
| | { |
| | var $message = false; |
| | var $messageType = false; |
| | var $faultCode = false; |
| | var $faultString = false; |
| | var $methodName = ''; |
| | var $params = array(); |
| |
|
| | |
| | var $_arraystructs = array(); |
| | var $_arraystructstypes = array(); |
| | var $_currentStructName = array(); |
| | var $_param; |
| | var $_value; |
| | var $_currentTag; |
| | var $_currentTagContents; |
| | |
| | var $_parser; |
| |
|
| | |
| | |
| | |
| | function __construct( $message ) |
| | { |
| | $this->message =& $message; |
| | } |
| |
|
| | |
| | |
| | |
| | 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; |
| | } |
| |
|
| | |
| | |
| | $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; |
| | } |
| |
|
| | |
| | $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; |
| | } |
| |
|
| | |
| | $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; |
| | } |
| |
|
| | |
| | $element_limit = 30000; |
| | if ( function_exists( 'apply_filters' ) ) { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | $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(); |
| | |
| | xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, false); |
| | |
| | xml_set_object($this->_parser, $this); |
| | xml_set_element_handler($this->_parser, 'tag_open', 'tag_close'); |
| | xml_set_character_data_handler($this->_parser, 'cdata'); |
| |
|
| | |
| | $chunk_size = 262144; |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | $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); |
| |
|
| | |
| | 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; |
| | |
| | case 'data': |
| | $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 (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; |
| | |
| | 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) { |
| | |
| | if ($this->_arraystructstypes[count($this->_arraystructstypes)-1] == 'struct') { |
| | |
| | $this->_arraystructs[count($this->_arraystructs)-1][$this->_currentStructName[count($this->_currentStructName)-1]] = $value; |
| | } else { |
| | |
| | $this->_arraystructs[count($this->_arraystructs)-1][] = $value; |
| | } |
| | } else { |
| | |
| | $this->params[] = $value; |
| | } |
| | } |
| | $this->_currentTagContents = ''; |
| | } |
| | } |
| |
|