From 3438209b7de1b8d17ee19eec4a59a3975fda800e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20=C3=81ngel=20Ducanto=20Hadad?= Date: Mon, 25 Nov 2024 09:41:44 +0100 Subject: [PATCH] fix: return better error if regexp is invalid MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Miguel Ángel Ducanto Hadad (cherry picked from commit 7cadaa22ac35f9d86dbcd923144e9625964bc481) --- fn.go | 6 ++++- fn_test.go | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 78 insertions(+), 2 deletions(-) diff --git a/fn.go b/fn.go index 400edc4..68ff21b 100644 --- a/fn.go +++ b/fn.go @@ -78,7 +78,11 @@ func (f *Function) RunFunction(_ context.Context, req *fnv1beta1.RunFunctionRequ // possibly avoid using regex for matching literal strings strictPattern = fmt.Sprintf("%s%s%s", START, string(before), END) } - re := regexp.MustCompile(strictPattern) + re, err := regexp.Compile(strictPattern) + if err != nil { + response.Fatal(rsp, errors.Wrapf(err, "cannot compile regex %s", strictPattern)) + return rsp, nil + } keys := []resource.Name{} for k := range desiredComposed { if re.MatchString(string(k)) { diff --git a/fn_test.go b/fn_test.go index 00515df..32f97a5 100644 --- a/fn_test.go +++ b/fn_test.go @@ -786,7 +786,7 @@ func TestRunFunction(t *testing.T) { }, }, "SequenceRegexAlreadyPrefixed": { - reason: "The function should delay the creation of second and fourth resources because the first and third are not ready", + reason: "The function should not modify the sequence regex, since it's already prefixed", args: args{ req: &fnv1beta1.RunFunctionRequest{ Input: resource.MustStructObject(&v1beta1.Input{ @@ -865,6 +865,78 @@ func TestRunFunction(t *testing.T) { }, }, }, + "SequenceRegexInvalidRegex": { + reason: "The function should return a fatal error because the regex is invalid", + args: args{ + req: &fnv1beta1.RunFunctionRequest{ + Input: resource.MustStructObject(&v1beta1.Input{ + Rules: []v1beta1.SequencingRule{ + { + Sequence: []resource.Name{ + `^(`, + "second", + }, + }, + }, + }), + Observed: &fnv1beta1.State{ + Composite: &fnv1beta1.Resource{ + Resource: resource.MustStructJSON(xr), + }, + Resources: map[string]*fnv1beta1.Resource{}, + }, + Desired: &fnv1beta1.State{ + Composite: &fnv1beta1.Resource{ + Resource: resource.MustStructJSON(xr), + }, + Resources: map[string]*fnv1beta1.Resource{ + "first-0": { + Resource: resource.MustStructJSON(mr), + Ready: fnv1beta1.Ready_READY_TRUE, + }, + "first-1": { + Resource: resource.MustStructJSON(mr), + Ready: fnv1beta1.Ready_READY_TRUE, + }, + "second": { + Resource: resource.MustStructJSON(mr), + Ready: fnv1beta1.Ready_READY_TRUE, + }, + }, + }, + }, + }, + want: want{ + rsp: &fnv1beta1.RunFunctionResponse{ + Meta: &fnv1beta1.ResponseMeta{Ttl: durationpb.New(response.DefaultTTL)}, + Results: []*fnv1beta1.Result{ + { + Severity: fnv1beta1.Severity_SEVERITY_FATAL, + Message: "cannot compile regex ^(: error parsing regexp: missing closing ): `^(`", + }, + }, + Desired: &fnv1beta1.State{ + Composite: &fnv1beta1.Resource{ + Resource: resource.MustStructJSON(xr), + }, + Resources: map[string]*fnv1beta1.Resource{ + "first-0": { + Resource: resource.MustStructJSON(mr), + Ready: fnv1beta1.Ready_READY_TRUE, + }, + "first-1": { + Resource: resource.MustStructJSON(mr), + Ready: fnv1beta1.Ready_READY_TRUE, + }, + "second": { + Resource: resource.MustStructJSON(mr), + Ready: fnv1beta1.Ready_READY_TRUE, + }, + }, + }, + }, + }, + }, } for name, tc := range cases {