Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JSONPath filter expression is invalid #365

Closed
dibyom opened this issue Jan 21, 2020 · 11 comments · Fixed by #376
Closed

JSONPath filter expression is invalid #365

dibyom opened this issue Jan 21, 2020 · 11 comments · Fixed by #376
Assignees
Labels
kind/bug Categorizes issue or PR as related to a bug.

Comments

@dibyom
Copy link
Member

dibyom commented Jan 21, 2020

Expected Behavior

Given the expression: $(body.taskRun.spec.outputs.resources[?(@.name == 'bucket')].resourceRef.name), the expression should be valid

Actual Behavior

User gets a "unterminated expression" error

{"level":"error","logger":"eventlistener","caller":"sink/sink.go:144","msg":"failed to ApplyEventValuesToParams: &{%!w(string=failed to replace JSONPath value for param bucket: {string $(body.taskRun.spec.outputs.resources[?(@.name == 'bucket')].resourceRef.name) []}: &{%!w(string=unterminated filter)})}","knative.dev/controller":"eventlistener","/triggers-eventid":"958bw","/trigger":"log-collection","stacktrace":"github.com/tektoncd/triggers/pkg/sink.Sink.processTrigger\n\t/workspace/go/src/github.com/tektoncd/triggers/pkg/sink/sink.go:144\ngithub.com/tektoncd/triggers/pkg/sink.Sink.HandleEvent.func1\n\t/workspace/go/src/github.com/tektoncd/triggers/pkg/sink/sink.go:93"}
@dibyom dibyom added the kind/question Issues or PRs that are questions around the project or a particular feature label Jan 21, 2020
@afrittoli
Copy link
Member

I tried a few more, but no luck

$(body.taskRun.spec.outputs.resources[?(@.name=='bucket')].resourceRef.name)
$(body.taskRun.spec.outputs.resources[?(@.name=="bucket")].resourceRef.name)
$(body.taskRun.spec.outputs.resources[?(@.name==\"bucket\")].resourceRef.name)

When I drop the filter it works fine:

$(body.taskRun.spec.outputs.resources[0].resourceRef.name)
$(body.taskRun.spec.outputs.resources[*].resourceRef.name)

@dibyom dibyom added this to the Triggers 0.2.1 milestone Jan 21, 2020
@dibyom dibyom removed the kind/question Issues or PRs that are questions around the project or a particular feature label Jan 21, 2020
@dibyom
Copy link
Member Author

dibyom commented Jan 21, 2020

/kind bug

@afrittoli
Copy link
Member

I tried on the latest codebase, adding a unit test in jsonpath_test.go with array filtering works fine:

{
		name: "Array filters",
		in:   `{"body":{"child":[{"a": "b", "w": "1"}, {"a": "c", "w": "2"}, {"a": "d", "w": "3"}]}}`,
		expr: "$(body.child[?(@.a == 'd')].w)",
		want: "3",
}

@dibyom
Copy link
Member Author

dibyom commented Jan 21, 2020

Now that's interesting...I'd have expected that to fail

@tekton-robot tekton-robot added the kind/bug Categorizes issue or PR as related to a bug. label Jan 21, 2020
@dibyom
Copy link
Member Author

dibyom commented Jan 21, 2020

The issue is with the tektonVar regex that is being used in applyEventValuesToParams

The regex is \$\(?([^\)]+)\) -- it keeps matching all chars that are not a ) so when it sees the brackets in the filter expression it returns prematurely leading to the unterminated expression.

Maybe we could use \$\((.*)\) which will match everything until the last ). This will work for the scenario but will break in the case that there are multiple JSONPath expressions in the same string.

@afrittoli
Copy link
Member

The need for a regex comes from the fact that we support embedding the jsonpath filter into text.
One simple solution could be to not support embedding jsonpath in text.
Alternatively we could try using recursion in regex to find balanced parenthesis - see https://www.regular-expressions.info/recurse.html#balanced - I've not tried that and I don't know if the golang regex library supports that?

@dibyom
Copy link
Member Author

dibyom commented Jan 22, 2020

The need for a regex comes from the fact that we support embedding the jsonpath filter into text.

yes, and that we support multiple jsonpath expressions in the same string

One simple solution could be to not support embedding jsonpath in text.

Yeah, especially since you can do that in templates already. I proposed something similar in #253 (Also related, #367)

One issue here though is that we'd be making a breaking change in a patch release

Alternatively we could try using recursion in regex to find balanced parenthesis - see https://www.regular-expressions.info/recurse.html#balanced - I've not tried that and I don't know if the golang regex library supports that?

Heh. Yeah I did try a couple on regex101. Though I think that needs recursion support which needs a PCRE implementation while the Go regex implementation uses Re2

Perhaps, we can get away with something hacky like splitting on $( and then using a regex to extract each expression?

@afrittoli
Copy link
Member

The need for a regex comes from the fact that we support embedding the jsonpath filter into text.

yes, and that we support multiple jsonpath expressions in the same string

One simple solution could be to not support embedding jsonpath in text.

Yeah, especially since you can do that in templates already. I proposed something similar in #253 (Also related, #367)

One issue here though is that we'd be making a breaking change in a patch release

Alternatively we could try using recursion in regex to find balanced parenthesis - see https://www.regular-expressions.info/recurse.html#balanced - I've not tried that and I don't know if the golang regex library supports that?

Heh. Yeah I did try a couple on regex101. Though I think that needs recursion support which needs a PCRE implementation while the Go regex implementation uses Re2

Perhaps, we can get away with something hacky like splitting on $( and then using a regex to extract each expression?

We could have some code - not based on regex - that looks for balanced parenthesis after a $( - but that same code code could then return the simplified jsonpath expression - I don't think we would need regex anymore? Alternatively the code that looks for balanced parenthesis could prepend/append some TOKEN e.g. __JSONPATHSTART__ and __JSONPATHEND__ that we then could use in the regex to get the jsonpath as regex groups like today.

@dibyom
Copy link
Member Author

dibyom commented Jan 22, 2020

/assign

@dibyom
Copy link
Member Author

dibyom commented Jan 22, 2020

We could have some code - not based on regex - that looks for balanced parenthesis after a $( - but that same code code could then return the simplified jsonpath expression - I don't think we would need regex anymore?

Yeah, since we are only really trying to remove the portion of the expression that tekton adds i.e. the leading $( and the last ) I think something like this might also work:

	multi = "$(body.child[?(@.a == 'd')].w)-$(asd)-blahblah"
	s := strings.Split(multi, "$(")
	for _, i := range s {
		if strings.Contains(i, ")") {
			 i = i[:strings.LastIndex(i, ")")]
			 fmt.Println(i)
		}
	}

@dibyom
Copy link
Member Author

dibyom commented Jan 22, 2020

dibyom added a commit to dibyom/triggers that referenced this issue Jan 22, 2020
We were previously using a regex to extract expressions within
TriggerBindings. The regex only extracted between the initial `$(`
and the first occurrence of the `)`. This meant that some valid
JSONPath expressions that contained brackets (e.g. filters) were
incorrectly extracted.

This commit fixes the issue by splitting the string on `$(` and then
extracting until the *last* occurrence of `)`.

Fixes tektoncd#365

Co-Authored-By: Andrea Frittoli <[email protected]>
Signed-off-by: Dibyo Mukherjee <[email protected]>
dibyom added a commit to dibyom/triggers that referenced this issue Jan 23, 2020
We were previously using a regex to extract expressions within
TriggerBindings. The regex only extracted between the initial `$(`
and the first occurrence of the `)`. This meant that some valid
JSONPath expressions that contained brackets (e.g. filters) were
incorrectly extracted.

This commit fixes the issue by splitting the string on `$(` and then
extracting until the first "unbalanced" occurrence of `)`.

Fixes tektoncd#365

Co-Authored-By: Andrea Frittoli <[email protected]>
Signed-off-by: Dibyo Mukherjee <[email protected]>
dibyom added a commit to dibyom/triggers that referenced this issue Jan 23, 2020
We were previously using a regex to extract expressions within
TriggerBindings. The regex only extracted between the initial `$(`
and the first occurrence of the `)`. This meant that some valid
JSONPath expressions that contained brackets (e.g. filters) were
incorrectly extracted.

This commit fixes the issue by splitting the string on `$(` and then
extracting until the first "unbalanced" occurrence of `)`.

Fixes tektoncd#365

Co-Authored-By: Andrea Frittoli <[email protected]>
Signed-off-by: Dibyo Mukherjee <[email protected]>
dibyom added a commit to dibyom/triggers that referenced this issue Jan 23, 2020
We were previously using a regex to extract expressions within
TriggerBindings. The regex only extracted between the initial `$(`
and the first occurrence of the `)`. This meant that some valid
JSONPath expressions that contained brackets (e.g. filters) were
incorrectly extracted.

This commit fixes the issue by splitting the string on `$(` and then
extracting until the first "unbalanced" occurrence of `)`.

Fixes tektoncd#365

Co-Authored-By: Andrea Frittoli <[email protected]>
Signed-off-by: Dibyo Mukherjee <[email protected]>
tekton-robot pushed a commit that referenced this issue Jan 23, 2020
We were previously using a regex to extract expressions within
TriggerBindings. The regex only extracted between the initial `$(`
and the first occurrence of the `)`. This meant that some valid
JSONPath expressions that contained brackets (e.g. filters) were
incorrectly extracted.

This commit fixes the issue by splitting the string on `$(` and then
extracting until the first "unbalanced" occurrence of `)`.

Fixes #365

Co-Authored-By: Andrea Frittoli <[email protected]>
Signed-off-by: Dibyo Mukherjee <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/bug Categorizes issue or PR as related to a bug.
Projects
None yet
3 participants