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 TypeVariable/WildcardType recursion causing stackoverflows #948

Merged
merged 6 commits into from
Oct 15, 2019

Conversation

ZacSweers
Copy link
Collaborator

@ZacSweers ZacSweers commented Oct 13, 2019

This fixes two related issues, one documented in #338. Both cases are solved borrowing the Gson solutions for them, since all the code/logic around wildcard types for them are borrowed from them as well.

The first is fixing recursion in Util#sub/supertypeOf using the solution from google/gson@a300148. This is a bugfix itself, but also necessary for the next issue.

The second is fixing recursion in Types#resolve() by tracking previously visited type variables using the solution from google/gson#1128

Resolves #338

Copy link

@dlew dlew left a comment

Choose a reason for hiding this comment

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

Mostly just found minor things; since the code was imported from Gson I'm not that concerned about the implementation being faulty.

* limitations under the License.
*/

package com.squareup.moshi.internal;
Copy link

Choose a reason for hiding this comment

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

I'm not entirely sure this should be in the internal package because it's testing changes made in Types, which is not in the internal package.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ahh good shout 37aaaae

/**
* Test fixes for infinite recursion on {@link Util#resolve(java.lang.reflect.Type, Class,
* java.lang.reflect.Type)}, described at <a href="https://github.com/google/gson/issues/440">Issue #440</a>
* and similar issues.
Copy link

Choose a reason for hiding this comment

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

I'm confused by this comment because the code that fixes it (in 7b73ce0) puts the fixes in Types, not Util.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Gson's GsonTypes has a bunch of stuff that's split into Moshi's Types and Util. In Moshi - this method is in Util

/**
* Test simplest case of recursion.
*/
@Test public void testRecursiveResolveSimple() {
Copy link

Choose a reason for hiding this comment

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

The other Moshi tests do not use the "testBlah" naming structure; they just do "blah."

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Part of dafa839

assertThat(adapter).isNotNull();
}

@Test public void testRecursiveTypeVariablesResolve1() {
Copy link

Choose a reason for hiding this comment

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

The other Moshi tests do not use the "testBlah" naming structure; they just do "blah."

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Part of dafa839

assertThat(adapter).isNotNull();
}

@Test public void testRecursiveTypeVariablesResolve12() {
Copy link

Choose a reason for hiding this comment

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

This is the nittiest of nits, but might as well fix gson's typo here (should be "Resolve2", not "Resolve12").

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@ZacSweers ZacSweers merged commit ae8b62b into master Oct 15, 2019
@ZacSweers ZacSweers deleted the z/genericsRecursion branch October 15, 2019 22:01
@@ -169,38 +171,52 @@ public static Type removeSubtypeWildcard(Type type) {
}

public static Type resolve(Type context, Class<?> contextRawType, Type toResolve) {
return resolve(context, contextRawType, toResolve, new HashSet<TypeVariable>());
Copy link
Collaborator

Choose a reason for hiding this comment

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

Copy link
Collaborator

Choose a reason for hiding this comment

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

I don‘t love this solution because it allocates a collection always even though this case is quite rare.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

What if we initialize with an empty capacity? Still an instance but minimizes the footprint for non-typevar users

Copy link
Collaborator

Choose a reason for hiding this comment

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

lets do that, but use null as the sentinel for empty?

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.

TypeVariable recursion causes stack overflow when creating field binding.
3 participants