Parser: fix ambiguity with whitespace in version ranges (#40344)

Allowing white space around `:` in version ranges introduces an ambiguity:

```
a@1: b
```

parses as `a@1:b` but should really be parsed as two separate specs `a@1:` and `b`.

With white space disallowed around `:` in ranges, the ambiguity is resolved.
This commit is contained in:
Harmen Stoppels 2023-11-01 09:08:57 +01:00 committed by GitHub
parent e5f3ffc04f
commit ac976a4bf4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 16 deletions

View file

@ -96,9 +96,9 @@
VALUE = r"(?:[a-zA-Z_0-9\-+\*.,:=\~\/\\]+)" VALUE = r"(?:[a-zA-Z_0-9\-+\*.,:=\~\/\\]+)"
QUOTED_VALUE = r"[\"']+(?:[a-zA-Z_0-9\-+\*.,:=\~\/\\\s]+)[\"']+" QUOTED_VALUE = r"[\"']+(?:[a-zA-Z_0-9\-+\*.,:=\~\/\\\s]+)[\"']+"
VERSION = r"=?([a-zA-Z0-9_][a-zA-Z_0-9\-\.]*\b)" VERSION = r"=?(?:[a-zA-Z0-9_][a-zA-Z_0-9\-\.]*\b)"
VERSION_RANGE = rf"({VERSION}\s*:\s*{VERSION}(?!\s*=)|:\s*{VERSION}(?!\s*=)|{VERSION}\s*:|:)" VERSION_RANGE = rf"(?:(?:{VERSION})?:(?:{VERSION}(?!\s*=))?)"
VERSION_LIST = rf"({VERSION_RANGE}|{VERSION})(\s*[,]\s*({VERSION_RANGE}|{VERSION}))*" VERSION_LIST = rf"(?:{VERSION_RANGE}|{VERSION})(?:\s*,\s*(?:{VERSION_RANGE}|{VERSION}))*"
class TokenBase(enum.Enum): class TokenBase(enum.Enum):

View file

@ -472,33 +472,46 @@ def _specfile_for(spec_str, filename):
[Token(TokenType.PROPAGATED_KEY_VALUE_PAIR, value='cflags=="-O3 -g"')], [Token(TokenType.PROPAGATED_KEY_VALUE_PAIR, value='cflags=="-O3 -g"')],
'cflags=="-O3 -g"', 'cflags=="-O3 -g"',
), ),
# Way too many spaces # Whitespace is allowed in version lists
("@1.2:1.4 , 1.6 ", [Token(TokenType.VERSION, value="@1.2:1.4 , 1.6")], "@1.2:1.4,1.6"),
# But not in ranges. `a@1:` and `b` are separate specs, not a single `a@1:b`.
( (
"@1.2 : 1.4 , 1.6 ", "a@1: b",
[Token(TokenType.VERSION, value="@1.2 : 1.4 , 1.6")],
"@1.2:1.4,1.6",
),
("@1.2 : develop", [Token(TokenType.VERSION, value="@1.2 : develop")], "@1.2:develop"),
(
"@1.2 : develop = foo",
[ [
Token(TokenType.VERSION, value="@1.2 :"), Token(TokenType.UNQUALIFIED_PACKAGE_NAME, value="a"),
Token(TokenType.VERSION, value="@1:"),
Token(TokenType.UNQUALIFIED_PACKAGE_NAME, value="b"),
],
"a@1:",
),
(
"@1.2: develop = foo",
[
Token(TokenType.VERSION, value="@1.2:"),
Token(TokenType.KEY_VALUE_PAIR, value="develop = foo"), Token(TokenType.KEY_VALUE_PAIR, value="develop = foo"),
], ],
"@1.2: develop=foo", "@1.2: develop=foo",
), ),
( (
"% intel @ 12.1 : 12.6 + debug", "@1.2:develop = foo",
[ [
Token(TokenType.COMPILER_AND_VERSION, value="% intel @ 12.1 : 12.6"), Token(TokenType.VERSION, value="@1.2:"),
Token(TokenType.KEY_VALUE_PAIR, value="develop = foo"),
],
"@1.2: develop=foo",
),
(
"% intel @ 12.1:12.6 + debug",
[
Token(TokenType.COMPILER_AND_VERSION, value="% intel @ 12.1:12.6"),
Token(TokenType.BOOL_VARIANT, value="+ debug"), Token(TokenType.BOOL_VARIANT, value="+ debug"),
], ],
"%intel@12.1:12.6+debug", "%intel@12.1:12.6+debug",
), ),
( (
"@ 12.1 : 12.6 + debug - qt_4", "@ 12.1:12.6 + debug - qt_4",
[ [
Token(TokenType.VERSION, value="@ 12.1 : 12.6"), Token(TokenType.VERSION, value="@ 12.1:12.6"),
Token(TokenType.BOOL_VARIANT, value="+ debug"), Token(TokenType.BOOL_VARIANT, value="+ debug"),
Token(TokenType.BOOL_VARIANT, value="- qt_4"), Token(TokenType.BOOL_VARIANT, value="- qt_4"),
], ],