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

OData query params URI decoding issues on "complex URLs" #693

Closed
shaunco opened this issue Sep 22, 2023 · 1 comment
Closed

OData query params URI decoding issues on "complex URLs" #693

shaunco opened this issue Sep 22, 2023 · 1 comment

Comments

@shaunco
Copy link

shaunco commented Sep 22, 2023

Most http libraries automatically handle URI encoding of query parameters. It would be expected that PineJS is able to accept URI encoded query parameters and decode them properly, however there seem to be some weird inconsistencies about when things need to be encoded and when they don't. For example, in open-balena-api, this request gets a Malformed url response:

/v6/device_type?%24filter=device_type_alias%2Fany(dta:dta/is_referenced_by__alias+eq+%27generic-amd64%27)&%24orderby=name+asc&%24select=id&%24top=1

whereas this works fine:

/v6/device_type?%24filter=device_type_alias/any(dta:dta/is_referenced_by__alias+eq+%27generic-amd64%27)&%24orderby=name+asc&%24select=id&%24top=1

The difference between the two is the / in device_type_alias/any being encoded as %2f. In fact, encoding any of /, (, ), or : in the filter value results in a Malformed url response but ' can be encoded as %27 and spaces as + or %20 without issue (or even not encoded), for example all of these fail:

/v6/device_type?%24filter=device_type_alias%2Fany%28dta%3Adta%2Fis_referenced_by__alias+eq+%27generic-amd64%27%29&%24orderby=name+asc&%24select=id&%24top=1
/v6/device_type?%24filter=device_type_alias/any%28dta%3Adta/is_referenced_by__alias+eq+%27generic-amd64%27%29&%24orderby=name+asc&%24select=id&%24top=1
/v6/device_type?%24filter=device_type_alias/any(dta%3Adta/is_referenced_by__alias+eq+%27generic-amd64%27)&%24orderby=name+asc&%24select=id&%24top=1
/v6/device_type?%24filter=device_type_alias/any%28dta:dta/is_referenced_by__alias+eq+%27generic-amd64%27%29&%24orderby=name+asc&%24select=id&%24top=1

I could be wrong, but the issue seems to be that this complex url check happens BEFORE a call to decodeURIComponent:

if (/[?&(]@/.test(url)) {

This means that when the /, (, ), or : are URI encoded, it skips straight to line 137 and calls parseOdata without ever calling decodeURIComponent:

return parseOdata(url);

On the other path, inside the if statement, OData parsing is done with the URI decoded params:

const parsedParams = ODataParser.parse(
decodeURIComponent(parameterAliasesString),
{
startRule: 'ProcessRule',
rule: 'QueryOptions',
},
);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant