lukaszlenart opened a new pull request, #1941:
URL: https://github.com/apache/struts/pull/1941

   Fixes [WW-5726](https://issues.apache.org/jira/browse/WW-5726)
   
   ## Problem
   
   A property that is mergeable (`@JsonMerge`, or merge enabled by 
configuration), has a value type deserializer (`@JsonTypeInfo` on the property 
or its declared type) and a non-null initial value is deserialized by Jackson 
past both authorizing wrappers. `BeanDeserializerBase.resolve()` builds a 
`MergingSettableBeanProperty` around the already-wrapped property; with a 
non-null current value it calls the `final` 
`SettableBeanProperty#deserializeWith`, which resolves a fresh deserializer for 
the existing value's class and deserializes into it in place. Neither 
`AuthorizingSettableBeanProperty.deserializeAndSet` nor 
`AuthorizingValueDeserializer` runs and `set()` is never called: the property 
binds unchecked and its members are authorized as the enclosing bean's own 
members, so a grant on a sibling of the same name authorizes the nested write. 
No type id is needed in the body — the subtype comes from the existing value.
   
   Sibling of WW-5725, which covered the other `set()` and value-deserializer 
entry points.
   
   ## Change
   
   `AuthorizingValueDeserializer` now carries the property's value 
`TypeDeserializer` and answers `supportsUpdate()` with `FALSE` when one is 
present. `resolve()` asks the value deserializer before it builds the merging 
wrapper — through whichever property wrapper it has put around the authorizing 
one by then (`ManagedReferenceProperty`, `ObjectIdReferenceProperty` included, 
since they carry the value deserializer through) — so the property stays on the 
ordinary authorized path: it is checked itself, its members under its own 
prefix, and the value is **replaced rather than merged**.
   
   - Under Jackson's default `MapperFeature.IGNORE_MERGE_FOR_UNMERGEABLE` the 
declined merge is silently ignored; an application that disabled that feature 
gets Jackson's own `InvalidDefinitionException` ("values of type X cannot be 
merged").
   - A non-polymorphic merge keeps merging (WW-5725 path, 
`testMergeIntoExistingValueIsAuthorized` unchanged).
   - A WARN at resolve time (once per mapper and bean type) makes the disabled 
merge visible.
   
   Hiding the merge info from the wrapper's `getMetadata()` was tried first and 
rejected in review: `ManagedReferenceProperty` and `ObjectIdReferenceProperty` 
copy the metadata field before `resolve()` consults it, so 
`@JsonManagedReference` or `@JsonIdentityInfo` on the polymorphic type kept the 
bypass open. Both are now regression tests.
   
   ## Compatibility
   
   This is decided when the deserializer is built, so it applies to every 
`JacksonJsonHandler`/`JacksonXmlHandler` user, not only when 
`struts.parameters.requireAnnotations=true`. An application that merges into a 
polymorphic property with a non-null initial value through the REST plugin must 
now send the type id in the body, and the existing value's state is replaced, 
not merged. No other property kind is affected. Version Notes entry to follow.
   
   ## Tests
   
   `ParameterAuthorizingModuleTest`: the ticket scenario (sibling grant no 
longer reaches the merged subtype), the `@JsonIdentityInfo` and 
`@JsonManagedReference` wrapper variants, the replace path through 
`readerForUpdating`, and the strict-mode refusal with 
`IGNORE_MERGE_FOR_UNMERGEABLE` disabled.
   
   `mvn test -DskipAssembly -pl plugins/rest`: 184 tests, 0 failures.
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to