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

Fix controller @Body Object parameters #11267

Merged
merged 2 commits into from
Oct 24, 2024
Merged

Fix controller @Body Object parameters #11267

merged 2 commits into from
Oct 24, 2024

Conversation

yawkat
Copy link
Member

@yawkat yawkat commented Oct 22, 2024

There's two bugs here.

Let's consider the following cases:

  1. application/x-www-form-urlencoded, @Body Object param (tested by the old FormDataDiskSpec)
  2. application/json, @Body Object param (prev. no test, tested by a new TCK test)
  3. application/x-weird, @Body Object param (prev. no test, tested by a new netty-specific test)
  4. application/x-weird, @Body MyRecord param (prev. no test, tested by a new netty-specific test)

Prior to 4.6, case 2 has a registered "normal" reader (the JSON reader) that can handle this case fine, the other three cases do not have readers and rely on fallback conversion logic. Forms have some special handling here.

In 4.6, the way raw type readers (e.g. that for String) were resolved changed. This means that for Object params, all raw type readers were now eligible, since they can read a subtype of Object (e.g. String). For cases 1, 3, and 4, this is a breaking change, since the reading is now done by a (random) raw type reader, instead of falling back to conversion logic.

This change broke the FormDataDiskSpec (case 1). To fix this, 1d09d95 introduced a check that would blanket-ignore the reader for all Object-typed params, falling back to the conversion logic. This fixed cases 1 and 3, but inadvertently broke case 2, since the JSON reader was also ignored.

Case 2 is apparently common enough that there have been multiple reports about it. It also exposed the second bug, a double-claim of the body, which is a fairly simple fix. But it shows that the fallback conversion logic had no test coverage, since this bug should trigger reliably. That is what BodyConversionSpec is there to improve.

My proposed fix is to make the raw message readers not apply to Object parameters, and to remove the band-aid fix from 1d09d95 that broke case 2.

Fixes #11266

There's two bugs here.

Let's consider the following cases:

1. `application/x-www-form-urlencoded`, `@Body Object` param (tested by the old FormDataDiskSpec)
2. `application/json`, `@Body Object` param (prev. no test, tested by a new TCK test)
3. `application/x-weird`, `@Body Object` param (prev. no test, tested by a new netty-specific test)
4. `application/x-weird`, `@Body MyRecord` param (prev. no test, tested by a new netty-specific test)

Prior to 4.6, case 2 has a registered "normal" reader (the JSON reader) that can handle this case fine, the other three cases do not have readers and rely on fallback conversion logic. Forms have some special handling here.

In 4.6, the way raw type readers (e.g. that for String) were resolved changed. This means that for `Object` params, all raw type readers were now eligible, since they can read a subtype of Object (e.g. String). For cases 1, 3, and 4, this is a breaking change, since the reading is now done by a (random) raw type reader, instead of falling back to conversion logic.

This change broke the FormDataDiskSpec (case 1). To fix this, 1d09d95 introduced a check that would blanket-ignore the reader for all Object-typed params, falling back to the conversion logic. This fixed cases 1 and 3, but inadvertently broke case 2, since the JSON reader was also ignored.

Case 2 is apparently common enough that there have been multiple reports about it. It also exposed the second bug, a double-claim of the body, which is a fairly simple fix. But it shows that the fallback conversion logic had no test coverage, since this bug should trigger reliably. That is what `BodyConversionSpec` is there to improve.

My proposed fix is to make the raw message readers not apply to Object parameters, and to remove the band-aid fix from 1d09d95 that broke case 2.

Fixes #11266
@yawkat yawkat added the type: bug Something isn't working label Oct 22, 2024
@sdelamo
Copy link
Contributor

sdelamo commented Oct 23, 2024

@yawkat can you change to graalvm 1.2.4 in your pr so the the build passes and we can merge it?

Copy link

@@ -38,6 +38,6 @@ public interface TypedMessageBodyReader<T> extends MessageBodyReader<T> {

@Override
default boolean isReadable(Argument<T> type, MediaType mediaType) {
return type.isAssignableFrom(getType());
return type.isAssignableFrom(getType()) && !type.getType().equals(Object.class);
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think this a correct fix, typed reader should only add a type and nothing else

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm open to suggestions. The new test cases cover the issue pretty well.

@dstepanov
Copy link
Contributor

Let's keep it this way. We shouldn't allow Object for body in the future

@graemerocher graemerocher merged commit 663f881 into 4.6.x Oct 24, 2024
21 checks passed
@graemerocher graemerocher deleted the object-body branch October 24, 2024 10:30
@graemerocher
Copy link
Contributor

@sdelamo @yawkat we need to merge up 4.6.x in 4.7.x

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug Something isn't working
Projects
No open projects
Status: Done
Development

Successfully merging this pull request may close these issues.

4 participants