Bladeren bron

[java] Try to encode urls more closely to how it's done on JavaScript

Closes #4564
Cauê Waneck 9 jaren geleden
bovenliggende
commit
f3a75b33d7
2 gewijzigde bestanden met toevoegingen van 59 en 3 verwijderingen
  1. 37 3
      std/StringTools.hx
  2. 22 0
      tests/unit/src/unit/issues/Issue4564.hx

+ 37 - 3
std/StringTools.hx

@@ -44,9 +44,7 @@ class StringTools {
 		#elseif cpp
 			return untyped s.__URLEncode();
 		#elseif java
-			try
-				return untyped __java__("java.net.URLEncoder.encode(s, \"UTF-8\")")
-			catch (e:Dynamic) throw e;
+			return postProcessUrlEncode(java.net.URLEncoder.encode(s, "UTF-8"));
 		#elseif cs
 			return untyped cs.system.Uri.EscapeDataString(s);
 		#elseif python
@@ -67,6 +65,42 @@ class StringTools {
 		#end
 	}
 
+#if java
+	private static function postProcessUrlEncode( s : String ) : String {
+		var ret = new StringBuf();
+		var i = 0,
+		    len = s.length;
+		while (i < len) {
+			switch(_charAt(s, i++)) {
+			case '+'.code:
+				ret.add('%20');
+			case '%'.code if (i <= len - 2):
+				var c1 = _charAt(s, i++),
+				    c2 = _charAt(s, i++);
+				switch[c1, c2] {
+				case ['2'.code, '1'.code]:
+					ret.addChar('!'.code);
+				case ['2'.code, '7'.code]:
+					ret.addChar('\''.code);
+				case ['2'.code, '8'.code]:
+					ret.addChar('('.code);
+				case ['2'.code, '9'.code]:
+					ret.addChar(')'.code);
+				case ['7'.code, 'E'.code]:
+					ret.addChar('-'.code);
+				case _:
+					ret.addChar('%'.code);
+					ret.addChar(cast c1);
+					ret.addChar(cast c2);
+				}
+			case chr:
+				ret.addChar(cast chr);
+			}
+		}
+		return ret.toString();
+	}
+#end
+
 	/**
 		Decode an URL using the standard format.
 	**/

+ 22 - 0
tests/unit/src/unit/issues/Issue4564.hx

@@ -0,0 +1,22 @@
+package unit.issues;
+
+class Issue4564 extends Test {
+	function test() {
+		inline function test(str:String, ?pos:haxe.PosInfos) {
+			eq(StringTools.urlDecode(StringTools.urlEncode(str)), str, pos);
+		}
+		eq(StringTools.urlEncode('[email protected]'), 'me%40home.com');
+		test('[email protected]');
+		eq(StringTools.urlEncode('Email Address'), 'Email%20Address');
+		test('Email Address');
+		eq(StringTools.urlEncode('Email Address!'), 'Email%20Address!');
+		test('Email Address!');
+		eq(StringTools.urlEncode('Email Address('), 'Email%20Address(');
+		test('Email Address(');
+		test('ção');
+		test('a%a');
+		test('a%20');
+		test('a%20a');
+		test('a%20a%');
+	}
+}