From 59e19fbc8c9d214b7b533f6ea41f665c7c2d7c66 Mon Sep 17 00:00:00 2001 From: Mahmood Ali Date: Wed, 21 Apr 2021 10:12:10 -0400 Subject: [PATCH 1/2] hcl2: handle unquoted undefined variables --- jobspec2/parse_test.go | 15 +++++++++++++++ jobspec2/types.config.go | 33 +++++++++++++++++++++++---------- 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/jobspec2/parse_test.go b/jobspec2/parse_test.go index 17492d6abfd9..a815cd0da9e7 100644 --- a/jobspec2/parse_test.go +++ b/jobspec2/parse_test.go @@ -873,6 +873,21 @@ func TestParse_UndefinedVariables(t *testing.T) { require.Equal(t, c, *job.Region) }) } + + t.Run("unquoted", func(t *testing.T) { + hcl := `job "example" { + region = meta.mytest +}` + + job, err := ParseWithConfig(&ParseConfig{ + Path: "input.hcl", + Body: []byte(hcl), + }) + require.NoError(t, err) + + require.Equal(t, "${meta.mytest}", *job.Region) + + }) } func TestParseServiceCheck(t *testing.T) { diff --git a/jobspec2/types.config.go b/jobspec2/types.config.go index 12bb58f344ae..2caa9604bfe8 100644 --- a/jobspec2/types.config.go +++ b/jobspec2/types.config.go @@ -1,7 +1,6 @@ package jobspec2 import ( - "bytes" "fmt" "strings" @@ -315,18 +314,32 @@ func (c *jobConfig) EvalContext() *hcl.EvalContext { end := t.SourceRange().End.Byte v := string(body[start:end]) - if i := bytes.IndexByte(body[end:], '}'); i != -1 { - v += string(body[end : end+i+1]) - } else { - // fallback for unexpected cases - v += "}" + + // find the start of inclusing "${..}" if it's inclused in one; otherwise, wrap it in one + quoted := false + for i := start - 1; i >= 1; i-- { + if body[i] == '{' && body[i-1] == '$' { + quoted = true + v = string(body[i-1:start]) + v + break + } else if body[i] != ' ' { + break + } } - if i := bytes.LastIndex(body[:start], []byte("${")); i != 0 { - v = string(body[i:start]) + v + if quoted { + for i := end + 1; i < len(body); i++ { + if body[i] == '}' { + v += string(body[end:i]) + } else if body[i] != ' ' { + // unexpected! + v += "}" + break + } + } + } else { - // fallback for unexpected cases - v = "${" + v + v = "${" + v + "}" } return cty.StringVal(v), nil From 9c7cb7ddb61569aa1d000b90714c2dfda68bedc6 Mon Sep 17 00:00:00 2001 From: Mahmood Ali Date: Wed, 21 Apr 2021 12:36:33 -0400 Subject: [PATCH 2/2] use isBracketed, a clearer term --- jobspec2/types.config.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jobspec2/types.config.go b/jobspec2/types.config.go index 2caa9604bfe8..28e059172142 100644 --- a/jobspec2/types.config.go +++ b/jobspec2/types.config.go @@ -316,10 +316,10 @@ func (c *jobConfig) EvalContext() *hcl.EvalContext { v := string(body[start:end]) // find the start of inclusing "${..}" if it's inclused in one; otherwise, wrap it in one - quoted := false + isBracketed := false for i := start - 1; i >= 1; i-- { if body[i] == '{' && body[i-1] == '$' { - quoted = true + isBracketed = true v = string(body[i-1:start]) + v break } else if body[i] != ' ' { @@ -327,7 +327,7 @@ func (c *jobConfig) EvalContext() *hcl.EvalContext { } } - if quoted { + if isBracketed { for i := end + 1; i < len(body); i++ { if body[i] == '}' { v += string(body[end:i])