Skip to content

Conversation

@pboos
Copy link
Contributor

@pboos pboos commented Jun 28, 2023

When a query parameter with a comma separated list is sent with , being encoded (e.g. 123%2C2%2C3 vs 1,2,3) then this would be interpreted as a string instead of a list.

This does a urldecode when passing the parameter to the validator.

@pboos pboos changed the title bugfix: encoded query parameter bugfix: encoded query parameter (web) Jun 29, 2023
@pboos pboos marked this pull request as ready for review June 29, 2023 05:46
@pboos pboos requested review from a team and dominik-riha June 29, 2023 05:46
@@ -1,4 +1,4 @@
openapi.validation.sample-rate=0.5
openapi.validation.sample-rate=1
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ Unrelated to fix. Increasing to 1 for better example.

var requestBuilder = new SimpleRequest.Builder(request.getMethod(), request.getUri().getPath());
URLEncodedUtils.parse(request.getUri(), StandardCharsets.UTF_8)
.forEach(p -> requestBuilder.withQueryParam(p.getName(), p.getValue()));
.forEach(p -> requestBuilder.withQueryParam(p.getName(), getQueryParameterValueWithOptionalDecode(p)));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ This is the actual fix. All the rest is just other small improvements.


public RequestMetaData buildRequestMetaData(HttpServletRequest request) {
var uri = ServletUriComponentsBuilder.fromRequest(request).build(Map.of());
var uri = ServletUriComponentsBuilder.fromRequest(request).build().toUri();
Copy link
Contributor Author

@pboos pboos Jun 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ Unrelated to fix. Not strictly needed, but this simplifies the code as internally the old call did this + additional unnecessary logic.


testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework:spring-web'
testImplementation 'org.springframework:spring-webmvc'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ Unrelated to fix. Not needed right now. But this dependency is useful for writing tests in the future.

Background:

I wrote some tests that were for a previous fix of the problem, but they got reverted as I found a nicer way to fix it. When I wrote those tests this dependency was needed for the tests to run. And it took a while to find this dependency to make the tests work. So better leave them for now so we save time in the future :)

@pboos pboos requested a review from huguenin June 29, 2023 07:33
) {
this.threadPoolExecutor = threadPoolExecutor;
this.validator = new OpenApiInteractionValidatorFactory().build(specificationFilePath, configuration);
this.validator = validator;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ To mock the validator this needs to be injected. So I improved the architecture here (should have done this from the beginning).

return requestBuilder.build();
}

private static String getQueryParameterValueWithOptionalDecode(NameValuePair p) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder why we pass in the NameValuePair instead of directly the value. Why not pass in p.getValue() and rename the method to nullSafeURLDecode?


@Test
public void testWhenEncodedQueryParamIsPassedThenValidationShouldHappenWithQueryParamDecoded() {
var uri = URI.create("https://api.example.com?ids=1%2C2%2C3");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any other cases we should test, e.g. when & or = is contained encoded in the value, or when we have multiple name-value pairs being passed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, added more tests for these cases you mentioned (and also for spaces encoded with +). Hope happy you are 😉 .

@pboos pboos requested a review from huguenin June 29, 2023 09:54
Copy link
Member

@huguenin huguenin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice. Feedback for next time: It would make sense to split up into different test cases, so that a test failure will give you more insight into the specific case that is failing. If your tests fail now, the "minimum failing example" won't be evident. Good for this PR though.

@pboos pboos merged commit 2cccbb4 into main Jun 29, 2023
@pboos pboos deleted the bugfix/fix-encoded-query-parameter branch June 29, 2023 15:29
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

Successfully merging this pull request may close these issues.

3 participants