Bug 1460198 - When calling SetRef/SetQuery/SetPathQueryRef you should do the same for the inner URI r=bz draft
authorValentin Gosu <valentin.gosu@gmail.com>
Sat, 12 May 2018 16:30:07 +0200
changeset 794535 895ec63d01244e358e1fdf067ddb2425b6b69742
parent 794526 809b0329507e97d46600f52fe33d1c0fb2e118cf
push id109703
push uservalentin.gosu@gmail.com
push dateSat, 12 May 2018 14:30:42 +0000
reviewersbz
bugs1460198
milestone62.0a1
Bug 1460198 - When calling SetRef/SetQuery/SetPathQueryRef you should do the same for the inner URI r=bz MozReview-Commit-ID: C7GCPgU2RJb
netwerk/base/nsSimpleNestedURI.cpp
netwerk/base/nsSimpleNestedURI.h
netwerk/test/unit/test_URIs.js
--- a/netwerk/base/nsSimpleNestedURI.cpp
+++ b/netwerk/base/nsSimpleNestedURI.cpp
@@ -19,16 +19,67 @@ namespace net {
 NS_IMPL_ISUPPORTS_INHERITED(nsSimpleNestedURI, nsSimpleURI, nsINestedURI)
 
 nsSimpleNestedURI::nsSimpleNestedURI(nsIURI* innerURI)
     : mInnerURI(innerURI)
 {
     NS_ASSERTION(innerURI, "Must have inner URI");
 }
 
+nsresult
+nsSimpleNestedURI::SetPathQueryRef(const nsACString &aPathQueryRef)
+{
+    NS_ENSURE_TRUE(mInnerURI, NS_ERROR_NOT_INITIALIZED);
+
+    nsCOMPtr<nsIURI> inner;
+    nsresult rv = NS_MutateURI(mInnerURI)
+                    .SetPathQueryRef(aPathQueryRef)
+                    .Finalize(inner);
+    NS_ENSURE_SUCCESS(rv, rv);
+    rv = nsSimpleURI::SetPathQueryRef(aPathQueryRef);
+    NS_ENSURE_SUCCESS(rv, rv);
+    // If the regular SetPathQueryRef worked, also set it on the inner URI
+    mInnerURI = inner;
+    return NS_OK;
+}
+
+nsresult
+nsSimpleNestedURI::SetQuery(const nsACString &aQuery)
+{
+    NS_ENSURE_TRUE(mInnerURI, NS_ERROR_NOT_INITIALIZED);
+
+    nsCOMPtr<nsIURI> inner;
+    nsresult rv = NS_MutateURI(mInnerURI)
+                    .SetQuery(aQuery)
+                    .Finalize(inner);
+    NS_ENSURE_SUCCESS(rv, rv);
+    rv = nsSimpleURI::SetQuery(aQuery);
+    NS_ENSURE_SUCCESS(rv, rv);
+    // If the regular SetQuery worked, also set it on the inner URI
+    mInnerURI = inner;
+    return NS_OK;
+}
+
+nsresult
+nsSimpleNestedURI::SetRef(const nsACString &aRef)
+{
+    NS_ENSURE_TRUE(mInnerURI, NS_ERROR_NOT_INITIALIZED);
+
+    nsCOMPtr<nsIURI> inner;
+    nsresult rv = NS_MutateURI(mInnerURI)
+                    .SetRef(aRef)
+                    .Finalize(inner);
+    NS_ENSURE_SUCCESS(rv, rv);
+    rv = nsSimpleURI::SetRef(aRef);
+    NS_ENSURE_SUCCESS(rv, rv);
+    // If the regular SetRef worked, also set it on the inner URI
+    mInnerURI = inner;
+    return NS_OK;
+}
+
 // nsISerializable
 
 NS_IMETHODIMP
 nsSimpleNestedURI::Read(nsIObjectInputStream *aStream)
 {
     NS_NOTREACHED("Use nsIURIMutator.read() instead");
     return NS_ERROR_NOT_IMPLEMENTED;
 }
--- a/netwerk/base/nsSimpleNestedURI.h
+++ b/netwerk/base/nsSimpleNestedURI.h
@@ -53,16 +53,19 @@ public:
 
     // Override the nsIClassInfo method GetClassIDNoAlloc to make sure our
     // nsISerializable impl works right.
     NS_IMETHOD GetClassIDNoAlloc(nsCID *aClassIDNoAlloc) override;
 
 protected:
     nsCOMPtr<nsIURI> mInnerURI;
 
+    nsresult SetPathQueryRef(const nsACString &aPathQueryRef) override;
+    nsresult SetQuery(const nsACString &aQuery) override;
+    nsresult SetRef(const nsACString &aRef) override;
     bool Deserialize(const mozilla::ipc::URIParams&);
     nsresult ReadPrivate(nsIObjectInputStream *stream);
 
 public:
     class Mutator final
         : public nsIURIMutator
         , public BaseURIMutator<nsSimpleNestedURI>
         , public nsISerializable
--- a/netwerk/test/unit/test_URIs.js
+++ b/netwerk/test/unit/test_URIs.js
@@ -514,20 +514,91 @@ function do_test_mutate_ref(aTest, aSuff
       do_info("testing that clearing path from " + 
               pathWithSuffix + " also clears .ref");
       testURI = testURI.mutate().setPathQueryRef("").finalize();
       Assert.equal(testURI.ref, "");
     }
   }
 }
 
+// Check that changing nested/about URIs works correctly.
+function check_nested_mutations()
+{
+  // nsNestedAboutURI
+  let uri1 = gIoService.newURI("about:blank#");
+  let uri2 = gIoService.newURI("about:blank");
+  let uri3 = uri1.mutate().setRef("").finalize();
+  do_check_uri_eq(uri3, uri2);
+  uri3 = uri2.mutate().setRef("#").finalize();
+  do_check_uri_eq(uri3, uri1);
+
+  uri1 = gIoService.newURI("about:blank?something");
+  uri2 = gIoService.newURI("about:blank");
+  uri3 = uri1.mutate().setQuery("").finalize();
+  do_check_uri_eq(uri3, uri2);
+  uri3 = uri2.mutate().setQuery("something").finalize();
+  do_check_uri_eq(uri3, uri1);
+
+  uri1 = gIoService.newURI("about:blank?query#ref");
+  uri2 = gIoService.newURI("about:blank");
+  uri3 = uri1.mutate().setPathQueryRef("blank").finalize();
+  do_check_uri_eq(uri3, uri2);
+  uri3 = uri2.mutate().setPathQueryRef("blank?query#ref").finalize();
+  do_check_uri_eq(uri3, uri1);
+
+  // nsSimpleNestedURI
+  uri1 = gIoService.newURI("view-source:http://example.com/path#");
+  uri2 = gIoService.newURI("view-source:http://example.com/path");
+  uri3 = uri1.mutate().setRef("").finalize();
+  do_check_uri_eq(uri3, uri2);
+  uri3 = uri2.mutate().setRef("#").finalize();
+  do_check_uri_eq(uri3, uri1);
+
+  uri1 = gIoService.newURI("view-source:http://example.com/path?something");
+  uri2 = gIoService.newURI("view-source:http://example.com/path");
+  uri3 = uri1.mutate().setQuery("").finalize();
+  do_check_uri_eq(uri3, uri2);
+  uri3 = uri2.mutate().setQuery("something").finalize();
+  do_check_uri_eq(uri3, uri1);
+
+  uri1 = gIoService.newURI("view-source:http://example.com/path?query#ref");
+  uri2 = gIoService.newURI("view-source:http://example.com/path");
+  uri3 = uri1.mutate().setPathQueryRef("path").finalize();
+  do_check_uri_eq(uri3, uri2);
+  uri3 = uri2.mutate().setPathQueryRef("path?query#ref").finalize();
+  do_check_uri_eq(uri3, uri1);
+
+  uri1 = gIoService.newURI("view-source:about:blank#");
+  uri2 = gIoService.newURI("view-source:about:blank");
+  uri3 = uri1.mutate().setRef("").finalize();
+  do_check_uri_eq(uri3, uri2);
+  uri3 = uri2.mutate().setRef("#").finalize();
+  do_check_uri_eq(uri3, uri1);
+
+  uri1 = gIoService.newURI("view-source:about:blank?something");
+  uri2 = gIoService.newURI("view-source:about:blank");
+  uri3 = uri1.mutate().setQuery("").finalize();
+  do_check_uri_eq(uri3, uri2);
+  uri3 = uri2.mutate().setQuery("something").finalize();
+  do_check_uri_eq(uri3, uri1);
+
+  uri1 = gIoService.newURI("view-source:about:blank?query#ref");
+  uri2 = gIoService.newURI("view-source:about:blank");
+  uri3 = uri1.mutate().setPathQueryRef("blank").finalize();
+  do_check_uri_eq(uri3, uri2);
+  uri3 = uri2.mutate().setPathQueryRef("blank?query#ref").finalize();
+  do_check_uri_eq(uri3, uri1);
+}
+
 // TEST MAIN FUNCTION
 // ------------------
 function run_test()
 {
+  check_nested_mutations();
+
   // UTF-8 check - From bug 622981
   // ASCII
   let base = gIoService.newURI("http://example.org/xenia?");
   let resolved = gIoService.newURI("?x", null, base);
   let expected = gIoService.newURI("http://example.org/xenia?x");
   do_info("Bug 662981: ACSII - comparing " + resolved.spec + " and " + expected.spec);
   Assert.ok(resolved.equals(expected));