Merge pull request #20 from returntocorp/sticky-tokens

Disallow whitespace in some multi-fragment constructs.
This commit is contained in:
Camden Cheek 2022-04-05 11:19:43 -06:00 committed by GitHub
commit 25c71d6a24
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 4950 additions and 4048 deletions

View file

@ -86,3 +86,111 @@ FROM --platform=linux/arm64 alpine-${VERSION}-z
(image_name
(expansion
(variable))))))
======================================================
No spaces in image name
======================================================
FROM a b c
---
(source_file
(ERROR
(from_instruction
(image_spec
(image_name)))))
======================================================
No spaces in image name before expansion
======================================================
FROM a $b
---
(source_file
(from_instruction
(ERROR)
(image_spec
(image_name
(expansion
(variable))))))
======================================================
No spaces in image name expansion
======================================================
FROM $ X
---
(source_file
(ERROR))
======================================================
No spaces in image tag expansion
======================================================
FROM a: $B
---
(source_file
(from_instruction
(ERROR
(image_name))
(image_spec
(image_name
(expansion
(variable))))))
======================================================
No spaces in image digest
======================================================
FROM a:b@ $c
---
(source_file
(from_instruction
(ERROR
(image_name)
(image_tag))
(image_spec
(image_name
(expansion
(variable))))))
======================================================
No spaces in image alias
======================================================
FROM a AS b c
---
(source_file
(ERROR
(from_instruction
(image_spec
(image_name))
(image_alias))))
======================================================
No spaces in image alias expansion
======================================================
FROM a AS b $C
---
(source_file
(from_instruction
(image_spec
(image_name))
(ERROR)
(image_alias
(expansion
(variable)))))

View file

@ -19,3 +19,55 @@ STOPSIGNAL SIGKILL
(source_file
(stopsignal_instruction))
=========================================================
Signal value with expansions
=========================================================
STOPSIGNAL A$BC${DE}F
---
(source_file
(stopsignal_instruction
(expansion
(variable))
(expansion
(variable))))
=========================================================
No space in signal value
=========================================================
STOPSIGNAL A B
---
(source_file
(ERROR
(stopsignal_instruction)))
=========================================================
No space in signal value before expansion
=========================================================
STOPSIGNAL A $B
---
(source_file
(stopsignal_instruction
(ERROR)
(expansion
(variable))))
=========================================================
No space in signal value within expansion
=========================================================
STOPSIGNAL A$ B
---
(source_file
(ERROR))

View file

@ -35,3 +35,15 @@ USER 1004:1004
(user_instruction
user: (unquoted_string)
group: (unquoted_string)))
===========================
No spaces in user:group
===========================
USER a: b
---
(source_file
(ERROR
(unquoted_string)))

View file

@ -106,13 +106,27 @@ module.exports = grammar({
optional(
seq(
token.immediate(":"),
field("group", alias($._user_name_or_group, $.unquoted_string))
field("group",
alias($._immediate_user_name_or_group, $.unquoted_string))
)
)
),
_user_name_or_group: ($) =>
repeat1(choice(/([a-z][-a-z0-9_]*|[0-9]+)/, $.expansion)),
seq(
choice(/([a-z][-a-z0-9_]*|[0-9]+)/, $.expansion),
repeat($._immediate_user_name_or_group_fragment)
),
// same as _user_name_or_group but sticks to previous token
_immediate_user_name_or_group: ($) =>
repeat1($._immediate_user_name_or_group_fragment),
_immediate_user_name_or_group_fragment: ($) =>
choice(
token.immediate(/([a-z][-a-z0-9_]*|[0-9]+)/),
$._immediate_expansion
),
workdir_instruction: ($) =>
seq(alias(/[wW][oO][rR][kK][dD][iI][rR]/, "WORKDIR"), $.path),
@ -138,7 +152,11 @@ module.exports = grammar({
$._stopsignal_value
),
_stopsignal_value: ($) => repeat1(choice(/[A-Z0-9]+/, $.expansion)),
_stopsignal_value: ($) =>
seq(
choice(/[A-Z0-9]+/, $.expansion),
repeat(choice(token.immediate(/[A-Z0-9]+/), $._immediate_expansion))
),
healthcheck_instruction: ($) =>
seq(
@ -170,13 +188,28 @@ module.exports = grammar({
/[^-\s\$]/, // cannot start with a '-' to avoid conflicts with params
$.expansion
),
repeat(choice(/[^\s\$]+/, $.expansion))
repeat(choice(token.immediate(/[^\s\$]+/), $._immediate_expansion))
),
expansion: ($) =>
seq("$", choice($.variable, seq("{", alias(/[^\}]+/, $.variable), "}"))),
expansion: $ =>
seq("$", $._expansion_body),
variable: ($) => /[a-zA-Z][a-zA-Z0-9_]*/,
// we have 2 rules b/c aliases don't work as expected on seq() directly
_immediate_expansion: $ => alias($._imm_expansion, $.expansion),
_imm_expansion: $ =>
seq(token.immediate("$"), $._expansion_body),
_expansion_body: $ =>
choice(
$.variable,
seq(
token.immediate("{"),
alias(token.immediate(/[^\}]+/), $.variable),
token.immediate("}")
)
),
variable: ($) => token.immediate(/[a-zA-Z][a-zA-Z0-9_]*/),
env_pair: ($) =>
seq(
@ -218,19 +251,19 @@ module.exports = grammar({
image_name: ($) =>
seq(
choice(/[^@:\s\$-]/, $.expansion),
repeat(choice(/[^@:\s\$]+/, $.expansion))
repeat(choice(token.immediate(/[^@:\s\$]+/), $._immediate_expansion))
),
image_tag: ($) =>
seq(
token.immediate(":"),
repeat1(choice(token.immediate(/[^@\s\$]+/), $.expansion))
repeat1(choice(token.immediate(/[^@\s\$]+/), $._immediate_expansion))
),
image_digest: ($) =>
seq(
token.immediate("@"),
repeat1(choice(token.immediate(/[a-zA-Z0-9:]+/), $.expansion))
repeat1(choice(token.immediate(/[a-zA-Z0-9:]+/), $._immediate_expansion))
),
param: ($) =>
@ -241,7 +274,10 @@ module.exports = grammar({
field("value", token.immediate(/[^\s]+/))
),
image_alias: ($) => repeat1(choice(/[-a-zA-Z0-9_]+/, $.expansion)),
image_alias: ($) => seq(
choice(/[-a-zA-Z0-9_]+/, $.expansion),
repeat(choice(token.immediate(/[-a-zA-Z0-9_]+/), $._immediate_expansion))
),
string_array: ($) =>
seq(
@ -278,7 +314,11 @@ module.exports = grammar({
seq(
'"',
repeat(
choice(token.immediate(/[^"\n\\\$]+/), $.escape_sequence, $.expansion)
choice(
token.immediate(/[^"\n\\\$]+/),
$.escape_sequence,
$._immediate_expansion
)
),
'"'
),
@ -288,7 +328,7 @@ module.exports = grammar({
choice(
token.immediate(/[^\s\n\"\\\$]+/),
token.immediate("\\ "),
$.expansion
$._immediate_expansion
)
),

View file

@ -519,7 +519,7 @@
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_user_name_or_group"
"name": "_immediate_user_name_or_group"
},
"named": true,
"value": "unquoted_string"
@ -535,8 +535,9 @@
]
},
"_user_name_or_group": {
"type": "REPEAT1",
"content": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
@ -548,7 +549,38 @@
"name": "expansion"
}
]
},
{
"type": "REPEAT",
"content": {
"type": "SYMBOL",
"name": "_immediate_user_name_or_group_fragment"
}
}
]
},
"_immediate_user_name_or_group": {
"type": "REPEAT1",
"content": {
"type": "SYMBOL",
"name": "_immediate_user_name_or_group_fragment"
}
},
"_immediate_user_name_or_group_fragment": {
"type": "CHOICE",
"members": [
{
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "PATTERN",
"value": "([a-z][-a-z0-9_]*|[0-9]+)"
}
},
{
"type": "SYMBOL",
"name": "_immediate_expansion"
}
]
},
"workdir_instruction": {
"type": "SEQ",
@ -669,8 +701,9 @@
]
},
"_stopsignal_value": {
"type": "REPEAT1",
"content": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
@ -682,8 +715,28 @@
"name": "expansion"
}
]
},
{
"type": "REPEAT",
"content": {
"type": "CHOICE",
"members": [
{
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "PATTERN",
"value": "[A-Z0-9]+"
}
},
{
"type": "SYMBOL",
"name": "_immediate_expansion"
}
]
}
}
]
},
"healthcheck_instruction": {
"type": "SEQ",
"members": [
@ -799,12 +852,15 @@
"type": "CHOICE",
"members": [
{
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "PATTERN",
"value": "[^\\s\\$]+"
}
},
{
"type": "SYMBOL",
"name": "expansion"
"name": "_immediate_expansion"
}
]
}
@ -819,6 +875,37 @@
"value": "$"
},
{
"type": "SYMBOL",
"name": "_expansion_body"
}
]
},
"_immediate_expansion": {
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_imm_expansion"
},
"named": true,
"value": "expansion"
},
"_imm_expansion": {
"type": "SEQ",
"members": [
{
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "STRING",
"value": "$"
}
},
{
"type": "SYMBOL",
"name": "_expansion_body"
}
]
},
"_expansion_body": {
"type": "CHOICE",
"members": [
{
@ -829,31 +916,41 @@
"type": "SEQ",
"members": [
{
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "STRING",
"value": "{"
}
},
{
"type": "ALIAS",
"content": {
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "PATTERN",
"value": "[^\\}]+"
}
},
"named": true,
"value": "variable"
},
{
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "STRING",
"value": "}"
}
]
}
]
}
]
},
"variable": {
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "PATTERN",
"value": "[a-zA-Z][a-zA-Z0-9_]*"
}
},
"env_pair": {
"type": "SEQ",
@ -1090,12 +1187,15 @@
"type": "CHOICE",
"members": [
{
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "PATTERN",
"value": "[^@:\\s\\$]+"
}
},
{
"type": "SYMBOL",
"name": "expansion"
"name": "_immediate_expansion"
}
]
}
@ -1126,7 +1226,7 @@
},
{
"type": "SYMBOL",
"name": "expansion"
"name": "_immediate_expansion"
}
]
}
@ -1157,7 +1257,7 @@
},
{
"type": "SYMBOL",
"name": "expansion"
"name": "_immediate_expansion"
}
]
}
@ -1203,8 +1303,9 @@
]
},
"image_alias": {
"type": "REPEAT1",
"content": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
@ -1216,8 +1317,28 @@
"name": "expansion"
}
]
},
{
"type": "REPEAT",
"content": {
"type": "CHOICE",
"members": [
{
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "PATTERN",
"value": "[-a-zA-Z0-9_]+"
}
},
{
"type": "SYMBOL",
"name": "_immediate_expansion"
}
]
}
}
]
},
"string_array": {
"type": "SEQ",
"members": [
@ -1388,7 +1509,7 @@
},
{
"type": "SYMBOL",
"name": "expansion"
"name": "_immediate_expansion"
}
]
}
@ -1420,7 +1541,7 @@
},
{
"type": "SYMBOL",
"name": "expansion"
"name": "_immediate_expansion"
}
]
}

File diff suppressed because it is too large Load diff