-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Add support for reflection access filter #1905
Add support for reflection access filter #1905
Conversation
Alternatively But I am not sure if this is worth it. What do you think? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for taking so long to get to this. I think this is an excellent addition. Accidental reflective access seems to be a major problem with Gson, and this will go some way towards mitigating that.
If you merge to HEAD I will try running this against Google's internal tests. I don't really expect any failures but we are sometimes surprised. Feel free to do just the merge initially and hold off on the documentation changes I suggested, until we know the results. Or go ahead and make them, as you prefer.
Have improved the documentation and fixed some issues with the previous implementation. I chose a slightly different wording for the sentences describing the standard platform packages. Please let me know if it is alright like this. As mentioned in #1905 (comment), should this be extended to support describing which filter returned the final result? Or do you think that is not worth it? |
@@ -101,6 +102,7 @@ | |||
private boolean useJdkUnsafe = DEFAULT_USE_JDK_UNSAFE; | |||
private ToNumberStrategy objectToNumberStrategy = DEFAULT_OBJECT_TO_NUMBER_STRATEGY; | |||
private ToNumberStrategy numberToNumberStrategy = DEFAULT_NUMBER_TO_NUMBER_STRATEGY; | |||
private final LinkedList<ReflectionAccessFilter> reflectionFilters = new LinkedList<ReflectionAccessFilter>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're on Java 7 now, right? So we should be able to use new LinkedList<>()
, and similarly in other places in the PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point! I completely forgot that Java 7 added that feature already. Would you mind if I create a separate PR which replaces all redundant type arguments with the diamond operator, and include these changes there?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems fair.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Have created #2104 for that.
Google's internal tests pass with this change, so we can merge it once the conflicts have been resolved and the remaining minor comments addressed. |
For Java < 9, AccessibleObject.canAccess is not available and therefore checks might pass even if object is not accessible, causing IllegalAccessException later.
…/reflection-access-filter
Thanks for running this against Google's internal tests! Just to verify: You do not think that supporting specifying which filter returned a result (see #1905 (comment)) is worth it, correct? I have added one commit improving |
@eamonnmcmanus, what do you think? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I lost track of this.
@@ -101,6 +102,7 @@ | |||
private boolean useJdkUnsafe = DEFAULT_USE_JDK_UNSAFE; | |||
private ToNumberStrategy objectToNumberStrategy = DEFAULT_OBJECT_TO_NUMBER_STRATEGY; | |||
private ToNumberStrategy numberToNumberStrategy = DEFAULT_NUMBER_TO_NUMBER_STRATEGY; | |||
private final LinkedList<ReflectionAccessFilter> reflectionFilters = new LinkedList<ReflectionAccessFilter>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems fair.
[![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [com.google.code.gson:gson-parent](https://github.com/google/gson) | `2.9.0` -> `2.10.1` | [![age](https://badges.renovateapi.com/packages/maven/com.google.code.gson:gson-parent/2.10.1/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/maven/com.google.code.gson:gson-parent/2.10.1/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/maven/com.google.code.gson:gson-parent/2.10.1/compatibility-slim/2.9.0)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/maven/com.google.code.gson:gson-parent/2.10.1/confidence-slim/2.9.0)](https://docs.renovatebot.com/merge-confidence/) | | [com.google.code.gson:gson](https://github.com/google/gson) | `2.9.0` -> `2.10.1` | [![age](https://badges.renovateapi.com/packages/maven/com.google.code.gson:gson/2.10.1/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/maven/com.google.code.gson:gson/2.10.1/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/maven/com.google.code.gson:gson/2.10.1/compatibility-slim/2.9.0)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/maven/com.google.code.gson:gson/2.10.1/confidence-slim/2.9.0)](https://docs.renovatebot.com/merge-confidence/) | --- ### ⚠ Dependency Lookup Warnings ⚠ Warnings were logged while processing this repo. Please check the Dependency Dashboard for more information. --- ### Release Notes <details> <summary>google/gson</summary> ### [`v2.10`](https://github.com/google/gson/blob/HEAD/CHANGELOG.md#Version-210) - Support for serializing and deserializing Java records, on Java ≥ 16. ([https://github.com/google/gson/pull/2201](https://github.com/google/gson/pull/2201)) - Add `JsonArray.asList` and `JsonObject.asMap` view methods ([https://github.com/google/gson/pull/2225](https://github.com/google/gson/pull/2225)) - Fix `TypeAdapterRuntimeTypeWrapper` not detecting reflective `TreeTypeAdapter` and `FutureTypeAdapter` ([https://github.com/google/gson/pull/1787](https://github.com/google/gson/pull/1787)) - Improve `JsonReader.skipValue()` ([https://github.com/google/gson/pull/2062](https://github.com/google/gson/pull/2062)) - Perform numeric conversion for primitive numeric type adapters ([https://github.com/google/gson/pull/2158](https://github.com/google/gson/pull/2158)) - Add `Gson.fromJson(..., TypeToken)` overloads ([https://github.com/google/gson/pull/1700](https://github.com/google/gson/pull/1700)) - Fix changes to `GsonBuilder` affecting existing `Gson` instances ([https://github.com/google/gson/pull/1815](https://github.com/google/gson/pull/1815)) - Make `JsonElement` conversion methods more consistent and fix javadoc ([https://github.com/google/gson/pull/2178](https://github.com/google/gson/pull/2178)) - Throw `UnsupportedOperationException` when `JsonWriter.jsonValue` is not supported ([https://github.com/google/gson/pull/1651](https://github.com/google/gson/pull/1651)) - Disallow `JsonObject` `Entry.setValue(null)` ([https://github.com/google/gson/pull/2167](https://github.com/google/gson/pull/2167)) - Fix `TypeAdapter.toJson` throwing AssertionError for custom IOException ([https://github.com/google/gson/pull/2172](https://github.com/google/gson/pull/2172)) - Convert null to JsonNull for `JsonArray.set` ([https://github.com/google/gson/pull/2170](https://github.com/google/gson/pull/2170)) - Fixed nullSafe usage. ([https://github.com/google/gson/pull/1555](https://github.com/google/gson/pull/1555)) - Validate `TypeToken.getParameterized` arguments ([https://github.com/google/gson/pull/2166](https://github.com/google/gson/pull/2166)) - Fix [#​1702](https://github.com/google/gson/issues/1702): Gson.toJson creates CharSequence which does not implement toString ([https://github.com/google/gson/pull/1703](https://github.com/google/gson/pull/1703)) - Prefer existing adapter for concurrent `Gson.getAdapter` calls ([https://github.com/google/gson/pull/2153](https://github.com/google/gson/pull/2153)) - Improve `ArrayTypeAdapter` for `Object[]` ([https://github.com/google/gson/pull/1716](https://github.com/google/gson/pull/1716)) - Improve `AppendableWriter` performance ([https://github.com/google/gson/pull/1706](https://github.com/google/gson/pull/1706)) ### [`v2.9.1`](https://github.com/google/gson/blob/HEAD/CHANGELOG.md#Version-291) - Make `Object` and `JsonElement` deserialization iterative rather than recursi[https://github.com/google/gson/pull/1912](https://github.com/google/gson/pull/1912)1912) - Added parsing support for enum that has overridden toString() method ([https://github.com/google/gson/pull/1950](https://github.com/google/gson/pull/1950)) - Removed support for building Gson with Gradle ([https://github.com/google/gson/pull/2081](https://github.com/google/gson/pull/2081)) - Removed obsolete `codegen` hierarchy ([https://github.com/google/gson/pull/2099](https://github.com/google/gson/pull/2099)) - Add support for reflection access filter ([https://github.com/google/gson/pull/1905](https://github.com/google/gson/pull/1905)) - Improve `TypeToken` creation validation ([https://github.com/google/gson/pull/2072](https://github.com/google/gson/pull/2072)) - Add explicit support for `float` in `JsonWriter` ([https://github.com/google/gson/pull/2130](https://github.com/google/gson/pull/2130), [https://github.com/google/gson/pull/2132](https://github.com/google/gson/pull/2132)) - Fail when parsing invalid local date ([https://github.com/google/gson/pull/2134](https://github.com/google/gson/pull/2134)) Also many small improvements to javadoc. </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about these updates again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://app.renovatebot.com/dashboard#github/elide-dev/v3). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNC4xMDIuMCIsInVwZGF0ZWRJblZlciI6IjM0LjEwMi4wIn0=-->
Adds a
ReflectionAccessFilter
which allows preventing to use the reflection based type adapter by accident, instead throwing an exception. This is quite useful to avoid depending on Java platform implementation details.A use case where this would help is stripe/stripe-java#1197, that pull request adds a check whether a returned adapter is
com.google.gson.internal.bind.ReflectiveTypeAdapterFactory
; the addition of aReflectionAccessFilter
would allow implementing this without having to rely on Gson internal implementation details.In the future it would probably be good to apply some of these access filters by default since it appears users are often by accident depending on implementation details, or are not aware of the consequences of this. However, the way
ReflectionAccessFilter
is designed would still allow overwriting this by registering a filter which returnsFilterResult.ALLOW
for all classes, in case users for some reason want to serialize or deserialize Java platform classes using reflection.Moshi by default prevents reflective access for platform classes, see internal
Util.isPlatformType(Class)
and its callers.