--- XML_RPC-1.1.0/Server.php.orig
+++ XML_RPC-1.1.0/Server.php
@@ -227,11 +227,12 @@
         $parser = xml_parser_create($XML_RPC_defencoding);
 
         $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]['isf_reason'] = '';
         $XML_RPC_xh[$parser]['params'] = array();
         $XML_RPC_xh[$parser]['method'] = "";
+        $XML_RPC_xh[$parser]['stack'] = array();	
+        $XML_RPC_xh[$parser]['valuestack'] = array();	
 
         $plist = '';
 
@@ -249,14 +250,19 @@
                                               xml_error_string(xml_get_error_code($parser)),
                                               xml_get_current_line_number($parser)));
             xml_parser_free($parser);
+        } else if ($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);
         } else {
             xml_parser_free($parser);
             $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 "<!-- " . $XML_RPC_xh[$parser]['params'][$i]. "-->\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);
             // now to deal with the method
--- XML_RPC-1.1.0/RPC.php.orig
+++ XML_RPC-1.1.0/RPC.php
@@ -74,6 +74,9 @@
 $GLOBALS['XML_RPC_err']["http_error"] = 5;
 $GLOBALS['XML_RPC_str']["http_error"] = "Didn't receive 200 OK from remote server.";
 
+$GLOBALS['XML_RPC_err']["invalid_request"] = 7;
+$GLOBALS['XML_RPC_str']["invalid_request"] = "Invalid request payload";
+
 $GLOBALS['XML_RPC_defencoding'] = "UTF-8";
 
 // let user errors start at 800
@@ -88,17 +91,40 @@
 $GLOBALS['XML_RPC_twoslash'] = $GLOBALS['XML_RPC_backslash'] . $GLOBALS['XML_RPC_backslash'];
 $GLOBALS['XML_RPC_twoslash'] = "2SLS";
 
+/*
+ * 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'),
+);
+
 // used to store state during parsing
 // quick explanation of components:
-//   st - used to build up a string for evaluation
 //   ac - used to accumulate values
-//   qt - used to decide if quotes are needed for evaluation
-//   cm - used to denote struct or array (comma needed)
 //   isf - used to indicate a fault
 //   lv - used to indicate "looking for a value": implements
 //        the logic to allow values with no types to be strings
 //   params - used to store parameters in method calls
 //   method - used to store method name
+//   stack  - array with genealogy of xml elements names:
+//            used to validate nesting of xmlrpc elements
 
 $GLOBALS['XML_RPC_xh'] = array();
 
@@ -144,21 +170,43 @@
 
 function XML_RPC_se($parser, $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;
+
+    // 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])) {
+	    $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":
     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
-        $XML_RPC_xh[$parser]['qt'] = 0;
-        break;
+	$cur_val = array();
+	$cur_val['values'] = array();
+	$cur_val['type'] = $name;
+	array_unshift($XML_RPC_xh[$parser]['valuestack'], $cur_val);
+	break;
 
+    case "METHODNAME":
     case "NAME":
-        $XML_RPC_xh[$parser]['st'] .= '"';
         $XML_RPC_xh[$parser]['ac'] = "";
         break;
 
@@ -167,15 +215,13 @@
         break;
 
     case "PARAM":
-        $XML_RPC_xh[$parser]['st'] = "";
+        $XML_RPC_xh[$parser]['value'] = null;
         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]['vt'] = 'value';
         $XML_RPC_xh[$parser]['ac'] = "";
-        $XML_RPC_xh[$parser]['qt'] = 0;
         // look for a value: if this is still 1 by the
         // time we reach the first data segment then the type is string
         // by implication and we need to add in a quote
@@ -188,33 +234,36 @@
     case "DOUBLE":
     case "DATETIME.ISO8601":
     case "BASE64":
-        $XML_RPC_xh[$parser]['ac'] = ""; // reset the accumulator
-
-        if ($name == "DATETIME.ISO8601" || $name == "STRING") {
-            $XML_RPC_xh[$parser]['qt'] = 1;
+	if ($XML_RPC_xh[$parser]['vt']!='value') {
+	    $XML_RPC_xh[$parser]['isf'] = 2;
+	    $XML_RPC_xh[$parser]['isf_reason'] = "$name element following a {$XML_RPC_xh[$parser]['vt']} element inside a single value";
+	    return;
+	}
 
-            if ($name == "DATETIME.ISO8601") {
-                $XML_RPC_xh[$parser]['vt'] = $XML_RPC_DateTime;
-            }
-
-        } elseif ($name == "BASE64") {
-            $XML_RPC_xh[$parser]['qt'] = 2;
-        } else {
-            // No quoting is required here -- but
-            // at the end of the element we must check
-            // for data format errors.
-            $XML_RPC_xh[$parser]['qt'] = 0;
-        }
+        $XML_RPC_xh[$parser]['ac'] = ""; // reset the accumulator
         break;
 
     case "MEMBER":
-        $XML_RPC_xh[$parser]['ac'] = "";
+        $XML_RPC_xh[$parser]['valuestack'][0]['name'] = '';
+        $XML_RPC_xh[$parser]['value'] = null;
         break;
 
+    case 'DATA':
+    case 'METHODCALL':
+    case 'METHODRESPONSE':
+    case 'PARAMS':
+	// valid elements that add little to processing
+	break;			
     default:
+        /// INVALID ELEMENT: RAISE ISF so that it is later recognized!!!
+        $XML_RPC_xh[$parser]['isf'] = 2;
+        $XML_RPC_xh[$parser]['isf_reason'] = "found not-xmlrpc xml element $name";
         break;
     }
 
+    // Save current element to stack
+    array_unshift($XML_RPC_xh[$parser]['stack'], $name);
+
     if ($name!="VALUE") {
         $XML_RPC_xh[$parser]['lv'] = 0;
     }
@@ -225,95 +274,127 @@
 {
     global $XML_RPC_xh,$XML_RPC_Types,$XML_RPC_String;
 
+    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);
-        }
-
+	$cur_val = array_shift($XML_RPC_xh[$parser]['valuestack']);
+	$XML_RPC_xh[$parser]['value'] = $cur_val['values'];
         $XML_RPC_xh[$parser]['st'] .= ")";
         $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":
         // special case here: we translate boolean 1 or 0 into PHP
         // constants true or false
         if ($XML_RPC_xh[$parser]['ac'] == '1') {
-            $XML_RPC_xh[$parser]['ac'] = "true";
+            $XML_RPC_xh[$parser]['value'] = "true";
         } else {
-            $XML_RPC_xh[$parser]['ac'] = "false";
+            $XML_RPC_xh[$parser]['value'] = "false";
         }
 
-        $XML_RPC_xh[$parser]['vt'] = strtolower($name);
-        // Drop through intentionally.
+        $XML_RPC_xh[$parser]['vt'] = $GLOBALS['XML_RPC_Boolean'];
+        $XML_RPC_xh[$parser]['ac'] = '';
+        $XML_RPC_xh[$parser]['lv'] = 3; // indicate we've found a value
+        break;
 
     case "I4":
     case "INT":
-    case "STRING":
+        // we have an I4, INT
+        // we must check that only 0123456789-.<space> are characters here
+        if (!ereg("^[+-]?[0123456789 \t\.]+$", $XML_RPC_xh[$parser]['ac'])) {
+            XML_RPC_Base::raiseError('Non-numeric value received in INT: '.$XML_RPC_xh[$parser]['ac'],
+                                     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]['value'] = (int)$XML_RPC_xh[$parser]['ac'];
+        }
+        $XML_RPC_xh[$parser]['vt'] = strtolower($name);
+        $XML_RPC_xh[$parser]['ac'] = '';
+        $XML_RPC_xh[$parser]['lv'] = 3; // indicate we've found a value
+	break;
+
     case "DOUBLE":
-    case "DATETIME.ISO8601":
-    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'] . "\"";
-        } elseif ($XML_RPC_xh[$parser]['qt'] == 2) {
-            $XML_RPC_xh[$parser]['st'] .= 'base64_decode("' . $XML_RPC_xh[$parser]['ac'] . '")';
-        } elseif ($name=="BOOLEAN") {
-            $XML_RPC_xh[$parser]['st'] .= $XML_RPC_xh[$parser]['ac'];
+        // we have an DOUBLE
+        // we must check that only eE0123456789-.<space> are characters here
+        if (!ereg("^[+-]?[eE0123456789 \t\.]+$", $XML_RPC_xh[$parser]['ac'])) {
+            XML_RPC_Base::raiseError('Non-numeric value received in DOUBLE: '.$XML_RPC_xh[$parser]['ac'],
+                                     XML_RPC_ERROR_NON_NUMERIC_FOUND);
+            $XML_RPC_xh[$parser]['value'] = XML_RPC_ERROR_NON_NUMERIC_FOUND;
         } else {
-            // we have an I4, INT or a DOUBLE
-            // we must check that only 0123456789-.<space> are characters here
-            if (!ereg("^\-?[0123456789 \t\.]+$", $XML_RPC_xh[$parser]['ac'])) {
-                $this->raiseError("Non-numeric value recieved in INT or DOUBLE", XML_RPC_ERROR_NON_NUMERIC_FOUND);
-                $XML_RPC_xh[$parser]['st'] .= "ERROR_NON_NUMERIC_FOUND";
-            } else {
-                // it's ok, add it on
-                $XML_RPC_xh[$parser]['st'] .= $XML_RPC_xh[$parser]['ac'];
-            }
+            // it's ok, add it on
+            $XML_RPC_xh[$parser]['value'] = (double)$XML_RPC_xh[$parser]['ac'];
         }
+        $XML_RPC_xh[$parser]['vt'] = $GLOBALS['XML_RPC_Double'];
+        $XML_RPC_xh[$parser]['ac'] = '';
+        $XML_RPC_xh[$parser]['lv'] = 3; // indicate we've found a value
+	break;
 
-        $XML_RPC_xh[$parser]['ac'] = "";
-        $XML_RPC_xh[$parser]['qt'] = 0;
+    case 'STRING':
+        $XML_RPC_xh[$parser]['vt'] = $GLOBALS['XML_RPC_String'];
+	$XML_RPC_xh[$parser]['value'] = $XML_RPC_xh[$parser]['ac'];
+        $XML_RPC_xh[$parser]['ac'] = '';
         $XML_RPC_xh[$parser]['lv'] = 3; // indicate we've found a value
-        break;
+	break;
+	
+    case 'DATETIME.ISO8601':
+        $XML_RPC_xh[$parser]['vt'] = $GLOBALS['XML_RPC_DateTime'];
+	$XML_RPC_xh[$parser]['value'] = $XML_RPC_xh[$parser]['ac'];
+        $XML_RPC_xh[$parser]['ac'] = '';
+        $XML_RPC_xh[$parser]['lv'] = 3; // indicate we've found a value
+	break;
+	
+    case 'BASE64':
+        $XML_RPC_xh[$parser]['vt'] = $GLOBALS['XML_RPC_Base64'];
+	$XML_RPC_xh[$parser]['value'] = base64_decode($XML_RPC_xh[$parser]['ac']);
+        $XML_RPC_xh[$parser]['ac'] = '';
+        $XML_RPC_xh[$parser]['lv'] = 3; // indicate we've found a value
+	break;
 
     case "VALUE":
-        // 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'] . "\"";
-        }
-
-        // This if () detects if no scalar was inside <VALUE></VALUE>
-        // 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'] .= ",";
-        }
+	if ($XML_RPC_xh[$parser]['vt']=='value') {
+	    $XML_RPC_xh[$parser]['value'] = $XML_RPC_xh[$parser]['ac'];
+	    $XML_RPC_xh[$parser]['vt'] == $XML_RPC_String;
+	}
+
+	$temp = new XML_RPC_Value($XML_RPC_xh[$parser]['value'], $XML_RPC_xh[$parser]['vt']);
+	
+	if (count($XML_RPC_xh[$parser]['valuestack']) && $XML_RPC_xh[$parser]['valuestack'][0]['type']=='ARRAY') {
+	    $XML_RPC_xh[$parser]['valuestack'][0]['values'][] = $temp;
+	} else {
+	    $XML_RPC_xh[$parser]['value'] = $temp;
+	}
         break;
 
     case "MEMBER":
         $XML_RPC_xh[$parser]['ac'] = "";
-        $XML_RPC_xh[$parser]['qt'] = 0;
+	if ($XML_RPC_xh[$parser]['value']) {
+	    $XML_RPC_xh[$parser]['valuestack'][0]['values'][$XML_RPC_xh[$parser]['valuestack'][0]['name']] = $XML_RPC_xh[$parser]['value'];
+	}
         break;
 
     case "DATA":
         $XML_RPC_xh[$parser]['ac'] = "";
-        $XML_RPC_xh[$parser]['qt'] = 0;
         break;
 
     case "PARAM":
-        $XML_RPC_xh[$parser]['params'][] = $XML_RPC_xh[$parser]['st'];
+	if ($XML_RPC_xh[$parser]['value']) {
+    	    $XML_RPC_xh[$parser]['params'][] = $XML_RPC_xh[$parser]['value'];
+	}
         break;
 
     case "METHODNAME":
@@ -336,7 +417,7 @@
         break;
     }
 
-    // if it's a valid type name, set the type
+    // if it's a valid type name, set the typ*e
     if (isset($XML_RPC_Types[strtolower($name)])) {
         $XML_RPC_xh[$parser]['vt'] = strtolower($name);
     }
@@ -347,27 +428,25 @@
 {
     global $XML_RPC_xh, $XML_RPC_backslash;
 
+    if ($XML_RPC_xh[$parser]['isf'] >= 2) {
+	return;
+    }
+
     if ($XML_RPC_xh[$parser]['lv'] != 3) {
         // "lookforvalue==3" means that we've found an entire value
         // and should discard any further character data
 
         if ($XML_RPC_xh[$parser]['lv'] == 1) {
-            // if we've found text and we're just in a <value> then
-            // turn quoting on, as this will be a string
-            $XML_RPC_xh[$parser]['qt'] = 1;
             // and say we've found a value
             $XML_RPC_xh[$parser]['lv'] = 2;
         }
 
         // replace characters that eval would
         // do special things with
-        if (isset($XML_RPC_xh[$parser]['ac'])) {
-            $XML_RPC_xh[$parser]['ac'] .= str_replace('$', '\$',
-                str_replace('"', '\"', str_replace(chr(92),
-                $XML_RPC_backslash, $data)));
-        } else {
+        if (!isset($XML_RPC_xh[$parser]['ac'])) {
             $XML_RPC_xh[$parser]['ac'] = '';
         }
+        $XML_RPC_xh[$parser]['ac'] .= $data;
     }
 }
 
@@ -675,11 +754,12 @@
 
         $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]['isf_reason'] = '';
         $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, XML_OPTION_CASE_FOLDING, true);
         xml_set_element_handler($parser, "XML_RPC_se", "XML_RPC_ee");
@@ -736,18 +816,22 @@
         }
         xml_parser_free($parser);
         if ($this->debug) {
-            print "<PRE>---EVALING---[" .
-            strlen($XML_RPC_xh[$parser]['st']) . " chars]---\n" .
-            htmlspecialchars($XML_RPC_xh[$parser]['st']) . ";\n---END---</PRE>";
-        }
-        if (strlen($XML_RPC_xh[$parser]['st']) == 0) {
+    	    print '<PRE>---PARSED---\n';
+	    var_dump($XML_RPC_xh[$parser]['value']);
+	    print '\n---END---</PRE>';
+        }
+	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']);
+	} else if (!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");
@@ -988,7 +1072,7 @@
                 $t[$id] = $cont->scalarval();
             }
             foreach ($t as $id => $cont) {
-                eval('$b->'.$id.' = $cont;');
+                $b->$id = $cont;
             }
         }
 
