From 811dfd3a136ff482c6d84fd19e6545bd76b60804 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Tue, 17 Dec 2024 21:38:51 +0800 Subject: [PATCH] Support schemeless funding URLs The [GitHub documentation][1] for FUNDING.yml specifically notes that if a custom URL is in the Array format, and includes `:` then it must be quoted. From this we can infer that the custom URL does not have to contain a `:` at all. The example for a Custom URL also gives an example of an unquoted URL without any `:` character: ``` custom: ["https://www.paypal.me/octocat", octocat.com] ``` However if a repository uses a URL in this format it is currently rejected because it does not specify a scheme. Furthermore the `parse_url` method treats the `octocat.com` example as a path and not a host. The same is true for URLs such as `octocat.com/funding/example.html`. This patch adds an additional allowance for the URL filter to capture the case where a URL has no scheme or host, but does have a path. [1]: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/displaying-a-sponsor-button-in-your-repository#about-funding-files --- src/Composer/Package/Loader/ValidatingArrayLoader.php | 8 ++++++++ .../Test/Package/Loader/ValidatingArrayLoaderTest.php | 8 ++++++++ tests/Composer/Test/Repository/Vcs/GitHubDriverTest.php | 2 +- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/Composer/Package/Loader/ValidatingArrayLoader.php b/src/Composer/Package/Loader/ValidatingArrayLoader.php index a6431d2df..1bc2145d3 100644 --- a/src/Composer/Package/Loader/ValidatingArrayLoader.php +++ b/src/Composer/Package/Loader/ValidatingArrayLoader.php @@ -623,6 +623,14 @@ class ValidatingArrayLoader implements LoaderInterface } $bits = parse_url($value); + if ($bits === false) { + return false; + } + + if (array_key_exists('path', $bits) && !array_key_exists('scheme', $bits) && !array_key_exists('host', $bits)) { + return true; + } + if (empty($bits['scheme']) || empty($bits['host'])) { return false; } diff --git a/tests/Composer/Test/Package/Loader/ValidatingArrayLoaderTest.php b/tests/Composer/Test/Package/Loader/ValidatingArrayLoaderTest.php index 9b70911ee..796cc5118 100644 --- a/tests/Composer/Test/Package/Loader/ValidatingArrayLoaderTest.php +++ b/tests/Composer/Test/Package/Loader/ValidatingArrayLoaderTest.php @@ -84,6 +84,14 @@ class ValidatingArrayLoaderTest extends TestCase [ 'url' => 'https://example.org/fund', ], + [ + 'type' => 'custom', + 'url' => 'example.com', + ], + [ + 'type' => 'custom', + 'url' => 'example.com/fund#fundus', + ], ], 'require' => [ 'a/b' => '1.*', diff --git a/tests/Composer/Test/Repository/Vcs/GitHubDriverTest.php b/tests/Composer/Test/Repository/Vcs/GitHubDriverTest.php index 9902af644..514572cda 100644 --- a/tests/Composer/Test/Repository/Vcs/GitHubDriverTest.php +++ b/tests/Composer/Test/Repository/Vcs/GitHubDriverTest.php @@ -166,7 +166,7 @@ class GitHubDriverTest extends TestCase ['url' => $repoApiUrl, 'body' => '{"master_branch": "test_master", "owner": {"login": "composer"}, "name": "packagist"}'], ['url' => 'https://api.github.com/repos/composer/packagist/contents/composer.json?ref=feature%2F3.2-foo', 'body' => '{"encoding":"base64","content":"'.base64_encode('{"support": {"source": "'.$repoUrl.'" }}').'"}'], ['url' => 'https://api.github.com/repos/composer/packagist/commits/feature%2F3.2-foo', 'body' => '{"commit": {"committer":{ "date": "2012-09-10"}}}'], - ['url' => 'https://api.github.com/repos/composer/packagist/contents/.github/FUNDING.yml', 'body' => '{"encoding": "base64", "content": "'.base64_encode("custom: https://example.com").'"}'], + ['url' => 'https://api.github.com/repos/composer/packagist/contents/.github/FUNDING.yml', 'body' => '{"encoding": "base64", "content": "'.base64_encode("custom: [\"https://example.com/funding\", octocat.com]").'"}'], ], true );