diff --git a/docs/how-to-parse.md b/docs/how-to-parse.md index 4ba1293..af01a34 100644 --- a/docs/how-to-parse.md +++ b/docs/how-to-parse.md @@ -16,7 +16,7 @@ To parse a VERS string: validate that the **type** is a known **type**. - The right hand side is a list of one or more constraints. Tools validate that this **constraints** string is not empty - ignoring spaces. + after splitting. - If the string is equal to '\*', the **constraints** value is '*'. Parsing is done and no further processing is needed for this VERS. A tool should report an error if there are characters other than '\*'. @@ -40,8 +40,11 @@ To parse a VERS string: (which implies an equality comparator of '=') - Tools should validate and report an error if the version is empty. - - If the version contains a percent '%' character, apply URL - quoting rules to unquote this string. + - If the version contains a percent '%' character, tools shall validate + that each '%' starts a valid percent-encoded triplet. + - Tools shall apply percent-decoding exactly once to the version string. + Tools shall report an error for invalid or non-canonical + percent-encoded sequences. - Append the parsed **constraints** strings to the constraints list. Finally: diff --git a/docs/standard/specification.md b/docs/standard/specification.md index cb1cb4b..dafec2d 100644 --- a/docs/standard/specification.md +++ b/docs/standard/specification.md @@ -138,9 +138,11 @@ error if any Whitespace character, for example SPACE (0x20), TAB (0x09), or LF ( 'vers:npm'. - Versions are case-sensitive. A **type** may specify its own case sensitivity. -- If a version in a **constraints** string contains **separator** or -**comparator** characters (i.e., '>', '<', '=', '!', '*', '|'), the version -shall be quoted using the URL quoting rules. This should be rare in practice. +- If a version in a **constraints** string contains any of these characters: + '>', '<', '=', '!', '*', '|', '%', these characters shall be + percent-encoded using URI percent-encoding rules. +- Percent-encoding in versions shall be canonical. Tools shall report an error + for invalid or non-canonical percent-encoded sequences. The list of **constraints** strings for a range are like a set of signposts in the version timeline of a package. The separators do not mean diff --git a/tests/vers_canonical_parse_test.json b/tests/vers_canonical_parse_test.json index a26c613..d6ce60b 100644 --- a/tests/vers_canonical_parse_test.json +++ b/tests/vers_canonical_parse_test.json @@ -59,6 +59,29 @@ "input": "vers:npm/>=2.0.0|<1.0.0", "expected_failure": true, "expected_failure_reason": "non-canonical VERS: constraints are not sorted by version" + }, + { + "description": "Parsing decodes canonical percent-encoding once for versions.", + "test_group": "base", + "test_type": "parse", + "input": "vers:npm/1.0%252F0", + "expected_output": { + "scheme": "npm", + "version_constraints": [ + [ + "=", + "1.0%2F0" + ] + ] + } + }, + { + "description": "Parsing fails when version percent-encoding is invalid.", + "test_group": "base", + "test_type": "parse", + "input": "vers:npm/1.0%2G0", + "expected_failure": true, + "expected_failure_reason": "non-canonical VERS: invalid percent-encoding in version" } ] }