diff --git a/src/Fault.php b/src/Fault.php index 109dc9c..851640e 100644 --- a/src/Fault.php +++ b/src/Fault.php @@ -10,6 +10,8 @@ namespace Zend\XmlRpc; +use SimpleXMLElement; + /** * XMLRPC Faults * @@ -171,7 +173,7 @@ public function getEncoding() * @param string $fault * @return boolean Returns true if successfully loaded fault response, false * if response was not a fault response - * @throws \Zend\XmlRpc\Exception\ExceptionInterface if no or faulty XML provided, or if fault + * @throws Exception\ExceptionInterface if no or faulty XML provided, or if fault * response does not contain either code or message */ public function loadXml($fault) @@ -180,12 +182,25 @@ public function loadXml($fault) throw new Exception\InvalidArgumentException('Invalid XML provided to fault'); } + $xmlErrorsFlag = libxml_use_internal_errors(true); try { - $xml = new \SimpleXMLElement($fault); + $xml = new SimpleXMLElement($fault); } catch (\Exception $e) { // Not valid XML throw new Exception\InvalidArgumentException('Failed to parse XML fault: ' . $e->getMessage(), 500, $e); } + if (!$xml instanceof SimpleXMLElement) { + $errors = libxml_get_errors(); + $errors = array_reduce($errors, function ($result, $item) { + if (empty($result)) { + return $item->message; + } + return $result . '; ' . $item->message; + }, ''); + libxml_use_internal_errors($xmlErrorsFlag); + throw new Exception\InvalidArgumentException('Failed to parse XML fault: ' . $errors, 500); + } + libxml_use_internal_errors($xmlErrorsFlag); // Check for fault if (!$xml->fault) { diff --git a/src/Request.php b/src/Request.php index 379c821..9d21689 100644 --- a/src/Request.php +++ b/src/Request.php @@ -10,6 +10,10 @@ namespace Zend\XmlRpc; +use DOMDocument; +use SimpleXMLElement; +use Zend\Stdlib\ErrorHandler; + /** * XmlRpc Request object * @@ -284,9 +288,10 @@ public function loadXml($request) } // @see ZF-12293 - disable external entities for security purposes - $loadEntities = libxml_disable_entity_loader(true); + $loadEntities = libxml_disable_entity_loader(true); + $xmlErrorsFlag = libxml_use_internal_errors(true); try { - $dom = new \DOMDocument; + $dom = new DOMDocument; $dom->loadXML($request); foreach ($dom->childNodes as $child) { if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) { @@ -295,14 +300,24 @@ public function loadXml($request) ); } } - $xml = simplexml_import_dom($dom); - //$xml = new \SimpleXMLElement($request); + ErrorHandler::start(); + $xml = simplexml_import_dom($dom); + $error = ErrorHandler::stop(); libxml_disable_entity_loader($loadEntities); + libxml_use_internal_errors($xmlErrorsFlag); } catch (\Exception $e) { // Not valid XML $this->fault = new Fault(631); $this->fault->setEncoding($this->getEncoding()); libxml_disable_entity_loader($loadEntities); + libxml_use_internal_errors($xmlErrorsFlag); + return false; + } + if (!$xml instanceof SimpleXMLElement || $error) { + // Not valid XML + $this->fault = new Fault(631); + $this->fault->setEncoding($this->getEncoding()); + libxml_use_internal_errors($xmlErrorsFlag); return false; } diff --git a/src/Server.php b/src/Server.php index 8ba0c3f..6a22434 100644 --- a/src/Server.php +++ b/src/Server.php @@ -172,8 +172,8 @@ public function __call($method, $params) * * @param string|array|callable $function Valid callback * @param string $namespace Optional namespace prefix + * @throws Server\Exception\InvalidArgumentException * @return void - * @throws \Zend\XmlRpc\Exception\InvalidArgumentException */ public function addFunction($function, $namespace = '') {