Selaa lähdekoodia

Fix FILTER_VALIDATE_URL not supporting IDNs

Jordi Boggiano 12 vuotta sitten
vanhempi
commit
cbd91b5952

+ 20 - 9
src/Composer/Package/Loader/ValidatingArrayLoader.php

@@ -91,7 +91,7 @@ class ValidatingArrayLoader implements LoaderInterface
                     }
                     }
                 }
                 }
                 if (isset($author['homepage']) && !$this->filterUrl($author['homepage'])) {
                 if (isset($author['homepage']) && !$this->filterUrl($author['homepage'])) {
-                    $this->warnings[] = 'authors.'.$key.'.homepage : invalid value, must be a valid http/https URL';
+                    $this->warnings[] = 'authors.'.$key.'.homepage : invalid value, must be an http/https URL';
                     unset($this->config['authors'][$key]['homepage']);
                     unset($this->config['authors'][$key]['homepage']);
                 }
                 }
                 if (isset($author['email']) && !filter_var($author['email'], FILTER_VALIDATE_EMAIL)) {
                 if (isset($author['email']) && !filter_var($author['email'], FILTER_VALIDATE_EMAIL)) {
@@ -120,16 +120,14 @@ class ValidatingArrayLoader implements LoaderInterface
                 unset($this->config['support']['email']);
                 unset($this->config['support']['email']);
             }
             }
 
 
-            if (isset($this->config['support']['irc'])
-                && (!filter_var($this->config['support']['irc'], FILTER_VALIDATE_URL) || !preg_match('{^irc://}iu', $this->config['support']['irc']))
-            ) {
-                $this->warnings[] = 'support.irc : invalid value, must be ';
+            if (isset($this->config['support']['irc']) && !$this->filterUrl($this->config['support']['irc'], array('irc'))) {
+                $this->warnings[] = 'support.irc : invalid value, must be a irc://<server>/<channel> URL';
                 unset($this->config['support']['irc']);
                 unset($this->config['support']['irc']);
             }
             }
 
 
             foreach (array('issues', 'forum', 'wiki', 'source') as $key) {
             foreach (array('issues', 'forum', 'wiki', 'source') as $key) {
                 if (isset($this->config['support'][$key]) && !$this->filterUrl($this->config['support'][$key])) {
                 if (isset($this->config['support'][$key]) && !$this->filterUrl($this->config['support'][$key])) {
-                    $this->warnings[] = 'support.'.$key.' : invalid value, must be a valid http/https URL';
+                    $this->warnings[] = 'support.'.$key.' : invalid value, must be an http/https URL';
                     unset($this->config['support'][$key]);
                     unset($this->config['support'][$key]);
                 }
                 }
             }
             }
@@ -318,7 +316,7 @@ class ValidatingArrayLoader implements LoaderInterface
         }
         }
 
 
         if (!$this->filterUrl($this->config[$property])) {
         if (!$this->filterUrl($this->config[$property])) {
-            $this->warnings[] = $property.' : invalid value, must be a valid http/https URL';
+            $this->warnings[] = $property.' : invalid value, must be an http/https URL';
             unset($this->config[$property]);
             unset($this->config[$property]);
 
 
             return false;
             return false;
@@ -327,8 +325,21 @@ class ValidatingArrayLoader implements LoaderInterface
         return true;
         return true;
     }
     }
 
 
-    private function filterUrl($value)
+    private function filterUrl($value, array $schemes = array('http', 'https'))
     {
     {
-        return filter_var($value, FILTER_VALIDATE_URL) && preg_match('{^https?://}iu', $value);
+        if ($value === '') {
+            return true;
+        }
+
+        $bits = parse_url($value);
+        if (empty($bits['scheme']) || empty($bits['host'])) {
+            return false;
+        }
+
+        if (!in_array($bits['scheme'], $schemes, true)) {
+            return false;
+        }
+
+        return true;
     }
     }
 }
 }

+ 2 - 1
src/Composer/Repository/ComposerRepository.php

@@ -58,7 +58,8 @@ class ComposerRepository extends ArrayRepository implements NotifiableRepository
             $repoConfig['url'] = (extension_loaded('openssl') ? 'https' : 'http') . substr($repoConfig['url'], 6);
             $repoConfig['url'] = (extension_loaded('openssl') ? 'https' : 'http') . substr($repoConfig['url'], 6);
         }
         }
 
 
-        if (function_exists('filter_var') && version_compare(PHP_VERSION, '5.3.3', '>=') && !filter_var($repoConfig['url'], FILTER_VALIDATE_URL)) {
+        $urlBits = parse_url($repoConfig['url']);
+        if (empty($urlBits['scheme']) || empty($urlBits['host'])) {
             throw new \UnexpectedValueException('Invalid url given for Composer repository: '.$repoConfig['url']);
             throw new \UnexpectedValueException('Invalid url given for Composer repository: '.$repoConfig['url']);
         }
         }
 
 

+ 2 - 1
src/Composer/Repository/PearRepository.php

@@ -49,7 +49,8 @@ class PearRepository extends ArrayRepository
             $repoConfig['url'] = 'http://'.$repoConfig['url'];
             $repoConfig['url'] = 'http://'.$repoConfig['url'];
         }
         }
 
 
-        if (function_exists('filter_var') && version_compare(PHP_VERSION, '5.3.3', '>=') && !filter_var($repoConfig['url'], FILTER_VALIDATE_URL)) {
+        $urlBits = parse_url($repoConfig['url']);
+        if (empty($urlBits['scheme']) || empty($urlBits['host'])) {
             throw new \UnexpectedValueException('Invalid url given for PEAR repository: '.$repoConfig['url']);
             throw new \UnexpectedValueException('Invalid url given for PEAR repository: '.$repoConfig['url']);
         }
         }
 
 

+ 6 - 6
tests/Composer/Test/Package/Loader/ValidatingArrayLoaderTest.php

@@ -60,7 +60,7 @@ class ValidatingArrayLoaderTest extends \PHPUnit_Framework_TestCase
                         ),
                         ),
                         array(
                         array(
                             'name' => 'Bob',
                             'name' => 'Bob',
-                            'homepage' => 'http://example.com',
+                            'homepage' => '',
                         ),
                         ),
                     ),
                     ),
                     'support' => array(
                     'support' => array(
@@ -243,7 +243,7 @@ class ValidatingArrayLoaderTest extends \PHPUnit_Framework_TestCase
                     'homepage' => 'foo:bar',
                     'homepage' => 'foo:bar',
                 ),
                 ),
                 array(
                 array(
-                    'homepage : invalid value, must be a valid http/https URL'
+                    'homepage : invalid value, must be an http/https URL'
                 )
                 )
             ),
             ),
             array(
             array(
@@ -257,10 +257,10 @@ class ValidatingArrayLoaderTest extends \PHPUnit_Framework_TestCase
                     ),
                     ),
                 ),
                 ),
                 array(
                 array(
-                    'support.source : invalid value, must be a valid http/https URL',
-                    'support.forum : invalid value, must be a valid http/https URL',
-                    'support.issues : invalid value, must be a valid http/https URL',
-                    'support.wiki : invalid value, must be a valid http/https URL',
+                    'support.source : invalid value, must be an http/https URL',
+                    'support.forum : invalid value, must be an http/https URL',
+                    'support.issues : invalid value, must be an http/https URL',
+                    'support.wiki : invalid value, must be an http/https URL',
                 )
                 )
             ),
             ),
         );
         );

+ 1 - 1
tests/Composer/Test/Repository/ComposerRepositoryTest.php

@@ -25,7 +25,7 @@ class ComposerRepositoryTest extends TestCase
     public function testLoadData(array $expected, array $repoPackages)
     public function testLoadData(array $expected, array $repoPackages)
     {
     {
         $repoConfig = array(
         $repoConfig = array(
-            'url' => 'file://',
+            'url' => 'http://example.org',
         );
         );
 
 
         $repository = $this->getMock(
         $repository = $this->getMock(