Bug 1144398 - Restrict charcters which are allowed in the URL hash (ref). r=mcmanus, a=abillings
authorValentin Gosu <valentin.gosu@gmail.com>
Wed, 18 Mar 2015 18:40:35 +0200
changeset 259619 35b6e9d50a3610957daa1895eb760e0b9afed9ce
parent 259618 86a6c3272b09f400d116771ca9f21feaf84b11db
child 259620 d46dc75c02ae4f014a33ec308e4859c74fd1f974
push idunknown
push userunknown
push dateunknown
reviewersmcmanus, abillings
bugs1144398
milestone38.0a2
Bug 1144398 - Restrict charcters which are allowed in the URL hash (ref). r=mcmanus, a=abillings
netwerk/base/nsStandardURL.cpp
netwerk/base/nsStandardURL.h
--- a/netwerk/base/nsStandardURL.cpp
+++ b/netwerk/base/nsStandardURL.cpp
@@ -1148,16 +1148,25 @@ nsStandardURL::SetSpec(const nsACString 
     const char *spec = flat.get();
     int32_t specLength = flat.Length();
 
     LOG(("nsStandardURL::SetSpec [spec=%s]\n", spec));
 
     if (!spec || !*spec)
         return NS_ERROR_MALFORMED_URI;
 
+    int32_t refPos = input.FindChar('#');
+    if (refPos != kNotFound) {
+        const nsCSubstring& sub = Substring(input, refPos, input.Length());
+        nsresult rv = CheckRefCharacters(sub);
+        if (NS_FAILED(rv)) {
+            return rv;
+        }
+    }
+
     // Make a backup of the curent URL
     nsStandardURL prevURL(false,false);
     prevURL.CopyMembers(this, eHonorRef);
     Clear();
 
     // filter out unexpected chars "\r\n\t" if necessary
     nsAutoCString buf1;
     if (net_FilterURIString(spec, buf1)) {
@@ -2422,44 +2431,70 @@ nsStandardURL::SetQuery(const nsACString
     if (shift) {
         mQuery.mLen = queryLen;
         mPath.mLen += shift;
         ShiftFromRef(shift);
     }
     return NS_OK;
 }
 
+nsresult
+nsStandardURL::CheckRefCharacters(const nsACString &input)
+{
+    nsACString::const_iterator start, end;
+    input.BeginReading(start);
+    input.EndReading(end);
+    for (; start != end; ++start) {
+        switch (*start) {
+            case 0x00:
+            case 0x09:
+            case 0x0A:
+            case 0x0D:
+                // These characters are not allowed in the Ref part.
+                return NS_ERROR_MALFORMED_URI;
+            default:
+                continue;
+        }
+    }
+    return NS_OK;
+}
+
 NS_IMETHODIMP
 nsStandardURL::SetRef(const nsACString &input)
 {
     ENSURE_MUTABLE();
 
     const nsPromiseFlatCString &flat = PromiseFlatCString(input);
     const char *ref = flat.get();
 
     LOG(("nsStandardURL::SetRef [ref=%s]\n", ref));
 
+    nsresult rv = CheckRefCharacters(input);
+    if (NS_FAILED(rv)) {
+        return rv;
+    }
+
     if (mPath.mLen < 0)
         return SetPath(flat);
 
     InvalidateCache();
 
     if (!ref || !*ref) {
         // remove existing ref
         if (mRef.mLen >= 0) {
             // remove ref and leading '#'
             mSpec.Cut(mRef.mPos - 1, mRef.mLen + 1);
             mPath.mLen -= (mRef.mLen + 1);
             mRef.mPos = 0;
             mRef.mLen = -1;
         }
         return NS_OK;
     }
-            
-    int32_t refLen = strlen(ref);
+
+    int32_t refLen = flat.Length();
     if (ref[0] == '#') {
         ref++;
         refLen--;
     }
     
     if (mRef.mLen < 0) {
         mSpec.Append('#');
         ++mPath.mLen;  // Include the # in the path.
--- a/netwerk/base/nsStandardURL.h
+++ b/netwerk/base/nsStandardURL.h
@@ -231,16 +231,18 @@ private:
     // fastload helper functions
     nsresult ReadSegment(nsIBinaryInputStream *, URLSegment &);
     nsresult WriteSegment(nsIBinaryOutputStream *, const URLSegment &);
 
     static void PrefsChanged(nsIPrefBranch *prefs, const char *pref);
 
     void FindHostLimit(nsACString::const_iterator& aStart,
                        nsACString::const_iterator& aEnd);
+    // Checks that the Ref contains only allowed characters
+    nsresult CheckRefCharacters(const nsACString &input);
 
     // mSpec contains the normalized version of the URL spec (UTF-8 encoded).
     nsCString mSpec;
     int32_t   mDefaultPort;
     int32_t   mPort;
 
     // url parts (relative to mSpec)
     URLSegment mScheme;