diff --git a/src/main/java/org/eclipse/yasson/internal/deserializer/types/UriDeserializer.java b/src/main/java/org/eclipse/yasson/internal/deserializer/types/UriDeserializer.java index 26ea0fb8e..d7b1b8702 100644 --- a/src/main/java/org/eclipse/yasson/internal/deserializer/types/UriDeserializer.java +++ b/src/main/java/org/eclipse/yasson/internal/deserializer/types/UriDeserializer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at @@ -14,6 +14,9 @@ import java.lang.reflect.Type; import java.net.URI; +import java.net.URISyntaxException; + +import jakarta.json.bind.JsonbException; import org.eclipse.yasson.internal.DeserializationContextImpl; @@ -28,6 +31,11 @@ class UriDeserializer extends TypeDeserializer { @Override Object deserializeStringValue(String value, DeserializationContextImpl context, Type rType) { - return URI.create(value); + try { + return new URI(value); + } catch (URISyntaxException e) { + // Exception will be caught and wrapped + throw new JsonbException("java.net.URI could not parse value " + value, e); + } } } diff --git a/src/main/java/org/eclipse/yasson/internal/deserializer/types/UrlDeserializer.java b/src/main/java/org/eclipse/yasson/internal/deserializer/types/UrlDeserializer.java index 54cd2f346..dbe79806b 100644 --- a/src/main/java/org/eclipse/yasson/internal/deserializer/types/UrlDeserializer.java +++ b/src/main/java/org/eclipse/yasson/internal/deserializer/types/UrlDeserializer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at @@ -16,6 +16,8 @@ import java.net.MalformedURLException; import java.net.URL; +import jakarta.json.bind.JsonbException; + import org.eclipse.yasson.internal.DeserializationContextImpl; /** @@ -29,12 +31,11 @@ class UrlDeserializer extends TypeDeserializer { @Override Object deserializeStringValue(String value, DeserializationContextImpl context, Type rType) { - URL url = null; try { - url = new URL(value); + return new URL(value); } catch (MalformedURLException e) { - e.printStackTrace(); + // Exception will be caught and wrapped + throw new JsonbException("java.net.URL could not parse value " + value, e); } - return url; } } diff --git a/src/test/java/org/eclipse/yasson/defaultmapping/specific/UnmarshallingUnsupportedTypesTest.java b/src/test/java/org/eclipse/yasson/defaultmapping/specific/UnmarshallingUnsupportedTypesTest.java index 4963b12e9..c9f5991be 100644 --- a/src/test/java/org/eclipse/yasson/defaultmapping/specific/UnmarshallingUnsupportedTypesTest.java +++ b/src/test/java/org/eclipse/yasson/defaultmapping/specific/UnmarshallingUnsupportedTypesTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at @@ -15,6 +15,8 @@ import java.lang.reflect.Type; import java.math.BigDecimal; import java.math.BigInteger; +import java.net.URI; +import java.net.URL; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; @@ -30,6 +32,7 @@ import org.eclipse.yasson.TestTypeToken; import org.eclipse.yasson.defaultmapping.generics.model.GenericTestClass; +import org.eclipse.yasson.defaultmapping.generics.model.ScalarValueWrapper; import org.eclipse.yasson.defaultmapping.specific.model.ClassWithUnsupportedFields; import org.eclipse.yasson.defaultmapping.specific.model.CustomUnsupportedInterface; import org.eclipse.yasson.defaultmapping.specific.model.SupportedTypes; @@ -69,7 +72,7 @@ public void setValue(String value) { String expected = "{\"customInterface\":{\"value\":\"value1\"}}"; assertEquals(expected, defaultJsonb.toJson(unsupported)); try { - defaultJsonb.fromJson(expected, ClassWithUnsupportedFields.class); + defaultJsonb.fromJson(expected, ClassWithUnsupportedFields.class); fail("Should report an error"); } catch (JsonbException e) { assertTrue(e.getMessage().contains("Cannot infer a type")); @@ -133,11 +136,11 @@ public void testMissingFieldDefaultNull() { @Test public void testMissingFieldIgnored() { - assertThrows(JsonbException.class, () -> { - Jsonb defaultConfig = JsonbBuilder.create(new JsonbConfig().setProperty(FAIL_ON_UNKNOWN_PROPERTIES, true)); - String json = "{\"nestedPojo\":{\"integerValue\":10,\"missingField\":5},\"optionalLong\":11}"; - SupportedTypes result = defaultConfig.fromJson(json, SupportedTypes.class); - }); + assertThrows(JsonbException.class, () -> { + Jsonb defaultConfig = JsonbBuilder.create(new JsonbConfig().setProperty(FAIL_ON_UNKNOWN_PROPERTIES, true)); + String json = "{\"nestedPojo\":{\"integerValue\":10,\"missingField\":5},\"optionalLong\":11}"; + SupportedTypes result = defaultConfig.fromJson(json, SupportedTypes.class); + }); } @Test @@ -223,11 +226,23 @@ public void testEmptyStringAsOptionalLong() { Type type = new TestTypeToken>(){}.getType(); assertFail("{\"field1\":\"\"}", type,"field1", Long.class); //We are reusing Long deserializer } + + @Test + public void testMalformedURL() { + Type type = new TestTypeToken>(){}.getType(); + assertFail("{\"value\":\"www.oracle.com\"}", type, "value", URL.class); + } + + @Test + public void testMalformedURI() { + Type type = new TestTypeToken>(){}.getType(); + assertFail("{\"value\":\"www .oracle .com\"}", type, "value", URI.class); + } private void assertFail(String json, Type type, String failureProperty, Class failurePropertyClass) { try { - defaultJsonb.fromJson(json, type); - fail(); + defaultJsonb.fromJson(json, type); + fail("Expected to catch JsonbException but did not"); } catch (JsonbException e) { if(!e.getMessage().contains(failureProperty) || !e.getMessage().contains(failurePropertyClass.getName())) { fail("Expected error message to contain '" + failureProperty + "' and '" + failurePropertyClass.getName() + "', but was: " +