From 8a52cdf35af9a714e9b330fa0aace6606b071c89 Mon Sep 17 00:00:00 2001
From: Andreas Gohr <andi@splitbrain.org>
Date: Thu, 1 Jul 2010 19:43:47 +0200
Subject: [PATCH] XML-RPC fix for untyped string values FS#1993

includes unit tests. Extensions welcome.
---
 .../inc/IXR_Library_IXR_Message.test.php      | 139 ++++++++++++++++++
 inc/IXR_Library.php                           |  11 +-
 2 files changed, 147 insertions(+), 3 deletions(-)
 create mode 100644 _test/cases/inc/IXR_Library_IXR_Message.test.php

diff --git a/_test/cases/inc/IXR_Library_IXR_Message.test.php b/_test/cases/inc/IXR_Library_IXR_Message.test.php
new file mode 100644
index 000000000..2a8133230
--- /dev/null
+++ b/_test/cases/inc/IXR_Library_IXR_Message.test.php
@@ -0,0 +1,139 @@
+<?php
+require_once DOKU_INC.'inc/IXR_Library.php';
+
+class ixr_library_ixr_message_test extends UnitTestCase {
+
+
+
+
+
+    function test_untypedvalue1(){
+        $xml = '<?xml version="1.0" encoding="UTF-8"?><methodCall><methodName>wiki.getBackLinks</methodName><params><param><value> change  </value></param></params></methodCall>';
+
+        $ixrmsg = new IXR_Message($xml);
+        $ixrmsg->parse();
+
+        $this->assertEqual($ixrmsg->messageType,'methodCall');
+        $this->assertEqual($ixrmsg->methodName,'wiki.getBackLinks');
+        $this->assertEqual($ixrmsg->params,array(' change  '));
+    }
+
+    function test_untypedvalue2(){
+        $xml = '<?xml version="1.0" encoding="UTF-8"?>
+                <methodCall>
+                    <methodName>wiki.getBackLinks</methodName>
+                    <params>
+                        <param>
+                            <value> change  </value>
+                        </param>
+                    </params>
+                </methodCall>';
+
+        $ixrmsg = new IXR_Message($xml);
+        $ixrmsg->parse();
+
+        $this->assertEqual($ixrmsg->messageType,'methodCall');
+        $this->assertEqual($ixrmsg->methodName,'wiki.getBackLinks');
+        $this->assertEqual($ixrmsg->params,array(' change  '));
+    }
+
+    function test_stringvalue1(){
+        $xml = '<?xml version="1.0" encoding="UTF-8"?><methodCall><methodName>wiki.getBackLinks</methodName><params><param><value><string> change  </string></value></param></params></methodCall>';
+
+        $ixrmsg = new IXR_Message($xml);
+        $ixrmsg->parse();
+
+        $this->assertEqual($ixrmsg->messageType,'methodCall');
+        $this->assertEqual($ixrmsg->methodName,'wiki.getBackLinks');
+        $this->assertEqual($ixrmsg->params,array(' change  '));
+    }
+
+    function test_stringvalue2(){
+        $xml = '<?xml version="1.0" encoding="UTF-8"?>
+                <methodCall>
+                    <methodName>wiki.getBackLinks</methodName>
+                    <params>
+                        <param>
+                            <value>
+                                <string> change  </string>
+                            </value>
+                        </param>
+                    </params>
+                </methodCall>';
+
+        $ixrmsg = new IXR_Message($xml);
+        $ixrmsg->parse();
+
+        $this->assertEqual($ixrmsg->messageType,'methodCall');
+        $this->assertEqual($ixrmsg->methodName,'wiki.getBackLinks');
+        $this->assertEqual($ixrmsg->params,array(' change  '));
+    }
+
+    function test_emptyvalue1(){
+        $xml = '<?xml version="1.0" encoding="UTF-8"?><methodCall><methodName>wiki.getBackLinks</methodName><params><param><value><string></string></value></param></params></methodCall>';
+
+        $ixrmsg = new IXR_Message($xml);
+        $ixrmsg->parse();
+
+        $this->assertEqual($ixrmsg->messageType,'methodCall');
+        $this->assertEqual($ixrmsg->methodName,'wiki.getBackLinks');
+        $this->assertEqual($ixrmsg->params,array(''));
+    }
+
+    function test_emptyvalue2(){
+        $xml = '<?xml version="1.0" encoding="UTF-8"?>
+                <methodCall>
+                    <methodName>wiki.getBackLinks</methodName>
+                    <params>
+                        <param>
+                            <value>
+                                <string></string>
+                            </value>
+                        </param>
+                    </params>
+                </methodCall>';
+
+        $ixrmsg = new IXR_Message($xml);
+        $ixrmsg->parse();
+
+        $this->assertEqual($ixrmsg->messageType,'methodCall');
+        $this->assertEqual($ixrmsg->methodName,'wiki.getBackLinks');
+        $this->assertEqual($ixrmsg->params,array(''));
+    }
+
+    function test_struct(){
+        $xml = '<?xml version=\'1.0\'?>
+                <methodCall>
+                <methodName>wiki.putPage</methodName>
+                <params>
+                <param>
+                <value><string>start</string></value>
+                </param>
+                <param>
+                <value><string>test text</string></value>
+                </param>
+                <param>
+                <value><struct>
+                <member>
+                <name>sum</name>
+                <value><string>xmlrpc edit</string></value>
+                </member>
+                <member>
+                <name>minor</name>
+                <value><string>1</string></value>
+                </member>
+                </struct></value>
+                </param>
+                </params>
+                </methodCall>';
+
+        $ixrmsg = new IXR_Message($xml);
+        $ixrmsg->parse();
+
+        $this->assertEqual($ixrmsg->messageType,'methodCall');
+        $this->assertEqual($ixrmsg->methodName,'wiki.putPage');
+        $this->assertEqual($ixrmsg->params,array('start','test text',array('sum'=>'xmlrpc edit','minor'=>'1')));
+    }
+
+}
+//Setup VIM: ex: et ts=4 enc=utf-8 :
diff --git a/inc/IXR_Library.php b/inc/IXR_Library.php
index 2fb7dfe68..c7f83a6d6 100644
--- a/inc/IXR_Library.php
+++ b/inc/IXR_Library.php
@@ -136,6 +136,7 @@ class IXR_Message {
     var $_value;
     var $_currentTag;
     var $_currentTagContents;
+    var $_lastseen;
     // The XML parser
     var $_parser;
     function IXR_Message ($message) {
@@ -194,6 +195,7 @@ class IXR_Message {
                 $this->_arraystructs[] = array();
                 break;
         }
+        $this->_lastseen = $tag;
     }
     function cdata($parser, $cdata) {
         $this->_currentTagContents .= $cdata;
@@ -225,9 +227,11 @@ class IXR_Message {
                 break;
             case 'value':
                 // "If no type is indicated, the type is string."
-                $value = (string)$this->_currentTagContents;
-                $this->_currentTagContents = '';
-                $valueFlag = true;
+                if($this->_lastseen == 'value'){
+                    $value = (string)$this->_currentTagContents;
+                    $this->_currentTagContents = '';
+                    $valueFlag = true;
+                }
                 break;
             case 'boolean':
                 $value = (boolean)trim($this->_currentTagContents);
@@ -278,6 +282,7 @@ class IXR_Message {
                 $this->params[] = $value;
             }
         }
+        $this->_lastseen = $tag;
     }
 }
 
-- 
GitLab