avoid emitting warnings when parsing bad xml; catch responses with both fault and...
authorgggeek <giunta.gaetano@gmail.com>
Tue, 23 Apr 2024 10:36:28 +0000 (10:36 +0000)
committergggeek <giunta.gaetano@gmail.com>
Tue, 23 Apr 2024 10:36:28 +0000 (10:36 +0000)
NEWS.md
src/Helper/XMLParser.php
tests/04ParsingTest.php

diff --git a/NEWS.md b/NEWS.md
index 69eb935..b86497c 100644 (file)
--- a/NEWS.md
+++ b/NEWS.md
@@ -1,3 +1,11 @@
+## XML-RPC for PHP version 4.10.3 - 2024/04/24
+
+* fixed: avoid emitting warnings when parsing some classes of malformed XML (issue #116)
+
+* fixed: the library will now return a Fault `Response` object with error code 2 whenever parsing some xml responses
+  which do not conform to the specification, namely those having both `fault` and `params` elements inside `methodResponse`
+
+
 ## XML-RPC for PHP version 4.10.2 - 2024/04/14
 
 * fixed: allow `Server` subclasses to use their own Parser to determine the Request's charset
index 9212d1f..70c92a4 100644 (file)
@@ -260,11 +260,10 @@ class XMLParser
             for ($offset = 0; $offset < $len; $offset += $this->maxChunkLength) {
                 $chunk = substr($data, $offset, $this->maxChunkLength);
                 // error handling: xml not well formed
-                if (!xml_parse($parser, $chunk, $offset + $this->maxChunkLength >= $len)) {
+                if (!@xml_parse($parser, $chunk, $offset + $this->maxChunkLength >= $len)) {
                     $errCode = xml_get_error_code($parser);
                     $errStr = sprintf('XML error %s: %s at line %d, column %d', $errCode, xml_error_string($errCode),
                         xml_get_current_line_number($parser), xml_get_current_column_number($parser));
-
                     $this->_xh['isf'] = 3;
                     $this->_xh['isf_reason'] = $errStr;
                 }
@@ -780,6 +779,9 @@ class XMLParser
                 } elseif ($this->_xh['isf'] == 0 && count($this->_xh['params']) !== 1) {
                     $this->_xh['isf'] = 2;
                     $this->_xh['isf_reason'] = "PARAMS element inside METHODRESPONSE should have exactly 1 PARAM";
+                } elseif ($this->_xh['isf'] == 1 && $this->_xh['params'] !== false) {
+                    $this->_xh['isf'] = 2;
+                    $this->_xh['isf_reason'] = "both FAULT and PARAMS elements found inside METHODRESPONSE";
                 }
                 break;
 
index 345d40f..4279531 100644 (file)
@@ -308,6 +308,28 @@ class ParsingTest extends PhpXmlRpc_LoggerAwareTestCase
 </methodResponse>';
         $r = $m->parseResponse($f);
         $this->assertEquals(2, $r->faultCode());
+
+        // having both 'params' and 'fault'
+        $f = '<?xml version="1.0"?>
+<methodResponse>
+<params>
+<param><value><string>system.methodHelp</string></value></param>
+</params>
+<fault><value><struct>
+<member><name>faultCode</name><value><int>888</int></value></member>
+<member><name>faultString</name><value><string>yolo</string></value></member>
+</struct></value></fault>
+</methodResponse>';
+        $r = $m->parseResponse($f);
+        $this->assertEquals(2, $r->faultCode());
+    }
+
+    public function testBuggyXML()
+    {
+        $m = $this->newRequest('dummy');
+        $r = $m->parseResponse("<\000\000\000\au\006");
+        $this->assertEquals(2, $r->faultCode());
+        //$this->assertStringContainsString('XML error', $r->faultString());
     }
 
     public function testBuggyHttp()