Browse Source

Add option to disable local XML file parsing.

Provide an option to disable reading local files. This is very useful
when accepting 'XML' data from request data. In this situation we don't
want to parse local file as XML.
Mark Story 10 years ago
parent
commit
2cde19f24c

+ 1 - 1
src/Controller/Component/RequestHandlerComponent.php

@@ -256,7 +256,7 @@ class RequestHandlerComponent extends Component
     public function convertXml($xml)
     {
         try {
-            $xml = Xml::build($xml);
+            $xml = Xml::build($xml, ['readFile' => false]);
             if (isset($xml->data)) {
                 return Xml::toArray($xml->data);
             }

+ 5 - 1
src/Utility/Xml.php

@@ -86,6 +86,9 @@ class Xml
      * - `return` Can be 'simplexml' to return object of SimpleXMLElement or 'domdocument' to return DOMDocument.
      * - `loadEntities` Defaults to false. Set to true to enable loading of `<!ENTITY` definitions. This
      *   is disabled by default for security reasons.
+     * - `readFile` Set to false to disable file reading. This is important to disable when
+     *   putting user data into Xml::build(). If enabled local files will be read if they exist.
+     *   Defaults to true for backwards compatibility reasons.
      * - If using array as input, you can pass `options` from Xml::fromArray.
      *
      * @param string|array $input XML string, a path to a file, a URL or an array
@@ -98,6 +101,7 @@ class Xml
         $defaults = [
             'return' => 'simplexml',
             'loadEntities' => false,
+            'readFile' => true
         ];
         $options += $defaults;
 
@@ -109,7 +113,7 @@ class Xml
             return static::_loadXml($input, $options);
         }
 
-        if (file_exists($input)) {
+        if ($options['readFile'] && file_exists($input)) {
             return static::_loadXml(file_get_contents($input), $options);
         }
 

+ 21 - 0
tests/TestCase/Controller/Component/RequestHandlerComponentTest.php

@@ -507,6 +507,27 @@ class RequestHandlerComponentTest extends TestCase
     }
 
     /**
+     * Test that file handles are ignored as XML data.
+     *
+     * @return void
+     * @triggers Controller.startup $this->Controller
+     */
+    public function testStartupIgnoreFileAsXml()
+    {
+        $this->Controller->request = $this->getMock('Cake\Network\Request', ['_readInput']);
+        $this->Controller->request->expects($this->any())
+            ->method('_readInput')
+            ->will($this->returnValue('/dev/random'));
+
+        $this->Controller->request->env('REQUEST_METHOD', 'POST');
+        $this->Controller->request->env('CONTENT_TYPE', 'application/xml');
+
+        $event = new Event('Controller.startup', $this->Controller);
+        $this->RequestHandler->startup($event);
+        $this->assertEquals([], $this->Controller->request->data);
+    }
+
+    /**
      * Test mapping a new type and having startup process it.
      *
      * @return void

+ 12 - 0
tests/TestCase/Utility/XmlTest.php

@@ -116,6 +116,18 @@ class XmlTest extends TestCase
     }
 
     /**
+     * Test that the readFile option disables local file parsing.
+     *
+     * @expectedException \Cake\Utility\Exception\XmlException
+     * @return void
+     */
+    public function testBuildFromFileWhenDisabled()
+    {
+        $xml = CORE_TESTS . 'Fixture/sample.xml';
+        $obj = Xml::build($xml, ['readFile' => false]);
+    }
+
+    /**
      * Test build() with a Collection instance.
      *
      * @return void