Skip to content

Location.getHref() throws MalformedURLException when location is "about:blank#foo" #298

@atnak

Description

@atnak

Problem in brief

java.net.MalformedURLException: unknown protocol: about is thrown by Location.getHref() when the location is about:blank and location.hash is also set.

Reproducing

The code below:

  • Prints about:blank#foo in Chrome / Firefox / Edge.
  • Prints about:blank in IE11.
  • Throws the aforementioned java.net.MalformedURLException: unknown protocol: about exception in HtmlUnit 2.46.0.
<html>
<head>
<script>
function test() {
    var iframe = document.getElementsByTagName('IFRAME')[0];

    iframe.contentWindow.location.hash = 'foo';
    console.log(iframe.contentWindow.location.href); // "about:blank#foo"
}
</script>
</head>
<body onload="test()">
<iframe src="about:blank"></iframe>
</body>
</html>

Details

The exception is thrown by this call to UrlUtils.getUrlWithNewRef() because it is internally using a version of new URL(...) that does not support the about protocol. Incidentally, the variable url itself initially holds "about:blank" because unlike getUrlWithNew*(), UrlUtils's other methods toUrl*() do support about:blank.

Possible fixes

Solution 1: Patch Location.getHref() with a hack for about:blank

     public String getHref() {
         final Page page = window_.getWebWindow().getEnclosedPage();
...
         try {
             URL url = page.getUrl();
             final boolean encodeHash = getBrowserVersion().hasFeature(JS_LOCATION_HREF_HASH_IS_ENCODED);
             final String hash = getHash(encodeHash);
             if (hash != null) {
+                if ("about:blank".equals(url.toExternalForm())) {
+                    return url.toExternalForm() + "#" + hash;
+                }
                 url = UrlUtils.getUrlWithNewRef(url, hash);
             }
             String s = url.toExternalForm();

Solution 2: Change UrlUtils to better support about:blank across all its methods

 	private static URL createNewUrl(final String protocol, final String authority,
 			final String path, final String ref, final String query) throws MalformedURLException {
 
...
 		if (ref != null) {
 			if (ref.isEmpty() || ref.charAt(0) != '#') {
 				s.append('#');
 			}
 			s.append(ref);
 		}
 
-		return new URL(s.toString());
+		return toUrlUnsafe(s.toString());
 	}

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions