php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #79684 C14N sorts the attributes (incorrectly) when not loaded
Submitted: 2020-06-09 15:25 UTC Modified: 2020-06-10 11:33 UTC
Votes:1
Avg. Score:3.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: and_spam+php_net at rump dot dk Assigned: cmb (profile)
Status: Not a bug Package: DOM XML related
PHP Version: 7.3.18 OS: Linux
Private report: No CVE-ID: None
 [2020-06-09 15:25 UTC] and_spam+php_net at rump dot dk
Description:
------------
The test script perform the same operation twice but the result (the last two lines) are different depending on if the XML has been created dynamically or loaded (in this case by storing the dynamically created XML and (re)loading it).

You may reorder the createAttribute lines as you want but the last two lines will always be the same - the last line being correct.

Test script:
---------------
$xml = new DOMDocument();

$element = $xml->createElement('saml:Assertion');
$xml_saml_assertion = $xml->appendChild($element);
	
$attribute = $xml->createAttribute('id');
$attribute->value = 'IDCard';
$xml_saml_assertion->appendChild($attribute);
	
$attribute = $xml->createAttribute('xmlns:saml');
$attribute->value = 'urn:oasis:names:tc:SAML:2.0:assertion';
$xml_saml_assertion->appendChild($attribute);
	
$attribute = $xml->createAttribute('Version');
$attribute->value = '2.0';
$xml_saml_assertion->appendChild($attribute);

print("<pre>" . htmlentities($xml->saveXML()) . "</pre><br>\n");
print("<pre>" . htmlentities($xml->C14N(TRUE)) . "</pre><br>\n");
$xml->loadXML($xml->saveXML());
print("<pre>" . htmlentities($xml->C14N(TRUE)) . "</pre><br>\n");

Expected result:
----------------
<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Version="2.0" id="IDCard"></saml:Assertion>



Actual result:
--------------
<saml:Assertion Version="2.0" id="IDCard" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"></saml:Assertion>

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-06-09 16:29 UTC] cmb@php.net
-Status: Open +Status: Not a bug -Assigned To: +Assigned To: cmb
 [2020-06-09 16:29 UTC] cmb@php.net
Just adding the namespace declaration as normal attribute is not
supported.  You should instead create the `saml:Assertion` element
as node with associated namespace; see <https://3v4l.org/lsIVL>
for the correct code.
 [2020-06-09 18:01 UTC] and_spam+php_net at rump dot dk
It is a bug!

The XML was just the smallest sample I could create to prove the point.
I could create a full code as suggested but the result is exactly the same.

Please reopen and examine this ticket. I can provide way more code if you want to.
 [2020-06-09 21:44 UTC] cmb@php.net
The DOM living standard states[1]:

| Return a new attribute whose local name is localName […]

and[2]:

| Attributes have a […] namespace prefix (null or a non-empty
| string), local name (a non-empty string) […]

So

    $xml->createAttribute('xmlns:saml');

creates an attribute with *local name* 'xmlns:saml', which is not
magically converted to a namespace declaration on the attribute's
element.  You can see that when you var_dump() the respective
attribute[3]; it's just a regular attribute with the localName
'xmlns:saml', and the namespace URI as testContent.  When you
convert this element to its textual representation, it looks like
its properly namespaced pendant, but it isn't quite the same
(unless reparsed).

[1] <https://dom.spec.whatwg.org/#dom-document-createattribute>
[2] <https://dom.spec.whatwg.org/#concept-attribute-local-name>
[3] <https://3v4l.org/NNUsV>
 [2020-06-10 03:05 UTC] a at b dot c dot de
I for one am not seeing the difference between

<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Version="2.0" id="IDCard"></saml:Assertion>

and 

<saml:Assertion Version="2.0" id="IDCard" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"></saml:Assertion>

I mean, the attributes are in a different order, but that has no significance, right?[1]

[1] https://www.w3.org/TR/REC-xml/#sec-starttags
 [2020-06-10 07:48 UTC] and_spam+php_net at rump dot dk
You are totally correct [a at b dot c dot de] but also wrong. ;-)
C14N are used to extract the XML as a string just as saveXML but the content, incl. attributes, have to be in a specific order so the hash of the text always return the same result.
 [2020-06-10 11:33 UTC] and_spam+php_net at rump dot dk
cmb@php.net: I stand corrected. Thanks. Sorry for not looking at your code example - I was to fast and just thought you were linking to some standard text.
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Wed Dec 02 04:01:24 2020 UTC