diff --git a/CHANGELOG.md b/CHANGELOG.md index 56f770609f4..1acf815d6fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ Note that this project **does not** adhere to [Semantic Versioning](http://semve - We fixed an issue where an exception could occur when saving the preferences [#7614](https://github.com/JabRef/jabref/issues/7614) - We fixed an issue where "Copy DOI url" in the right-click menu of the Entry List would just copy the DOI and not the DOI url. [#8389](https://github.com/JabRef/jabref/issues/8389) - We fixed an issue where opening the console from the drop-down menu would cause an exception. [#8466](https://github.com/JabRef/jabref/issues/8466) +- We fixed an issue where pasting a URL was replacing + signs by spaces making the URL unreachable. [#8448](https://github.com/JabRef/jabref/issues/8448) ### Removed diff --git a/src/main/java/org/jabref/logic/formatter/bibtexfields/CleanupUrlFormatter.java b/src/main/java/org/jabref/logic/formatter/bibtexfields/CleanupUrlFormatter.java index e1299e520e9..d14596de208 100644 --- a/src/main/java/org/jabref/logic/formatter/bibtexfields/CleanupUrlFormatter.java +++ b/src/main/java/org/jabref/logic/formatter/bibtexfields/CleanupUrlFormatter.java @@ -1,7 +1,9 @@ package org.jabref.logic.formatter.bibtexfields; import java.net.URLDecoder; +import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; +import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -9,7 +11,10 @@ import org.jabref.logic.l10n.Localization; /** - * Cleanup URL link + * Cleanup URL link. + *
+ * Expose string representations URL links clean up logic. + *
*/ public class CleanupUrlFormatter extends Formatter { @@ -26,14 +31,30 @@ public String getKey() { return "cleanup_url"; } + /** + * Escape and decodes a String from the application/x-www-form-urlencoded MIME format. + *+ * Method will also try to find a URL placed after "url=" or "to=". + *
+ * The conversion process is the same as executed by {@link URLDecoder} to try to + * take guarantees against code injections. + *
+ * The plus sign is replaced by its correspondent code (%2b) to avoid the character + * to be replaced by a space during the decoding execution. + * + * @param url should not be null + * @return the decoded URL as a String representation + * + * @see URLDecoder#decode(String, Charset) + */ @Override - public String format(String value) { - String decodedLink = value; - String toDecode = value; - - Matcher matcher = PATTERN_URL.matcher(value); + public String format(String url) { + var toDecode = Objects + .requireNonNull(url, "Null url") + .replaceAll("\\+", "%2b"); + Matcher matcher = PATTERN_URL.matcher(toDecode); if (matcher.find()) { - toDecode = matcher.group(1); + return URLDecoder.decode(matcher.group(1), StandardCharsets.UTF_8); } return URLDecoder.decode(toDecode, StandardCharsets.UTF_8); } @@ -46,8 +67,9 @@ public String getDescription() { @Override public String getExampleInput() { return "https://www.google.de/url?sa=t&rct=j&q=&esrc=s&source=web&cd=11&cad=" + - "rja&uact=8&ved=0ahUKEwjg3ZrB_ZPXAhVGuhoKHYdOBOg4ChAWCCYwAA&url=" + - "http%3A%2F%2Fwww.focus.de%2Fgesundheit%2Fratgeber%2Fherz%2Ftest%2" + - "Flebenserwartung-werden-sie-100-jahre-alt_aid_363828.html" + "&usg=AOvVaw1G6m2jf-pTHYkXceii4hXU"; + "rja&uact=8&ved=0ahUKEwjg3ZrB_ZPXAhVGuhoKHYdOBOg4ChAWCCYwAA&url=" + + "http%3A%2F%2Fwww.focus.de%2Fgesundheit%2Fratgeber%2Fherz%2Ftest%2" + + "Flebenserwartung-werden-sie-100-jahre-alt_aid_363828.html" + + "&usg=AOvVaw1G6m2jf-pTHYkXceii4hXU"; } } diff --git a/src/test/java/org/jabref/logic/formatter/bibtexfields/CleanupUrlFormatterTest.java b/src/test/java/org/jabref/logic/formatter/bibtexfields/CleanupUrlFormatterTest.java index 8e577b44593..822eb6f082b 100644 --- a/src/test/java/org/jabref/logic/formatter/bibtexfields/CleanupUrlFormatterTest.java +++ b/src/test/java/org/jabref/logic/formatter/bibtexfields/CleanupUrlFormatterTest.java @@ -51,4 +51,12 @@ void formatExample() { "gesundheit/ratgeber/herz/test/lebenserwartung-werden-sie-100-jahre-alt_aid_363828.html", formatter.format(formatter.getExampleInput())); } + + @Test + void shouldNotReplacePlusOperatorAsASignInURL() { + assertEquals( + "https://www.chicago.gov/content/dam/city/depts/cdot/Red Light Cameras/2022/Sutton+Tilahun_Chicago-Camera-Ticket_Exec Summary-Final-Jan10.pdf", + formatter.format("https://www.chicago.gov/content/dam/city/depts/cdot/Red Light Cameras/2022/Sutton+Tilahun_Chicago-Camera-Ticket_Exec Summary-Final-Jan10.pdf") + ); + } }