Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP DOMDocument createElement obfuscates ampersand

I am using PHP DOMDocument library in order to create a 'script' tag element with a, well, a javascript value and insert it in the DOM.

This is what I do:

$scriptElement = $doc->createElement('script',$scriptTagVal);
echo $scriptElement->nodeValue;                                                                  
$someNode->parentNode->insertBefore($scriptElement,$postRttScriptNode); 

This behaves the way I expect it to, it inserts an element right before 'someNode'. However, it does something strange, it obfuscates the ampersand (&). Single Ampersands (&) do not exist, and double Ampersands (&&) are bought down to single ampersands.

Crazy? Well, I tried doing this:

$scriptElement = $doc->createElement('script','return "undefined" !== typeof b **&&** null !== b ? b.getAttribute("content") : 0');

And if I echo out $scriptElement->nodeValue,

I get

return "undefined" !== typeof b **&** null !== b ? b.getAttribute("content") : 0'

I am assuming this is virtually unheard of, but I tried creating different elements with values that contain double ampersands. Something like:

 $scriptElement = $doc->createElement('p','Why does DOMDocument obfuscate double
            ampersands(&&)');    

And the result that is outputted to my browser is a

tag with the value:

Why does DOMDocument obfuscate double ampersands(

Special characters perhaps? Is there anyway I can get around this? I mean, surely there has to be a way to use DOMDocument to insert javascript in HTML, right?

like image 753
Parijat Kalia Avatar asked Jun 24 '14 00:06

Parijat Kalia


1 Answers

As noted in http://www.php.net/manual/en/domdocument.createelement.php

The value will not be escaped. Use DOMDocument::createTextNode() to create a text node with escaping support

With that you can try:

$doc = new DomDocument();
$scriptContent = 'return "undefined" !== typeof b **&&** null !== b ? b.getAttribute("content") : 0';
$scriptElement = $doc->createElement('script');
$scriptElement->appendChild($doc->createTextNode($scriptContent));
$doc->appendChild($scriptElement);
echo $doc->saveXML();

you may need to use $doc->ownerDocument->createTextNode() when building your text node, this is untested as I don't have a run-able code snippet.

like image 164
Scuzzy Avatar answered Sep 29 '22 12:09

Scuzzy