转义 URI 中的中括号和大括号 (#4261)

This commit is contained in:
Glavo
2025-08-14 16:16:43 +08:00
committed by GitHub
parent f239140055
commit 10bda7e6f4
2 changed files with 24 additions and 18 deletions

View File

@@ -146,7 +146,10 @@ public final class NetworkUtils {
boolean left = true; boolean left = true;
while (i < location.length()) { while (i < location.length()) {
char ch = location.charAt(i); char ch = location.charAt(i);
if (ch == ' ' || ch >= 0x80) if (ch == ' '
|| ch == '[' || ch == ']'
|| ch == '{' || ch == '}'
|| ch >= 0x80)
break; break;
else if (ch == '?') else if (ch == '?')
left = false; left = false;
@@ -163,6 +166,15 @@ public final class NetworkUtils {
for (; i < location.length(); i++) { for (; i < location.length(); i++) {
char ch = location.charAt(i); char ch = location.charAt(i);
if (ch == ' ') {
if (left)
builder.append("%20");
else
builder.append('+');
} else if (ch == '?') {
left = false;
builder.append('?');
} else if (ch >= 0x80 || (left && (ch == '[' || ch == ']' || ch == '{' || ch == '}'))) {
if (Character.isSurrogate(ch)) { if (Character.isSurrogate(ch)) {
if (Character.isHighSurrogate(ch) && i < location.length() - 1) { if (Character.isHighSurrogate(ch) && i < location.length() - 1) {
char ch2 = location.charAt(i + 1); char ch2 = location.charAt(i + 1);
@@ -179,15 +191,6 @@ public final class NetworkUtils {
continue; continue;
} }
if (ch == ' ') {
if (left)
builder.append("%20");
else
builder.append('+');
} else if (ch == '?') {
left = false;
builder.append('?');
} else if (ch >= 0x80) {
encodeCodePoint(builder, ch); encodeCodePoint(builder, ch);
} else { } else {
builder.append(ch); builder.append(ch);

View File

@@ -36,9 +36,12 @@ public class NetworkUtilsTest {
assertEquals("https://github.com/HMCL-dev/HMCL/commits?author=Glavo", encodeLocation("https://github.com/HMCL-dev/HMCL/commits?author=Glavo")); assertEquals("https://github.com/HMCL-dev/HMCL/commits?author=Glavo", encodeLocation("https://github.com/HMCL-dev/HMCL/commits?author=Glavo"));
assertEquals("https://www.example.com/file%20with%20space", encodeLocation("https://www.example.com/file with space")); assertEquals("https://www.example.com/file%20with%20space", encodeLocation("https://www.example.com/file with space"));
assertEquals("https://www.example.com/file%20with%20space", encodeLocation("https://www.example.com/file%20with%20space")); assertEquals("https://www.example.com/file%20with%20space", encodeLocation("https://www.example.com/file%20with%20space"));
assertEquals("https://www.example.com/%5Bfile%5D", encodeLocation("https://www.example.com/[file]"));
assertEquals("https://www.example.com/%7Bfile%7D", encodeLocation("https://www.example.com/{file}"));
assertEquals("https://www.example.com/%E6%B5%8B%E8%AF%95", encodeLocation("https://www.example.com/测试")); assertEquals("https://www.example.com/%E6%B5%8B%E8%AF%95", encodeLocation("https://www.example.com/测试"));
assertEquals("https://www.example.com/%F0%9F%98%87", encodeLocation("https://www.example.com/\uD83D\uDE07")); assertEquals("https://www.example.com/%F0%9F%98%87", encodeLocation("https://www.example.com/\uD83D\uDE07"));
assertEquals("https://www.example.com/test?a=10+20", encodeLocation("https://www.example.com/test?a=10 20")); assertEquals("https://www.example.com/test?a=10+20", encodeLocation("https://www.example.com/test?a=10 20"));
assertEquals("https://www.example.com/test?a=10+20&b=[30]&c={40}", encodeLocation("https://www.example.com/test?a=10 20&b=[30]&c={40}"));
assertEquals("https://www.example.com/%E6%B5%8B%E8%AF%95?a=10+20", encodeLocation("https://www.example.com/测试?a=10 20")); assertEquals("https://www.example.com/%E6%B5%8B%E8%AF%95?a=10+20", encodeLocation("https://www.example.com/测试?a=10 20"));
// Invalid surrogate pair // Invalid surrogate pair