11package com .fasterxml .jackson .databind .deser .std ;
22
33import java .io .IOException ;
4- import java .util .Collection ;
5- import java .util .Objects ;
4+ import java .util .*;
65
76import com .fasterxml .jackson .annotation .JsonFormat ;
87
9- import com .fasterxml .jackson .core .*;
8+ import com .fasterxml .jackson .core .JsonParser ;
9+ import com .fasterxml .jackson .core .JsonToken ;
1010
1111import com .fasterxml .jackson .databind .*;
1212import com .fasterxml .jackson .databind .annotation .JacksonStdImpl ;
@@ -171,16 +171,15 @@ public ValueInstantiator getValueInstantiator() {
171171 /**********************************************************
172172 */
173173
174- @ SuppressWarnings ("unchecked" )
175174 @ Override
176175 public Collection <String > deserialize (JsonParser p , DeserializationContext ctxt )
177176 throws IOException
178177 {
179178 if (_delegateDeserializer != null ) {
180- return ( Collection < String >) _valueInstantiator .createUsingDelegate (ctxt ,
181- _delegateDeserializer .deserialize (p , ctxt ));
179+ return castToCollection ( _valueInstantiator .createUsingDelegate (ctxt ,
180+ _delegateDeserializer .deserialize (p , ctxt ))) ;
182181 }
183- final Collection <String > result = ( Collection < String >) _valueInstantiator .createUsingDefault (ctxt );
182+ final Collection <String > result = castToCollection ( _valueInstantiator .createUsingDefault (ctxt ) );
184183 return deserialize (p , ctxt , result );
185184 }
186185
@@ -273,7 +272,6 @@ public Object deserializeWithType(JsonParser p, DeserializationContext ctxt,
273272 * throw an exception, or try to handle value as if member of implicit
274273 * array, depending on configuration.
275274 */
276- @ SuppressWarnings ("unchecked" )
277275 private final Collection <String > handleNonArray (JsonParser p , DeserializationContext ctxt ,
278276 Collection <String > result ) throws IOException
279277 {
@@ -285,7 +283,7 @@ private final Collection<String> handleNonArray(JsonParser p, DeserializationCon
285283 if (p .hasToken (JsonToken .VALUE_STRING )) {
286284 return _deserializeFromString (p , ctxt );
287285 }
288- return ( Collection < String >) ctxt .handleUnexpectedToken (_containerType , p );
286+ return castToCollection ( ctxt .handleUnexpectedToken (_containerType , p ) );
289287 }
290288 // Strings are one of "native" (intrinsic) types, so there's never type deserializer involved
291289 JsonDeserializer <String > valueDes = _valueDeserializer ;
@@ -307,15 +305,15 @@ private final Collection<String> handleNonArray(JsonParser p, DeserializationCon
307305 final CoercionAction act = ctxt .findCoercionAction (logicalType (), handledType (),
308306 CoercionInputShape .EmptyString );
309307 if (act != CoercionAction .Fail ) {
310- return ( Collection < String >) _deserializeFromEmptyString (p , ctxt , act , handledType (),
311- "empty String (\" \" )" );
308+ return castToCollection ( _deserializeFromEmptyString (p , ctxt , act , handledType (),
309+ "empty String (\" \" )" )) ;
312310 }
313311 } else if (_isBlank (textValue )) {
314312 final CoercionAction act = ctxt .findCoercionFromBlankString (logicalType (), handledType (),
315313 CoercionAction .Fail );
316314 if (act != CoercionAction .Fail ) {
317- return ( Collection < String >) _deserializeFromEmptyString (p , ctxt , act , handledType (),
318- "blank String (all whitespace)" );
315+ return castToCollection ( _deserializeFromEmptyString (p , ctxt , act , handledType (),
316+ "blank String (all whitespace)" )) ;
319317 }
320318 }
321319 // if coercion failed, we can still add it to a list
@@ -330,4 +328,24 @@ private final Collection<String> handleNonArray(JsonParser p, DeserializationCon
330328 result .add (value );
331329 return result ;
332330 }
331+
332+ // Used to avoid type pollution: see
333+ // https://micronaut-projects.github.io/micronaut-test/latest/guide/#typePollution
334+ // for details
335+ //
336+ // @since 2.18
337+ @ SuppressWarnings ("unchecked" )
338+ private static Collection <String > castToCollection (Object o ) {
339+ if (o != null ) {
340+ // fast path for specific classes to avoid type pollution:
341+ // https://micronaut-projects.github.io/micronaut-test/latest/guide/#typePollution
342+ if (o .getClass () == ArrayList .class ) {
343+ return (ArrayList <String >) o ;
344+ }
345+ if (o .getClass () == HashSet .class ) {
346+ return (HashSet <String >) o ;
347+ }
348+ }
349+ return (Collection <String >) o ;
350+ }
333351}
0 commit comments