From 1ca7576b5595f96ebeeb3cf3d19b783b7af92830 Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Tue, 30 Aug 2016 23:36:37 -0700 Subject: [PATCH] Fixed #1353 --- release-notes/VERSION | 4 + .../deser/std/FromStringDeserializer.java | 3 + .../deser/JDKStringLikeTypesTest.java | 173 +++++++++--------- 3 files changed, 97 insertions(+), 83 deletions(-) diff --git a/release-notes/VERSION b/release-notes/VERSION index 4395ef364b..1d745f9a5f 100644 --- a/release-notes/VERSION +++ b/release-notes/VERSION @@ -9,6 +9,10 @@ Project: jackson-databind #1341: FAIL_ON_MISSING_EXTERNAL_TYPE_ID_PROPERTY (contributed by Connor K) +2.8.3 (not yet released) + +#1353: Improve error-handling for `java.net.URL` deserialization + 2.8.2 (30-Aug-2016) #1315: Binding numeric values can BigDecimal lose precision diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/std/FromStringDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/deser/std/FromStringDeserializer.java index dc999f3251..1fdf9f4510 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/std/FromStringDeserializer.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/std/FromStringDeserializer.java @@ -3,6 +3,7 @@ import java.io.*; import java.net.InetAddress; import java.net.InetSocketAddress; +import java.net.MalformedURLException; import java.net.URI; import java.net.URL; import java.nio.charset.Charset; @@ -115,6 +116,8 @@ public T deserialize(JsonParser p, DeserializationContext ctxt) throws IOExcepti } } catch (IllegalArgumentException iae) { cause = iae; + } catch (MalformedURLException me) { + cause = me; } String msg = "not a valid textual representation"; if (cause != null) { diff --git a/src/test/java/com/fasterxml/jackson/databind/deser/JDKStringLikeTypesTest.java b/src/test/java/com/fasterxml/jackson/databind/deser/JDKStringLikeTypesTest.java index 3bfd1e8c43..cef00c19b9 100644 --- a/src/test/java/com/fasterxml/jackson/databind/deser/JDKStringLikeTypesTest.java +++ b/src/test/java/com/fasterxml/jackson/databind/deser/JDKStringLikeTypesTest.java @@ -66,6 +66,20 @@ public StackTraceElement deserialize(JsonParser jp, private final ObjectMapper MAPPER = objectMapper(); + // [databind#239] + public void testByteBuffer() throws Exception + { + byte[] INPUT = new byte[] { 1, 3, 9, -1, 6 }; + String exp = MAPPER.writeValueAsString(INPUT); + ByteBuffer result = MAPPER.readValue(exp, ByteBuffer.class); + assertNotNull(result); + assertEquals(INPUT.length, result.remaining()); + for (int i = 0; i < INPUT.length; ++i) { + assertEquals(INPUT[i], result.get()); + } + assertEquals(0, result.remaining()); + } + public void testCharset() throws Exception { Charset UTF8 = Charset.forName("UTF-8"); @@ -226,51 +240,6 @@ public void testRegexps() throws IOException Pattern result = MAPPER.readValue(json, Pattern.class); assertEquals(exp.pattern(), result.pattern()); } - - public void testURI() throws Exception - { - final ObjectReader reader = MAPPER.readerFor(URI.class); - final URI value = new URI("http://foo.com"); - assertEquals(value, reader.readValue("\""+value.toString()+"\"")); - - // Also: empty String should be handled properly - URI result = reader.readValue(quote("")); - assertNotNull(result); - assertEquals(URI.create(""), result); - - // and finally: broken URI should give proper failure - try { - result = reader.readValue(quote("a b")); - fail("Should not accept malformed URI, instead got: "+result); - } catch (InvalidFormatException e) { - verifyException(e, "not a valid textual representation"); - } - } - - public void testURIAsArray() throws Exception - { - final ObjectReader reader = MAPPER.readerFor(URI.class); - final URI value = new URI("http://foo.com"); - try { - reader.without(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS) - .readValue("[\""+value.toString()+"\"]"); - fail("Did not throw exception for single value array when UNWRAP_SINGLE_VALUE_ARRAYS is disabled"); - } catch (JsonMappingException e) { - verifyException(e, "out of START_ARRAY token"); - } - - try { - reader.with(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS) - .readValue("[\""+value.toString()+"\",\""+value.toString()+"\"]"); - fail("Did not throw exception for single value array when there were multiple values"); - } catch (JsonMappingException e) { - verifyException(e, "more than a single value in the array"); - } - assertEquals(value, - reader.with(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS) - .readValue("[\""+value.toString()+"\"]")); - } - public void testStackTraceElement() throws Exception { StackTraceElement elem = null; @@ -290,26 +259,6 @@ public void testStackTraceElement() throws Exception assertFalse(back.isNativeMethod()); } - // [databind#239] - public void testByteBuffer() throws Exception - { - byte[] INPUT = new byte[] { 1, 3, 9, -1, 6 }; - String exp = MAPPER.writeValueAsString(INPUT); - ByteBuffer result = MAPPER.readValue(exp, ByteBuffer.class); - assertNotNull(result); - assertEquals(INPUT.length, result.remaining()); - for (int i = 0; i < INPUT.length; ++i) { - assertEquals(INPUT[i], result.get()); - } - assertEquals(0, result.remaining()); - } - - public void testStringBuilder() throws Exception - { - StringBuilder sb = MAPPER.readValue(quote("abc"), StringBuilder.class); - assertEquals("abc", sb.toString()); - } - // [databind#429] public void testStackTraceElementWithCustom() throws Exception { @@ -342,6 +291,82 @@ public void testStackTraceElementWithCustom() throws Exception assertEquals(StackTraceBean.NUM, traces[1].getLineNumber()); } + public void testStringBuilder() throws Exception + { + StringBuilder sb = MAPPER.readValue(quote("abc"), StringBuilder.class); + assertEquals("abc", sb.toString()); + } + + public void testURI() throws Exception + { + final ObjectReader reader = MAPPER.readerFor(URI.class); + final URI value = new URI("http://foo.com"); + assertEquals(value, reader.readValue("\""+value.toString()+"\"")); + + // Also: empty String should be handled properly + URI result = reader.readValue(quote("")); + assertNotNull(result); + assertEquals(URI.create(""), result); + + // and finally: broken URI should give proper failure + try { + result = reader.readValue(quote("a b")); + fail("Should not accept malformed URI, instead got: "+result); + } catch (InvalidFormatException e) { + verifyException(e, "not a valid textual representation"); + } + } + + public void testURIAsArray() throws Exception + { + final ObjectReader reader = MAPPER.readerFor(URI.class); + final URI value = new URI("http://foo.com"); + try { + reader.without(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS) + .readValue("[\""+value.toString()+"\"]"); + fail("Did not throw exception for single value array when UNWRAP_SINGLE_VALUE_ARRAYS is disabled"); + } catch (JsonMappingException e) { + verifyException(e, "out of START_ARRAY token"); + } + + try { + reader.with(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS) + .readValue("[\""+value.toString()+"\",\""+value.toString()+"\"]"); + fail("Did not throw exception for single value array when there were multiple values"); + } catch (JsonMappingException e) { + verifyException(e, "more than a single value in the array"); + } + assertEquals(value, + reader.with(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS) + .readValue("[\""+value.toString()+"\"]")); + } + + public void testURL() throws Exception + { + URL exp = new URL("http://foo.com"); + assertEquals(exp, MAPPER.readValue("\""+exp.toString()+"\"", URL.class)); + + // trivial case; null to null, embedded URL to URL + TokenBuffer buf = new TokenBuffer(null, false); + buf.writeObject(null); + assertNull(MAPPER.readValue(buf.asParser(), URL.class)); + buf.close(); + + // then, URLitself come as is: + buf = new TokenBuffer(null, false); + buf.writeObject(exp); + assertSame(exp, MAPPER.readValue(buf.asParser(), URL.class)); + buf.close(); + + // and finally, invalid URL should be handled appropriately too + try { + URL result = MAPPER.readValue(quote("a b"), URL.class); + fail("Should not accept malformed URI, instead got: "+result); + } catch (InvalidFormatException e) { + verifyException(e, "not a valid textual representation"); + } + } + public void testUUID() throws Exception { final ObjectMapper mapper = objectMapper(); @@ -449,22 +474,4 @@ public void testUUIDAux() throws Exception assertEquals(value, value2); buf.close(); } - - public void testURL() throws Exception - { - URL value = new URL("http://foo.com"); - assertEquals(value, MAPPER.readValue("\""+value.toString()+"\"", URL.class)); - - // trivial case; null to null, embedded URL to URL - TokenBuffer buf = new TokenBuffer(null, false); - buf.writeObject(null); - assertNull(MAPPER.readValue(buf.asParser(), URL.class)); - buf.close(); - - // then, URLitself come as is: - buf = new TokenBuffer(null, false); - buf.writeObject(value); - assertSame(value, MAPPER.readValue(buf.asParser(), URL.class)); - buf.close(); - } }