From: gggeek Date: Wed, 30 Dec 2020 10:59:38 +0000 (+0000) Subject: WIP more support for xmlrpc-polyfill X-Git-Tag: plcapi-7.1-0~3^2~99 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=57812a66f7e807af1c37d4e79913776b52dfd2c3;p=plcapi.git WIP more support for xmlrpc-polyfill --- diff --git a/src/Helper/Charset.php b/src/Helper/Charset.php index 2f41143..22604d2 100644 --- a/src/Helper/Charset.php +++ b/src/Helper/Charset.php @@ -9,9 +9,13 @@ class Charset // tables used for transcoding different charsets into us-ascii xml protected $xml_iso88591_Entities = array("in" => array(), "out" => array()); - /// @todo add to iso table the characters from cp_1252 range, i.e. 128 to 159? - /// These will NOT be present in true ISO-8859-1, but will save the unwary windows user from sending junk - /// (though no luck when receiving them...) + /// @todo should we add to the latin-1 table the characters from cp_1252 range, i.e. 128 to 159 ? + /// Those will NOT be present in true ISO-8859-1, but will save the unwary windows user from sending junk + /// (though no luck when receiving them...) + /// Note also that, apparently, while 'ISO/IEC 8859-1' has no characters defined for bytes 128 to 159, + /// IANA ISO-8859-1 does have well-defined 'C1' control codes for those - wikipedia's page on latin-1 says: + /// "ISO-8859-1 is the IANA preferred name for this standard when supplemented with the C0 and C1 control codes from ISO/IEC 6429." + /// Check what mbstring/iconv do by default with those? /* protected $xml_cp1252_Entities = array('in' => array(), out' => array( '€', '?', '‚', 'ƒ', @@ -37,6 +41,7 @@ class Charset /** * This class is singleton for performance reasons. + * @todo can't we just make $xml_iso88591_Entities a static variable instead ? * * @return Charset */ @@ -49,6 +54,9 @@ class Charset return self::$instance; } + /** + * @todo move the creation of the charset tables to be on-demand. This saves memory and time when latin-1 is not used at all + */ private function __construct() { for ($i = 0; $i < 32; $i++) { diff --git a/src/Helper/Logger.php b/src/Helper/Logger.php index 12932e7..01804c8 100644 --- a/src/Helper/Logger.php +++ b/src/Helper/Logger.php @@ -59,6 +59,7 @@ class Logger /** * Writes a message to the error log + * @param string $message */ public function errorLog($message) { diff --git a/src/Helper/XMLParser.php b/src/Helper/XMLParser.php index 9e7efdd..10ffaa4 100644 --- a/src/Helper/XMLParser.php +++ b/src/Helper/XMLParser.php @@ -11,6 +11,7 @@ use PhpXmlRpc\Value; class XMLParser { const RETURN_XMLRPCVALS = 'xmlrpcvals'; + const RETURN_EPIVALS = 'epivals'; const RETURN_PHP = 'phpvals'; const ACCEPT_REQUEST = 1; @@ -122,10 +123,15 @@ class XMLParser xml_set_object($parser, $this); - if ($returnType == self::RETURN_PHP) { - xml_set_element_handler($parser, 'xmlrpc_se', 'xmlrpc_ee_fast'); - } else { - xml_set_element_handler($parser, 'xmlrpc_se', 'xmlrpc_ee'); + switch($returnType) { + case self::RETURN_PHP: + xml_set_element_handler($parser, 'xmlrpc_se', 'xmlrpc_ee_fast'); + break; + case self::RETURN_EPIVALS: + xml_set_element_handler($parser, 'xmlrpc_se', 'xmlrpc_ee_epi'); + break; + default: + xml_set_element_handler($parser, 'xmlrpc_se', 'xmlrpc_ee'); } xml_set_character_data_handler($parser, 'xmlrpc_cd'); @@ -331,9 +337,9 @@ class XMLParser * xml parser handler function for close element tags. * @param resource $parser * @param string $name - * @param bool $rebuildXmlrpcvals + * @param int $rebuildXmlrpcvals >1 for rebuilding xmlrpcvals, 0 for rebuilding php values, -1 for xmlrpc-extension compatibility */ - public function xmlrpc_ee($parser, $name, $rebuildXmlrpcvals = true) + public function xmlrpc_ee($parser, $name, $rebuildXmlrpcvals = 1) { if ($this->_xh['isf'] < 2) { // push this element name from stack @@ -350,7 +356,7 @@ class XMLParser $this->_xh['vt'] = Value::$xmlrpcString; } - if ($rebuildXmlrpcvals) { + if ($rebuildXmlrpcvals > 0) { // build the xmlrpc val out of the data received, and substitute it $temp = new Value($this->_xh['value'], $this->_xh['vt']); // in case we got info about underlying php class, save it @@ -358,27 +364,33 @@ class XMLParser if (isset($this->_xh['php_class'])) { $temp->_php_class = $this->_xh['php_class']; } - // check if we are inside an array or struct: - // if value just built is inside an array, let's move it into array on the stack - $vscount = count($this->_xh['valuestack']); - if ($vscount && $this->_xh['valuestack'][$vscount - 1]['type'] == 'ARRAY') { - $this->_xh['valuestack'][$vscount - 1]['values'][] = $temp; - } else { - $this->_xh['value'] = $temp; + $this->_xh['value'] = $temp; + } elseif ($rebuildXmlrpcvals < 0) { + if ($this->_xh['vt'] == Value::$xmlrpcDateTime) { + $this->_xh['value'] = (object)array( + 'xmlrpc_type' => 'datetime', + 'scalar' => $this->_xh['value'], + 'timestamp' => \PhpXmlRpc\Helper\Date::iso8601Decode($this->_xh['value']) + ); + } elseif ($this->_xh['vt'] == Value::$xmlrpcBase64) { + $this->_xh['value'] = (object)array( + 'xmlrpc_type' => 'base64', + 'scalar' => $this->_xh['value'] + ); } } else { - /// @todo this needs to treat correctly php-serialized objects, + /// @todo this should handle php-serialized objects, /// since std deserializing is done by php_xmlrpc_decode, /// which we will not be calling... - if (isset($this->_xh['php_class'])) { - } + //if (isset($this->_xh['php_class'])) { + //} + } - // check if we are inside an array or struct: - // if value just built is inside an array, let's move it into array on the stack - $vscount = count($this->_xh['valuestack']); - if ($vscount && $this->_xh['valuestack'][$vscount - 1]['type'] == 'ARRAY') { - $this->_xh['valuestack'][$vscount - 1]['values'][] = $this->_xh['value']; - } + // check if we are inside an array or struct: + // if value just built is inside an array, let's move it into array on the stack + $vscount = count($this->_xh['valuestack']); + if ($vscount && $this->_xh['valuestack'][$vscount - 1]['type'] == 'ARRAY') { + $this->_xh['valuestack'][$vscount - 1]['values'][] = $this->_xh['value']; } break; case 'BOOLEAN': @@ -514,7 +526,17 @@ class XMLParser */ public function xmlrpc_ee_fast($parser, $name) { - $this->xmlrpc_ee($parser, $name, false); + $this->xmlrpc_ee($parser, $name, 0); + } + + /** + * Used in decoding xmlrpc requests/responses while building xmlrpc-extension Values (plain php for all but base64 and datetime). + * @param resource $parser + * @param string $name + */ + public function xmlrpc_ee_epi($parser, $name) + { + $this->xmlrpc_ee($parser, $name, -1); } /** diff --git a/src/Server.php b/src/Server.php index 3516f94..ffbe21e 100644 --- a/src/Server.php +++ b/src/Server.php @@ -664,7 +664,7 @@ class Server if ($this->functions_parameters_type == 'epivals') { $r = call_user_func_array($func, array($methName, $params, $this->user_data)); // mimic EPI behaviour: if we get an array that looks like an error, make it - // an eror response + // an error response if (is_array($r) && array_key_exists('faultCode', $r) && array_key_exists('faultString', $r)) { $r = new Response(0, (integer)$r['faultCode'], (string)$r['faultString']); } else { diff --git a/tests/3LocalhostTest.php b/tests/3LocalhostTest.php index 2ec0150..5f4c63a 100644 --- a/tests/3LocalhostTest.php +++ b/tests/3LocalhostTest.php @@ -125,7 +125,7 @@ class LocalhostTest extends PhpXmlRpc_PolyfillTestCase /** * @param PhpXmlRpc\Request|array $msg - * @param int|array $errorCode + * @param int|array $errorCode expected error codes * @param bool $returnResponse * @return mixed|\PhpXmlRpc\Response|\PhpXmlRpc\Response[]|\PhpXmlRpc\Value|string|null */