提交 5ef65f8c 编写于 作者: I igerasim

8221518: Normalize normalization

Reviewed-by: chegar, igerasim, ahgross, rhalade
上级 a453be93
/* /*
* Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1995, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -33,6 +33,7 @@ import java.io.ObjectStreamField; ...@@ -33,6 +33,7 @@ import java.io.ObjectStreamField;
import java.io.ObjectInputStream.GetField; import java.io.ObjectInputStream.GetField;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import sun.net.util.IPAddressUtil;
import sun.security.util.SecurityConstants; import sun.security.util.SecurityConstants;
/** /**
...@@ -414,13 +415,19 @@ public final class URL implements java.io.Serializable { ...@@ -414,13 +415,19 @@ public final class URL implements java.io.Serializable {
} }
ref = parts.getRef(); ref = parts.getRef();
// Note: we don't do validation of the URL here. Too risky to change // Note: we don't do full validation of the URL here. Too risky to change
// right now, but worth considering for future reference. -br // right now, but worth considering for future reference. -br
if (handler == null && if (handler == null &&
(handler = getURLStreamHandler(protocol)) == null) { (handler = getURLStreamHandler(protocol)) == null) {
throw new MalformedURLException("unknown protocol: " + protocol); throw new MalformedURLException("unknown protocol: " + protocol);
} }
this.handler = handler; this.handler = handler;
if (host != null && isBuiltinStreamHandler(handler)) {
String s = IPAddressUtil.checkExternalForm(this);
if (s != null) {
throw new MalformedURLException(s);
}
}
} }
/** /**
...@@ -943,7 +950,12 @@ public final class URL implements java.io.Serializable { ...@@ -943,7 +950,12 @@ public final class URL implements java.io.Serializable {
* @since 1.5 * @since 1.5
*/ */
public URI toURI() throws URISyntaxException { public URI toURI() throws URISyntaxException {
return new URI (toString()); URI uri = new URI(toString());
if (authority != null && isBuiltinStreamHandler(handler)) {
String s = IPAddressUtil.checkAuthority(this);
if (s != null) throw new URISyntaxException(authority, s);
}
return uri;
} }
/** /**
...@@ -1400,6 +1412,10 @@ public final class URL implements java.io.Serializable { ...@@ -1400,6 +1412,10 @@ public final class URL implements java.io.Serializable {
return replacementURL; return replacementURL;
} }
boolean isBuiltinStreamHandler(URLStreamHandler handler) {
return isBuiltinStreamHandler(handler.getClass().getName());
}
private boolean isBuiltinStreamHandler(String handlerClassName) { private boolean isBuiltinStreamHandler(String handlerClassName) {
return (handlerClassName.startsWith(BUILTIN_HANDLERS_PREFIX)); return (handlerClassName.startsWith(BUILTIN_HANDLERS_PREFIX));
} }
......
/* /*
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1995, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -532,12 +532,15 @@ public abstract class URLStreamHandler { ...@@ -532,12 +532,15 @@ public abstract class URLStreamHandler {
* @see java.net.URL#set(java.lang.String, java.lang.String, int, java.lang.String, java.lang.String) * @see java.net.URL#set(java.lang.String, java.lang.String, int, java.lang.String, java.lang.String)
* @since 1.3 * @since 1.3
*/ */
protected void setURL(URL u, String protocol, String host, int port, protected void setURL(URL u, String protocol, String host, int port,
String authority, String userInfo, String path, String authority, String userInfo, String path,
String query, String ref) { String query, String ref) {
if (this != u.handler) { if (this != u.handler) {
throw new SecurityException("handler for url different from " + throw new SecurityException("handler for url different from " +
"this handler"); "this handler");
} else if (host != null && u.isBuiltinStreamHandler(this)) {
String s = IPAddressUtil.checkHostString(host);
if (s != null) throw new IllegalArgumentException(s);
} }
// ensure that no one can reset the protocol on a given URL. // ensure that no one can reset the protocol on a given URL.
u.set(u.getProtocol(), host, port, authority, userInfo, path, query, ref); u.set(u.getProtocol(), host, port, authority, userInfo, path, query, ref);
......
...@@ -25,6 +25,9 @@ ...@@ -25,6 +25,9 @@
package sun.net.util; package sun.net.util;
import java.net.URL;
import java.util.Arrays;
public class IPAddressUtil { public class IPAddressUtil {
private final static int INADDR4SZ = 4; private final static int INADDR4SZ = 4;
private final static int INADDR16SZ = 16; private final static int INADDR16SZ = 16;
...@@ -287,4 +290,182 @@ public class IPAddressUtil { ...@@ -287,4 +290,182 @@ public class IPAddressUtil {
} }
return false; return false;
} }
// See java.net.URI for more details on how to generate these
// masks.
//
// square brackets
private static final long L_IPV6_DELIMS = 0x0L; // "[]"
private static final long H_IPV6_DELIMS = 0x28000000L; // "[]"
// RFC 3986 gen-delims
private static final long L_GEN_DELIMS = 0x8400800800000000L; // ":/?#[]@"
private static final long H_GEN_DELIMS = 0x28000001L; // ":/?#[]@"
// These gen-delims can appear in authority
private static final long L_AUTH_DELIMS = 0x400000000000000L; // "@[]:"
private static final long H_AUTH_DELIMS = 0x28000001L; // "@[]:"
// colon is allowed in userinfo
private static final long L_COLON = 0x400000000000000L; // ":"
private static final long H_COLON = 0x0L; // ":"
// slash should be encoded in authority
private static final long L_SLASH = 0x800000000000L; // "/"
private static final long H_SLASH = 0x0L; // "/"
// backslash should always be encoded
private static final long L_BACKSLASH = 0x0L; // "\"
private static final long H_BACKSLASH = 0x10000000L; // "\"
// ASCII chars 0-31 + 127 - various controls + CRLF + TAB
private static final long L_NON_PRINTABLE = 0xffffffffL;
private static final long H_NON_PRINTABLE = 0x8000000000000000L;
// All of the above
private static final long L_EXCLUDE = 0x84008008ffffffffL;
private static final long H_EXCLUDE = 0x8000000038000001L;
private static final char[] OTHERS = {
8263,8264,8265,8448,8449,8453,8454,10868,
65109,65110,65119,65131,65283,65295,65306,65311,65312
};
// Tell whether the given character is found by the given mask pair
public static boolean match(char c, long lowMask, long highMask) {
if (c < 64)
return ((1L << c) & lowMask) != 0;
if (c < 128)
return ((1L << (c - 64)) & highMask) != 0;
return false; // other non ASCII characters are not filtered
}
// returns -1 if the string doesn't contain any characters
// from the mask, the index of the first such character found
// otherwise.
public static int scan(String s, long lowMask, long highMask) {
int i = -1, len;
if (s == null || (len = s.length()) == 0) return -1;
boolean match = false;
while (++i < len && !(match = match(s.charAt(i), lowMask, highMask)));
if (match) return i;
return -1;
}
public static int scan(String s, long lowMask, long highMask, char[] others) {
int i = -1, len;
if (s == null || (len = s.length()) == 0) return -1;
boolean match = false;
char c, c0 = others[0];
while (++i < len && !(match = match((c=s.charAt(i)), lowMask, highMask))) {
if (c >= c0 && (Arrays.binarySearch(others, c) > -1)) {
match = true; break;
}
}
if (match) return i;
return -1;
}
private static String describeChar(char c) {
if (c < 32 || c == 127) {
if (c == '\n') return "LF";
if (c == '\r') return "CR";
return "control char (code=" + (int)c + ")";
}
if (c == '\\') return "'\\'";
return "'" + c + "'";
}
private static String checkUserInfo(String str) {
// colon is permitted in user info
int index = scan(str, L_EXCLUDE & ~L_COLON,
H_EXCLUDE & ~H_COLON);
if (index >= 0) {
return "Illegal character found in user-info: "
+ describeChar(str.charAt(index));
}
return null;
}
private static String checkHost(String str) {
int index;
if (str.startsWith("[") && str.endsWith("]")) {
str = str.substring(1, str.length() - 1);
if (isIPv6LiteralAddress(str)) {
index = str.indexOf('%');
if (index >= 0) {
index = scan(str = str.substring(index),
L_NON_PRINTABLE | L_IPV6_DELIMS,
H_NON_PRINTABLE | H_IPV6_DELIMS);
if (index >= 0) {
return "Illegal character found in IPv6 scoped address: "
+ describeChar(str.charAt(index));
}
}
return null;
}
return "Unrecognized IPv6 address format";
} else {
index = scan(str, L_EXCLUDE, H_EXCLUDE);
if (index >= 0) {
return "Illegal character found in host: "
+ describeChar(str.charAt(index));
}
}
return null;
}
private static String checkAuth(String str) {
int index = scan(str,
L_EXCLUDE & ~L_AUTH_DELIMS,
H_EXCLUDE & ~H_AUTH_DELIMS);
if (index >= 0) {
return "Illegal character found in authority: "
+ describeChar(str.charAt(index));
}
return null;
}
// check authority of hierarchical URL. Appropriate for
// HTTP-like protocol handlers
public static String checkAuthority(URL url) {
String s, u, h;
if (url == null) return null;
if ((s = checkUserInfo(u = url.getUserInfo())) != null) {
return s;
}
if ((s = checkHost(h = url.getHost())) != null) {
return s;
}
if (h == null && u == null) {
return checkAuth(url.getAuthority());
}
return null;
}
// minimal syntax checks - deeper check may be performed
// by the appropriate protocol handler
public static String checkExternalForm(URL url) {
String s;
if (url == null) return null;
int index = scan(s = url.getUserInfo(),
L_NON_PRINTABLE | L_SLASH,
H_NON_PRINTABLE | H_SLASH);
if (index >= 0) {
return "Illegal character found in authority: "
+ describeChar(s.charAt(index));
}
if ((s = checkHostString(url.getHost())) != null) {
return s;
}
return null;
}
public static String checkHostString(String host) {
if (host == null) return null;
int index = scan(host,
L_NON_PRINTABLE | L_SLASH,
H_NON_PRINTABLE | H_SLASH,
OTHERS);
if (index >= 0) {
return "Illegal character found in host: "
+ describeChar(host.charAt(index));
}
return null;
}
} }
/* /*
* Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1994, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -36,6 +36,7 @@ import java.io.BufferedInputStream; ...@@ -36,6 +36,7 @@ import java.io.BufferedInputStream;
import java.io.FilterInputStream; import java.io.FilterInputStream;
import java.io.FilterOutputStream; import java.io.FilterOutputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.net.SocketPermission; import java.net.SocketPermission;
import java.net.UnknownHostException; import java.net.UnknownHostException;
...@@ -47,6 +48,7 @@ import java.util.StringTokenizer; ...@@ -47,6 +48,7 @@ import java.util.StringTokenizer;
import java.util.Iterator; import java.util.Iterator;
import java.security.Permission; import java.security.Permission;
import sun.net.NetworkClient; import sun.net.NetworkClient;
import sun.net.util.IPAddressUtil;
import sun.net.www.MessageHeader; import sun.net.www.MessageHeader;
import sun.net.www.MeteredStream; import sun.net.www.MeteredStream;
import sun.net.www.URLConnection; import sun.net.www.URLConnection;
...@@ -155,6 +157,21 @@ public class FtpURLConnection extends URLConnection { ...@@ -155,6 +157,21 @@ public class FtpURLConnection extends URLConnection {
} }
} }
static URL checkURL(URL u) throws IllegalArgumentException {
if (u != null) {
if (u.toExternalForm().indexOf('\n') > -1) {
Exception mfue = new MalformedURLException("Illegal character in URL");
throw new IllegalArgumentException(mfue.getMessage(), mfue);
}
}
String s = IPAddressUtil.checkAuthority(u);
if (s != null) {
Exception mfue = new MalformedURLException(s);
throw new IllegalArgumentException(mfue.getMessage(), mfue);
}
return u;
}
/** /**
* Creates an FtpURLConnection from a URL. * Creates an FtpURLConnection from a URL.
* *
...@@ -168,7 +185,7 @@ public class FtpURLConnection extends URLConnection { ...@@ -168,7 +185,7 @@ public class FtpURLConnection extends URLConnection {
* Same as FtpURLconnection(URL) with a per connection proxy specified * Same as FtpURLconnection(URL) with a per connection proxy specified
*/ */
FtpURLConnection(URL url, Proxy p) { FtpURLConnection(URL url, Proxy p) {
super(url); super(checkURL(url));
instProxy = p; instProxy = p;
host = url.getHost(); host = url.getHost();
port = url.getPort(); port = url.getPort();
......
/* /*
* Copyright (c) 1995, 2018, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1995, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -66,6 +66,7 @@ import java.util.HashSet; ...@@ -66,6 +66,7 @@ import java.util.HashSet;
import java.util.HashMap; import java.util.HashMap;
import java.util.Set; import java.util.Set;
import sun.net.*; import sun.net.*;
import sun.net.util.IPAddressUtil;
import sun.net.www.*; import sun.net.www.*;
import sun.net.www.http.HttpClient; import sun.net.www.http.HttpClient;
import sun.net.www.http.PosterOutputStream; import sun.net.www.http.PosterOutputStream;
...@@ -850,8 +851,13 @@ public class HttpURLConnection extends java.net.HttpURLConnection { ...@@ -850,8 +851,13 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
throw new MalformedURLException("Illegal character in URL"); throw new MalformedURLException("Illegal character in URL");
} }
} }
String s = IPAddressUtil.checkAuthority(u);
if (s != null) {
throw new MalformedURLException(s);
}
return u; return u;
} }
protected HttpURLConnection(URL u, Proxy p, Handler handler) protected HttpURLConnection(URL u, Proxy p, Handler handler)
throws IOException { throws IOException {
super(checkURL(u)); super(checkURL(u));
......
...@@ -45,6 +45,7 @@ import java.security.Permission; ...@@ -45,6 +45,7 @@ import java.security.Permission;
import java.security.Principal; import java.security.Principal;
import java.util.Map; import java.util.Map;
import java.util.List; import java.util.List;
import sun.net.util.IPAddressUtil;
import sun.net.www.http.HttpClient; import sun.net.www.http.HttpClient;
/** /**
...@@ -86,6 +87,10 @@ public class HttpsURLConnectionImpl ...@@ -86,6 +87,10 @@ public class HttpsURLConnectionImpl
throw new MalformedURLException("Illegal character in URL"); throw new MalformedURLException("Illegal character in URL");
} }
} }
String s = IPAddressUtil.checkAuthority(u);
if (s != null) {
throw new MalformedURLException(s);
}
return u; return u;
} }
// For both copies of the file, uncomment one line and comment the other // For both copies of the file, uncomment one line and comment the other
...@@ -333,7 +338,7 @@ public class HttpsURLConnectionImpl ...@@ -333,7 +338,7 @@ public class HttpsURLConnectionImpl
* @param key the keyword by which the request is known * @param key the keyword by which the request is known
* (e.g., "<code>accept</code>"). * (e.g., "<code>accept</code>").
* @param value the value associated with it. * @param value the value associated with it.
* @see #getRequestProperties(java.lang.String) * @see #getRequestProperty(java.lang.String)
* @since 1.4 * @since 1.4
*/ */
public void addRequestProperty(String key, String value) { public void addRequestProperty(String key, String value) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册