From 736b0479986f194252a47fc07615662d45b4a35e Mon Sep 17 00:00:00 2001 From: garvinhicking Date: Mon, 15 Aug 2005 10:34:47 +0000 Subject: [PATCH] Upgrade to PEAR XML_RPC 1.4.0 --- bundled-libs/.current_version | 2 +- bundled-libs/XML/RPC.php | 206 +++++++++++++++++++++++--------- bundled-libs/XML/RPC/Dump.php | 2 +- bundled-libs/XML/RPC/Server.php | 20 +++- 4 files changed, 166 insertions(+), 64 deletions(-) diff --git a/bundled-libs/.current_version b/bundled-libs/.current_version index 55509d4..c1d852c 100644 --- a/bundled-libs/.current_version +++ b/bundled-libs/.current_version @@ -5,7 +5,7 @@ Net_Socket 1.0.6 Net_URL 1.0.14 PEAR 1.3.5 Text_Wiki 0.25.0 -XML_RPC 1.3.3 +XML_RPC 1.4.0 Onyx 1.0 (customized) Smarty 2.6.9 Net_DNSBL 1.0.0 diff --git a/bundled-libs/XML/RPC.php b/bundled-libs/XML/RPC.php index 7f4f022..0068123 100644 --- a/bundled-libs/XML/RPC.php +++ b/bundled-libs/XML/RPC.php @@ -32,7 +32,7 @@ * @author Martin Jansen * @author Daniel Convissor * @copyright 1999-2001 Edd Dumbill, 2001-2005 The PHP Group - * @version CVS: $Id: RPC.php,v 1.81 2005/07/14 02:15:26 danielc Exp $ + * @version CVS: $Id: RPC.php,v 1.83 2005/08/14 20:25:35 danielc Exp $ * @link http://pear.php.net/package/XML_RPC */ @@ -154,6 +154,7 @@ $GLOBALS['XML_RPC_err'] = array( 'introspect_unknown' => 4, 'http_error' => 5, 'not_response_object' => 6, + 'invalid_request' => 7, ); /** @@ -167,6 +168,7 @@ $GLOBALS['XML_RPC_str'] = array( 'introspect_unknown' => 'Can\'t introspect: method unknown', 'http_error' => 'Didn\'t receive 200 OK from remote server.', 'not_response_object' => 'The requested method didn\'t return an XML_RPC_Response object.', + 'invalid_request' => 'Invalid request payload', ); @@ -196,11 +198,35 @@ $GLOBALS['XML_RPC_errxml'] = 100; $GLOBALS['XML_RPC_backslash'] = chr(92) . chr(92); +/** + * Valid parents of XML elements + * @global array $GLOBALS['XML_RPC_valid_parents'] + */ +$GLOBALS['XML_RPC_valid_parents'] = array( + 'BOOLEAN' => array('VALUE'), + 'I4' => array('VALUE'), + 'INT' => array('VALUE'), + 'STRING' => array('VALUE'), + 'DOUBLE' => array('VALUE'), + 'DATETIME.ISO8601' => array('VALUE'), + 'BASE64' => array('VALUE'), + 'ARRAY' => array('VALUE'), + 'STRUCT' => array('VALUE'), + 'PARAM' => array('PARAMS'), + 'METHODNAME' => array('METHODCALL'), + 'PARAMS' => array('METHODCALL', 'METHODRESPONSE'), + 'MEMBER' => array('STRUCT'), + 'NAME' => array('MEMBER'), + 'DATA' => array('ARRAY'), + 'FAULT' => array('METHODRESPONSE'), + 'VALUE' => array('MEMBER', 'DATA', 'PARAM', 'FAULT'), +); + + /** * Stores state during parsing * * quick explanation of components: - * + st = builds up a string for evaluation * + ac = accumulates values * + qt = decides if quotes are needed for evaluation * + cm = denotes struct or array (comma needed) @@ -222,22 +248,58 @@ $GLOBALS['XML_RPC_xh'] = array(); */ function XML_RPC_se($parser_resource, $name, $attrs) { - global $XML_RPC_xh, $XML_RPC_DateTime, $XML_RPC_String; + global $XML_RPC_xh, $XML_RPC_DateTime, $XML_RPC_String, $XML_RPC_valid_parents; $parser = (int) $parser_resource; + // if invalid xmlrpc already detected, skip all processing + if ($XML_RPC_xh[$parser]['isf'] >= 2) { + return; + } + + // check for correct element nesting + // top level element can only be of 2 types + if (count($XML_RPC_xh[$parser]['stack']) == 0) { + if ($name != 'METHODRESPONSE' && $name != 'METHODCALL') { + $XML_RPC_xh[$parser]['isf'] = 2; + $XML_RPC_xh[$parser]['isf_reason'] = 'missing top level xmlrpc element'; + return; + } + } else { + // not top level element: see if parent is OK + if (!in_array($XML_RPC_xh[$parser]['stack'][0], $XML_RPC_valid_parents[$name])) { + $name = preg_replace('[^a-zA-Z0-9._-]', '', $name); + $XML_RPC_xh[$parser]['isf'] = 2; + $XML_RPC_xh[$parser]['isf_reason'] = "xmlrpc element $name cannot be child of {$XML_RPC_xh[$parser]['stack'][0]}"; + return; + } + } + switch ($name) { case 'STRUCT': + $XML_RPC_xh[$parser]['cm']++; + + // turn quoting off + $XML_RPC_xh[$parser]['qt'] = 0; + + $cur_val = array(); + $cur_val['value'] = array(); + $cur_val['members'] = 1; + array_unshift($XML_RPC_xh[$parser]['valuestack'], $cur_val); + break; + case 'ARRAY': - $XML_RPC_xh[$parser]['st'] .= 'array('; $XML_RPC_xh[$parser]['cm']++; - // this last line turns quoting off - // this means if we get an empty array we'll - // simply get a bit of whitespace in the eval + + // turn quoting off $XML_RPC_xh[$parser]['qt'] = 0; + + $cur_val = array(); + $cur_val['value'] = array(); + $cur_val['members'] = 0; + array_unshift($XML_RPC_xh[$parser]['valuestack'], $cur_val); break; case 'NAME': - $XML_RPC_xh[$parser]['st'] .= '"'; $XML_RPC_xh[$parser]['ac'] = ''; break; @@ -246,11 +308,10 @@ function XML_RPC_se($parser_resource, $name, $attrs) break; case 'PARAM': - $XML_RPC_xh[$parser]['st'] = ''; + $XML_RPC_xh[$parser]['valuestack'] = array(); break; case 'VALUE': - $XML_RPC_xh[$parser]['st'] .= 'new XML_RPC_Value('; $XML_RPC_xh[$parser]['lv'] = 1; $XML_RPC_xh[$parser]['vt'] = $XML_RPC_String; $XML_RPC_xh[$parser]['ac'] = ''; @@ -288,8 +349,21 @@ function XML_RPC_se($parser_resource, $name, $attrs) case 'MEMBER': $XML_RPC_xh[$parser]['ac'] = ''; + break; + + case 'DATA': + case 'METHODCALL': + case 'METHODNAME': + case 'METHODRESPONSE': + case 'PARAMS': + // valid elements that add little to processing + break; } + + // Save current element to stack + array_unshift($XML_RPC_xh[$parser]['stack'], $name); + if ($name != 'VALUE') { $XML_RPC_xh[$parser]['lv'] = 0; } @@ -305,22 +379,27 @@ function XML_RPC_ee($parser_resource, $name) global $XML_RPC_xh, $XML_RPC_Types, $XML_RPC_String; $parser = (int) $parser_resource; + if ($XML_RPC_xh[$parser]['isf'] >= 2) { + return; + } + + // push this element from stack + // NB: if XML validates, correct opening/closing is guaranteed and + // we do not have to check for $name == $curr_elem. + // we also checked for proper nesting at start of elements... + $curr_elem = array_shift($XML_RPC_xh[$parser]['stack']); + switch ($name) { case 'STRUCT': case 'ARRAY': - if ($XML_RPC_xh[$parser]['cm'] - && substr($XML_RPC_xh[$parser]['st'], -1) == ',') - { - $XML_RPC_xh[$parser]['st'] = substr($XML_RPC_xh[$parser]['st'], 0, -1); - } - - $XML_RPC_xh[$parser]['st'] .= ')'; + $cur_val = array_shift($XML_RPC_xh[$parser]['valuestack']); + $XML_RPC_xh[$parser]['value'] = $cur_val['value']; $XML_RPC_xh[$parser]['vt'] = strtolower($name); $XML_RPC_xh[$parser]['cm']--; break; case 'NAME': - $XML_RPC_xh[$parser]['st'] .= $XML_RPC_xh[$parser]['ac'] . '" => '; + $XML_RPC_xh[$parser]['valuestack'][0]['name'] = $XML_RPC_xh[$parser]['ac']; break; case 'BOOLEAN': @@ -343,22 +422,21 @@ function XML_RPC_ee($parser_resource, $name) case 'BASE64': if ($XML_RPC_xh[$parser]['qt'] == 1) { // we use double quotes rather than single so backslashification works OK - $XML_RPC_xh[$parser]['st'] .= '"' . $XML_RPC_xh[$parser]['ac'] . '"'; + $XML_RPC_xh[$parser]['value'] = $XML_RPC_xh[$parser]['ac']; } elseif ($XML_RPC_xh[$parser]['qt'] == 2) { - $XML_RPC_xh[$parser]['st'] .= 'base64_decode("' - . $XML_RPC_xh[$parser]['ac'] . '")'; + $XML_RPC_xh[$parser]['value'] = base64_decode($XML_RPC_xh[$parser]['ac']); } elseif ($name == 'BOOLEAN') { - $XML_RPC_xh[$parser]['st'] .= $XML_RPC_xh[$parser]['ac']; + $XML_RPC_xh[$parser]['value'] = $XML_RPC_xh[$parser]['ac']; } else { // we have an I4, INT or a DOUBLE // we must check that only 0123456789-. are characters here if (!ereg("^[+-]?[0123456789 \t\.]+$", $XML_RPC_xh[$parser]['ac'])) { XML_RPC_Base::raiseError('Non-numeric value received in INT or DOUBLE', XML_RPC_ERROR_NON_NUMERIC_FOUND); - $XML_RPC_xh[$parser]['st'] .= 'XML_RPC_ERROR_NON_NUMERIC_FOUND'; + $XML_RPC_xh[$parser]['value'] = XML_RPC_ERROR_NON_NUMERIC_FOUND; } else { // it's ok, add it on - $XML_RPC_xh[$parser]['st'] .= $XML_RPC_xh[$parser]['ac']; + $XML_RPC_xh[$parser]['value'] = $XML_RPC_xh[$parser]['ac']; } } @@ -371,24 +449,35 @@ function XML_RPC_ee($parser_resource, $name) // deal with a string value if (strlen($XML_RPC_xh[$parser]['ac']) > 0 && $XML_RPC_xh[$parser]['vt'] == $XML_RPC_String) { - - $XML_RPC_xh[$parser]['st'] .= '"' . $XML_RPC_xh[$parser]['ac'] . '"'; + $XML_RPC_xh[$parser]['value'] = $XML_RPC_xh[$parser]['ac']; } - // This if () detects if no scalar was inside - // and pads an empty "". - if ($XML_RPC_xh[$parser]['st'][strlen($XML_RPC_xh[$parser]['st'])-1] == '(') { - $XML_RPC_xh[$parser]['st'] .= '""'; - } - $XML_RPC_xh[$parser]['st'] .= ", '" . $XML_RPC_xh[$parser]['vt'] . "')"; - if ($XML_RPC_xh[$parser]['cm']) { - $XML_RPC_xh[$parser]['st'] .= ','; + $temp = new XML_RPC_Value($XML_RPC_xh[$parser]['value'], $XML_RPC_xh[$parser]['vt']); + + $cur_val = array_shift($XML_RPC_xh[$parser]['valuestack']); + if (is_array($cur_val)) { + if ($cur_val['members']==0) { + $cur_val['value'][] = $temp; + } else { + $XML_RPC_xh[$parser]['value'] = $temp; + } + array_unshift($XML_RPC_xh[$parser]['valuestack'], $cur_val); + } else { + $XML_RPC_xh[$parser]['value'] = $temp; } break; case 'MEMBER': $XML_RPC_xh[$parser]['ac'] = ''; $XML_RPC_xh[$parser]['qt'] = 0; + + $cur_val = array_shift($XML_RPC_xh[$parser]['valuestack']); + if (is_array($cur_val)) { + if ($cur_val['members']==1) { + $cur_val['value'][$cur_val['name']] = $XML_RPC_xh[$parser]['value']; + } + array_unshift($XML_RPC_xh[$parser]['valuestack'], $cur_val); + } break; case 'DATA': @@ -397,7 +486,7 @@ function XML_RPC_ee($parser_resource, $name) break; case 'PARAM': - $XML_RPC_xh[$parser]['params'][] = $XML_RPC_xh[$parser]['st']; + $XML_RPC_xh[$parser]['params'][] = $XML_RPC_xh[$parser]['value']; break; case 'METHODNAME': @@ -440,9 +529,7 @@ function XML_RPC_cd($parser_resource, $data) if (!isset($XML_RPC_xh[$parser]['ac'])) { $XML_RPC_xh[$parser]['ac'] = ''; } - $XML_RPC_xh[$parser]['ac'] .= str_replace('$', '\$', - str_replace('"', '\"', str_replace(chr(92), - $XML_RPC_backslash, $data))); + $XML_RPC_xh[$parser]['ac'] .= $data; } } @@ -456,7 +543,7 @@ function XML_RPC_cd($parser_resource, $data) * @author Martin Jansen * @author Daniel Convissor * @copyright 1999-2001 Edd Dumbill, 2001-2005 The PHP Group - * @version Release: 1.3.3 + * @version Release: 1.4.0 * @link http://pear.php.net/package/XML_RPC */ class XML_RPC_Base { @@ -501,7 +588,7 @@ class XML_RPC_Base { * @author Martin Jansen * @author Daniel Convissor * @copyright 1999-2001 Edd Dumbill, 2001-2005 The PHP Group - * @version Release: 1.3.3 + * @version Release: 1.4.0 * @link http://pear.php.net/package/XML_RPC */ class XML_RPC_Client extends XML_RPC_Base { @@ -855,7 +942,7 @@ class XML_RPC_Client extends XML_RPC_Base { } $resp = $msg->parseResponseFile($fp); - $meta = stream_get_meta_data($fp); + $meta = socket_get_status($fp); if ($meta['timed_out']) { fclose($fp); $this->errstr = 'RPC server did not send response before timeout.'; @@ -890,7 +977,7 @@ class XML_RPC_Client extends XML_RPC_Base { $this->headers = 'POST '; } $this->headers .= $this->path. " HTTP/1.0\r\n"; - + $this->headers .= "User-Agent: PEAR XML_RPC\r\n"; $this->headers .= 'Host: ' . $this->server . "\r\n"; @@ -923,7 +1010,7 @@ class XML_RPC_Client extends XML_RPC_Base { * @author Martin Jansen * @author Daniel Convissor * @copyright 1999-2001 Edd Dumbill, 2001-2005 The PHP Group - * @version Release: 1.3.3 + * @version Release: 1.4.0 * @link http://pear.php.net/package/XML_RPC */ class XML_RPC_Response extends XML_RPC_Base @@ -1014,7 +1101,7 @@ class XML_RPC_Response extends XML_RPC_Base * @author Martin Jansen * @author Daniel Convissor * @copyright 1999-2001 Edd Dumbill, 2001-2005 The PHP Group - * @version Release: 1.3.3 + * @version Release: 1.4.0 * @link http://pear.php.net/package/XML_RPC */ class XML_RPC_Message extends XML_RPC_Base @@ -1253,11 +1340,12 @@ class XML_RPC_Message extends XML_RPC_Base $XML_RPC_xh = array(); $XML_RPC_xh[$parser] = array(); - $XML_RPC_xh[$parser]['st'] = ''; $XML_RPC_xh[$parser]['cm'] = 0; $XML_RPC_xh[$parser]['isf'] = 0; $XML_RPC_xh[$parser]['ac'] = ''; $XML_RPC_xh[$parser]['qt'] = ''; + $XML_RPC_xh[$parser]['stack'] = array(); + $XML_RPC_xh[$parser]['valuestack'] = array(); xml_parser_set_option($parser_resource, XML_OPTION_CASE_FOLDING, true); xml_set_element_handler($parser_resource, 'XML_RPC_se', 'XML_RPC_ee'); @@ -1265,9 +1353,9 @@ class XML_RPC_Message extends XML_RPC_Base $hdrfnd = 0; if ($this->debug) { - print "
---GOT---\n";
+            print "\n
---GOT---\n";
             print isset($_SERVER['SERVER_PROTOCOL']) ? htmlspecialchars($data) : $data;
-            print "\n---END---\n
"; + print "\n---END---
\n"; } // See if response is a 200 or a 100 then a 200, else raise error. @@ -1284,9 +1372,8 @@ class XML_RPC_Message extends XML_RPC_Base xml_parser_free($parser_resource); return $r; } - // gotta get rid of headers here - + // gotta get rid of headers here if (!$hdrfnd && ($brpos = strpos($data,"\r\n\r\n"))) { $XML_RPC_xh[$parser]['ha'] = substr($data, 0, $brpos); $data = substr($data, $brpos + 4); @@ -1315,20 +1402,27 @@ class XML_RPC_Message extends XML_RPC_Base xml_parser_free($parser_resource); return $r; } + xml_parser_free($parser_resource); + if ($this->debug) { - print '
---EVALING---[' .
-            strlen($XML_RPC_xh[$parser]['st']) . " chars]---\n" .
-            htmlspecialchars($XML_RPC_xh[$parser]['st']) . ";\n---END---
"; + print "\n
---PARSED---\n";
+            var_dump($XML_RPC_xh[$parser]['value']);
+            print "---END---
\n"; } - if (strlen($XML_RPC_xh[$parser]['st']) == 0) { + + if ($XML_RPC_xh[$parser]['isf'] > 1) { + $r = new XML_RPC_Response(0, $XML_RPC_err['invalid_return'], + $XML_RPC_str['invalid_return'].' '.$XML_RPC_xh[$parser]['isf_reason']); + } elseif (!is_object($XML_RPC_xh[$parser]['value'])) { // then something odd has happened // and it's time to generate a client side error // indicating something odd went on $r = new XML_RPC_Response(0, $XML_RPC_err['invalid_return'], $XML_RPC_str['invalid_return']); } else { - @eval('$v=' . $XML_RPC_xh[$parser]['st'] . '; $allOK=1;'); + $v = $XML_RPC_xh[$parser]['value']; + $allOK=1; if ($XML_RPC_xh[$parser]['isf']) { $f = $v->structmem('faultCode'); $fs = $v->structmem('faultString'); @@ -1353,7 +1447,7 @@ class XML_RPC_Message extends XML_RPC_Base * @author Martin Jansen * @author Daniel Convissor * @copyright 1999-2001 Edd Dumbill, 2001-2005 The PHP Group - * @version Release: 1.3.3 + * @version Release: 1.4.0 * @link http://pear.php.net/package/XML_RPC */ class XML_RPC_Value extends XML_RPC_Base @@ -1626,7 +1720,7 @@ class XML_RPC_Value extends XML_RPC_Base $t[$id] = $cont->scalarval(); } foreach ($t as $id => $cont) { - @eval('$b->'.$id.' = $cont;'); + $b->$id = $cont; } } diff --git a/bundled-libs/XML/RPC/Dump.php b/bundled-libs/XML/RPC/Dump.php index 84eaa20..d1844f0 100644 --- a/bundled-libs/XML/RPC/Dump.php +++ b/bundled-libs/XML/RPC/Dump.php @@ -42,7 +42,7 @@ function XML_RPC_Dump($value) * @category Web Services * @package XML_RPC * @author Christian Weiske - * @version Release: 1.3.3 + * @version Release: 1.4.0 * @link http://pear.php.net/package/XML_RPC */ class XML_RPC_Dump diff --git a/bundled-libs/XML/RPC/Server.php b/bundled-libs/XML/RPC/Server.php index 5752c23..90831a1 100644 --- a/bundled-libs/XML/RPC/Server.php +++ b/bundled-libs/XML/RPC/Server.php @@ -32,7 +32,7 @@ * @author Martin Jansen * @author Daniel Convissor * @copyright 1999-2001 Edd Dumbill, 2001-2005 The PHP Group - * @version CVS: $Id: Server.php,v 1.28 2005/07/07 01:21:29 danielc Exp $ + * @version CVS: $Id: Server.php,v 1.29 2005/08/14 20:25:35 danielc Exp $ * @link http://pear.php.net/package/XML_RPC */ @@ -213,7 +213,7 @@ function XML_RPC_Server_methodHelp($server, $m) $dmap = $server->dmap; $sysCall = 0; } - // print "\n"; + if (isset($dmap[$methName])) { if ($dmap[$methName]['docstring']) { $r = new XML_RPC_Response(new XML_RPC_Value($dmap[$methName]['docstring']), @@ -269,7 +269,7 @@ function XML_RPC_Server_debugmsg($m) * @author Martin Jansen * @author Daniel Convissor * @copyright 1999-2001 Edd Dumbill, 2001-2005 The PHP Group - * @version Release: 1.3.3 + * @version Release: 1.4.0 * @link http://pear.php.net/package/XML_RPC */ class XML_RPC_Server @@ -504,11 +504,12 @@ class XML_RPC_Server $parser = (int) $parser_resource; $XML_RPC_xh[$parser] = array(); - $XML_RPC_xh[$parser]['st'] = ''; $XML_RPC_xh[$parser]['cm'] = 0; $XML_RPC_xh[$parser]['isf'] = 0; $XML_RPC_xh[$parser]['params'] = array(); $XML_RPC_xh[$parser]['method'] = ''; + $XML_RPC_xh[$parser]['stack'] = array(); + $XML_RPC_xh[$parser]['valuestack'] = array(); $plist = ''; @@ -525,14 +526,21 @@ class XML_RPC_Server xml_error_string(xml_get_error_code($parser_resource)), xml_get_current_line_number($parser_resource))); xml_parser_free($parser_resource); + } elseif ($XML_RPC_xh[$parser]['isf']>1) { + $r = new XML_RPC_Response(0, + $XML_RPC_err['invalid_request'], + $XML_RPC_str['invalid_request'] + . ': ' + . $XML_RPC_xh[$parser]['isf_reason']); + xml_parser_free($parser_resource); } else { xml_parser_free($parser_resource); $m = new XML_RPC_Message($XML_RPC_xh[$parser]['method']); // now add parameters in for ($i = 0; $i < sizeof($XML_RPC_xh[$parser]['params']); $i++) { // print '\n"; - $plist .= "$i - " . $XML_RPC_xh[$parser]['params'][$i] . " \n"; - @eval('$m->addParam(' . $XML_RPC_xh[$parser]['params'][$i] . ');'); + $plist .= "$i - " . var_export($XML_RPC_xh[$parser]['params'][$i], true) . " \n"; + $m->addParam($XML_RPC_xh[$parser]['params'][$i]); } XML_RPC_Server_debugmsg($plist); -- 2.39.5