summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerrit Uitslag <klapinklapin@gmail.com>2014-10-03 00:46:37 +0200
committerGerrit Uitslag <klapinklapin@gmail.com>2014-10-03 00:46:37 +0200
commit0a8880f674dca9ad836481eb6d5403510bf886f5 (patch)
tree1cac13600bd2febc8fc70496a2688b7290ba315d
parenta6eab1402c41508e5406f4b8e635d012fa684247 (diff)
downloadrpg-0a8880f674dca9ad836481eb6d5403510bf886f5.tar.gz
rpg-0a8880f674dca9ad836481eb6d5403510bf886f5.tar.bz2
Update IXR lib from 1.61 to 1.7.4 + WP improvements
Update to latest Incutio XML-RPC Library include also some Wordpress improvements (see for more details the log of the lib as included in WP: https://core.trac.wordpress.org/log/trunk/src/wp-includes/class-IXR.php )
-rw-r--r--inc/IXR_Library.php211
1 files changed, 147 insertions, 64 deletions
diff --git a/inc/IXR_Library.php b/inc/IXR_Library.php
index 699f8baa8..839298680 100644
--- a/inc/IXR_Library.php
+++ b/inc/IXR_Library.php
@@ -1,21 +1,46 @@
<?php
+
/**
- * IXR - The Inutio XML-RPC Library - (c) Incutio Ltd 2002
+ * IXR - The Incutio XML-RPC Library
+ *
+ * Copyright (c) 2010, Incutio Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * - Neither the name of Incutio Ltd. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
*
- * @version 1.61
- * @author Simon Willison
- * @date 11th July 2003
- * @link http://scripts.incutio.com/xmlrpc/
- * @link http://scripts.incutio.com/xmlrpc/manual.php
- * @license Artistic License http://www.opensource.org/licenses/artistic-license.php
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package IXR
+ * @since 1.5
+ *
+ * @copyright Incutio Ltd 2010 (http://www.incutio.com)
+ * @version 1.7.4 7th September 2010
+ * @author Simon Willison
+ * @link http://scripts.incutio.com/xmlrpc/ Site/manual
*
* Modified for DokuWiki
* @author Andreas Gohr <andi@splitbrain.org>
*/
-
-/**
- * Class IXR_Value
- */
class IXR_Value {
/** @var IXR_Value[]|IXR_Date|IXR_Base64|int|bool|double|string */
@@ -34,7 +59,7 @@ class IXR_Value {
}
$this->type = $type;
if($type == 'struct') {
- /* Turn all the values in the array in to new IXR_Value objects */
+ // Turn all the values in the array in to new IXR_Value objects
foreach($this->data as $key => $value) {
$this->data[$key] = new IXR_Value($value);
}
@@ -59,6 +84,7 @@ class IXR_Value {
if(is_double($this->data)) {
return 'double';
}
+
// Deal with IXR object types base64 and date
if(is_object($this->data) && is_a($this->data, 'IXR_Date')) {
return 'date';
@@ -66,16 +92,17 @@ class IXR_Value {
if(is_object($this->data) && is_a($this->data, 'IXR_Base64')) {
return 'base64';
}
+
// If it is a normal PHP object convert it in to a struct
if(is_object($this->data)) {
-
$this->data = get_object_vars($this->data);
return 'struct';
}
if(!is_array($this->data)) {
return 'string';
}
- /* We have an array - is it an array or a struct ? */
+
+ // We have an array - is it an array or a struct?
if($this->isStruct($this->data)) {
return 'struct';
} else {
@@ -87,7 +114,7 @@ class IXR_Value {
* @return bool|string
*/
function getXml() {
- /* Return XML for this value */
+ // Return XML for this value
switch($this->type) {
case 'boolean':
return '<boolean>' . (($this->data) ? '1' : '0') . '</boolean>';
@@ -127,11 +154,12 @@ class IXR_Value {
}
/**
+ * Checks whether or not the supplied array is a struct or not
+ *
* @param array $array
- * @return bool
+ * @return boolean
*/
function isStruct($array) {
- /* Nasty function to check if an array is a struct or not */
$expected = 0;
foreach($array as $key => $value) {
if((string) $key != (string) $expected) {
@@ -144,7 +172,11 @@ class IXR_Value {
}
/**
- * Class IXR_Message
+ * IXR_MESSAGE
+ *
+ * @package IXR
+ * @since 1.5
+ *
*/
class IXR_Message {
var $message;
@@ -153,6 +185,7 @@ class IXR_Message {
var $faultString;
var $methodName;
var $params;
+
// 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
@@ -169,7 +202,7 @@ class IXR_Message {
* @param string $message
*/
function IXR_Message($message) {
- $this->message = $message;
+ $this->message =& $message;
}
/**
@@ -177,7 +210,10 @@ class IXR_Message {
*/
function parse() {
// first remove the XML declaration
- $this->message = preg_replace('/<\?xml(.*)?\?' . '>/', '', $this->message);
+ // merged from WP #10698 - this method avoids the RAM usage of preg_replace on very large messages
+ $header = preg_replace('/<\?xml.*?\?' . '>/', '', substr($this->message, 0, 100), 1);
+ $this->message = substr_replace($this->message, $header, 0, 100);
+
// workaround for a bug in PHP/libxml2, see http://bugs.php.net/bug.php?id=45996
$this->message = str_replace('&lt;', '&#60;', $this->message);
$this->message = str_replace('&gt;', '&#62;', $this->message);
@@ -195,13 +231,23 @@ class IXR_Message {
xml_set_object($this->_parser, $this);
xml_set_element_handler($this->_parser, 'tag_open', 'tag_close');
xml_set_character_data_handler($this->_parser, 'cdata');
- if(!xml_parse($this->_parser, $this->message)) {
- /* die(sprintf('XML error: %s at line %d',
- xml_error_string(xml_get_error_code($this->_parser)),
- xml_get_current_line_number($this->_parser))); */
- return false;
- }
+ $chunk_size = 262144; // 256Kb, parse in chunks to avoid the RAM usage on very large messages
+ $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)) {
+ return false;
+ }
+ if($final) {
+ break;
+ }
+ } while(true);
xml_parser_free($this->_parser);
+
// Grab the error messages, if any
if($this->messageType == 'fault') {
$this->faultCode = $this->params[0]['faultCode'];
@@ -216,8 +262,9 @@ class IXR_Message {
* @param $attr
*/
function tag_open($parser, $tag, $attr) {
- $this->_currentTag = $tag;
$this->_currentTagContents = '';
+ $this->_currentTag = $tag;
+
switch($tag) {
case 'methodCall':
case 'methodResponse':
@@ -225,7 +272,7 @@ class IXR_Message {
$this->messageType = $tag;
break;
/* Deal with stacks of arrays and structs */
- case 'data': // data is to all intents and puposes more interesting than array
+ case 'data': // data is to all intents and purposes more interesting than array
$this->_arraystructstypes[] = 'array';
$this->_arraystructs[] = array();
break;
@@ -255,41 +302,33 @@ class IXR_Message {
case 'int':
case 'i4':
$value = (int) trim($this->_currentTagContents);
- $this->_currentTagContents = '';
$valueFlag = true;
break;
case 'double':
$value = (double) trim($this->_currentTagContents);
- $this->_currentTagContents = '';
$valueFlag = true;
break;
case 'string':
$value = (string) $this->_currentTagContents;
- $this->_currentTagContents = '';
$valueFlag = true;
break;
case 'dateTime.iso8601':
$value = new IXR_Date(trim($this->_currentTagContents));
- // $value = $iso->getTimestamp();
- $this->_currentTagContents = '';
$valueFlag = true;
break;
case 'value':
// "If no type is indicated, the type is string."
if($this->_lastseen == 'value') {
$value = (string) $this->_currentTagContents;
- $this->_currentTagContents = '';
$valueFlag = true;
}
break;
case 'boolean':
$value = (boolean) trim($this->_currentTagContents);
- $this->_currentTagContents = '';
$valueFlag = true;
break;
case 'base64':
$value = base64_decode($this->_currentTagContents);
- $this->_currentTagContents = '';
$valueFlag = true;
break;
/* Deal with stacks of arrays and structs */
@@ -304,19 +343,13 @@ class IXR_Message {
break;
case 'name':
$this->_currentStructName[] = trim($this->_currentTagContents);
- $this->_currentTagContents = '';
break;
case 'methodName':
$this->methodName = trim($this->_currentTagContents);
- $this->_currentTagContents = '';
break;
}
+
if($valueFlag) {
- /*
- if (!is_array($value) && !is_object($value)) {
- $value = trim($value);
- }
- */
if(count($this->_arraystructs) > 0) {
// Add value to struct or array
if($this->_arraystructstypes[count($this->_arraystructstypes) - 1] == 'struct') {
@@ -327,16 +360,20 @@ class IXR_Message {
$this->_arraystructs[count($this->_arraystructs) - 1][] = $value;
}
} else {
- // Just add as a paramater
+ // Just add as a parameter
$this->params[] = $value;
}
}
+ $this->_currentTagContents = '';
$this->_lastseen = $tag;
}
}
/**
- * Class IXR_Server
+ * IXR_Server
+ *
+ * @package IXR
+ * @since 1.5
*/
class IXR_Server {
var $data;
@@ -349,14 +386,18 @@ class IXR_Server {
/**
* @param array|bool $callbacks
* @param bool $data
+ * @param bool $wait
*/
- function IXR_Server($callbacks = false, $data = false) {
+ function IXR_Server($callbacks = false, $data = false, $wait = false) {
$this->setCapabilities();
if($callbacks) {
$this->callbacks = $callbacks;
}
$this->setCallbacks();
- $this->serve($data);
+
+ if(!$wait) {
+ $this->serve($data);
+ }
}
/**
@@ -367,6 +408,7 @@ class IXR_Server {
$postData = trim(http_get_raw_post_data());
if(!$postData) {
+ header('Content-Type: text/plain'); // merged from WP #9093
die('XML-RPC server accepts POST requests only.');
}
$data = $postData;
@@ -379,13 +421,16 @@ class IXR_Server {
$this->error(-32600, 'server error. invalid xml-rpc. not conforming to spec. Request must be a methodCall');
}
$result = $this->call($this->message->methodName, $this->message->params);
+
// Is the result an error?
if(is_a($result, 'IXR_Error')) {
$this->error($result);
}
+
// Encode the result
$r = new IXR_Value($result);
$resultxml = $r->getXml();
+
// Create the XML
$xml = <<<EOD
<methodResponse>
@@ -413,11 +458,12 @@ EOD;
return new IXR_Error(-32601, 'server error. requested method ' . $methodname . ' does not exist.');
}
$method = $this->callbacks[$methodname];
+
// Perform the callback and send the response
# Removed for DokuWiki to have a more consistent interface
# if (count($args) == 1) {
- # // If only one paramater just send that instead of the whole array
+ # // If only one parameter just send that instead of the whole array
# $args = $args[0];
# }
@@ -427,7 +473,7 @@ EOD;
$args = (array) $args;
// Are we dealing with a function or a method?
- if(substr($method, 0, 5) == 'this:') {
+ if(is_string($method) && substr($method, 0, 5) == 'this:') {
// It's a class method - check it exists
$method = substr($method, 5);
if(!method_exists($this, $method)) {
@@ -446,12 +492,16 @@ EOD;
}
} else {
// It's a function - does it exist?
- if(!function_exists($method)) {
+ if(is_array($method)) {
+ if(!is_callable(array($method[0], $method[1]))) {
+ return new IXR_Error(-32601, 'server error. requested object method "' . $method[1] . '" does not exist.');
+ }
+ } else if(!function_exists($method)) {
return new IXR_Error(-32601, 'server error. requested function "' . $method . '" does not exist.');
}
+
// Call the function
- #$result = $method($args);
- $result = call_user_func_array($method, $args);
+ $result = call_user_func($method, $args);
}
return $result;
}
@@ -469,7 +519,7 @@ EOD;
}
/**
- * @param $xml
+ * @param string $xml
*/
function output($xml) {
header('Content-Type: text/xml; charset=utf-8');
@@ -554,7 +604,10 @@ EOD;
}
/**
- * Class IXR_Request
+ * IXR_Request
+ *
+ * @package IXR
+ * @since 1.5
*/
class IXR_Request {
/** @var string */
@@ -603,6 +656,11 @@ EOD;
}
/**
+ * IXR_Client
+ *
+ * @package IXR
+ * @since 1.5
+ *
* Changed for DokuWiki to use DokuHTTPClient
*
* This should be compatible to the original class, but uses DokuWiki's
@@ -615,6 +673,8 @@ class IXR_Client extends DokuHTTPClient {
var $posturl = '';
/** @var IXR_Message|bool */
var $message = false;
+
+ // Storage place for an error message
/** @var IXR_Error|bool */
var $xmlerror = false;
@@ -622,8 +682,9 @@ class IXR_Client extends DokuHTTPClient {
* @param string $server
* @param string|bool $path
* @param int $port
+ * @param int $timeout
*/
- function IXR_Client($server, $path = false, $port = 80) {
+ function IXR_Client($server, $path = false, $port = 80, $timeout = 15) {
parent::__construct();
if(!$path) {
// Assume we have been given a URL instead
@@ -631,6 +692,7 @@ class IXR_Client extends DokuHTTPClient {
} else {
$this->posturl = 'http://' . $server . ':' . $port . $path;
}
+ $this->timeout = $timeout;
}
/**
@@ -662,11 +724,13 @@ class IXR_Client extends DokuHTTPClient {
$this->xmlerror = new IXR_Error(-32700, 'parse error. not well formed');
return false;
}
+
// Is the message a fault?
if($this->message->messageType == 'fault') {
$this->xmlerror = new IXR_Error($this->message->faultCode, $this->message->faultString);
return false;
}
+
// Message must be OK
return true;
}
@@ -702,7 +766,10 @@ class IXR_Client extends DokuHTTPClient {
}
/**
- * Class IXR_Error
+ * IXR_Error
+ *
+ * @package IXR
+ * @since 1.5
*/
class IXR_Error {
var $code;
@@ -714,7 +781,7 @@ class IXR_Error {
*/
function IXR_Error($code, $message) {
$this->code = $code;
- $this->message = $message;
+ $this->message = htmlspecialchars($message);
}
/**
@@ -745,7 +812,10 @@ EOD;
}
/**
- * Class IXR_Date
+ * IXR_Date
+ *
+ * @package IXR
+ * @since 1.5
*/
class IXR_Date {
var $year;
@@ -754,6 +824,7 @@ class IXR_Date {
var $hour;
var $minute;
var $second;
+ var $timezone;
/**
* @param int|string $time
@@ -777,6 +848,7 @@ class IXR_Date {
$this->hour = gmdate('H', $timestamp);
$this->minute = gmdate('i', $timestamp);
$this->second = gmdate('s', $timestamp);
+ $this->timezone = '';
}
/**
@@ -797,7 +869,7 @@ class IXR_Date {
* @return string
*/
function getIso() {
- return $this->year . $this->month . $this->day . 'T' . $this->hour . ':' . $this->minute . ':' . $this->second;
+ return $this->year . $this->month . $this->day . 'T' . $this->hour . ':' . $this->minute . ':' . $this->second . $this->timezone;
}
/**
@@ -816,7 +888,10 @@ class IXR_Date {
}
/**
- * Class IXR_Base64
+ * IXR_Base64
+ *
+ * @package IXR
+ * @since 1.5
*/
class IXR_Base64 {
var $data;
@@ -837,12 +912,15 @@ class IXR_Base64 {
}
/**
- * Class IXR_IntrospectionServer
+ * IXR_IntrospectionServer
+ *
+ * @package IXR
+ * @since 1.5
*/
class IXR_IntrospectionServer extends IXR_Server {
/** @var array[] */
- var $signatures/** @var string[] */
- ;
+ var $signatures;
+ /** @var string[] */
var $help;
function IXR_IntrospectionServer() {
@@ -900,6 +978,7 @@ class IXR_IntrospectionServer extends IXR_Server {
if($args && !is_array($args)) {
$args = array($args);
}
+
// Over-rides default call method, adds signature check
if(!$this->hasMethod($methodname)) {
return new IXR_Error(-32601, 'server error. requested method "' . $this->message->methodName . '" not specified.');
@@ -913,6 +992,7 @@ class IXR_IntrospectionServer extends IXR_Server {
// print 'Num of args: '.count($args).' Num in signature: '.count($signature);
return new IXR_Error(-32602, 'server error. wrong number of method parameters');
}
+
// Check the argument types
$ok = true;
$argsbackup = $args;
@@ -1011,7 +1091,10 @@ class IXR_IntrospectionServer extends IXR_Server {
}
/**
- * Class IXR_ClientMulticall
+ * IXR_ClientMulticall
+ *
+ * @package IXR
+ * @since 1.5
*/
class IXR_ClientMulticall extends IXR_Client {