From 41dc9f79de82c8d0b0bfb68546b9f42949c172ed Mon Sep 17 00:00:00 2001 From: Philip Conrad Date: Wed, 6 Jul 2022 13:14:49 -0400 Subject: [PATCH] topdown: is_valid functions no longer error. (#4844) This commit updates the `*.is_valid` functions to no longer produce errors when providing wrong-typed arguments. Instead, they will now return true/false for all inputs. Tests and WASM versions of these builtins have been updated to match the new behavior. Fixes #4760. Signed-off-by: Philip Conrad --- test/cases/testdata/jsonbuiltins/test-is-valid.yaml | 10 ++++++---- topdown/encoding.go | 6 +++--- topdown/graphql.go | 4 ++-- topdown/semver.go | 3 +-- wasm/src/encoding.c | 4 ++-- 5 files changed, 14 insertions(+), 13 deletions(-) diff --git a/test/cases/testdata/jsonbuiltins/test-is-valid.yaml b/test/cases/testdata/jsonbuiltins/test-is-valid.yaml index 60366f6371..35c0748cad 100644 --- a/test/cases/testdata/jsonbuiltins/test-is-valid.yaml +++ b/test/cases/testdata/jsonbuiltins/test-is-valid.yaml @@ -12,6 +12,7 @@ cases: ] p = [x | doc = documents[_]; json.is_valid(doc, x)] + strict_error: true want_result: - x: - false @@ -28,9 +29,9 @@ cases: } query: data.generated.p = x input: {"foo": 1} - want_error: operand 1 must be string but got number - want_error_code: eval_type_error strict_error: true + want_result: + - x: false - note: jsonbuiltins/yaml is_valid query: data.generated.p = x @@ -49,6 +50,7 @@ cases: ] p = [x | doc = documents[_]; yaml.is_valid(doc, x)] + strict_error: true want_result: - x: - true @@ -65,6 +67,6 @@ cases: } query: data.generated.p = x input: {"foo": 1} - want_error: operand 1 must be string but got number - want_error_code: eval_type_error strict_error: true + want_result: + - x: false diff --git a/topdown/encoding.go b/topdown/encoding.go index 73b9cc72d2..fa9b197121 100644 --- a/topdown/encoding.go +++ b/topdown/encoding.go @@ -55,7 +55,7 @@ func builtinJSONIsValid(a ast.Value) (ast.Value, error) { str, err := builtins.StringOperand(a, 1) if err != nil { - return nil, err + return ast.Boolean(false), nil } return ast.Boolean(json.Valid([]byte(str))), nil @@ -83,7 +83,7 @@ func builtinBase64Decode(a ast.Value) (ast.Value, error) { func builtinBase64IsValid(a ast.Value) (ast.Value, error) { str, err := builtins.StringOperand(a, 1) if err != nil { - return nil, err + return ast.Boolean(false), nil } _, err = base64.StdEncoding.DecodeString(string(str)) @@ -257,7 +257,7 @@ func builtinYAMLUnmarshal(a ast.Value) (ast.Value, error) { func builtinYAMLIsValid(a ast.Value) (ast.Value, error) { str, err := builtins.StringOperand(a, 1) if err != nil { - return nil, err + return ast.Boolean(false), nil } var x interface{} diff --git a/topdown/graphql.go b/topdown/graphql.go index 74caebe6b2..8a2c7e4dd4 100644 --- a/topdown/graphql.go +++ b/topdown/graphql.go @@ -343,11 +343,11 @@ func builtinGraphQLIsValid(_ BuiltinContext, operands []*ast.Term, iter func(*as // feed them to the GraphQL parser functions. rawQuery, err := builtins.StringOperand(operands[0].Value, 1) if err != nil { - return err + return iter(ast.BooleanTerm(false)) } rawSchema, err := builtins.StringOperand(operands[1].Value, 1) if err != nil { - return err + return iter(ast.BooleanTerm(false)) } // Generate ASTs/errors for the GraphQL schema and query. diff --git a/topdown/semver.go b/topdown/semver.go index b91a5a9997..20c02d2365 100644 --- a/topdown/semver.go +++ b/topdown/semver.go @@ -40,8 +40,7 @@ func builtinSemVerCompare(bctx BuiltinContext, args []*ast.Term, iter func(*ast. func builtinSemVerIsValid(bctx BuiltinContext, args []*ast.Term, iter func(*ast.Term) error) error { versionString, err := builtins.StringOperand(args[0].Value, 1) if err != nil { - result := ast.BooleanTerm(false) - return iter(result) + return iter(ast.BooleanTerm(false)) } result := true diff --git a/wasm/src/encoding.c b/wasm/src/encoding.c index 82e2d8b727..9b22d7f641 100644 --- a/wasm/src/encoding.c +++ b/wasm/src/encoding.c @@ -223,7 +223,7 @@ opa_value *opa_base64_is_valid(opa_value *a) { if (opa_value_type(a) != OPA_STRING) { - return NULL; + return opa_boolean(false); } opa_string_t *s = opa_cast_string(a); @@ -323,7 +323,7 @@ opa_value *opa_json_is_valid(opa_value *a) { if (opa_value_type(a) != OPA_STRING) { - return NULL; + return opa_boolean(false); }