是否有关于针对未编码的URL执行URLDecoder的问题?

时间:2016-01-06 13:08:38

标签: java urlencode urldecode

目前将URLEncoder和URLDecoder合并到一些代码中。 已经保存了许多URL,这些URL将由URLDecoder例程处理,该例程最初未由URLEncoder例程处理。

根据某些测试,它不会出现问题,但我没有测试过所有方案。

我确实注意到一些像/这样的字符,即使最初没有编码,也只能通过解码程序找到正常编码的字符。

这导致我过于简单的分析。似乎URLDecoder例程实质上检查了%的URL和接下来的2个字节(使用了UTF-8)。只要在之前保存的关闭网址中没有任何%,则在URLDecoder例程处理时不应该出现问题。听起来不错吗?

1 个答案:

答案 0 :(得分:2)

是的,虽然它适用于"简单"在某些情况下,如果为包含某些特殊字符的未编码URL调用URLDecoder.decode,您可能会遇到a)异常或b)意外行为。

考虑以下示例:它会为第三个测试抛出一个java.lang.IllegalArgumentException: URLDecoder: Incomplete trailing escape (%) pattern,它将在第二次测试中毫无例外地更改URL(而常规编码/解码没有问题):

import java.net.URLDecoder;
import java.net.URLEncoder;

public class Test {
    public static void main(String[] args) throws Exception {
        test("http://www.foo.bar/");
        test("http://www.foo.bar/?q=a+b");
        test("http://www.foo.bar/?q=äöüß%"); // Will throw exception
    }

    private static void test(String url) throws Exception {
        String encoded = URLEncoder.encode(url, "UTF-8");
        String decoded = URLDecoder.decode(encoded, "UTF-8");
        System.out.println("encoded: " + encoded);
        System.out.println("decoded: " + decoded);
        System.out.println(URLDecoder.decode(decoded, "UTF-8"));
    }
}

输出(注意+符号消失的方式):

encoded: http%3A%2F%2Fwww.foo.bar%2F
decoded: http://www.foo.bar/
http://www.foo.bar/
encoded: http%3A%2F%2Fwww.foo.bar%2F%3Fq%3Da%2Bb
decoded: http://www.foo.bar/?q=a+b
http://www.foo.bar/?q=a b
encoded: http%3A%2F%2Fwww.foo.bar%2F%3Fq%3D%C3%A4%C3%B6%C3%BC%C3%9F%25
decoded: http://www.foo.bar/?q=äöüß%
Exception in thread "main" java.lang.IllegalArgumentException: URLDecoder: Incomplete trailing escape (%) pattern
    at java.net.URLDecoder.decode(Unknown Source)
    at Test.test(Test.java:16)

对于这两种情况,请参阅javadoc of URLDecoder

  
      
  • 加号" +"转换成空格字符" "
  •   
  • 形式的序列"%xy"将被视为表示一个字节,其中xy是8位的两位十六进制表示。   然后,所有子字符串包含一个或多个这些字节序列   连续将被其编码的字符替换   会导致那些连续的字节。编码方案用于   解码这些字符可能是指定的,或者如果未指定,则   将使用平台的默认编码。
  •   

如果您确定未编码的网址不包含+%,那么我说它可以安全地拨打URLDecoder.decode。否则,我建议实施额外的检查,例如尝试解码并与原作比较(参见this question on SO)。