Skip to content

Commit

Permalink
Prepare for 2.12.6.1 release
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Mar 26, 2022
1 parent 8f9c632 commit 83b928d
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 64 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.7-SNAPSHOT</version>
<version>2.12.6.1-SNAPSHOT</version>
<name>jackson-databind</name>
<packaging>bundle</packaging>
<description>General data-binding functionality for Jackson: works on core streaming API</description>
Expand Down
4 changes: 4 additions & 0 deletions release-notes/VERSION-2.x
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ Project: jackson-databind
=== Releases ===
------------------------------------------------------------------------

2.12.6.1 (26-Mar-2022)

#2816: Optimize UntypedObjectDeserializer wrt recursion [CVE-2020-36518]

2.12.6 (15-Dec-2021)

#3280: Can not deserialize json to enum value with Object-/Array-valued input,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,10 +218,9 @@ && getClass() == UntypedObjectDeserializer.class) {
*/
@Override
public boolean isCachable() {
/* 26-Mar-2015, tatu: With respect to [databind#735], there are concerns over
* cachability. It seems like we SHOULD be safe here; but just in case there
* are problems with false sharing, this may need to be revisited.
*/
// 26-Mar-2015, tatu: With respect to [databind#735], there are concerns over
// cachability. It seems like we SHOULD be safe here; but just in case there
// are problems with false sharing, this may need to be revisited.
return true;
}

Expand Down Expand Up @@ -269,9 +268,8 @@ public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOEx
if (_numberDeserializer != null) {
return _numberDeserializer.deserialize(p, ctxt);
}
/* Caller may want to get all integral values returned as {@link java.math.BigInteger},
* or {@link java.lang.Long} for consistency
*/
// Caller may want to get all integral values returned as {@link java.math.BigInteger},
// or {@link java.lang.Long} for consistency
if (ctxt.hasSomeOfFeatures(F_MASK_INT_COERCIONS)) {
return _coerceIntegral(p, ctxt);
}
Expand Down Expand Up @@ -494,7 +492,6 @@ protected Object mapArray(JsonParser p, DeserializationContext ctxt,
protected Object mapObject(JsonParser p, DeserializationContext ctxt) throws IOException
{
String key1;

JsonToken t = p.currentToken();

if (t == JsonToken.START_OBJECT) {
Expand Down Expand Up @@ -649,10 +646,9 @@ protected Object mapObject(JsonParser p, DeserializationContext ctxt,
}

/*
/**********************************************************
/* Separate "vanilla" implementation for common case of
/* no custom deserializer overrides
/**********************************************************
/**********************************************************************
/* Separate "vanilla" implementation for common case of no deser overrides
/**********************************************************************
*/

/**
Expand All @@ -665,11 +661,13 @@ public static class Vanilla
{
private static final long serialVersionUID = 1L;

// Arbitrarily chosen.
// Introduced to resolve CVE-2020-36518 and as a temporary hotfix for #2816
private static final int MAX_DEPTH = 1000;

public final static Vanilla std = new Vanilla();

/**
* @since 2.9
*/
// @since 2.9
protected final boolean _nonMerging;

public Vanilla() { this(false); }
Expand Down Expand Up @@ -699,64 +697,76 @@ public Boolean supportsUpdate(DeserializationConfig config) {
}

@Override
public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException
public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
return deserialize(p, ctxt, 0);
}

private Object deserialize(JsonParser p, DeserializationContext ctxt, int depth) throws IOException
{
switch (p.currentTokenId()) {
case JsonTokenId.ID_START_OBJECT:
{
case JsonTokenId.ID_START_OBJECT: {
JsonToken t = p.nextToken();
if (t == JsonToken.END_OBJECT) {
return new LinkedHashMap<String,Object>(2);
return new LinkedHashMap<String, Object>(2);
}
}
case JsonTokenId.ID_FIELD_NAME:
return mapObject(p, ctxt);
case JsonTokenId.ID_START_ARRAY:
{
case JsonTokenId.ID_FIELD_NAME:
if (depth > MAX_DEPTH) {
throw new JsonParseException(p, "JSON is too deeply nested.");
}

return mapObject(p, ctxt, depth);
case JsonTokenId.ID_START_ARRAY: {
JsonToken t = p.nextToken();
if (t == JsonToken.END_ARRAY) { // and empty one too
if (ctxt.isEnabled(DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY)) {
if (ctxt.isEnabled(
DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY)) {
return NO_OBJECTS;
}
return new ArrayList<Object>(2);
}
}
if (ctxt.isEnabled(DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY)) {
return mapArrayToArray(p, ctxt);
}
return mapArray(p, ctxt);
case JsonTokenId.ID_EMBEDDED_OBJECT:
return p.getEmbeddedObject();
case JsonTokenId.ID_STRING:
return p.getText();

case JsonTokenId.ID_NUMBER_INT:
if (ctxt.hasSomeOfFeatures(F_MASK_INT_COERCIONS)) {
return _coerceIntegral(p, ctxt);
if (depth > MAX_DEPTH) {
throw new JsonParseException(p, "JSON is too deeply nested.");
}
return p.getNumberValue(); // should be optimal, whatever it is

case JsonTokenId.ID_NUMBER_FLOAT:
if (ctxt.isEnabled(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS)) {
return p.getDecimalValue();
if (ctxt.isEnabled(DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY)) {
return mapArrayToArray(p, ctxt, depth);
}
return p.getNumberValue();
return mapArray(p, ctxt, depth);
case JsonTokenId.ID_EMBEDDED_OBJECT:
return p.getEmbeddedObject();
case JsonTokenId.ID_STRING:
return p.getText();

case JsonTokenId.ID_NUMBER_INT:
if (ctxt.hasSomeOfFeatures(F_MASK_INT_COERCIONS)) {
return _coerceIntegral(p, ctxt);
}
return p.getNumberValue(); // should be optimal, whatever it is

case JsonTokenId.ID_TRUE:
return Boolean.TRUE;
case JsonTokenId.ID_FALSE:
return Boolean.FALSE;
case JsonTokenId.ID_NUMBER_FLOAT:
if (ctxt.isEnabled(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS)) {
return p.getDecimalValue();
}
return p.getNumberValue();

case JsonTokenId.ID_END_OBJECT:
// 28-Oct-2015, tatu: [databind#989] We may also be given END_OBJECT (similar to FIELD_NAME),
// if caller has advanced to the first token of Object, but for empty Object
return new LinkedHashMap<String,Object>(2);
case JsonTokenId.ID_TRUE:
return Boolean.TRUE;
case JsonTokenId.ID_FALSE:
return Boolean.FALSE;

case JsonTokenId.ID_NULL: // 08-Nov-2016, tatu: yes, occurs
return null;
case JsonTokenId.ID_END_OBJECT:
// 28-Oct-2015, tatu: [databind#989] We may also be given END_OBJECT (similar to FIELD_NAME),
// if caller has advanced to the first token of Object, but for empty Object
return new LinkedHashMap<String, Object>(2);

//case JsonTokenId.ID_END_ARRAY: // invalid
default:
case JsonTokenId.ID_NULL: // 08-Nov-2016, tatu: yes, occurs
return null;

//case JsonTokenId.ID_END_ARRAY: // invalid
default:
}
return ctxt.handleUnexpectedToken(Object.class, p);
}
Expand Down Expand Up @@ -807,7 +817,6 @@ public Object deserialize(JsonParser p, DeserializationContext ctxt, Object into
if (_nonMerging) {
return deserialize(p, ctxt);
}

switch (p.currentTokenId()) {
case JsonTokenId.ID_END_OBJECT:
case JsonTokenId.ID_END_ARRAY:
Expand Down Expand Up @@ -865,15 +874,16 @@ public Object deserialize(JsonParser p, DeserializationContext ctxt, Object into
return deserialize(p, ctxt);
}

protected Object mapArray(JsonParser p, DeserializationContext ctxt) throws IOException
protected Object mapArray(JsonParser p, DeserializationContext ctxt, int depth) throws IOException
{
Object value = deserialize(p, ctxt);
++depth;
Object value = deserialize(p, ctxt, depth);
if (p.nextToken() == JsonToken.END_ARRAY) {
ArrayList<Object> l = new ArrayList<Object>(2);
l.add(value);
return l;
}
Object value2 = deserialize(p, ctxt);
Object value2 = deserialize(p, ctxt, depth);
if (p.nextToken() == JsonToken.END_ARRAY) {
ArrayList<Object> l = new ArrayList<Object>(2);
l.add(value);
Expand All @@ -887,7 +897,7 @@ protected Object mapArray(JsonParser p, DeserializationContext ctxt) throws IOEx
values[ptr++] = value2;
int totalSize = ptr;
do {
value = deserialize(p, ctxt);
value = deserialize(p, ctxt, depth);
++totalSize;
if (ptr >= values.length) {
values = buffer.appendCompletedChunk(values);
Expand All @@ -904,12 +914,13 @@ protected Object mapArray(JsonParser p, DeserializationContext ctxt) throws IOEx
/**
* Method called to map a JSON Array into a Java Object array (Object[]).
*/
protected Object[] mapArrayToArray(JsonParser p, DeserializationContext ctxt) throws IOException {
protected Object[] mapArrayToArray(JsonParser p, DeserializationContext ctxt, int depth) throws IOException {
++depth;
ObjectBuffer buffer = ctxt.leaseObjectBuffer();
Object[] values = buffer.resetAndStart();
int ptr = 0;
do {
Object value = deserialize(p, ctxt);
Object value = deserialize(p, ctxt, depth);
if (ptr >= values.length) {
values = buffer.appendCompletedChunk(values);
ptr = 0;
Expand All @@ -922,12 +933,13 @@ protected Object[] mapArrayToArray(JsonParser p, DeserializationContext ctxt) th
/**
* Method called to map a JSON Object into a Java value.
*/
protected Object mapObject(JsonParser p, DeserializationContext ctxt) throws IOException
protected Object mapObject(JsonParser p, DeserializationContext ctxt, int depth) throws IOException
{
++depth;
// will point to FIELD_NAME at this point, guaranteed
String key1 = p.getText();
p.nextToken();
Object value1 = deserialize(p, ctxt);
Object value1 = deserialize(p, ctxt, depth);

String key2 = p.nextFieldName();
if (key2 == null) { // single entry; but we want modifiable
Expand All @@ -936,7 +948,7 @@ protected Object mapObject(JsonParser p, DeserializationContext ctxt) throws IOE
return result;
}
p.nextToken();
Object value2 = deserialize(p, ctxt);
Object value2 = deserialize(p, ctxt, depth);

String key = p.nextFieldName();
if (key == null) {
Expand All @@ -958,7 +970,7 @@ protected Object mapObject(JsonParser p, DeserializationContext ctxt) throws IOE

do {
p.nextToken();
final Object newValue = deserialize(p, ctxt);
final Object newValue = deserialize(p, ctxt, depth);
final Object oldValue = result.put(key, newValue);
if (oldValue != null) {
return _mapObjectWithDups(p, ctxt, result, key, oldValue, newValue,
Expand Down

0 comments on commit 83b928d

Please sign in to comment.