Skip to content

Commit

Permalink
Merge branch '2.18' into 2.19
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Dec 21, 2024
2 parents ec24929 + 6214e5c commit 8767b3d
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 13 deletions.
2 changes: 2 additions & 0 deletions release-notes/CREDITS-2.x
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,8 @@ Jonas Konrad (yawkat@github)
* Contributed fix for #3655: `ObjectMapper` default heap consumption increased significantly
from 2.13.x to 2.14.0
(2.14.1)
* Contributed fix for #4848: Avoid type pollution in `StringCollectionDeserializer`
(2.18.3)
Jirka Kremser (Jiri-Kremser@github)
* Suggested #924: SequenceWriter.writeAll() could accept Iterable
Expand Down
2 changes: 2 additions & 0 deletions release-notes/VERSION-2.x
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ Project: jackson-databind
(fix by Joo-Hyuk K)
#4844: Fix wrapped array handling wrt `null` by `StdDeserializer`
(fix by Stanislav S)
#4848: Avoid type pollution in `StringCollectionDeserializer`
(contributed by Jonas K)
#4860: `ConstructorDetector.USE_PROPERTIES_BASED` does not work with
multiple constructors since 2.18
(reported by Tomáš P)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package com.fasterxml.jackson.databind.deser.std;

import java.io.IOException;
import java.util.Collection;
import java.util.Objects;
import java.util.*;

import com.fasterxml.jackson.annotation.JsonFormat;

import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;

import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
import com.fasterxml.jackson.databind.cfg.CoercionAction;
Expand Down Expand Up @@ -170,16 +171,15 @@ public ValueInstantiator getValueInstantiator() {
/**********************************************************
*/

@SuppressWarnings("unchecked")
@Override
public Collection<String> deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException
{
if (_delegateDeserializer != null) {
return (Collection<String>) _valueInstantiator.createUsingDelegate(ctxt,
_delegateDeserializer.deserialize(p, ctxt));
return castToCollection(_valueInstantiator.createUsingDelegate(ctxt,
_delegateDeserializer.deserialize(p, ctxt)));
}
final Collection<String> result = (Collection<String>) _valueInstantiator.createUsingDefault(ctxt);
final Collection<String> result = castToCollection(_valueInstantiator.createUsingDefault(ctxt));
return deserialize(p, ctxt, result);
}

Expand Down Expand Up @@ -272,7 +272,6 @@ public Object deserializeWithType(JsonParser p, DeserializationContext ctxt,
* throw an exception, or try to handle value as if member of implicit
* array, depending on configuration.
*/
@SuppressWarnings("unchecked")
private final Collection<String> handleNonArray(JsonParser p, DeserializationContext ctxt,
Collection<String> result) throws IOException
{
Expand All @@ -284,7 +283,7 @@ private final Collection<String> handleNonArray(JsonParser p, DeserializationCon
if (p.hasToken(JsonToken.VALUE_STRING)) {
return _deserializeFromString(p, ctxt);
}
return (Collection<String>) ctxt.handleUnexpectedToken(_containerType, p);
return castToCollection(ctxt.handleUnexpectedToken(_containerType, p));
}
// Strings are one of "native" (intrinsic) types, so there's never type deserializer involved
JsonDeserializer<String> valueDes = _valueDeserializer;
Expand All @@ -306,15 +305,15 @@ private final Collection<String> handleNonArray(JsonParser p, DeserializationCon
final CoercionAction act = ctxt.findCoercionAction(logicalType(), handledType(),
CoercionInputShape.EmptyString);
if (act != CoercionAction.Fail) {
return (Collection<String>) _deserializeFromEmptyString(p, ctxt, act, handledType(),
"empty String (\"\")");
return castToCollection(_deserializeFromEmptyString(p, ctxt, act, handledType(),
"empty String (\"\")"));
}
} else if (_isBlank(textValue)) {
final CoercionAction act = ctxt.findCoercionFromBlankString(logicalType(), handledType(),
CoercionAction.Fail);
if (act != CoercionAction.Fail) {
return (Collection<String>) _deserializeFromEmptyString(p, ctxt, act, handledType(),
"blank String (all whitespace)");
return castToCollection(_deserializeFromEmptyString(p, ctxt, act, handledType(),
"blank String (all whitespace)"));
}
}
// if coercion failed, we can still add it to a list
Expand All @@ -329,4 +328,24 @@ private final Collection<String> handleNonArray(JsonParser p, DeserializationCon
result.add(value);
return result;
}

// Used to avoid type pollution: see
// https://micronaut-projects.github.io/micronaut-test/latest/guide/#typePollution
// for details
//
// @since 2.18
@SuppressWarnings("unchecked")
private static Collection<String> castToCollection(Object o) {
if (o != null) {
// fast path for specific classes to avoid type pollution:
// https://micronaut-projects.github.io/micronaut-test/latest/guide/#typePollution
if (o.getClass() == ArrayList.class) {
return (ArrayList<String>) o;
}
if (o.getClass() == HashSet.class) {
return (HashSet<String>) o;
}
}
return (Collection<String>) o;
}
}

0 comments on commit 8767b3d

Please sign in to comment.