Validate generic type arguments (simplified alternative to #6254) - #6259
martinfrancois wants to merge 3 commits into
Conversation
…nceof, validate self-referenced arguments - Error messages now carry the polymorphic base type and the complete type id, the same as the container-level checks, and name the offending type argument and the type parameter it was declared as. - Replace the `instanceof DeserializationContext` check with a protected no-op hook in `DatabindContext` that `DeserializationContext` overrides. - Use `introspectClassAnnotations` for the `SubTypeValidator` call; the bean description is only used to report a denial. - Compare the approved base type with `equals` in `BaseTypeAllowingValidator`. - Validate the type a `ResolvedRecursiveType` refers to: the projection of `SelfSupplier<X>` onto `Supplier` yields `Supplier<SelfSupplier<X>>` whose argument is a self-reference with no type parameters of its own, so `X` was never validated. - Bring the `_validateTypeParameter` javadoc up to date and add a release note naming both behaviour changes. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
284d63f to
57c410f
Compare
| if (!param.isEnumType()) { | ||
| Validity baseValidity = ptv.validateBaseType(config, declaredType); | ||
| if (baseValidity == Validity.DENIED) { | ||
| throw _typeParameterDeniedException(polymorphicBase, typeId, | ||
| declaredType, param, ptv, true); | ||
| } |
There was a problem hiding this comment.
⚠️ Bug: Denied declared base type rejects type arguments that used to pass
_validateTypeParameter now calls ptv.validateBaseType(config, declaredType) for every type argument and throws right away on DENIED. declaredType is often the unknown type (Object), because it stands in for unbound, wildcard, Object and subtype-only parameters. So a BasicPolymorphicTypeValidator built with denyForExactBaseType(Object.class) plus allowIfSubType("com.example.") will now reject ids like java.util.ArrayList<com.example.Foo> for a List<Object> or Map<String,Object> base. Before this change, the same argument was approved through validateSubClassName, and that rule still passes on the name check.
The top-level path only calls validateBaseType once, when the type deserializer is built; it is not re-checked for each type id. This PR applies it to a type the user never declared as a polymorphic base, which breaks existing configurations in a patch release. Fix: treat DENIED from the declared parameter's base check like INDETERMINATE and fall through to the name- and class-based checks, or skip the base check when declaredType is Object/unknown.
Was this helpful? React with 👍 / 👎
There was a problem hiding this comment.
Intended. The declared type argument is treated as the base type in both directions: allowIfBaseType(X) approves subtypes of X as arguments, and denyForExactBaseType(X) rejects them, the same way both work for the top-level type. Letting a DENIED fall through to the name checks would make an Object argument easier to pass than an Object property. Jackson itself only writes generic type ids for EnumSet and EnumMap, where the arguments are enums (exempt from the PTV) or Object (skipped), so ids Jackson wrote are unaffected.
There was a problem hiding this comment.
Gitar can change code and merge on your behalf, so it only acts on requests from people who can push. This needs Write access to this repository.
Code Review
|
| Auto-apply | Compact |
|
|
Was this helpful? React with 👍 / 👎 | Powered by Gitar — free for open source
Alternative to #6254
Summary by Gitar
DatabindContextBaseTypeAllowingValidatorand_validateGenericSubTypehook for unsafe class checksThis will update automatically on new commits.