diff --git a/jablib/src/main/java/org/jabref/logic/util/URLUtil.java b/jablib/src/main/java/org/jabref/logic/util/URLUtil.java index e8fac8488f5..a77e96829f6 100644 --- a/jablib/src/main/java/org/jabref/logic/util/URLUtil.java +++ b/jablib/src/main/java/org/jabref/logic/util/URLUtil.java @@ -97,7 +97,21 @@ public static boolean isURL(String url) { * @throws MalformedURLException if the URL is malformed and cannot be converted to a {@link URL}. */ public static URL create(String url) throws MalformedURLException { - return createUri(url).toURL(); + if (url == null || url.trim().isEmpty()) { + throw new IllegalArgumentException("URL must not be null or empty."); + } + try { + URI parsedUri = new URI(url.trim()); + if (!parsedUri.isAbsolute()) { + throw new MalformedURLException("URI is not absolute: " + url); + } + if (parsedUri.getScheme() == null || parsedUri.getHost() == null) { + throw new MalformedURLException("URI must include both scheme and host: " + url); + } + return parsedUri.toURL(); + } catch (URISyntaxException | IllegalArgumentException e) { + throw new MalformedURLException("Invalid URI: " + url + " | " + e.getMessage()); + } } /** diff --git a/jablib/src/test/java/org/jabref/logic/net/URLUtilTest.java b/jablib/src/test/java/org/jabref/logic/net/URLUtilTest.java index 1728c8c898e..83b8a07afba 100644 --- a/jablib/src/test/java/org/jabref/logic/net/URLUtilTest.java +++ b/jablib/src/test/java/org/jabref/logic/net/URLUtilTest.java @@ -1,6 +1,8 @@ package org.jabref.logic.net; +import java.net.MalformedURLException; import java.net.URI; +import java.net.URL; import org.jabref.logic.util.URLUtil; @@ -8,6 +10,9 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; class URLUtilTest { @@ -87,4 +92,49 @@ void createUriShouldHandlePipeCharacter() { URI uri = URLUtil.createUri(input); assertEquals("http://example.com/test%7Cfile", uri.toString()); } + + @Test + void validUrl() throws MalformedURLException { + String input = "http://example.com"; + + URL result = URLUtil.create(input); + assertNotNull(result); + assertNotEquals("", result.toString().trim()); + assertEquals(input, result.toString()); + } + + @Test + void nullUrl() { + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> + URLUtil.create(null)); + assertTrue(exception.getMessage().contains("null or empty")); + } + + @Test + void emptyUrl() { + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> + URLUtil.create(" ")); + assertTrue(exception.getMessage().contains("null or empty")); + } + + @Test + void uriMissingScheme() { + MalformedURLException exception = assertThrows(MalformedURLException.class, () -> + URLUtil.create("www.example.com")); + assertTrue(exception.getMessage().contains("not absolute")); + } + + @Test + void uriMissingHost() { + MalformedURLException exception = assertThrows(MalformedURLException.class, () -> + URLUtil.create("mailto:someone@example.com")); + assertTrue(exception.getMessage().contains("must include both scheme and host")); + } + + @Test + void malformedSyntax() { + MalformedURLException exception = assertThrows(MalformedURLException.class, () -> + URLUtil.create("http://[invalid-url]")); + assertTrue(exception.getMessage().contains("Invalid URI")); + } }