Skip to content

Commit

Permalink
fix: handle additional broken macro definitions
Browse files Browse the repository at this point in the history
Signed-off-by: Felipe Zipitria <[email protected]>
  • Loading branch information
fzipi committed Oct 27, 2024
1 parent 18ae0d8 commit f540825
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 15 deletions.
31 changes: 17 additions & 14 deletions experimental/plugins/macro/macro.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,42 +95,42 @@ func expandToken(tx plugintypes.TransactionState, token macroToken) string {
// [2] macroToken{text: "%{var.bar}", variable: &variables.Var, key: "bar"}
func (m *macro) compile(input string) error {
l := len(input)
if l == 0 {
if l < 4 { // we need to have at least %{} plus one char to be considered text for a macro
return fmt.Errorf("empty macro")
}

currentToken := strings.Builder{}
m.original = input
var currentToken strings.Builder
isMacro := false

for i := 0; i < l; i++ {
c := input[i]
if c == '%' && (i <= l && input[i+1] == '{') {
// we have a macro

if c == '%' && i+1 < l && input[i+1] == '{' {
if currentToken.Len() > 0 {
// we add the text token
m.tokens = append(m.tokens, macroToken{
text: currentToken.String(),
variable: variables.Unknown,
key: "",
})
currentToken.Reset()
}
currentToken.Reset()
isMacro = true
i++
i++ // Skip '{'
continue
}

if isMacro {
if c == '}' {
// we close a macro
isMacro = false
// TODO(jcchavezs): key should only be empty in single collections
if input[i-1] == '.' {
return fmt.Errorf("empty variable name")
}
varName, key, _ := strings.Cut(currentToken.String(), ".")
v, err := variables.Parse(varName)
if err != nil {
return fmt.Errorf("unknown variable %q", varName)
}
// we add the variable token
m.tokens = append(m.tokens, macroToken{
text: currentToken.String(),
variable: v,
Expand All @@ -140,8 +140,7 @@ func (m *macro) compile(input string) error {
continue
}

if !(c == '.' || c == '_' || c == '-' || (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
currentToken.WriteByte(c)
if !isValidMacroChar(c) {
return fmt.Errorf("malformed variable starting with %q", "%{"+currentToken.String())
}

Expand All @@ -152,10 +151,10 @@ func (m *macro) compile(input string) error {
}
continue
}
// we have a normal character

currentToken.WriteByte(c)
}
// if there is something left

if currentToken.Len() > 0 {
m.tokens = append(m.tokens, macroToken{
text: currentToken.String(),
Expand All @@ -166,6 +165,10 @@ func (m *macro) compile(input string) error {
return nil
}

func isValidMacroChar(c byte) bool {
return c == '.' || c == '_' || c == '-' || (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')
}

// String returns the original string
func (m *macro) String() string {
return m.original
Expand Down
34 changes: 33 additions & 1 deletion experimental/plugins/macro/macro_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,39 @@ func TestCompile(t *testing.T) {
}
})

t.Run("malformed macro", func(t *testing.T) {
t.Run("single percent sign", func(t *testing.T) {
m := &macro{}
err := m.compile("%")
if err == nil {
t.Errorf("expected error for single percent sign")
}
})

t.Run("empty braces", func(t *testing.T) {
m := &macro{}
err := m.compile("%{}")
if err == nil {
t.Errorf("expected error for empty braces")
}
})

t.Run("missing key", func(t *testing.T) {
m := &macro{}
err := m.compile("%{tx.}")
if err == nil {
t.Errorf("expected error for missing key")
}
})

t.Run("missing collection", func(t *testing.T) {
m := &macro{}
err := m.compile("%{.key}")
if err == nil {
t.Errorf("expected error for missing collection")
}
})

t.Run("malformed macros", func(t *testing.T) {
for _, test := range []string{"%{tx.count", "%{{tx.count}", "%{{tx.{count}", "something %{tx.count"} {
t.Run(test, func(t *testing.T) {
m := &macro{}
Expand Down

0 comments on commit f540825

Please sign in to comment.