Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions builtin/builtin.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,9 @@ var Builtins = []*Function{
{
Name: "trimPrefix",
Func: func(args ...any) (any, error) {
if len(args) == 0 {
return nil, fmt.Errorf("not enough arguments to call trimPrefix")
}
s := " "
if len(args) == 2 {
s = args[1].(string)
Expand All @@ -236,6 +239,9 @@ var Builtins = []*Function{
{
Name: "trimSuffix",
Func: func(args ...any) (any, error) {
if len(args) == 0 {
return nil, fmt.Errorf("not enough arguments to call trimSuffix")
}
s := " "
if len(args) == 2 {
s = args[1].(string)
Expand Down Expand Up @@ -312,6 +318,9 @@ var Builtins = []*Function{
{
Name: "repeat",
Safe: func(args ...any) (any, uint, error) {
if len(args) < 2 {
return nil, 0, fmt.Errorf("not enough arguments to call repeat")
}
s := args[0].(string)
n := runtime.ToInt(args[1])
if n < 0 {
Expand All @@ -327,6 +336,9 @@ var Builtins = []*Function{
{
Name: "join",
Func: func(args ...any) (any, error) {
if len(args) == 0 {
return nil, fmt.Errorf("not enough arguments to call join")
}
glue := ""
if len(args) == 2 {
glue = args[1].(string)
Expand Down Expand Up @@ -354,27 +366,39 @@ var Builtins = []*Function{
{
Name: "indexOf",
Func: func(args ...any) (any, error) {
if len(args) < 2 {
return nil, fmt.Errorf("not enough arguments to call indexOf")
}
return strings.Index(args[0].(string), args[1].(string)), nil
},
Types: types(strings.Index),
},
{
Name: "lastIndexOf",
Func: func(args ...any) (any, error) {
if len(args) < 2 {
return nil, fmt.Errorf("not enough arguments to call lastIndexOf")
}
return strings.LastIndex(args[0].(string), args[1].(string)), nil
},
Types: types(strings.LastIndex),
},
{
Name: "hasPrefix",
Func: func(args ...any) (any, error) {
if len(args) < 2 {
return nil, fmt.Errorf("not enough arguments to call hasPrefix")
}
return strings.HasPrefix(args[0].(string), args[1].(string)), nil
},
Types: types(strings.HasPrefix),
},
{
Name: "hasSuffix",
Func: func(args ...any) (any, error) {
if len(args) < 2 {
return nil, fmt.Errorf("not enough arguments to call hasSuffix")
}
return strings.HasSuffix(args[0].(string), args[1].(string)), nil
},
Types: types(strings.HasSuffix),
Expand Down Expand Up @@ -436,6 +460,9 @@ var Builtins = []*Function{
{
Name: "toJSON",
Func: func(args ...any) (any, error) {
if len(args) == 0 {
return nil, fmt.Errorf("not enough arguments to call toJSON")
}
b, err := json.MarshalIndent(args[0], "", " ")
if err != nil {
return nil, err
Expand All @@ -447,6 +474,9 @@ var Builtins = []*Function{
{
Name: "fromJSON",
Func: func(args ...any) (any, error) {
if len(args) == 0 {
return nil, fmt.Errorf("not enough arguments to call fromJSON")
}
var v any
err := json.Unmarshal([]byte(args[0].(string)), &v)
if err != nil {
Expand All @@ -459,13 +489,19 @@ var Builtins = []*Function{
{
Name: "toBase64",
Func: func(args ...any) (any, error) {
if len(args) == 0 {
return nil, fmt.Errorf("not enough arguments to call toBase64")
}
return base64.StdEncoding.EncodeToString([]byte(args[0].(string))), nil
},
Types: types(new(func(string) string)),
},
{
Name: "fromBase64",
Func: func(args ...any) (any, error) {
if len(args) == 0 {
return nil, fmt.Errorf("not enough arguments to call fromBase64")
}
b, err := base64.StdEncoding.DecodeString(args[0].(string))
if err != nil {
return nil, err
Expand Down Expand Up @@ -505,17 +541,26 @@ var Builtins = []*Function{
{
Name: "duration",
Func: func(args ...any) (any, error) {
if len(args) == 0 {
return nil, fmt.Errorf("not enough arguments to call duration")
}
return time.ParseDuration(args[0].(string))
},
Types: types(time.ParseDuration),
},
{
Name: "date",
Func: func(args ...any) (any, error) {
if len(args) == 0 {
return nil, fmt.Errorf("not enough arguments to call date")
}
tz, ok := args[0].(*time.Location)
if ok {
args = args[1:]
}
if len(args) == 0 {
return nil, fmt.Errorf("not enough arguments to call date")
}

date := args[0].(string)
if len(args) == 2 {
Expand Down Expand Up @@ -585,6 +630,9 @@ var Builtins = []*Function{
{
Name: "timezone",
Func: func(args ...any) (any, error) {
if len(args) == 0 {
return nil, fmt.Errorf("not enough arguments to call timezone")
}
tz, err := time.LoadLocation(args[0].(string))
if err != nil {
return nil, err
Expand All @@ -596,6 +644,9 @@ var Builtins = []*Function{
{
Name: "first",
Func: func(args ...any) (any, error) {
if len(args) != 1 {
return nil, fmt.Errorf("invalid number of arguments (expected 1, got %d)", len(args))
}
defer func() {
if r := recover(); r != nil {
return
Expand All @@ -619,6 +670,9 @@ var Builtins = []*Function{
{
Name: "last",
Func: func(args ...any) (any, error) {
if len(args) != 1 {
return nil, fmt.Errorf("invalid number of arguments (expected 1, got %d)", len(args))
}
defer func() {
if r := recover(); r != nil {
return
Expand Down
1 change: 1 addition & 0 deletions test/fuzz/fuzz_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ func FuzzExpr(f *testing.F) {
regexp.MustCompile(`invalid order .*, expected asc or desc`),
regexp.MustCompile(`unknown order, use asc or desc`),
regexp.MustCompile(`cannot use .* as a key for groupBy: type is not comparable`),
regexp.MustCompile(`not enough arguments to call .*`),
}

env := NewEnv()
Expand Down
7 changes: 0 additions & 7 deletions testdata/generated.txt
Original file line number Diff line number Diff line change
Expand Up @@ -763,7 +763,6 @@ $env not contains $env?.[Bar]?.add()
$env not contains $env?.[Bar]?.ok
$env not contains $env?.[String?.str]
$env not contains $env?.[String]
$env not contains $env?.[first(foobar, greet)]
$env not contains $env?.[foobar?.array()]
$env not contains $env?.[foobar]
$env not contains $env?.[toJSON(foobar)]
Expand Down Expand Up @@ -3513,7 +3512,6 @@ $env?.[Bar]?.str(f64)
$env?.[Bar]?.str(f64, array)
$env?.[Bar]?.str(foobar)
$env?.[Bar]?.str(greet)
$env?.[Bar]?.str(list | first(true, foobar))
$env?.[Bar]?.str(list)
$env?.[Bar]?.str(nil)
$env?.[Bar]?.str.Bar
Expand Down Expand Up @@ -3645,7 +3643,6 @@ $env?.[String]?.String(foobar)
$env?.[String]?.String(foobar, $env)
$env?.[String]?.String(foobar?.[list])?.str()
$env?.[String]?.String(greet)
$env?.[String]?.String(last($env, String))
$env?.[String]?.String(ok && foobar)
$env?.[String]?.String.add
$env?.[String]?.String.split(false, add).str.array
Expand Down Expand Up @@ -6984,7 +6981,6 @@ $env[:str] not in foo || true
0 == $env?.[Bar | get(foo)]
0 == $env?.[Bar]
0 == $env?.[String]
0 == $env?.[first(0, ok)]
0 == $env?.[foobar]
0 == $env?.[foobar]?.add
0 == $env?.[str]
Expand Down Expand Up @@ -18596,7 +18592,6 @@ foo not in $env?.[foobar?.f64]
foo not in $env?.[foobar?.foo]
foo not in $env?.[foobar]
foo not in $env?.[foobar]?.[greet]
foo not in $env?.[nil | last(foobar)]
foo not in $env?.[nil]
foo not in $env?.foobar
foo not in $env?.foobar?.greet(foobar)
Expand Down Expand Up @@ -28092,7 +28087,6 @@ nil != $env?.Bar?.list()
nil != $env?.Bar?.str()
nil != $env?.String
nil != $env?.String?.[i]
nil != $env?.[1.0 | first(nil)]
nil != $env?.[Bar]
nil != $env?.[Bar]?.Bar
nil != $env?.[String]
Expand Down Expand Up @@ -36587,7 +36581,6 @@ true in $env?.String
true in $env?.[Bar]
true in $env?.[String]
true in $env?.[first(foobar)]
true in $env?.[foobar | last(nil)]
true in $env?.[foobar]
true not in $env?.Bar
true not in $env?.String
Expand Down
Loading