Skip to content

Commit

Permalink
Fix #114: make empty String fail to deserialize to null under "stri…
Browse files Browse the repository at this point in the history
…ct" mode
  • Loading branch information
kupci authored and cowtowncoder committed Sep 15, 2019
1 parent 08b9106 commit 48ba124
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ public LocalDate deserialize(JsonParser parser, DeserializationContext context)
if (parser.hasToken(JsonToken.VALUE_STRING)) {
String string = parser.getText().trim();
if (string.length() == 0) {
if (!isLenient()) {
return _failForNotLenient(parser, context, JsonToken.VALUE_STRING);
}
return null;
}
// as per [datatype-jsr310#37], only check for optional (and, incorrect...) time marker 'T'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,21 @@ public LocalDateTimeDeserializer(DateTimeFormatter formatter) {
super(LocalDateTime.class, formatter);
}

/**
* Since 2.10
*/
protected LocalDateTimeDeserializer(LocalDateTimeDeserializer base, Boolean leniency) {
super(base, leniency);
}

@Override
protected LocalDateTimeDeserializer withDateFormat(DateTimeFormatter formatter) {
return new LocalDateTimeDeserializer(formatter);
}

// !!! TODO: lenient vs strict?
@Override
protected LocalDateTimeDeserializer withLeniency(Boolean leniency) {
return this;
return new LocalDateTimeDeserializer(this, leniency);
}

@Override
Expand All @@ -69,6 +75,9 @@ public LocalDateTime deserialize(JsonParser parser, DeserializationContext conte
if (parser.hasTokenId(JsonTokenId.ID_STRING)) {
String string = parser.getText().trim();
if (string.length() == 0) {
if (!isLenient()) {
return _failForNotLenient(parser, context, JsonToken.VALUE_STRING);
}
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
import java.time.Month;
import java.time.ZoneOffset;
import java.time.temporal.Temporal;
import java.util.Map;

import com.fasterxml.jackson.core.type.TypeReference;
import org.junit.Test;

import static org.junit.Assert.assertEquals;
Expand All @@ -27,6 +29,7 @@ public class LocalDateDeserTest extends ModuleTestBase
{
private final ObjectMapper MAPPER = newMapper();
private final ObjectReader READER = MAPPER.readerFor(LocalDate.class);
private final TypeReference<Map<String, LocalDate>> MAP_TYPE_REF = new TypeReference<Map<String, LocalDate>>() { };

final static class Wrapper {
@JsonFormat(pattern="yyyy_MM_dd'T'HH:mmZ",
Expand Down Expand Up @@ -159,6 +162,58 @@ public void testStricDeserializeFromInt() throws Exception
// be content with just one...
}

/*
/**********************************************************
/* Tests for empty string handling
*/
/**********************************************************
*/

@Test
public void testLenientDeserializeFromEmptyString() throws Exception {

String key = "date";
ObjectMapper mapper = newMapper();
ObjectReader objectReader = mapper.readerFor(MAP_TYPE_REF);

String dateValAsNullStr = null;
String dateValAsEmptyStr = "";

String valueFromNullStr = mapper.writeValueAsString(asMap(key, dateValAsNullStr));
Map<String, LocalDate> actualMapFromNullStr = objectReader.readValue(valueFromNullStr);
LocalDate actualDateFromNullStr = actualMapFromNullStr.get(key);
assertNull(actualDateFromNullStr);

String valueFromEmptyStr = mapper.writeValueAsString(asMap(key, dateValAsEmptyStr));
Map<String, LocalDate> actualMapFromEmptyStr = objectReader.readValue(valueFromEmptyStr);
LocalDate actualDateFromEmptyStr = actualMapFromEmptyStr.get(key);
assertEquals("empty string failed to deserialize to null with lenient setting",actualDateFromNullStr, actualDateFromEmptyStr);
}

@Test( expected = MismatchedInputException.class)
public void testStrictDeserializFromEmptyString() throws Exception {

final String key = "date";
final ObjectMapper mapper = mapperBuilder()
.withConfigOverride(LocalDate.class,
c -> c.setFormat(JsonFormat.Value.forLeniency(false))
)
.build();
final ObjectReader objectReader = mapper.readerFor(MAP_TYPE_REF);
final String dateValAsNullStr = null;

// even with strict, null value should be deserialized without throwing an exception
String valueFromNullStr = mapper.writeValueAsString(asMap(key, dateValAsNullStr));
Map<String, LocalDate> actualMapFromNullStr = objectReader.readValue(valueFromNullStr);
assertNull(actualMapFromNullStr.get(key));

String dateValAsEmptyStr = "";
// TODO: nothing stops us from writing an empty string, maybe there should be a check there too?
String valueFromEmptyStr = mapper.writeValueAsString(asMap("date", dateValAsEmptyStr));
// with strict, deserializing an empty string is not permitted
objectReader.readValue(valueFromEmptyStr);
}

/*
/**********************************************************
/* Tests for alternate array handling
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,14 @@
import java.time.temporal.Temporal;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import java.util.TimeZone;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.DeserializationProblemHandler;
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
Expand All @@ -46,6 +49,7 @@ public class LocalDateTimeDeserTest
{
private final static ObjectMapper MAPPER = newMapper();
private final static ObjectReader READER = MAPPER.readerFor(LocalDateTime.class);
private final TypeReference<Map<String, LocalDateTime>> MAP_TYPE_REF = new TypeReference<Map<String, LocalDateTime>>() { };

/*
/**********************************************************
Expand Down Expand Up @@ -174,6 +178,58 @@ public void testBadDeserializationAsString01() throws Throwable
}
}

/*
/**********************************************************
/* Tests for empty string handling
*/
/**********************************************************
*/

@Test
public void testLenientDeserializeFromEmptyString() throws Exception {

String key = "datetime";
ObjectMapper mapper = newMapper();
ObjectReader objectReader = mapper.readerFor(MAP_TYPE_REF);

String dateValAsNullStr = null;
String dateValAsEmptyStr = "";

String valueFromNullStr = mapper.writeValueAsString(asMap(key, dateValAsNullStr));
Map<String, LocalDateTime> actualMapFromNullStr = objectReader.readValue(valueFromNullStr);
LocalDateTime actualDateFromNullStr = actualMapFromNullStr.get(key);
assertNull(actualDateFromNullStr);

String valueFromEmptyStr = mapper.writeValueAsString(asMap(key, dateValAsEmptyStr));
Map<String, LocalDateTime> actualMapFromEmptyStr = objectReader.readValue(valueFromEmptyStr);
LocalDateTime actualDateFromEmptyStr = actualMapFromEmptyStr.get(key);
assertEquals("empty string failed to deserialize to null with lenient setting",actualDateFromNullStr, actualDateFromEmptyStr);
}

@Test( expected = MismatchedInputException.class)
public void testStrictDeserializFromEmptyString() throws Exception {

final String key = "datetime";
final ObjectMapper mapper = mapperBuilder()
.withConfigOverride(LocalDateTime.class,
c -> c.setFormat(JsonFormat.Value.forLeniency(false))
)
.build();
final ObjectReader objectReader = mapper.readerFor(MAP_TYPE_REF);
final String dateValAsNullStr = null;

// even with strict, null value should be deserialized without throwing an exception
String valueFromNullStr = mapper.writeValueAsString(asMap(key, dateValAsNullStr));
Map<String, LocalDateTime> actualMapFromNullStr = objectReader.readValue(valueFromNullStr);
assertNull(actualMapFromNullStr.get(key));

String dateValAsEmptyStr = "";
// TODO: nothing stops us from writing an empty string, maybe there should be a check there too?
String valueFromEmptyStr = mapper.writeValueAsString(asMap("date", dateValAsEmptyStr));
// with strict, deserializing an empty string is not permitted
objectReader.readValue(valueFromEmptyStr);
}

/*
/**********************************************************
/* Tests for alternate array handling
Expand Down

0 comments on commit 48ba124

Please sign in to comment.