[ 
https://issues.apache.org/jira/browse/WW-5790?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Lukasz Lenart reassigned WW-5790:
---------------------------------

    Assignee: Lukasz Lenart

> REST two-phase body copy writes constructor defaults over values already set 
> on the target
> ------------------------------------------------------------------------------------------
>
>                 Key: WW-5790
>                 URL: https://issues.apache.org/jira/browse/WW-5790
>             Project: Struts 2
>          Issue Type: Bug
>          Components: Plugin - REST
>            Reporter: Lukasz Lenart
>            Assignee: Lukasz Lenart
>            Priority: Major
>             Fix For: 7.5.0
>
>
> Follow-up to [WW-5789|https://issues.apache.org/jira/browse/WW-5789], which 
> covered the handlers that do not read the body at all.
> When {{struts.parameters.requireAnnotations=true}} and the selected 
> content-type handler does not implement 
> {{AuthorizationAwareContentTypeHandler}}, 
> {{ContentTypeInterceptor.applyTwoPhaseDeserialize}} creates a fresh instance 
> of the target with its no-arg constructor, lets the handler fill it from the 
> body, and then copies every non-null property from that instance onto the 
> real target. The copy cannot tell a value the body supplied from a value the 
> constructor assigned, so a property the body omits is still copied when it 
> has a non-null constructor default. That overwrites whatever was on the 
> target before the {{rest}} interceptor ran: a value bound by {{params}}, or 
> one loaded in {{prepare()}}.
> Affected handlers: {{XStreamHandler}} (shipped, registered by the 
> application) and any application-provided handler that does not declare the 
> marker. The handlers shipped as default ({{JacksonJsonHandler}}, 
> {{JacksonXmlHandler}}, {{JuneauXmlHandler}}) are not affected, they authorize 
> during deserialization.
> Example: a ModelDriven model declares {{private String status = "new";}}. The 
> request carries {{status=approved}} as a query parameter and an XML body that 
> only contains {{name}}. After the stack runs, {{status}} is {{new}}.
> Possible direction: compare each property of the filled instance against a 
> second, untouched fresh instance and copy only what the handler changed, 
> threading that baseline through the nested-bean recursion. A body value that 
> happens to equal the constructor default would then not be applied over a 
> differing existing value, which is the same ambiguity the copy already has 
> for null.
> Tests to add in {{ContentTypeInterceptorIntegrationTest}}: a non-aware 
> handler that fills part of a model with a constructor default, asserting the 
> omitted property keeps its prior value.



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to