Compare commits

..

No commits in common. "2ae47b770fe76ab9ac4c2f6f50b5c5b2fb0bf5e1" and "10e793fc39a582e12a61aed4fa2ca1151c9634e5" have entirely different histories.

5 changed files with 19 additions and 144 deletions

View file

@ -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

View file

@ -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.

View file

@ -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>("test") {
publishing {
publications {
create<MavenPublication>("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"])
}
}

View file

@ -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);
}
}
}

View file

@ -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);
});
}
}