diff --git a/src/Composer/Repository/Vcs/GitLabDriver.php b/src/Composer/Repository/Vcs/GitLabDriver.php index 042c1d8a9..ed91056d4 100644 --- a/src/Composer/Repository/Vcs/GitLabDriver.php +++ b/src/Composer/Repository/Vcs/GitLabDriver.php @@ -228,7 +228,24 @@ class GitLabDriver extends VcsDriver */ public function getApiUrl() { - return $this->scheme.'://'.$this->originUrl.'/api/v3/projects/'.$this->owner.'%2F'.$this->repository; + return $this->scheme.'://'.$this->originUrl.'/api/v3/projects/'.$this->urlEncodeAll($this->owner).'%2F'.$this->urlEncodeAll($this->repository); + } + + /** + * Urlencode all non alphanumeric characters. rawurlencode() can not be used as it does not encode `.` + * + * @param string $string + * @return string + */ + private function urlEncodeAll($string) + { + $encoded = ''; + for ($i = 0; isset($string[$i]); $i++) { + $character = $string[$i]; + if (!ctype_alnum($character)) $character = '%' . sprintf('%02X', ord($character)); + $encoded .= $character; + } + return $encoded; } /** diff --git a/src/Composer/Util/Filesystem.php b/src/Composer/Util/Filesystem.php index 847f8d8ee..2ac6a54fe 100644 --- a/src/Composer/Util/Filesystem.php +++ b/src/Composer/Util/Filesystem.php @@ -444,7 +444,8 @@ class Filesystem $prefix = ''; $absolute = false; - if (preg_match('{^([0-9a-z]+:(?://(?:[a-z]:)?)?)}i', $path, $match)) { + // extract a prefix being a protocol://, protocol:, protocol://drive: or simply drive: + if (preg_match('{^( [0-9a-z]{2,}+: (?: // (?: [a-z]: )? )? | [a-z]: )}ix', $path, $match)) { $prefix = $match[1]; $path = substr($path, strlen($prefix)); } diff --git a/tests/Composer/Test/Util/FilesystemTest.php b/tests/Composer/Test/Util/FilesystemTest.php index 17297b916..4e60b0ce9 100644 --- a/tests/Composer/Test/Util/FilesystemTest.php +++ b/tests/Composer/Test/Util/FilesystemTest.php @@ -204,12 +204,18 @@ class FilesystemTest extends TestCase array('../foo', '../foo'), array('c:/foo/bar', 'c:/foo//bar'), array('C:/foo/bar', 'C:/foo/./bar'), + array('C:/foo/bar', 'C://foo//bar'), + array('C:/foo/bar', 'C:///foo//bar'), array('C:/bar', 'C:/foo/../bar'), array('/bar', '/foo/../bar/'), array('phar://c:/Foo', 'phar://c:/Foo/Bar/..'), + array('phar://c:/Foo', 'phar://c:///Foo/Bar/..'), array('phar://c:/', 'phar://c:/Foo/Bar/../../../..'), array('/', '/Foo/Bar/../../../..'), array('/', '/'), + array('/', '//'), + array('/', '///'), + array('/Foo', '///Foo'), array('c:/', 'c:\\'), array('../src', 'Foo/Bar/../../../src'), array('c:../b', 'c:.\\..\\a\\..\\b'),