Properly escape delimiters in path in UrlBuilder

Specifically %-encode ? and # passed to setPath so they're not confused
with the start of the query-string or hash.

Bug: issue 8885
Change-Id: I599e4b8e4506d704a5b8867b1c1551b735f3ce50
diff --git a/user/src/com/google/gwt/http/client/UrlBuilder.java b/user/src/com/google/gwt/http/client/UrlBuilder.java
index bd2b047..9c48468 100644
--- a/user/src/com/google/gwt/http/client/UrlBuilder.java
+++ b/user/src/com/google/gwt/http/client/UrlBuilder.java
@@ -64,7 +64,7 @@
 
     // http://www.google.com:80/path/to/file.html
     if (path != null && !"".equals(path)) {
-      url.append("/").append(URL.encode(path));
+      url.append("/").append(URL.encode(path).replace("?", "%3F").replace("#", "%23"));
     }
 
     // Generate the query string.
diff --git a/user/test/com/google/gwt/http/client/UrlBuilderTest.java b/user/test/com/google/gwt/http/client/UrlBuilderTest.java
index 6733de6..67fb123 100644
--- a/user/test/com/google/gwt/http/client/UrlBuilderTest.java
+++ b/user/test/com/google/gwt/http/client/UrlBuilderTest.java
@@ -43,6 +43,16 @@
 
     builder = new UrlBuilder();
     builder.setHost("google.com");
+    builder.setPath("?not-query#not-hash");
+    builder.setParameter("not=value&not-next", "&not-next=pair");
+    builder.setParameter("#not-hash", "#not-hash");
+    builder.setHash("hash#in-hash");
+    assertEquals(
+        "http://google.com/%3Fnot-query%23not-hash?not%3Dvalue%26not-next=%26not-next%3Dpair&%23not-hash=%23not-hash#hash%23in-hash",
+        builder.buildString());
+
+    builder = new UrlBuilder();
+    builder.setHost("google.com");
     builder.setPath("path");
     builder.setHash("hash");