Skip to content

Commit

Permalink
Fix #1095
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Jan 30, 2016
1 parent 44f35a9 commit 21ca921
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 12 deletions.
3 changes: 3 additions & 0 deletions release-notes/VERSION
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ Project: jackson-databind
#1079: Add back `TypeFactory.constructType(Type, Class)` as "deprecated" in 2.7.1
#1083: Field in base class is not recognized, when using `@JsonType.defaultImpl`
(reported by Julian H)
#1095: Prevent coercion of `int` from empty String to `null` if
`DeserializationFeature .FAIL_ON_NULL_FOR_PRIMITIVES` is `true`
(reported by yzmyyff@github)
#1102: Handling of deprecated `SimpleType.construct()` too minimalistic
(reported by Thibault K)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,8 @@
import java.math.BigInteger;
import java.util.HashSet;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.core.JsonTokenId;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;

Expand Down Expand Up @@ -150,6 +144,18 @@ public final T getNullValue(DeserializationContext ctxt) throws JsonMappingExcep
public final T getNullValue() {
return _nullValue;
}

@Override
public T getEmptyValue(DeserializationContext ctxt) throws JsonMappingException {
// [databind#1095]: Should not allow coercion from into null from Empty String
// either, if `null` not allowed
if (_primitive && ctxt.isEnabled(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES)) {
throw ctxt.mappingException(
"Can not map Empty String as null into type %s (set DeserializationConfig.DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES to 'false' to allow)",
handledType().toString());
}
return _nullValue;
}
}

/*
Expand Down Expand Up @@ -226,7 +232,7 @@ public ShortDeserializer(Class<Short> cls, Short nvl)

@Override
public Short deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
throws IOException
{
return _parseShort(jp, ctxt);
}
Expand All @@ -248,7 +254,7 @@ public CharacterDeserializer(Class<Character> cls, Character nvl)

@Override
public Character deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException, JsonProcessingException
throws IOException
{
switch (p.getCurrentTokenId()) {
case JsonTokenId.ID_NUMBER_INT: // ok iff ascii value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,30 @@ public void testIntWithOverride() throws Exception
assertEquals(9, result._v);
}

public void testEmptyToNullCoercionForPrimitives() throws Exception {
_testEmptyToNullCoercion(int.class, Integer.valueOf(0));
_testEmptyToNullCoercion(long.class, Long.valueOf(0));
_testEmptyToNullCoercion(double.class, Double.valueOf(0.0));
_testEmptyToNullCoercion(float.class, Float.valueOf(0.0f));
}

private void _testEmptyToNullCoercion(Class<?> primType, Object emptyValue) throws Exception
{
final String EMPTY = "\"\"";

// as per [databind#1095] should only allow coercion from empty String,
// if `null` is acceptable
ObjectReader intR = MAPPER.readerFor(primType);
assertEquals(emptyValue, intR.readValue(EMPTY));
try {
intR.with(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES)
.readValue("\"\"");
fail("Should not have passed");
} catch (JsonMappingException e) {
verifyException(e, "Can not map Empty String");
}
}

/*
/**********************************************************
/* Then tests for wrappers
Expand Down Expand Up @@ -324,14 +348,14 @@ public void testCharacterWrapper() throws Exception
assertNull(wrapper.getV());

final ObjectMapper mapper = new ObjectMapper();
mapper.enable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES);
try {
mapper.enable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES);
mapper.readValue("{\"v\":null}", CharacterBean.class);
fail("Attempting to deserialize a 'null' JSON reference into a 'char' property did not throw an exception");
} catch (JsonMappingException exp) {
//Exception thrown as required
}

mapper.disable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES);
final CharacterBean charBean = MAPPER.readValue(new StringReader("{\"v\":null}"), CharacterBean.class);
assertNotNull(wrapper);
Expand Down

0 comments on commit 21ca921

Please sign in to comment.