Selaa lähdekoodia

Merge pull request #375 from urakozz/master

Fixing tests for bugfixed PHP versions
Johannes 10 vuotta sitten
vanhempi
commit
43bdac4986

+ 31 - 1
src/JMS/Serializer/XmlDeserializationVisitor.php

@@ -63,7 +63,7 @@ class XmlDeserializationVisitor extends AbstractVisitor
         $dom->loadXML($data);
         $dom->loadXML($data);
         foreach ($dom->childNodes as $child) {
         foreach ($dom->childNodes as $child) {
             if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) {
             if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) {
-                $internalSubset = str_replace(array("\n", "\r"), '', $child->internalSubset);
+                $internalSubset = $this->getDomDocumentTypeEntitySubset($child, $data);
                 if (!in_array($internalSubset, $this->doctypeWhitelist, true)) {
                 if (!in_array($internalSubset, $this->doctypeWhitelist, true)) {
                     throw new InvalidArgumentException(sprintf(
                     throw new InvalidArgumentException(sprintf(
                         'The document type "%s" is not allowed. If it is safe, you may add it to the whitelist configuration.',
                         'The document type "%s" is not allowed. If it is safe, you may add it to the whitelist configuration.',
@@ -346,4 +346,34 @@ class XmlDeserializationVisitor extends AbstractVisitor
     {
     {
         return $this->doctypeWhitelist;
         return $this->doctypeWhitelist;
     }
     }
+
+    /**
+     * Retrieves internalSubset even in bugfixed php versions
+     *
+     * @param \DOMDocumentType $child
+     * @param string $data
+     * @return string
+     */
+    private function getDomDocumentTypeEntitySubset(\DOMDocumentType $child, $data)
+    {
+        if(null !== $child->internalSubset){
+            return str_replace(array("\n", "\r"), '', $child->internalSubset);
+        }
+        $startPos = $endPos = stripos($data, '<!doctype');
+        $braces = 0;
+        do {
+            $char = $data[$endPos++];
+            if($char === '<'){
+                ++$braces;
+            }
+            if($char === '>'){
+                --$braces;
+            }
+        } while ($braces > 0);
+        $internalSubset = substr($data, $startPos, $endPos-$startPos);
+        $internalSubset = str_replace(array("\n", "\r"), '', $internalSubset);
+        $internalSubset = preg_replace('/\s{2,}/', ' ', $internalSubset);
+        $internalSubset = str_replace(array("[ <!", "> ]>"), array('[<!', '>]>'), $internalSubset);
+        return $internalSubset;
+    }
 }
 }

+ 2 - 0
tests/JMS/Serializer/Tests/Serializer/XmlSerializationTest.php

@@ -93,6 +93,7 @@ class XmlSerializationTest extends BaseSerializationTest
      */
      */
     public function testExternalEntitiesAreDisabledByDefault()
     public function testExternalEntitiesAreDisabledByDefault()
     {
     {
+        
         $this->deserialize('<?xml version="1.0"?>
         $this->deserialize('<?xml version="1.0"?>
             <!DOCTYPE author [
             <!DOCTYPE author [
                 <!ENTITY foo SYSTEM "php://filter/read=convert.base64-encode/resource='.basename(__FILE__).'">
                 <!ENTITY foo SYSTEM "php://filter/read=convert.base64-encode/resource='.basename(__FILE__).'">
@@ -108,6 +109,7 @@ class XmlSerializationTest extends BaseSerializationTest
      */
      */
     public function testDocumentTypesAreNotAllowed()
     public function testDocumentTypesAreNotAllowed()
     {
     {
+        
         $this->deserialize('<?xml version="1.0"?><!DOCTYPE foo><foo></foo>', 'stdClass');
         $this->deserialize('<?xml version="1.0"?><!DOCTYPE foo><foo></foo>', 'stdClass');
     }
     }