diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index e4f46c2..ef31be6 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -15,15 +15,13 @@ jobs: java-version: [ 11, 17, 19 ] steps: - - name: Checkout source repository - uses: actions/checkout@v3 + - uses: actions/checkout@v2 with: fetch-depth: 0 - name: Set up JDK ${{ matrix.java-version }} - uses: actions/setup-java@v2 + uses: actions/setup-java@v1 with: - distribution: 'temurin' java-version: ${{ matrix.java-version }} - name: Grant execute permission for gradlew diff --git a/README.md b/README.md index ef9d3f2..d72c1c9 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,5 @@ [![License](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![Nexus Snapshot](https://img.shields.io/nexus/s/com.uwyn/urlencoder?server=https%3A%2F%2Fs01.oss.sonatype.org%2F)](https://s01.oss.sonatype.org/content/repositories/snapshots/com/uwyn/urlencoder/) -[![Release](https://img.shields.io/github/release/gbevin/urlencoder.svg)](https://github.com/gbevin/urlencoder/releases/latest) -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.uwyn/urlencoder/badge.svg?color=blue)](https://maven-badges.herokuapp.com/maven-central/com.uwyn/urlencoder) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=gbevin_urlencoder&metric=alert_status)](https://sonarcloud.io/dashboard?id=gbevin_urlencoder) [![GitHub CI](https://github.com/gbevin/urlencoder/actions/workflows/gradle.yml/badge.svg)](https://github.com/gbevin/urlencoder/actions/workflows/gradle.yml) @@ -12,26 +10,27 @@ A simple library to encode/decode URL parameters. This library was extracted from the [RIFE2 Web Application Framework](https://rife2.com). A Kotlin version can also be found at [https://github.com/ethauvin/urlencoder](https://github.com/ethauvin/urlencoder). -For decades, we've been using [java.net.URLEncoder](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/URLEncoder.html) +For decades, we've been using `[java.net.URLEncoder](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/URLEncoder.html) because of its improper naming. It is actually intended to encode HTML form parameters, not URLs, causing the wrong escape sequences to be used. -Additionally, `java.net.URLEncoder` allocates memory even when no encoding is +Additionally, java.net.URLEncoder allocates memory even when no encoding is necessary, significantly impacting performance. This library has a negligible -performance impact when a specified string doesn't need to be encoded. +performance impact when the string that is passed in doesn't need to be encoded. Android's [Uri.encode](https://developer.android.com/reference/android/net/Uri#encode(java.lang.String,%20java.lang.String)) -also addresses these issues, but does not currently support [unicode surrogate pairs](https://learn.microsoft.com/en-us/globalization/encoding/surrogate-pairs). - +also addresses these issues. ## Examples (TL;DR) ```java UrlEncoder.encode("a test &"); // -> "a%20test%20%26" +UrlEncoder.encode("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVQXYZ0123456789-_.~"); // -> "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVQXYZ0123456789-_.~" UrlEncoder.encode("%#okékÉȢ smile!😁"); // -> "%25%23ok%C3%A9k%C3%89%C8%A2%20smile%21%F0%9F%98%81" UrlEncoder.encode("?test=a test", "?="); // -> ?test=a%20test UrlEncoder.decode("a%20test%20%26"); // -> "a test &" +UrlEncoder.decode("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVQXYZ0123456789-_.~"); // -> "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVQXYZ0123456789-_.~" UrlEncoder.decode("%25%23ok%C3%A9k%C3%89%C8%A2%20smile%21%F0%9F%98%81"); // -> "%#okékÉȢ smile!😁" ``` @@ -40,8 +39,8 @@ To use with [Gradle](https://gradle.org/), include the following dependency in y ```gradle dependencies { - implementation("com.uwyn:urlencoder:1.0.0") + implementation("com.uwyn:urlencoder:0.9-SNAPSHOT") } ``` -Instructions for using with Maven, Ivy, etc. can be found on [Maven Central](https://maven-badges.herokuapp.com/maven-central/com.uwyn/urlencoder). +Instructions for using with Maven, Ivy, etc. can be found on Maven Central. diff --git a/lib/build.gradle.kts b/lib/build.gradle.kts index ae809c3..d4d2d43 100644 --- a/lib/build.gradle.kts +++ b/lib/build.gradle.kts @@ -7,10 +7,10 @@ plugins { } group = "com.uwyn" -version = "1.0.1-SNAPSHOT" base { - archivesName.set(rootProject.name) + archivesName.set("urlencoder") + version = "0.9-SNAPSHOT" } java { @@ -21,12 +21,6 @@ java { } } -tasks.jar { - manifest { - attributes["Main-Class"] = "com.uwyn.urlencoder.UrlEncoder" - } -} - tasks.jacocoTestReport { reports { xml.required.set(true) @@ -57,11 +51,11 @@ tasks.named("test") { publishing { publications { create("mavenJava") { - artifactId = rootProject.name + artifactId = "urlencoder" from(components["java"]) pom { - name.set("URLEncoder") - description.set("A simple library to encode/decode URL parameters") + name.set("URL Encoder") + description.set("A simple library to encode/decode URL parameters.") url.set("https://github.com/gbevin/urlencoder") licenses { license { @@ -105,4 +99,4 @@ publishing { signing { sign(publishing.publications["mavenJava"]) -} +} \ No newline at end of file diff --git a/lib/src/main/java/com/uwyn/urlencoder/UrlEncoder.java b/lib/src/main/java/com/uwyn/urlencoder/UrlEncoder.java index 497d58a..080af04 100644 --- a/lib/src/main/java/com/uwyn/urlencoder/UrlEncoder.java +++ b/lib/src/main/java/com/uwyn/urlencoder/UrlEncoder.java @@ -67,7 +67,7 @@ public final class UrlEncoder { byte[] bytes_buffer = null; var bytes_pos = 0; var i = 0; - while (i < length) { + while(i < length) { ch = source.charAt(i); if (ch == '%') { @@ -137,7 +137,7 @@ public final class UrlEncoder { * @since 1.0 */ public static String encode(String source) { - return encode(source, (String) null); + return encode(source, (String)null); } /** @@ -174,7 +174,7 @@ public final class UrlEncoder { StringBuilder out = null; char ch; var i = 0; - while (i < source.length()) { + while(i < source.length()) { ch = source.charAt(i); if (isUnreservedUriChar(ch) || (allow != null && allow.indexOf(ch) != -1)) { if (out != null) { @@ -218,57 +218,4 @@ public final class UrlEncoder { private static boolean isUnreservedUriChar(char ch) { return ch <= '~' && UNRESERVED_URI_CHARS.get(ch); } - - static class MainResult { - final String output; - final int status; - - public MainResult(String output, int status) { - this.output = output; - this.status = status; - } - } - - static MainResult handleMain(String[] arguments) { - var valid_arguments = true; - if (arguments.length < 1 || - arguments.length > 2) { - valid_arguments = false; - } else if (!arguments[0].startsWith("-")) { - if (arguments.length > 1) { - valid_arguments = false; - } - } else { - if (!arguments[0].equals("-e") && - !arguments[0].equals("-d")) { - valid_arguments = false; - } - } - - if (!valid_arguments) { - return new MainResult("Usage : java " + UrlEncoder.class.getName() + " [-ed] text" + System.lineSeparator() + - "Encode and decode URL parameters." + System.lineSeparator() + - " -e encode (default)" + System.lineSeparator() + - " -d decode", 1); - } - - if (1 == arguments.length) { - return new MainResult(UrlEncoder.encode(arguments[0]), 0); - } else if (arguments[0].equals("-e")) { - return new MainResult(UrlEncoder.encode(arguments[1]), 0); - } - - return new MainResult(UrlEncoder.decode(arguments[1]), 0); - } - - public static void main(String[] arguments) { - var result = handleMain(arguments); - if (result.status == 0) { - System.out.println(result.output); - System.exit(0); - } else { - System.err.println(result.output); - System.exit(result.status); - } - } } diff --git a/lib/src/test/java/com/uwyn/urlencoder/UrlEncoderTest.java b/lib/src/test/java/com/uwyn/urlencoder/UrlEncoderTest.java index b587598..530dd4c 100644 --- a/lib/src/test/java/com/uwyn/urlencoder/UrlEncoderTest.java +++ b/lib/src/test/java/com/uwyn/urlencoder/UrlEncoderTest.java @@ -23,7 +23,6 @@ class UrlEncoderTest { @Test void testDecodeURL() { assertNull(UrlEncoder.decode(null)); - assertSame("", UrlEncoder.decode("")); assertSame(same, UrlEncoder.decode(same)); validMap.forEach((expected, source) -> assertEquals(expected, UrlEncoder.decode(source))); @@ -44,66 +43,4 @@ class UrlEncoderTest { assertEquals("?test=a%20test", UrlEncoder.encode("?test=a test", '?', '=')); assertEquals("aaa", UrlEncoder.encode("aaa", 'a')); } - - @Test - void testMainNoArgs() { - var result = UrlEncoder.handleMain(new String[0]); - assertEquals(1, result.status); - assertTrue(result.output.contains(UrlEncoder.class.getName())); - } - - @Test - void testMainTooManyArgs() { - var result = UrlEncoder.handleMain(new String[] {"-x", "-g", "f"}); - assertEquals(1, result.status); - assertTrue(result.output.contains(UrlEncoder.class.getName())); - } - - @Test - void testMainWrongArgs1() { - var result = UrlEncoder.handleMain(new String[] {"-p"}); - assertEquals(1, result.status); - assertTrue(result.output.contains(UrlEncoder.class.getName())); - } - - @Test - void testMainWrongArgs2() { - var result = UrlEncoder.handleMain(new String[] {"-x", "txt"}); - assertEquals(1, result.status); - assertTrue(result.output.contains(UrlEncoder.class.getName())); - } - - @Test - void testMainWrongArgs3() { - var result = UrlEncoder.handleMain(new String[] {"stuff", "txt"}); - assertEquals(1, result.status); - assertTrue(result.output.contains(UrlEncoder.class.getName())); - } - - @Test - void testDecodeMainOption() { - validMap.forEach((expected, source) -> { - var result = UrlEncoder.handleMain(new String[] {"-d", source}); - assertEquals(0, result.status); - assertEquals(expected, result.output); - }); - } - - @Test - void testEncodeMainDefault() { - validMap.forEach((source, expected) -> { - var result = UrlEncoder.handleMain(new String[] {source}); - assertEquals(0, result.status); - assertEquals(expected, result.output); - }); - } - - @Test - void testEncodeMainOption() { - validMap.forEach((source, expected) -> { - var result = UrlEncoder.handleMain(new String[] {"-e", source}); - assertEquals(0, result.status); - assertEquals(expected, result.output); - }); - } }