Bug #66084 [Opn]: simplexml_load_string() mangles empty node name

From: Date: Thu, 03 Apr 2014 17:28:09 +0000
Subject: Bug #66084 [Opn]: simplexml_load_string() mangles empty node name
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-185074@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=66084&edit=1

 ID:                 66084
 User updated by:    php at kenman dot net
 Reported by:        php at kenman dot net
 Summary:            simplexml_load_string() mangles empty node name
 Status:             Open
 Type:               Bug
 Package:            SimpleXML related
 Operating System:   Win7
 PHP Version:        5.5Git-2013-11-12 (snap)
 Block user comment: N
 Private report:     N

 New Comment:

I respectfully disagree, this is not merely a var_dump() issue. It may be true that there are
var_dump() anomalies here, but that's not the root of the issue.

The bug was exposed for me by missing data in the final output (JSON). I traced the data stream back
and discovered what's reported in this ticket.

Here's a reproduction that doesn't use var_dump():

echo
json_encode(simplexml_load_string('<a><b/><c><x/></c></a>')),
PHP_EOL;
echo json_encode(simplexml_load_string('<a><b/><c>
<x/></c></a>'));


Previous Comments:
------------------------------------------------------------------------
[2014-04-02 15:55:47] ab@php.net

Ref bug #52463, same var_dump() issue.

------------------------------------------------------------------------
[2013-11-14 21:57:55] php at kenman dot net

Just a note for anyone else that might come across this problem...

A little background: I create the XML originally as a DOMDocument, and then I call saveXML() to
generate the XML string. Then, I load that XML with simplexml_load_string() and eventually convert
it to JSON (don't ask about the convoluted process, not my choice).

I was able to work-around the issue by setting DOMDocument->formatOutput = true -- as per my last
note, the whitespace seems to hide the issue, and so now when I pass it to simplexml_load_string() I
get the expected output.

------------------------------------------------------------------------
[2013-11-14 17:23:21] php at kenman dot net

This just keeps getting stranger; apparently, whitespace influences this behavior.

Both of these lines produce the expected output:

    var_dump(simplexml_load_string('<a><b/><c>
<x/></c></a>')->c);
    var_dump(simplexml_load_string('<a><b/><c><x/>
</c></a>')->c);

However, whitespace added at any other point in the string will still produce the unexpected output.

------------------------------------------------------------------------
[2013-11-12 19:31:40] php at kenman dot net

Curiously, the element is actually present at the expected string key, even though it's not
represented in the raw var_dump():

var_dump(isset(simplexml_load_string('<a><b/><c><x/></c></a>')->c->x));

That will return TRUE, even though var_dump() exposes no such element (nor does get_object_vars()).

------------------------------------------------------------------------
[2013-11-12 17:31:16] php at kenman dot net

Description:
------------
Since PHP 5.4.16 (at least), simplexml_load_string() incorrectly interprets some XML strings. For
specific inputs with empty nodes, node names are converted to integers.

Works as expected in 5.3.10 (libxml 2.7.7); does not work as expected in 5.4.16 (libxml 2.7.8) or
5.5.6-dev (libxml 2.9.1). Seems to be related to libxml2's xmlReadMemory(), though don't
quote me on that.

Further observations:

* Removing the <b/> node results in the expected output, though otherwise manipulating
<b/> (adding text content, including a closing tag, etc.) has no effect.
* Changing the problematic node to non-selfclosing has no effect.
* Adding a value to <x>, such as <x>1</x>, results in the expected output.
* Adding an attribute to <x> has no effect.
* Including the XML prologue has no effect.
* libxml_use_internal_errors(true) does not report any errors.
* The libxml option LIBXML_NOEMPTYTAG seems to have no effect.

Test script:
---------------
var_dump(simplexml_load_string('<a><b/><c><x/></c></a>')->c);

Expected result:
----------------
object(SimpleXMLElement)#2 (1) {
  ["x"]=>
  object(SimpleXMLElement)#3 (0) {
  }
}

Actual result:
--------------
object(SimpleXMLElement)#2 (1) {
  [0]=>
  object(SimpleXMLElement)#3 (1) {
    [0]=>
    object(SimpleXMLElement)#4 (0) {
    }
  }
}


------------------------------------------------------------------------



-- 
Edit this bug report at https://bugs.php.net/bug.php?id=66084&edit=1


Thread (23 messages)

« previous php.bugs (#185074) next »