<?php // -*-c++-*-\r
// by Edd Dumbill (C) 1999-2002\r
// <edd@usefulinc.com>\r
-// $Id: xmlrpc.inc.php,v 1.4.2.2 2005-07-03 05:16:44 kimitake Exp $\r
-// $NucleusJP: xmlrpc.inc.php,v 1.4.2.1 2005/06/30 21:23:01 kimitake Exp $\r
+// $Id: xmlrpc.inc.php,v 1.4.2.3 2005-08-16 05:25:58 kimitake Exp $\r
+// $NucleusJP: xmlrpc.inc.php,v 1.4.2.2 2005/07/03 05:16:44 kimitake Exp $\r
\r
// Copyright (c) 1999,2000,2002 Edd Dumbill.\r
// All rights reserved.\r
global $xmlrpcI4;\r
global $xmlrpcInt;\r
global $xmlrpcDouble;\r
+ global $xmlrpcBoolean;\r
global $xmlrpcString;\r
global $xmlrpcDateTime;\r
global $xmlrpcBase64;\r
$xmlrpcStruct => 3\r
);\r
\r
+ $xmlrpc_valid_parents = array(\r
+ 'BOOLEAN' => array('VALUE'),\r
+ 'I4' => array('VALUE'),\r
+ 'INT' => array('VALUE'),\r
+ 'STRING' => array('VALUE'),\r
+ 'DOUBLE' => array('VALUE'),\r
+ 'DATETIME.ISO8601' => array('VALUE'),\r
+ 'BASE64' => array('VALUE'),\r
+ 'ARRAY' => array('VALUE'),\r
+ 'STRUCT' => array('VALUE'),\r
+ 'PARAM' => array('PARAMS'),\r
+ 'METHODNAME' => array('METHODCALL'), \r
+ 'PARAMS' => array('METHODCALL', 'METHODRESPONSE'),\r
+ 'MEMBER' => array('STRUCT'),\r
+ 'NAME' => array('MEMBER'),\r
+ 'DATA' => array('ARRAY'),\r
+ 'FAULT' => array('METHODRESPONSE'),\r
+ 'VALUE' => array('MEMBER', 'DATA', 'PARAM', 'FAULT'),\r
+ );\r
+\r
$xmlEntities=array(\r
'amp' => '&',\r
'quot' => '"',\r
$xmlrpcstr['no_ssl']='No SSL support compiled in.';\r
$xmlrpcerr['curl_fail']=8;\r
$xmlrpcstr['curl_fail']='CURL error';\r
-\r
+ $xmlrpcerr['invalid_request']=15;\r
+ $xmlrpcstr['invalid_request']='Invalid request payload';\r
\r
$xmlrpcerr['multicall_notstruct'] = 9;\r
$xmlrpcstr['multicall_notstruct'] = 'system.multicall expected struct';\r
$xmlrpc_internalencoding='ISO-8859-1';\r
\r
$xmlrpcName='XML-RPC for PHP';\r
- $xmlrpcVersion='1.1.1';\r
+ $xmlrpcVersion='1.2';\r
\r
// let user errors start at 800\r
$xmlrpcerruser=800;\r
\r
// used to store state during parsing\r
// quick explanation of components:\r
- // st - used to build up a string for evaluation\r
// ac - used to accumulate values\r
- // qt - used to decide if quotes are needed for evaluation\r
- // cm - used to denote struct or array (comma needed)\r
// isf - used to indicate a fault\r
// lv - used to indicate "looking for a value": implements\r
// the logic to allow values with no types to be strings\r
// params - used to store parameters in method calls\r
// method - used to store method name\r
+ // stack - array with genealogy of xml elements names:\r
+ // used to validate nesting of xmlrpc elements\r
\r
$_xh=array();\r
\r
\r
function xmlrpc_se($parser, $name, $attrs)\r
{\r
- global $_xh, $xmlrpcDateTime, $xmlrpcString;\r
+ global $_xh, $xmlrpcDateTime, $xmlrpcString, $xmlrpc_valid_parents;\r
+\r
+ // if invalid xmlrpc already detected, skip all processing\r
+ if ($_xh[$parser]['isf'] < 2)\r
+ {\r
+\r
+ // check for correct element nesting\r
+ // top level element can only be of 2 types\r
+ if (count($_xh[$parser]['stack']) == 0)\r
+ {\r
+ if ($name != 'METHODRESPONSE' && $name != 'METHODCALL')\r
+ {\r
+ $_xh[$parser]['isf'] = 2;\r
+ $_xh[$parser]['isf_reason'] = 'missing top level xmlrpc element';\r
+ return;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ // not top level element: see if parent is OK\r
+ if (!in_array($_xh[$parser]['stack'][0], $xmlrpc_valid_parents[$name]))\r
+ {\r
+ $_xh[$parser]['isf'] = 2;\r
+ $_xh[$parser]['isf_reason'] = "xmlrpc element $name cannot be child of {$_xh[$parser]['stack'][0]}";\r
+ return;\r
+ }\r
+ }\r
\r
switch($name)\r
{\r
case 'STRUCT':\r
case 'ARRAY':\r
- $_xh[$parser]['st'].='array(';\r
- $_xh[$parser]['cm']++;\r
+ //$_xh[$parser]['st'].='array(';\r
+ //$_xh[$parser]['cm']++;\r
// this last line turns quoting off\r
// this means if we get an empty array we'll\r
// simply get a bit of whitespace in the eval\r
- $_xh[$parser]['qt']=0;\r
+ //$_xh[$parser]['qt']=0;\r
+\r
+ // create an empty array to hold child values, and push it onto appropriate stack\r
+ $cur_val = array();\r
+ $cur_val['values'] = array();\r
+ $cur_val['type'] = $name;\r
+ array_unshift($_xh[$parser]['valuestack'], $cur_val);\r
break;\r
+ case 'METHODNAME':\r
case 'NAME':\r
- $_xh[$parser]['st'].='"';\r
+ //$_xh[$parser]['st'].='"';\r
$_xh[$parser]['ac']='';\r
break;\r
case 'FAULT':\r
$_xh[$parser]['isf']=1;\r
break;\r
case 'PARAM':\r
- $_xh[$parser]['st']='';\r
+ //$_xh[$parser]['st']='';\r
+ // clear value, so we can check later if no value will passed for this param/member\r
+ $_xh[$parser]['value']=null;\r
break;\r
case 'VALUE':\r
- $_xh[$parser]['st'].='new xmlrpcval(';\r
- $_xh[$parser]['vt']=$xmlrpcString;\r
+ //$_xh[$parser]['st'].='new xmlrpcval(';\r
+ // look for a value: if this is still true by the\r
+ // time we reach the end tag for value then the type is string\r
+ // by implication\r
+ $_xh[$parser]['vt']='value';\r
$_xh[$parser]['ac']='';\r
- $_xh[$parser]['qt']=0;\r
+ //$_xh[$parser]['qt']=0;\r
$_xh[$parser]['lv']=1;\r
- // look for a value: if this is still 1 by the\r
- // time we reach the first data segment then the type is string\r
- // by implication and we need to add in a quote\r
break;\r
case 'I4':\r
case 'INT':\r
case 'DOUBLE':\r
case 'DATETIME.ISO8601':\r
case 'BASE64':\r
- $_xh[$parser]['ac']=''; // reset the accumulator\r
+ if ($_xh[$parser]['vt']!='value')\r
+ {\r
+ //two data elements inside a value: an error occurred!\r
+ $_xh[$parser]['isf'] = 2;\r
+ $_xh[$parser]['isf_reason'] = "$name element following a {$_xh[$parser]['vt']} element inside a single value";\r
+ return;\r
+ }\r
+\r
+ // reset the accumulator\r
+ $_xh[$parser]['ac']='';\r
\r
- if ($name=='DATETIME.ISO8601' || $name=='STRING')\r
+ /*if ($name=='DATETIME.ISO8601' || $name=='STRING')\r
{\r
$_xh[$parser]['qt']=1;\r
if ($name=='DATETIME.ISO8601')\r
// at the end of the element we must check\r
// for data format errors.\r
$_xh[$parser]['qt']=0;\r
- }\r
+ }*/\r
break;\r
case 'MEMBER':\r
- $_xh[$parser]['ac']='';\r
+ //$_xh[$parser]['ac']='';\r
+ // avoid warnings later on if no NAME is found before VALUE inside\r
+ // a struct member predefining member name as NULL\r
+ $_xh[$parser]['valuestack'][0]['name'] = '';\r
+ // clear value, so we can check later if no value will passed for this param/member\r
+ $_xh[$parser]['value']=null;\r
+ break;\r
+ case 'DATA':\r
+ case 'METHODCALL':\r
+ case 'METHODRESPONSE':\r
+ case 'PARAMS':\r
+ // valid elements that add little to processing\r
break;\r
default:\r
+ /// INVALID ELEMENT: RAISE ISF so that it is later recognized!!!\r
+ $_xh[$parser]['isf'] = 2;\r
+ $_xh[$parser]['isf_reason'] = "found not-xmlrpc xml element $name";\r
break;\r
}\r
\r
+ // Save current element name to stack, to validate nesting\r
+ array_unshift($_xh[$parser]['stack'], $name);\r
+\r
if ($name!='VALUE')\r
{\r
$_xh[$parser]['lv']=0;\r
}\r
}\r
+ }\r
\r
function xmlrpc_ee($parser, $name)\r
{\r
- global $_xh,$xmlrpcTypes,$xmlrpcString;\r
+ global $_xh,$xmlrpcTypes,$xmlrpcString,$xmlrpcDateTime;\r
+\r
+ if ($_xh[$parser]['isf'] < 2)\r
+ {\r
+\r
+ // push this element name from stack\r
+ // NB: if XML validates, correct opening/closing is guaranteed and\r
+ // we do not have to check for $name == $curr_elem.\r
+ // we also checked for proper nesting at start of elements...\r
+ $curr_elem = array_shift($_xh[$parser]['stack']); \r
\r
switch($name)\r
{\r
case 'STRUCT':\r
case 'ARRAY':\r
- if ($_xh[$parser]['cm'] && substr($_xh[$parser]['st'], -1) ==',')\r
- {\r
- $_xh[$parser]['st']=substr($_xh[$parser]['st'],0,-1);\r
- }\r
- $_xh[$parser]['st'].=')';\r
+ //if ($_xh[$parser]['cm'] && substr($_xh[$parser]['st'], -1) ==',')\r
+ //{\r
+ // $_xh[$parser]['st']=substr($_xh[$parser]['st'],0,-1);\r
+ //}\r
+ //$_xh[$parser]['st'].=')';\r
+\r
+ // fetch out of stack array of values, and promote it to current value\r
+ $cur_val = array_shift($_xh[$parser]['valuestack']);\r
+ $_xh[$parser]['value'] = $cur_val['values'];\r
+\r
$_xh[$parser]['vt']=strtolower($name);\r
- $_xh[$parser]['cm']--;\r
+ //$_xh[$parser]['cm']--;\r
break;\r
case 'NAME':\r
- $_xh[$parser]['st'].= $_xh[$parser]['ac'] . '" => ';\r
+ //$_xh[$parser]['st'].= $_xh[$parser]['ac'] . '" => ';\r
+ $_xh[$parser]['valuestack'][0]['name'] = $_xh[$parser]['ac'];\r
break;\r
case 'BOOLEAN':\r
- // special case here: we translate boolean 1 or 0 into PHP\r
- // constants true or false\r
- // NB: this simple checks helps a lot sanitizing input, ie no\r
- // security problems around here\r
- if ($_xh[$parser]['ac']=='1')\r
- {\r
- $_xh[$parser]['ac']='true';\r
- }\r
- else\r
- {\r
- $_xh[$parser]['ac']='false';\r
- }\r
- $_xh[$parser]['vt']=strtolower($name);\r
- // Drop through intentionally.\r
case 'I4':\r
case 'INT':\r
case 'STRING':\r
case 'DOUBLE':\r
case 'DATETIME.ISO8601':\r
case 'BASE64':\r
- if ($_xh[$parser]['qt']==1)\r
+ $_xh[$parser]['vt']=strtolower($name);\r
+ //if ($_xh[$parser]['qt']==1) \r
+ if ($name=='STRING')\r
{\r
// we use double quotes rather than single so backslashification works OK\r
- $_xh[$parser]['st'].='"'. $_xh[$parser]['ac'] . '"';\r
+ //$_xh[$parser]['st'].='"'. $_xh[$parser]['ac'] . '"';\r
+ $_xh[$parser]['value']=$_xh[$parser]['ac'];\r
+ }\r
+ elseif ($name=='DATETIME.ISO8601')\r
+ {\r
+ $_xh[$parser]['vt']=$xmlrpcDateTime;\r
+ $_xh[$parser]['value']=$_xh[$parser]['ac'];\r
}\r
- elseif ($_xh[$parser]['qt']==2)\r
+ elseif ($name=='BASE64')\r
{\r
- $_xh[$parser]['st'].='base64_decode("'. $_xh[$parser]['ac'] . '")';\r
+ //$_xh[$parser]['st'].='base64_decode("'. $_xh[$parser]['ac'] . '")';\r
+\r
+ ///@todo check for failure of base64 decoding / catch warnings\r
+ $_xh[$parser]['value']=base64_decode($_xh[$parser]['ac']);\r
}\r
elseif ($name=='BOOLEAN')\r
{\r
- $_xh[$parser]['st'].=$_xh[$parser]['ac'];\r
+ // special case here: we translate boolean 1 or 0 into PHP\r
+ // constants true or false\r
+ // NB: this simple checks helps a lot sanitizing input, ie no\r
+ // security problems around here\r
+ if ($_xh[$parser]['ac']=='1')\r
+ {\r
+ //$_xh[$parser]['ac']='true'; \r
+ $_xh[$parser]['value']=true;\r
+ }\r
+ else\r
+ {\r
+ //$_xh[$parser]['ac']='false';\r
+ // log if receiveing something strange, even though we set the value to false anyway\r
+ if ($_xh[$parser]['ac']!='0')\r
+ error_log('XML-RPC: invalid value received in BOOLEAN: '.$_xh[$parser]['ac']);\r
+ $_xh[$parser]['value']=false;\r
+ }\r
+ //$_xh[$parser]['st'].=$_xh[$parser]['ac'];\r
}\r
elseif ($name=='DOUBLE')\r
{\r
// TODO: find a better way of throwing an error\r
// than this!\r
error_log('XML-RPC: non numeric value received in DOUBLE: '.$_xh[$parser]['ac']);\r
- $_xh[$parser]['st'].="'ERROR_NON_NUMERIC_FOUND'";\r
+ //$_xh[$parser]['st'].="'ERROR_NON_NUMERIC_FOUND'";\r
+ $_xh[$parser]['value']='ERROR_NON_NUMERIC_FOUND';\r
}\r
else\r
{\r
// it's ok, add it on\r
- $_xh[$parser]['st'].=(double)$_xh[$parser]['ac'];\r
+ //$_xh[$parser]['st'].=(double)$_xh[$parser]['ac'];\r
+ $_xh[$parser]['value']=(double)$_xh[$parser]['ac'];\r
}\r
}\r
else\r
// TODO: find a better way of throwing an error\r
// than this!\r
error_log('XML-RPC: non numeric value received in INT: '.$_xh[$parser]['ac']);\r
- $_xh[$parser]['st'].="'ERROR_NON_NUMERIC_FOUND'";\r
+ //$_xh[$parser]['st'].="'ERROR_NON_NUMERIC_FOUND'";\r
+ $_xh[$parser]['value']='ERROR_NON_NUMERIC_FOUND';\r
}\r
else\r
{\r
// it's ok, add it on\r
- $_xh[$parser]['st'].=(int)$_xh[$parser]['ac'];\r
+ //$_xh[$parser]['st'].=(int)$_xh[$parser]['ac'];\r
+ $_xh[$parser]['value']=(int)$_xh[$parser]['ac'];\r
}\r
}\r
$_xh[$parser]['ac']='';\r
- $_xh[$parser]['qt']=0;\r
+ //$_xh[$parser]['qt']=0;\r
$_xh[$parser]['lv']=3; // indicate we've found a value\r
break;\r
case 'VALUE':\r
- // deal with a string value\r
- if (strlen($_xh[$parser]['ac'])>0 &&\r
+ // This if() detects if no scalar was inside <VALUE></VALUE>\r
+ if ($_xh[$parser]['vt']=='value')\r
+ {\r
+ $_xh[$parser]['value']=$_xh[$parser]['ac'];\r
+ $_xh[$parser]['vt']=$xmlrpcString;\r
+ }\r
+ /*if (strlen($_xh[$parser]['ac'])>0 &&\r
$_xh[$parser]['vt']==$xmlrpcString)\r
{\r
$_xh[$parser]['st'].='"'. $_xh[$parser]['ac'] . '"';\r
if ($_xh[$parser]['cm'])\r
{\r
$_xh[$parser]['st'].=',';\r
+ }*/\r
+\r
+ // build the xmlrpc val out of the data received, and substitute it\r
+ $temp = new xmlrpcval($_xh[$parser]['value'], $_xh[$parser]['vt']);\r
+ // check if we are inside an array or struct:\r
+ // if value just built is inside an array, let's move it into array on the stack\r
+ if (count($_xh[$parser]['valuestack']) && $_xh[$parser]['valuestack'][0]['type']=='ARRAY')\r
+ {\r
+ $_xh[$parser]['valuestack'][0]['values'][] = $temp;\r
+ }\r
+ else\r
+ {\r
+ $_xh[$parser]['value'] = $temp;\r
}\r
break;\r
case 'MEMBER':\r
$_xh[$parser]['ac']='';\r
- $_xh[$parser]['qt']=0;\r
+ //$_xh[$parser]['qt']=0;\r
+ // add to array in the stack the last element built\r
+ // unless no VALUE was found\r
+ if ($_xh[$parser]['value'])\r
+ $_xh[$parser]['valuestack'][0]['values'][$_xh[$parser]['valuestack'][0]['name']] = $_xh[$parser]['value'];\r
+ else\r
+ error_log('XML-RPC: missing VALUE inside STRUCT in received xml');\r
break;\r
case 'DATA':\r
$_xh[$parser]['ac']='';\r
- $_xh[$parser]['qt']=0;\r
+ //$_xh[$parser]['qt']=0;\r
break;\r
case 'PARAM':\r
- $_xh[$parser]['params'][]=$_xh[$parser]['st'];\r
+ //$_xh[$parser]['params'][]=$_xh[$parser]['st'];\r
+ if ($_xh[$parser]['value'])\r
+ $_xh[$parser]['params'][]=$_xh[$parser]['value'];\r
+ else\r
+ error_log('XML-RPC: missing VALUE inside PARAM in received xml');\r
break;\r
case 'METHODNAME':\r
$_xh[$parser]['method']=ereg_replace("^[\n\r\t ]+", '', $_xh[$parser]['ac']);\r
break;\r
- // BOOLEAN HAS BEEN ENUMERATED ABOVE!\r
- /*case 'BOOLEAN':\r
- // special case here: we translate boolean 1 or 0 into PHP\r
- // constants true or false\r
- if ($_xh[$parser]['ac']=='1')\r
- {\r
- $_xh[$parser]['ac']='true';\r
- }\r
- else\r
- {\r
- $_xh[$parser]['ac']='false';\r
- $_xh[$parser]['vt']=strtolower($name);\r
- }\r
- break;*/\r
+ case 'PARAMS':\r
+ case 'FAULT':\r
+ case 'METHODCALL':\r
+ case 'METHORESPONSE':\r
+ break;\r
default:\r
+ // End of INVALID ELEMENT!\r
+ // shall we add an assert here for unreachable code???\r
break;\r
}\r
// if it's a valid type name, set the type\r
- if (isset($xmlrpcTypes[strtolower($name)]))\r
+ /*if (isset($xmlrpcTypes[strtolower($name)]))\r
{\r
$_xh[$parser]['vt']=strtolower($name);\r
+ }*/\r
+\r
}\r
}\r
\r
//if (ereg("^[\n\r \t]+$", $data)) return;\r
// print "adding [${data}]\n";\r
\r
+ // skip processing if xml fault already detected\r
+ if ($_xh[$parser]['isf'] < 2)\r
+ {\r
if ($_xh[$parser]['lv']!=3)\r
{\r
// "lookforvalue==3" means that we've found an entire value\r
{\r
// if we've found text and we're just in a <value> then\r
// turn quoting on, as this will be a string\r
- $_xh[$parser]['qt']=1;\r
+ //$_xh[$parser]['qt']=1;\r
// and say we've found a value\r
$_xh[$parser]['lv']=2;\r
}\r
{\r
$_xh[$parser]['ac'] = '';\r
}\r
- $_xh[$parser]['ac'].=str_replace('$', '\$', str_replace('"', '\"', str_replace(chr(92),$xmlrpc_backslash, $data)));\r
+ //$_xh[$parser]['ac'].=str_replace('$', '\$', str_replace('"', '\"', str_replace(chr(92),$xmlrpc_backslash, $data)));\r
+ $_xh[$parser]['ac'].=$data;\r
+ }\r
}\r
}\r
\r
function xmlrpc_dh($parser, $data)\r
{\r
global $_xh, $xmlrpc_backslash;\r
+\r
+ // skip processing if xml fault already detected\r
+ if ($parser[$_xh]['isf'] < 2)\r
+ {\r
if (substr($data, 0, 1) == '&' && substr($data, -1, 1) == ';')\r
{\r
if ($_xh[$parser]['lv']==1)\r
{\r
- $_xh[$parser]['qt']=1;\r
+ //$_xh[$parser]['qt']=1;\r
$_xh[$parser]['lv']=2;\r
}\r
- $_xh[$parser]['ac'].=str_replace('$', '\$', str_replace('"', '\"', str_replace(chr(92),$xmlrpc_backslash, $data)));\r
+ //$_xh[$parser]['ac'].=str_replace('$', '\$', str_replace('"', '\"', str_replace(chr(92),$xmlrpc_backslash, $data)));\r
+ $_xh[$parser]['ac'].=$data;\r
+ }\r
}\r
}\r
\r
\r
function serialize()\r
{\r
- global $xmlrpc_defencoding;\r
$result = "<methodResponse>\n";\r
if ($this->errno)\r
{\r
</member>\r
<member>\r
<name>faultString</name>\r
-<value><string>' . mb_convert_encoding(xmlrpc_encode_entitites($this->errstr), $xmlrpc_defencoding, _CHARSET) . '</string></value>\r
+<value><string>' . xmlrpc_encode_entitites($this->errstr) . '</string></value>\r
</member>\r
</struct>\r
</value>\r
$_xh=array();\r
$_xh[$parser]=array();\r
$_xh[$parser]['headers'] = array();\r
+ $_xh[$parser]['stack'] = array();\r
+ $_xh[$parser]['valuestack'] = array();\r
\r
// separate HTTP headers from data\r
if (ereg("^HTTP", $data))\r
if ($bd)\r
$data = substr($data, 0, $bd);\r
\r
- $_xh[$parser]['st']='';\r
- $_xh[$parser]['cm']=0;\r
+ //$_xh[$parser]['st']='';\r
+ //$_xh[$parser]['cm']=0;\r
$_xh[$parser]['isf']=0;\r
+ $_xh[$parser]['isf_reason']=0;\r
$_xh[$parser]['ac']='';\r
- $_xh[$parser]['qt']='';\r
+ //$_xh[$parser]['qt']='';\r
\r
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);\r
// G. Giunta 2005/02/13: PHP internally uses ISO-8859-1, so we have to tell\r
return $r;\r
}\r
xml_parser_free($parser);\r
+\r
+ if ($_xh[$parser]['isf'] > 1)\r
+ {\r
if ($this->debug)\r
{\r
- print "<PRE>---EVALING---[" .\r
- strlen($_xh[$parser]['st']) . " chars]---\n" .\r
- htmlspecialchars($_xh[$parser]['st']) . ";\n---END---</PRE>";\r
+ ///@todo echo something for user?\r
+ }\r
+\r
+ $r = new xmlrpcresp(0, $xmlrpcerr['invalid_return'],\r
+ $xmlrpcstr['invalid_return'] . ' ' . $_xh[$parser]['isf_reason']);\r
}\r
- if (strlen($_xh[$parser]['st'])==0)\r
+ //else if (strlen($_xh[$parser]['st'])==0)\r
+ else if (!is_object($_xh[$parser]['value']))\r
{\r
// then something odd has happened\r
// and it's time to generate a client side error\r
}\r
else\r
{\r
- $allOK=0;\r
- @eval('$v=' . $_xh[$parser]['st'] . '; $allOK=1;');\r
- if (!$allOK)\r
+\r
+ if ($this->debug)\r
{\r
- $r = new xmlrpcresp(0, $xmlrpcerr['invalid_return'], $xmlrpcstr['invalid_return']);\r
+ //print "<PRE>---EVALING---[" .\r
+ //strlen($_xh[$parser]['st']) . " chars]---\n" .\r
+ //htmlspecialchars($_xh[$parser]['st']) . ";\n---END---</PRE>";\r
+ print "<PRE>---PARSED---\n" ;\r
+ var_dump($_xh[$parser]['value']);\r
+ print "\n---END---</PRE>";\r
}\r
- else\r
+\r
+ //$allOK=0;\r
+ //@eval('$v=' . $_xh[$parser]['st'] . '; $allOK=1;');\r
+ //if (!$allOK)\r
+ //{\r
+ // $r = new xmlrpcresp(0, $xmlrpcerr['invalid_return'], $xmlrpcstr['invalid_return']);\r
+ //}\r
+ //else\r
+ $v = $_xh[$parser]['value'];\r
if ($_xh[$parser]['isf'])\r
{\r
$errno_v = $v->structmem('faultCode');\r
\r
function addScalar($val, $type='string')\r
{\r
- global $xmlrpcTypes, $xmlrpcBoolean, $xmlrpc_defencoding;\r
+ global $xmlrpcTypes, $xmlrpcBoolean;\r
\r
if ($this->mytype==1)\r
{\r
{\r
$rs='';\r
global $xmlrpcTypes, $xmlrpcBase64, $xmlrpcString,\r
- $xmlrpcBoolean, $xmlrpc_defencoding;\r
+ $xmlrpcBoolean;\r
switch(@$xmlrpcTypes[$typ])\r
{\r
case 3:\r
// $rs.="<${typ}>" . htmlentities($val). "</${typ}>";\r
\r
// N. Leenheer 2005/6/30: Use CDATA instead... \r
- $rs.="<${typ}><![CDATA[" . mb_convert_encoding($val, $xmlrpc_defencoding, _CHARSET). "]]></${typ}>";\r
+ $rs.="<${typ}><![CDATA[" . $val. "]]></${typ}>";\r
break;\r
default:\r
$rs.="<${typ}>${val}</${typ}>";\r
@reset($t);\r
while(list($id,$cont) = @each($t))\r
{\r
- eval('$b->'.$id.' = $cont;');\r
+ //eval('$b->'.$id.' = $cont;');\r
+ @$b->$id = $cont;\r
}\r
}\r
// end contrib\r
<?php\r
// by Edd Dumbill (C) 1999-2002\r
// <edd@usefulinc.com>\r
-// $Id: xmlrpcs.inc.php,v 1.4.2.1 2005-06-30 21:23:01 kimitake Exp $\r
-// $NucleusJP$\r
+// $Id: xmlrpcs.inc.php,v 1.4.2.2 2005-08-16 05:25:58 kimitake Exp $\r
+// $NucleusJP: xmlrpcs.inc.php,v 1.4.2.1 2005/06/30 21:23:01 kimitake Exp $\r
\r
// Copyright (c) 1999,2000,2002 Edd Dumbill.\r
// All rights reserved.\r
$parser = xml_parser_create($xmlrpc_defencoding);\r
\r
$_xh[$parser]=array();\r
- $_xh[$parser]['st']='';\r
- $_xh[$parser]['cm']=0;\r
+ //$_xh[$parser]['st']='';\r
+ //$_xh[$parser]['cm']=0;\r
$_xh[$parser]['isf']=0;\r
+ $_xh[$parser]['isf_reason']='';\r
$_xh[$parser]['params']=array();\r
+ $_xh[$parser]['stack']=array();\r
+ $_xh[$parser]['valuestack'] = array();\r
$_xh[$parser]['method']='';\r
\r
// decompose incoming XML into request structure\r
xml_parser_free($parser);\r
}\r
else\r
+ if ($_xh[$parser]['isf'])\r
{\r
xml_parser_free($parser);\r
+ $r=new xmlrpcresp(0,\r
+ $xmlrpcerr['invalid_request'],\r
+ $xmlrpcstr['invalid_request'] . ' ' . $_xh[$parser]['isf_reason']);\r
+ }\r
+ else\r
+ {\r
+ xml_parser_free($parser);\r
+\r
$m=new xmlrpcmsg($_xh[$parser]['method']);\r
// now add parameters in\r
$plist='';\r
- $allOK = 1;\r
+ //$allOK = 1;\r
for($i=0; $i<sizeof($_xh[$parser]['params']); $i++)\r
{\r
//print "<!-- " . $_xh[$parser]['params'][$i]. "-->\n";\r
$plist.="$i - " . $_xh[$parser]['params'][$i]. ";\n";\r
- $allOK = 0;\r
- @eval('$m->addParam(' . $_xh[$parser]['params'][$i]. '); $allOK=1;');\r
- if (!$allOK)\r
- {\r
- break;\r
- }\r
+ //$allOK = 0;\r
+ //@eval('$m->addParam(' . $_xh[$parser]['params'][$i]. '); $allOK=1;');\r
+ @$m->addParam($_xh[$parser]['params'][$i]);\r
+ //if (!$allOK)\r
+ //{\r
+ // break;\r
+ //}\r
}\r
// uncomment this to really see what the server's getting!\r
// xmlrpc_debugmsg($plist);\r
- if (!$allOK)\r
- {\r
- $r = new xmlrpcresp(0,\r
- $xmlrpcerr['incorrect_params'],\r
- $xmlrpcstr['incorrect_params'] . ": xml error in param " . $i);\r
- }\r
- else\r
- {\r
+ //if (!$allOK)\r
+ //{\r
+ // $r = new xmlrpcresp(0,\r
+ // $xmlrpcerr['incorrect_params'],\r
+ // $xmlrpcstr['incorrect_params'] . ": xml error in param " . $i);\r
+ //}\r
+ //else\r
+ //{\r
$r = $this->execute($m);\r
- }\r
+ //}\r
}\r
return $r;\r
}\r
<?php // -*-c++-*-\r
// by Edd Dumbill (C) 1999-2002\r
// <edd@usefulinc.com>\r
-// $Id: xmlrpc.inc.php,v 1.4.4.1 2005-06-30 21:19:18 kimitake Exp $\r
-// $NucleusJP$\r
+// $Id: xmlrpc.inc.php,v 1.4.4.2 2005-08-16 05:26:18 kimitake Exp $\r
+// $NucleusJP: xmlrpc.inc.php,v 1.4.2.2 2005/07/03 05:16:44 kimitake Exp $\r
\r
// Copyright (c) 1999,2000,2002 Edd Dumbill.\r
// All rights reserved.\r
global $xmlrpcI4;\r
global $xmlrpcInt;\r
global $xmlrpcDouble;\r
+ global $xmlrpcBoolean;\r
global $xmlrpcString;\r
global $xmlrpcDateTime;\r
global $xmlrpcBase64;\r
$xmlrpcStruct => 3\r
);\r
\r
+ $xmlrpc_valid_parents = array(\r
+ 'BOOLEAN' => array('VALUE'),\r
+ 'I4' => array('VALUE'),\r
+ 'INT' => array('VALUE'),\r
+ 'STRING' => array('VALUE'),\r
+ 'DOUBLE' => array('VALUE'),\r
+ 'DATETIME.ISO8601' => array('VALUE'),\r
+ 'BASE64' => array('VALUE'),\r
+ 'ARRAY' => array('VALUE'),\r
+ 'STRUCT' => array('VALUE'),\r
+ 'PARAM' => array('PARAMS'),\r
+ 'METHODNAME' => array('METHODCALL'), \r
+ 'PARAMS' => array('METHODCALL', 'METHODRESPONSE'),\r
+ 'MEMBER' => array('STRUCT'),\r
+ 'NAME' => array('MEMBER'),\r
+ 'DATA' => array('ARRAY'),\r
+ 'FAULT' => array('METHODRESPONSE'),\r
+ 'VALUE' => array('MEMBER', 'DATA', 'PARAM', 'FAULT'),\r
+ );\r
+\r
$xmlEntities=array(\r
'amp' => '&',\r
'quot' => '"',\r
$xmlrpcstr['no_ssl']='No SSL support compiled in.';\r
$xmlrpcerr['curl_fail']=8;\r
$xmlrpcstr['curl_fail']='CURL error';\r
-\r
+ $xmlrpcerr['invalid_request']=15;\r
+ $xmlrpcstr['invalid_request']='Invalid request payload';\r
\r
$xmlrpcerr['multicall_notstruct'] = 9;\r
$xmlrpcstr['multicall_notstruct'] = 'system.multicall expected struct';\r
$xmlrpc_internalencoding='ISO-8859-1';\r
\r
$xmlrpcName='XML-RPC for PHP';\r
- $xmlrpcVersion='1.1.1';\r
+ $xmlrpcVersion='1.2';\r
\r
// let user errors start at 800\r
$xmlrpcerruser=800;\r
\r
// used to store state during parsing\r
// quick explanation of components:\r
- // st - used to build up a string for evaluation\r
// ac - used to accumulate values\r
- // qt - used to decide if quotes are needed for evaluation\r
- // cm - used to denote struct or array (comma needed)\r
// isf - used to indicate a fault\r
// lv - used to indicate "looking for a value": implements\r
// the logic to allow values with no types to be strings\r
// params - used to store parameters in method calls\r
// method - used to store method name\r
+ // stack - array with genealogy of xml elements names:\r
+ // used to validate nesting of xmlrpc elements\r
\r
$_xh=array();\r
\r
\r
function xmlrpc_se($parser, $name, $attrs)\r
{\r
- global $_xh, $xmlrpcDateTime, $xmlrpcString;\r
+ global $_xh, $xmlrpcDateTime, $xmlrpcString, $xmlrpc_valid_parents;\r
+\r
+ // if invalid xmlrpc already detected, skip all processing\r
+ if ($_xh[$parser]['isf'] < 2)\r
+ {\r
+\r
+ // check for correct element nesting\r
+ // top level element can only be of 2 types\r
+ if (count($_xh[$parser]['stack']) == 0)\r
+ {\r
+ if ($name != 'METHODRESPONSE' && $name != 'METHODCALL')\r
+ {\r
+ $_xh[$parser]['isf'] = 2;\r
+ $_xh[$parser]['isf_reason'] = 'missing top level xmlrpc element';\r
+ return;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ // not top level element: see if parent is OK\r
+ if (!in_array($_xh[$parser]['stack'][0], $xmlrpc_valid_parents[$name]))\r
+ {\r
+ $_xh[$parser]['isf'] = 2;\r
+ $_xh[$parser]['isf_reason'] = "xmlrpc element $name cannot be child of {$_xh[$parser]['stack'][0]}";\r
+ return;\r
+ }\r
+ }\r
\r
switch($name)\r
{\r
case 'STRUCT':\r
case 'ARRAY':\r
- $_xh[$parser]['st'].='array(';\r
- $_xh[$parser]['cm']++;\r
+ //$_xh[$parser]['st'].='array(';\r
+ //$_xh[$parser]['cm']++;\r
// this last line turns quoting off\r
// this means if we get an empty array we'll\r
// simply get a bit of whitespace in the eval\r
- $_xh[$parser]['qt']=0;\r
+ //$_xh[$parser]['qt']=0;\r
+\r
+ // create an empty array to hold child values, and push it onto appropriate stack\r
+ $cur_val = array();\r
+ $cur_val['values'] = array();\r
+ $cur_val['type'] = $name;\r
+ array_unshift($_xh[$parser]['valuestack'], $cur_val);\r
break;\r
+ case 'METHODNAME':\r
case 'NAME':\r
- $_xh[$parser]['st'].='"';\r
+ //$_xh[$parser]['st'].='"';\r
$_xh[$parser]['ac']='';\r
break;\r
case 'FAULT':\r
$_xh[$parser]['isf']=1;\r
break;\r
case 'PARAM':\r
- $_xh[$parser]['st']='';\r
+ //$_xh[$parser]['st']='';\r
+ // clear value, so we can check later if no value will passed for this param/member\r
+ $_xh[$parser]['value']=null;\r
break;\r
case 'VALUE':\r
- $_xh[$parser]['st'].='new xmlrpcval(';\r
- $_xh[$parser]['vt']=$xmlrpcString;\r
+ //$_xh[$parser]['st'].='new xmlrpcval(';\r
+ // look for a value: if this is still true by the\r
+ // time we reach the end tag for value then the type is string\r
+ // by implication\r
+ $_xh[$parser]['vt']='value';\r
$_xh[$parser]['ac']='';\r
- $_xh[$parser]['qt']=0;\r
+ //$_xh[$parser]['qt']=0;\r
$_xh[$parser]['lv']=1;\r
- // look for a value: if this is still 1 by the\r
- // time we reach the first data segment then the type is string\r
- // by implication and we need to add in a quote\r
break;\r
case 'I4':\r
case 'INT':\r
case 'DOUBLE':\r
case 'DATETIME.ISO8601':\r
case 'BASE64':\r
- $_xh[$parser]['ac']=''; // reset the accumulator\r
+ if ($_xh[$parser]['vt']!='value')\r
+ {\r
+ //two data elements inside a value: an error occurred!\r
+ $_xh[$parser]['isf'] = 2;\r
+ $_xh[$parser]['isf_reason'] = "$name element following a {$_xh[$parser]['vt']} element inside a single value";\r
+ return;\r
+ }\r
+\r
+ // reset the accumulator\r
+ $_xh[$parser]['ac']='';\r
\r
- if ($name=='DATETIME.ISO8601' || $name=='STRING')\r
+ /*if ($name=='DATETIME.ISO8601' || $name=='STRING')\r
{\r
$_xh[$parser]['qt']=1;\r
if ($name=='DATETIME.ISO8601')\r
// at the end of the element we must check\r
// for data format errors.\r
$_xh[$parser]['qt']=0;\r
- }\r
+ }*/\r
break;\r
case 'MEMBER':\r
- $_xh[$parser]['ac']='';\r
+ //$_xh[$parser]['ac']='';\r
+ // avoid warnings later on if no NAME is found before VALUE inside\r
+ // a struct member predefining member name as NULL\r
+ $_xh[$parser]['valuestack'][0]['name'] = '';\r
+ // clear value, so we can check later if no value will passed for this param/member\r
+ $_xh[$parser]['value']=null;\r
+ break;\r
+ case 'DATA':\r
+ case 'METHODCALL':\r
+ case 'METHODRESPONSE':\r
+ case 'PARAMS':\r
+ // valid elements that add little to processing\r
break;\r
default:\r
+ /// INVALID ELEMENT: RAISE ISF so that it is later recognized!!!\r
+ $_xh[$parser]['isf'] = 2;\r
+ $_xh[$parser]['isf_reason'] = "found not-xmlrpc xml element $name";\r
break;\r
}\r
\r
+ // Save current element name to stack, to validate nesting\r
+ array_unshift($_xh[$parser]['stack'], $name);\r
+\r
if ($name!='VALUE')\r
{\r
$_xh[$parser]['lv']=0;\r
}\r
}\r
+ }\r
\r
function xmlrpc_ee($parser, $name)\r
{\r
- global $_xh,$xmlrpcTypes,$xmlrpcString;\r
+ global $_xh,$xmlrpcTypes,$xmlrpcString,$xmlrpcDateTime;\r
+\r
+ if ($_xh[$parser]['isf'] < 2)\r
+ {\r
+\r
+ // push this element name from stack\r
+ // NB: if XML validates, correct opening/closing is guaranteed and\r
+ // we do not have to check for $name == $curr_elem.\r
+ // we also checked for proper nesting at start of elements...\r
+ $curr_elem = array_shift($_xh[$parser]['stack']); \r
\r
switch($name)\r
{\r
case 'STRUCT':\r
case 'ARRAY':\r
- if ($_xh[$parser]['cm'] && substr($_xh[$parser]['st'], -1) ==',')\r
- {\r
- $_xh[$parser]['st']=substr($_xh[$parser]['st'],0,-1);\r
- }\r
- $_xh[$parser]['st'].=')';\r
+ //if ($_xh[$parser]['cm'] && substr($_xh[$parser]['st'], -1) ==',')\r
+ //{\r
+ // $_xh[$parser]['st']=substr($_xh[$parser]['st'],0,-1);\r
+ //}\r
+ //$_xh[$parser]['st'].=')';\r
+\r
+ // fetch out of stack array of values, and promote it to current value\r
+ $cur_val = array_shift($_xh[$parser]['valuestack']);\r
+ $_xh[$parser]['value'] = $cur_val['values'];\r
+\r
$_xh[$parser]['vt']=strtolower($name);\r
- $_xh[$parser]['cm']--;\r
+ //$_xh[$parser]['cm']--;\r
break;\r
case 'NAME':\r
- $_xh[$parser]['st'].= $_xh[$parser]['ac'] . '" => ';\r
+ //$_xh[$parser]['st'].= $_xh[$parser]['ac'] . '" => ';\r
+ $_xh[$parser]['valuestack'][0]['name'] = $_xh[$parser]['ac'];\r
break;\r
case 'BOOLEAN':\r
- // special case here: we translate boolean 1 or 0 into PHP\r
- // constants true or false\r
- // NB: this simple checks helps a lot sanitizing input, ie no\r
- // security problems around here\r
- if ($_xh[$parser]['ac']=='1')\r
- {\r
- $_xh[$parser]['ac']='true';\r
- }\r
- else\r
- {\r
- $_xh[$parser]['ac']='false';\r
- }\r
- $_xh[$parser]['vt']=strtolower($name);\r
- // Drop through intentionally.\r
case 'I4':\r
case 'INT':\r
case 'STRING':\r
case 'DOUBLE':\r
case 'DATETIME.ISO8601':\r
case 'BASE64':\r
- if ($_xh[$parser]['qt']==1)\r
+ $_xh[$parser]['vt']=strtolower($name);\r
+ //if ($_xh[$parser]['qt']==1) \r
+ if ($name=='STRING')\r
{\r
// we use double quotes rather than single so backslashification works OK\r
- $_xh[$parser]['st'].='"'. $_xh[$parser]['ac'] . '"';\r
+ //$_xh[$parser]['st'].='"'. $_xh[$parser]['ac'] . '"';\r
+ $_xh[$parser]['value']=$_xh[$parser]['ac'];\r
+ }\r
+ elseif ($name=='DATETIME.ISO8601')\r
+ {\r
+ $_xh[$parser]['vt']=$xmlrpcDateTime;\r
+ $_xh[$parser]['value']=$_xh[$parser]['ac'];\r
}\r
- elseif ($_xh[$parser]['qt']==2)\r
+ elseif ($name=='BASE64')\r
{\r
- $_xh[$parser]['st'].='base64_decode("'. $_xh[$parser]['ac'] . '")';\r
+ //$_xh[$parser]['st'].='base64_decode("'. $_xh[$parser]['ac'] . '")';\r
+\r
+ ///@todo check for failure of base64 decoding / catch warnings\r
+ $_xh[$parser]['value']=base64_decode($_xh[$parser]['ac']);\r
}\r
elseif ($name=='BOOLEAN')\r
{\r
- $_xh[$parser]['st'].=$_xh[$parser]['ac'];\r
+ // special case here: we translate boolean 1 or 0 into PHP\r
+ // constants true or false\r
+ // NB: this simple checks helps a lot sanitizing input, ie no\r
+ // security problems around here\r
+ if ($_xh[$parser]['ac']=='1')\r
+ {\r
+ //$_xh[$parser]['ac']='true'; \r
+ $_xh[$parser]['value']=true;\r
+ }\r
+ else\r
+ {\r
+ //$_xh[$parser]['ac']='false';\r
+ // log if receiveing something strange, even though we set the value to false anyway\r
+ if ($_xh[$parser]['ac']!='0')\r
+ error_log('XML-RPC: invalid value received in BOOLEAN: '.$_xh[$parser]['ac']);\r
+ $_xh[$parser]['value']=false;\r
+ }\r
+ //$_xh[$parser]['st'].=$_xh[$parser]['ac'];\r
}\r
elseif ($name=='DOUBLE')\r
{\r
// TODO: find a better way of throwing an error\r
// than this!\r
error_log('XML-RPC: non numeric value received in DOUBLE: '.$_xh[$parser]['ac']);\r
- $_xh[$parser]['st'].="'ERROR_NON_NUMERIC_FOUND'";\r
+ //$_xh[$parser]['st'].="'ERROR_NON_NUMERIC_FOUND'";\r
+ $_xh[$parser]['value']='ERROR_NON_NUMERIC_FOUND';\r
}\r
else\r
{\r
// it's ok, add it on\r
- $_xh[$parser]['st'].=(double)$_xh[$parser]['ac'];\r
+ //$_xh[$parser]['st'].=(double)$_xh[$parser]['ac'];\r
+ $_xh[$parser]['value']=(double)$_xh[$parser]['ac'];\r
}\r
}\r
else\r
// TODO: find a better way of throwing an error\r
// than this!\r
error_log('XML-RPC: non numeric value received in INT: '.$_xh[$parser]['ac']);\r
- $_xh[$parser]['st'].="'ERROR_NON_NUMERIC_FOUND'";\r
+ //$_xh[$parser]['st'].="'ERROR_NON_NUMERIC_FOUND'";\r
+ $_xh[$parser]['value']='ERROR_NON_NUMERIC_FOUND';\r
}\r
else\r
{\r
// it's ok, add it on\r
- $_xh[$parser]['st'].=(int)$_xh[$parser]['ac'];\r
+ //$_xh[$parser]['st'].=(int)$_xh[$parser]['ac'];\r
+ $_xh[$parser]['value']=(int)$_xh[$parser]['ac'];\r
}\r
}\r
$_xh[$parser]['ac']='';\r
- $_xh[$parser]['qt']=0;\r
+ //$_xh[$parser]['qt']=0;\r
$_xh[$parser]['lv']=3; // indicate we've found a value\r
break;\r
case 'VALUE':\r
- // deal with a string value\r
- if (strlen($_xh[$parser]['ac'])>0 &&\r
+ // This if() detects if no scalar was inside <VALUE></VALUE>\r
+ if ($_xh[$parser]['vt']=='value')\r
+ {\r
+ $_xh[$parser]['value']=$_xh[$parser]['ac'];\r
+ $_xh[$parser]['vt']=$xmlrpcString;\r
+ }\r
+ /*if (strlen($_xh[$parser]['ac'])>0 &&\r
$_xh[$parser]['vt']==$xmlrpcString)\r
{\r
$_xh[$parser]['st'].='"'. $_xh[$parser]['ac'] . '"';\r
if ($_xh[$parser]['cm'])\r
{\r
$_xh[$parser]['st'].=',';\r
+ }*/\r
+\r
+ // build the xmlrpc val out of the data received, and substitute it\r
+ $temp = new xmlrpcval($_xh[$parser]['value'], $_xh[$parser]['vt']);\r
+ // check if we are inside an array or struct:\r
+ // if value just built is inside an array, let's move it into array on the stack\r
+ if (count($_xh[$parser]['valuestack']) && $_xh[$parser]['valuestack'][0]['type']=='ARRAY')\r
+ {\r
+ $_xh[$parser]['valuestack'][0]['values'][] = $temp;\r
+ }\r
+ else\r
+ {\r
+ $_xh[$parser]['value'] = $temp;\r
}\r
break;\r
case 'MEMBER':\r
$_xh[$parser]['ac']='';\r
- $_xh[$parser]['qt']=0;\r
+ //$_xh[$parser]['qt']=0;\r
+ // add to array in the stack the last element built\r
+ // unless no VALUE was found\r
+ if ($_xh[$parser]['value'])\r
+ $_xh[$parser]['valuestack'][0]['values'][$_xh[$parser]['valuestack'][0]['name']] = $_xh[$parser]['value'];\r
+ else\r
+ error_log('XML-RPC: missing VALUE inside STRUCT in received xml');\r
break;\r
case 'DATA':\r
$_xh[$parser]['ac']='';\r
- $_xh[$parser]['qt']=0;\r
+ //$_xh[$parser]['qt']=0;\r
break;\r
case 'PARAM':\r
- $_xh[$parser]['params'][]=$_xh[$parser]['st'];\r
+ //$_xh[$parser]['params'][]=$_xh[$parser]['st'];\r
+ if ($_xh[$parser]['value'])\r
+ $_xh[$parser]['params'][]=$_xh[$parser]['value'];\r
+ else\r
+ error_log('XML-RPC: missing VALUE inside PARAM in received xml');\r
break;\r
case 'METHODNAME':\r
$_xh[$parser]['method']=ereg_replace("^[\n\r\t ]+", '', $_xh[$parser]['ac']);\r
break;\r
- // BOOLEAN HAS BEEN ENUMERATED ABOVE!\r
- /*case 'BOOLEAN':\r
- // special case here: we translate boolean 1 or 0 into PHP\r
- // constants true or false\r
- if ($_xh[$parser]['ac']=='1')\r
- {\r
- $_xh[$parser]['ac']='true';\r
- }\r
- else\r
- {\r
- $_xh[$parser]['ac']='false';\r
- $_xh[$parser]['vt']=strtolower($name);\r
- }\r
- break;*/\r
+ case 'PARAMS':\r
+ case 'FAULT':\r
+ case 'METHODCALL':\r
+ case 'METHORESPONSE':\r
+ break;\r
default:\r
+ // End of INVALID ELEMENT!\r
+ // shall we add an assert here for unreachable code???\r
break;\r
}\r
// if it's a valid type name, set the type\r
- if (isset($xmlrpcTypes[strtolower($name)]))\r
+ /*if (isset($xmlrpcTypes[strtolower($name)]))\r
{\r
$_xh[$parser]['vt']=strtolower($name);\r
+ }*/\r
+\r
}\r
}\r
\r
//if (ereg("^[\n\r \t]+$", $data)) return;\r
// print "adding [${data}]\n";\r
\r
+ // skip processing if xml fault already detected\r
+ if ($_xh[$parser]['isf'] < 2)\r
+ {\r
if ($_xh[$parser]['lv']!=3)\r
{\r
// "lookforvalue==3" means that we've found an entire value\r
{\r
// if we've found text and we're just in a <value> then\r
// turn quoting on, as this will be a string\r
- $_xh[$parser]['qt']=1;\r
+ //$_xh[$parser]['qt']=1;\r
// and say we've found a value\r
$_xh[$parser]['lv']=2;\r
}\r
{\r
$_xh[$parser]['ac'] = '';\r
}\r
- $_xh[$parser]['ac'].=str_replace('$', '\$', str_replace('"', '\"', str_replace(chr(92),$xmlrpc_backslash, $data)));\r
+ //$_xh[$parser]['ac'].=str_replace('$', '\$', str_replace('"', '\"', str_replace(chr(92),$xmlrpc_backslash, $data)));\r
+ $_xh[$parser]['ac'].=$data;\r
+ }\r
}\r
}\r
\r
function xmlrpc_dh($parser, $data)\r
{\r
global $_xh, $xmlrpc_backslash;\r
+\r
+ // skip processing if xml fault already detected\r
+ if ($parser[$_xh]['isf'] < 2)\r
+ {\r
if (substr($data, 0, 1) == '&' && substr($data, -1, 1) == ';')\r
{\r
if ($_xh[$parser]['lv']==1)\r
{\r
- $_xh[$parser]['qt']=1;\r
+ //$_xh[$parser]['qt']=1;\r
$_xh[$parser]['lv']=2;\r
}\r
- $_xh[$parser]['ac'].=str_replace('$', '\$', str_replace('"', '\"', str_replace(chr(92),$xmlrpc_backslash, $data)));\r
+ //$_xh[$parser]['ac'].=str_replace('$', '\$', str_replace('"', '\"', str_replace(chr(92),$xmlrpc_backslash, $data)));\r
+ $_xh[$parser]['ac'].=$data;\r
+ }\r
}\r
}\r
\r
$_xh=array();\r
$_xh[$parser]=array();\r
$_xh[$parser]['headers'] = array();\r
+ $_xh[$parser]['stack'] = array();\r
+ $_xh[$parser]['valuestack'] = array();\r
\r
// separate HTTP headers from data\r
if (ereg("^HTTP", $data))\r
if ($bd)\r
$data = substr($data, 0, $bd);\r
\r
- $_xh[$parser]['st']='';\r
- $_xh[$parser]['cm']=0;\r
+ //$_xh[$parser]['st']='';\r
+ //$_xh[$parser]['cm']=0;\r
$_xh[$parser]['isf']=0;\r
+ $_xh[$parser]['isf_reason']=0;\r
$_xh[$parser]['ac']='';\r
- $_xh[$parser]['qt']='';\r
+ //$_xh[$parser]['qt']='';\r
\r
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);\r
// G. Giunta 2005/02/13: PHP internally uses ISO-8859-1, so we have to tell\r
return $r;\r
}\r
xml_parser_free($parser);\r
+\r
+ if ($_xh[$parser]['isf'] > 1)\r
+ {\r
if ($this->debug)\r
{\r
- print "<PRE>---EVALING---[" .\r
- strlen($_xh[$parser]['st']) . " chars]---\n" .\r
- htmlspecialchars($_xh[$parser]['st']) . ";\n---END---</PRE>";\r
+ ///@todo echo something for user?\r
+ }\r
+\r
+ $r = new xmlrpcresp(0, $xmlrpcerr['invalid_return'],\r
+ $xmlrpcstr['invalid_return'] . ' ' . $_xh[$parser]['isf_reason']);\r
}\r
- if (strlen($_xh[$parser]['st'])==0)\r
+ //else if (strlen($_xh[$parser]['st'])==0)\r
+ else if (!is_object($_xh[$parser]['value']))\r
{\r
// then something odd has happened\r
// and it's time to generate a client side error\r
}\r
else\r
{\r
- $allOK=0;\r
- @eval('$v=' . $_xh[$parser]['st'] . '; $allOK=1;');\r
- if (!$allOK)\r
+\r
+ if ($this->debug)\r
{\r
- $r = new xmlrpcresp(0, $xmlrpcerr['invalid_return'], $xmlrpcstr['invalid_return']);\r
+ //print "<PRE>---EVALING---[" .\r
+ //strlen($_xh[$parser]['st']) . " chars]---\n" .\r
+ //htmlspecialchars($_xh[$parser]['st']) . ";\n---END---</PRE>";\r
+ print "<PRE>---PARSED---\n" ;\r
+ var_dump($_xh[$parser]['value']);\r
+ print "\n---END---</PRE>";\r
}\r
- else\r
+\r
+ //$allOK=0;\r
+ //@eval('$v=' . $_xh[$parser]['st'] . '; $allOK=1;');\r
+ //if (!$allOK)\r
+ //{\r
+ // $r = new xmlrpcresp(0, $xmlrpcerr['invalid_return'], $xmlrpcstr['invalid_return']);\r
+ //}\r
+ //else\r
+ $v = $_xh[$parser]['value'];\r
if ($_xh[$parser]['isf'])\r
{\r
$errno_v = $v->structmem('faultCode');\r
@reset($t);\r
while(list($id,$cont) = @each($t))\r
{\r
- eval('$b->'.$id.' = $cont;');\r
+ //eval('$b->'.$id.' = $cont;');\r
+ @$b->$id = $cont;\r
}\r
}\r
// end contrib\r
<?php\r
// by Edd Dumbill (C) 1999-2002\r
// <edd@usefulinc.com>\r
-// $Id: xmlrpcs.inc.php,v 1.5.2.1 2005-06-30 21:19:18 kimitake Exp $\r
-// $NucleusJP$\r
+// $Id: xmlrpcs.inc.php,v 1.5.2.2 2005-08-16 05:26:18 kimitake Exp $\r
+// $NucleusJP: xmlrpcs.inc.php,v 1.4.2.1 2005/06/30 21:23:01 kimitake Exp $\r
\r
// Copyright (c) 1999,2000,2002 Edd Dumbill.\r
// All rights reserved.\r
$parser = xml_parser_create($xmlrpc_defencoding);\r
\r
$_xh[$parser]=array();\r
- $_xh[$parser]['st']='';\r
- $_xh[$parser]['cm']=0;\r
+ //$_xh[$parser]['st']='';\r
+ //$_xh[$parser]['cm']=0;\r
$_xh[$parser]['isf']=0;\r
+ $_xh[$parser]['isf_reason']='';\r
$_xh[$parser]['params']=array();\r
+ $_xh[$parser]['stack']=array();\r
+ $_xh[$parser]['valuestack'] = array();\r
$_xh[$parser]['method']='';\r
\r
// decompose incoming XML into request structure\r
xml_parser_free($parser);\r
}\r
else\r
+ if ($_xh[$parser]['isf'])\r
{\r
xml_parser_free($parser);\r
+ $r=new xmlrpcresp(0,\r
+ $xmlrpcerr['invalid_request'],\r
+ $xmlrpcstr['invalid_request'] . ' ' . $_xh[$parser]['isf_reason']);\r
+ }\r
+ else\r
+ {\r
+ xml_parser_free($parser);\r
+\r
$m=new xmlrpcmsg($_xh[$parser]['method']);\r
// now add parameters in\r
$plist='';\r
- $allOK = 1;\r
+ //$allOK = 1;\r
for($i=0; $i<sizeof($_xh[$parser]['params']); $i++)\r
{\r
//print "<!-- " . $_xh[$parser]['params'][$i]. "-->\n";\r
$plist.="$i - " . $_xh[$parser]['params'][$i]. ";\n";\r
- $allOK = 0;\r
- @eval('$m->addParam(' . $_xh[$parser]['params'][$i]. '); $allOK=1;');\r
- if (!$allOK)\r
- {\r
- break;\r
- }\r
+ //$allOK = 0;\r
+ //@eval('$m->addParam(' . $_xh[$parser]['params'][$i]. '); $allOK=1;');\r
+ @$m->addParam($_xh[$parser]['params'][$i]);\r
+ //if (!$allOK)\r
+ //{\r
+ // break;\r
+ //}\r
}\r
// uncomment this to really see what the server's getting!\r
// xmlrpc_debugmsg($plist);\r
- if (!$allOK)\r
- {\r
- $r = new xmlrpcresp(0,\r
- $xmlrpcerr['incorrect_params'],\r
- $xmlrpcstr['incorrect_params'] . ": xml error in param " . $i);\r
- }\r
- else\r
- {\r
+ //if (!$allOK)\r
+ //{\r
+ // $r = new xmlrpcresp(0,\r
+ // $xmlrpcerr['incorrect_params'],\r
+ // $xmlrpcstr['incorrect_params'] . ": xml error in param " . $i);\r
+ //}\r
+ //else\r
+ //{\r
$r = $this->execute($m);\r
- }\r
+ //}\r
}\r
return $r;\r
}\r