Fix format function {{, }} are escapes (#752)
* Fix format function {{, }} are escapes Added some tests for some corner cases * Update format function added 2 error checks
This commit is contained in:
parent
0ff204b615
commit
43d46aa62f
2 changed files with 38 additions and 6 deletions
|
@ -4,11 +4,11 @@ import (
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/robertkrimen/otto"
|
"github.com/robertkrimen/otto"
|
||||||
|
@ -266,11 +266,35 @@ func vmEndsWith(vm *otto.Otto) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func vmFormat(vm *otto.Otto) {
|
func vmFormat(vm *otto.Otto) {
|
||||||
_ = vm.Set("format", func(s string, vals ...string) string {
|
_ = vm.Set("format", func(s string, vals ...otto.Value) string {
|
||||||
for i, v := range vals {
|
ex := regexp.MustCompile(`(\{[0-9]+\}|\{.?|\}.?)`)
|
||||||
s = strings.ReplaceAll(s, fmt.Sprintf("{%d}", i), v)
|
return ex.ReplaceAllStringFunc(s, func(seg string) string {
|
||||||
|
switch seg {
|
||||||
|
case "{{":
|
||||||
|
return "{"
|
||||||
|
case "}}":
|
||||||
|
return "}"
|
||||||
|
default:
|
||||||
|
if len(seg) < 3 || !strings.HasPrefix(seg, "{") {
|
||||||
|
log.Errorf("The following format string is invalid: '%v'", s)
|
||||||
|
return ""
|
||||||
}
|
}
|
||||||
return s
|
_i := seg[1 : len(seg)-1]
|
||||||
|
i, err := strconv.ParseInt(_i, 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("The following format string is invalid: '%v'. Error: %v", s, err)
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if i >= int64(len(vals)) {
|
||||||
|
log.Errorf("The following format string references more arguments than were supplied: '%v'", s)
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if vals[i].IsNull() || vals[i].IsUndefined() {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return vals[i].String()
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -110,6 +110,14 @@ func TestEvaluate(t *testing.T) {
|
||||||
{"env.key", "value", ""},
|
{"env.key", "value", ""},
|
||||||
{"secrets.CASE_INSENSITIVE_SECRET", "value", ""},
|
{"secrets.CASE_INSENSITIVE_SECRET", "value", ""},
|
||||||
{"secrets.case_insensitive_secret", "value", ""},
|
{"secrets.case_insensitive_secret", "value", ""},
|
||||||
|
{"format('{{0}}', 'test')", "{0}", ""},
|
||||||
|
{"format('{{{0}}}', 'test')", "{test}", ""},
|
||||||
|
{"format('}}')", "}", ""},
|
||||||
|
{"format('echo Hello {0} ${{Test}}', 'World')", "echo Hello World ${Test}", ""},
|
||||||
|
{"format('echo Hello {0} ${{Test}}', github.undefined_property)", "echo Hello ${Test}", ""},
|
||||||
|
{"format('echo Hello {0}{1} ${{Te{0}st}}', github.undefined_property, 'World')", "echo Hello World ${Test}", ""},
|
||||||
|
{"format('{0}', '{1}', 'World')", "{1}", ""},
|
||||||
|
{"format('{{{0}', '{1}', 'World')", "{{1}", ""},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, table := range tables {
|
for _, table := range tables {
|
||||||
|
|
Loading…
Reference in a new issue