Bug 1369317 - Make sure nsSimpleURI::SetPathQueryRef escapes its non-ASCII argument r=mcmanus draft
authorValentin Gosu <valentin.gosu@gmail.com>
Sun, 13 Aug 2017 10:03:28 +0200
changeset 645527 b465a6bff65297c2e119c3b0a262825788f8346a
parent 645526 726bda4f13bdab7c3e22eed29f6a8cd9bccb024f
child 645528 bc1dfc585066e09ece9511e6751cf36d33b79bef
push id73775
push uservalentin.gosu@gmail.com
push dateSun, 13 Aug 2017 08:03:58 +0000
reviewersmcmanus
bugs1369317
milestone57.0a1
Bug 1369317 - Make sure nsSimpleURI::SetPathQueryRef escapes its non-ASCII argument r=mcmanus MozReview-Commit-ID: JBloDTiYFN
netwerk/base/nsSimpleURI.cpp
netwerk/base/nsSimpleURI.h
--- a/netwerk/base/nsSimpleURI.cpp
+++ b/netwerk/base/nsSimpleURI.cpp
@@ -307,17 +307,18 @@ nsSimpleURI::SetSpec(const nsACString &a
         return NS_ERROR_MALFORMED_URI;
 
     mScheme.Truncate();
     DebugOnly<int32_t> n = spec.Left(mScheme, colonPos);
     NS_ASSERTION(n == colonPos, "Left failed");
     ToLowerCase(mScheme);
 
     // This sets mPath, mQuery and mRef.
-    return SetPathQueryRef(Substring(spec, colonPos + 1));
+    return SetPathQueryRefEscaped(Substring(spec, colonPos + 1),
+                                  /* needsEscape = */ false);
 }
 
 NS_IMETHODIMP
 nsSimpleURI::GetScheme(nsACString &result)
 {
     result = mScheme;
     return NS_OK;
 }
@@ -456,20 +457,32 @@ nsSimpleURI::GetPathQueryRef(nsACString 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSimpleURI::SetPathQueryRef(const nsACString &aPath)
 {
     NS_ENSURE_STATE(mMutable);
 
+    return SetPathQueryRefEscaped(aPath, true);
+}
+nsresult
+nsSimpleURI::SetPathQueryRefEscaped(const nsACString &aPath, bool aNeedsEscape)
+{
+    nsresult rv;
     nsAutoCString path;
-    if (!path.Assign(aPath, fallible)) {
-        return NS_ERROR_OUT_OF_MEMORY;
+    if (aNeedsEscape) {
+        rv = NS_EscapeURL(aPath, esc_OnlyNonASCII, path, fallible);
+        if (NS_FAILED(rv)) {
+          return rv;
+        }
+    } else {
+        path.Assign(aPath);
     }
+
     int32_t queryPos = path.FindChar('?');
     int32_t hashPos = path.FindChar('#');
 
     if (queryPos != kNotFound && hashPos != kNotFound && hashPos < queryPos) {
         queryPos = kNotFound;
     }
 
     nsAutoCString query;
@@ -497,17 +510,17 @@ nsSimpleURI::SetPathQueryRef(const nsACS
     mIsRefValid = false;
     mRef.Truncate();
 
     // The path
     if (!mPath.Assign(path, fallible)) {
         return NS_ERROR_OUT_OF_MEMORY;
     }
 
-    nsresult rv = SetQuery(query);
+    rv = SetQuery(query);
     if (NS_FAILED(rv)) {
         return rv;
     }
 
     return SetRef(hash);
 }
 
 NS_IMETHODIMP
--- a/netwerk/base/nsSimpleURI.h
+++ b/netwerk/base/nsSimpleURI.h
@@ -95,16 +95,18 @@ protected:
     virtual nsSimpleURI* StartClone(RefHandlingEnum refHandlingMode,
                                     const nsACString& newRef);
 
     // Helper to share code between Clone methods.
     virtual nsresult CloneInternal(RefHandlingEnum refHandlingMode,
                                    const nsACString &newRef,
                                    nsIURI** clone);
 
+    nsresult SetPathQueryRefEscaped(const nsACString &aPath, bool aNeedsEscape);
+
     nsCString mScheme;
     nsCString mPath; // NOTE: mPath does not include ref, as an optimization
     nsCString mRef;  // so that URIs with different refs can share string data.
     nsCString mQuery;  // so that URLs with different querys can share string data.
     bool mMutable;
     bool mIsRefValid; // To distinguish between empty-ref and no-ref.
     bool mIsQueryValid; // To distinguish between empty-query and no-query.
 };