Some time ago I’d written a modification to the XML-RPC lib from Incutio (see http://www.icheb.info/2007/01/28/ixr-incutio-xml-rpc-with-ssl-support/).

But there was more… Today, a friend mailed me with a problem (and solution) for a new problem everyone has missed so far.
I’ve placed a modified version online at: http://www.icheb.nl/icheb_info_blog/IXR/IXR_Library.inc.php_2.txt

If you actually want to know what’s wrong, and why, click the more button below ;) .

Recently, I had to create some webservices using the IXR Library.

After having designed the webservices, I created the server according to a basic IXRServer extend.

Just to test, I then wrote a simple client, which worked just fine.
However, when I wanted to migrate the PHP based client to an AJAX based web client, I stumbled upon some issues.

Let me try to explain this by example.

A pretty normal XML request for IXR looks as follows (without the xml declaration):
<pre lang="xml" line="1">

ixr.test.fetchVar

testvar testvar2
</pre>

Take note of the fact that this request has NO typing information, for it cannot be generated by the JS libraries I use.
Under normal circumstances (using the IXRClient), the parameter type information would have shown, as in e.g.:

<pre lang="xml" line="1"> testvar testvar2</pre>

It is exactly this however, that creates the issue. Where the normal IXRCLient will correctly return data,
The AJAX based client will not show anything.

Digging into the code, I discovered the error. Things start to go wrong as soon as there’s NO typing information available for a parameter.

Dumping my data, I discovered that all ‘newline’ characters were left intact.
In the case as described, there’s more then one: just after , after and after

For the first encountered variable, I this end up with a parsed value of “\n\n\ntestvar”
Every encountered newline character seems to be added to the value, but NOT removed, as I expected.

Now for a solution:
Inside the IXRMessage, things are parsed by an XMLParser.
Inside the ‘tag_close’ call, things are rendered and converted to contain correct values.
Except for in case, the case where there’s no typing information!
In every other case (except for base64), the value to be set is first trim()’d.

The code for the ‘value’ tag, however, is NOT:
<pre lang="PHP" line="1"> case ‘value’:
// “If no type is indicated, the type is string.”
if (trim($this->_currentTagContents) != ”) {
$value = (string)$this->_currentTagContents;
$this->_currentTagContents = ”;
$valueFlag = true;
}
break;
</pre>

As one can see from the code above, the if-statement does a trim, but the trimmed string is NEVER assigned.
One possible solution for the code above could be (I decided to break down in two lines):

<pre lang="php" line="1">
if (trim($this->_currentTagContents) != ”) {
$value = trim($this->_currentTagContents);
$value = (string)$value;
$this->_currentTagContents = ”;
$valueFlag = true;
}
break;
</pre>

This solution now also strips the surrounding whitespace, tabs, newlines, etc from the input, as can be expected!

Rogier van Dongen, thank you for this patch :) .

, ,
Trackback

no comment untill now

Add your comment now

You must be logged in to post a comment.