diff options
| -rw-r--r-- | lua/mason-core/purl.lua | 8 | ||||
| -rw-r--r-- | tests/fixtures/purl-test-suite-data.json | 12 | ||||
| -rw-r--r-- | tests/mason-core/purl_spec.lua | 32 |
3 files changed, 42 insertions, 10 deletions
diff --git a/lua/mason-core/purl.lua b/lua/mason-core/purl.lua index 6bda134f..65acbdd1 100644 --- a/lua/mason-core/purl.lua +++ b/lua/mason-core/purl.lua @@ -16,7 +16,7 @@ local function percent_encode(char) return ("%%%x"):format(string.byte(char, 1, 1)) end -local decode_percent_encoding = _.gsub("%%([A-F0-9][A-F0-9])", _.compose(string.char, parse_hex)) +local decode_percent_encoding = _.gsub("%%([A-Fa-f0-9][A-Fa-f0-9])", _.compose(string.char, parse_hex)) local encode_percent_encoding = _.gsub("[!#$&'%(%)%*%+;=%?@%[%] ]", percent_encode) local function validate_conan(purl) @@ -162,6 +162,11 @@ local github = _.evolve { namespace = _.to_lower, } +local composer = _.evolve { + name = _.to_lower, + namespace = _.to_lower, +} + local is_mlflow_azuredatabricks = _.all_pass { _.prop_eq("type", "mlflow"), _.path_satisfies(_.matches "^https?://.*azuredatabricks%.net", { "qualifiers", "repository_url" }), @@ -176,6 +181,7 @@ local type_validations = _.cond { local type_transforms = _.cond { { _.prop_eq("type", "bitbucket"), bitbucket }, + { _.prop_eq("type", "composer"), composer }, { _.prop_eq("type", "github"), github }, { _.prop_eq("type", "pypi"), pypi }, { _.prop_eq("type", "huggingface"), huggingface }, diff --git a/tests/fixtures/purl-test-suite-data.json b/tests/fixtures/purl-test-suite-data.json index 0e156278..3856ab4e 100644 --- a/tests/fixtures/purl-test-suite-data.json +++ b/tests/fixtures/purl-test-suite-data.json @@ -540,6 +540,18 @@ "is_invalid": false }, { + "description": "composer names are not case sensitive", + "purl": "pkg:composer/Laravel/Laravel@5.5.0", + "canonical_purl": "pkg:composer/laravel/laravel@5.5.0", + "type": "composer", + "namespace": "laravel", + "name": "laravel", + "version": "5.5.0", + "qualifiers": null, + "subpath": null, + "is_invalid": false + }, + { "description": "splits checksum qualifier", "purl": "pkg:github/rust-lang/rust-analyzer@2022-12-05?download_url=https://github.com/rust-lang/rust-analyzer/releases/download/2022-12-05/rust-analyzer-aarch64-apple-darwin.gz&checksum=sha1:256d83a0a59929099e7564169ef444c5e4088afc,sha256:28461b29ac0da9c653616e1d96092c85f86e24dd448d0fbe1973aa4c6d9b8b44", "canonical_purl": "pkg:github/rust-lang/rust-analyzer@2022-12-05?checksum=sha1:256d83a0a59929099e7564169ef444c5e4088afc,sha256:28461b29ac0da9c653616e1d96092c85f86e24dd448d0fbe1973aa4c6d9b8b44&download_url=https://github.com/rust-lang/rust-analyzer/releases/download/2022-12-05/rust-analyzer-aarch64-apple-darwin.gz", diff --git a/tests/mason-core/purl_spec.lua b/tests/mason-core/purl_spec.lua index d6032068..64a7dc91 100644 --- a/tests/mason-core/purl_spec.lua +++ b/tests/mason-core/purl_spec.lua @@ -1,5 +1,5 @@ +local Purl = require "mason-core.purl" local Result = require "mason-core.result" -local purl = require "mason-core.purl" describe("purl", function() it("should parse well-formed PURLs", function() @@ -16,7 +16,7 @@ describe("purl", function() version = "2022-11-28", subpath = "bin/rust-analyzer", }, - purl.parse "pkg:github/rust-lang/rust-analyzer@2022-11-28?target=linux_x64_gnu&download_url=https://github.com/rust-lang/rust-analyzer/releases/download/2022-11-28/rust-analyzer-x86_64-unknown-linux-gnu.gz#bin/rust-analyzer" + Purl.parse "pkg:github/rust-lang/rust-analyzer@2022-11-28?target=linux_x64_gnu&download_url=https://github.com/rust-lang/rust-analyzer/releases/download/2022-11-28/rust-analyzer-x86_64-unknown-linux-gnu.gz#bin/rust-analyzer" ) assert.same( @@ -29,7 +29,7 @@ describe("purl", function() qualifiers = nil, subpath = nil, }, - purl.parse "pkg:github/rust-lang/rust-analyzer@2025-04-20" + Purl.parse "pkg:github/rust-lang/rust-analyzer@2025-04-20" ) assert.same( @@ -42,7 +42,7 @@ describe("purl", function() qualifiers = nil, subpath = nil, }, - purl.parse "pkg:npm/typescript-language-server@10.23.1" + Purl.parse "pkg:npm/typescript-language-server@10.23.1" ) assert.same( @@ -55,7 +55,7 @@ describe("purl", function() qualifiers = nil, subpath = nil, }, - purl.parse "pkg:pypi/python-language-server" + Purl.parse "pkg:pypi/python-language-server" ) assert.same( @@ -65,12 +65,26 @@ describe("purl", function() scheme = "pkg", type = "npm", }, - purl.parse "pkg:npm/%40angular/cli" + Purl.parse "pkg:npm/%40angular/cli" ) end) it("should fail to parse invalid PURLs", function() - assert.same(Result.failure "Malformed purl (invalid scheme).", purl.parse "scam:github/react@18.0.0") + assert.same(Result.failure "Malformed purl (invalid scheme).", Purl.parse "scam:github/react@18.0.0") + end) + + it("should treat percent-encoded components as case insensitive", function() + local purl = { + name = "sonarlint-vscode", + namespace = "sonarsource", + scheme = "pkg", + type = "github", + version = "3.18.0+70423" .. string.char(0xab), + } + assert.same(Result.success(purl), Purl.parse "pkg:github/SonarSource/sonarlint-vscode@3.18.0%2b70423%ab") + assert.same(Result.success(purl), Purl.parse "pkg:github/SonarSource/sonarlint-vscode@3.18.0%2B70423%aB") + assert.same(Result.success(purl), Purl.parse "pkg:github/SonarSource/sonarlint-vscode@3.18.0%2b70423%AB") + assert.same(Result.success(purl), Purl.parse "pkg:github/SonarSource/sonarlint-vscode@3.18.0%2B70423%Ab") end) end) @@ -89,7 +103,7 @@ describe("purl test suite ::", function() for _, test in ipairs(test_fixture) do it(test.description, function() - local result = purl.parse(test.purl) + local result = Purl.parse(test.purl) if test.is_invalid then assert.is_true(result:is_failure()) else @@ -106,7 +120,7 @@ describe("purl test suite ::", function() result ) - assert.equals(test.canonical_purl, purl.compile(result:get_or_throw())) + assert.equals(test.canonical_purl, Purl.compile(result:get_or_throw())) end end) end |
