Bug 1433624 - Move URLParams' Parse and Extract methods to MozURL; r?valentin draft
authorAnthony Ramine <n.oxyde@gmail.com>
Fri, 26 Jan 2018 19:13:30 +0100
changeset 751018 a813cec0db4cea1022c7a7f17b2955e2ba4cc8a7
parent 751017 5f18850383870618cec8c9b734c00cc9a9b8ffb6
child 751019 d29f2d463feeb5ae1e7718015fc56df68718ccc5
push id97816
push userbmo:nox@mozilla.com
push dateSun, 04 Feb 2018 14:40:11 +0000
reviewersvalentin
bugs1433624
milestone60.0a1
Bug 1433624 - Move URLParams' Parse and Extract methods to MozURL; r?valentin MozReview-Commit-ID: CAzuyufsoUP
caps/OriginAttributes.cpp
dom/base/BodyUtil.cpp
dom/url/URLSearchParams.cpp
dom/url/URLSearchParams.h
netwerk/base/MozURL.cpp
netwerk/base/MozURL.h
toolkit/components/thumbnails/PageThumbsProtocol.cpp
--- a/caps/OriginAttributes.cpp
+++ b/caps/OriginAttributes.cpp
@@ -3,16 +3,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/OriginAttributes.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/dom/URLSearchParams.h"
 #include "mozilla/dom/quota/QuotaManager.h"
+#include "mozilla/net/MozURL.h"
 #include "nsIEffectiveTLDService.h"
 #include "nsIURI.h"
 #include "nsIURIWithPrincipal.h"
 
 namespace mozilla {
 
 using dom::URLParams;
 
@@ -158,31 +159,30 @@ OriginAttributes::CreateAnonymizedSuffix
   }
 
   attrs.CreateSuffix(aStr);
 }
 
 namespace {
 
 class MOZ_STACK_CLASS PopulateFromSuffixIterator final
-  : public URLParams::ForEachIterator
+  : public MozURL::ForEachFormUrlencoded
 {
 public:
   explicit PopulateFromSuffixIterator(OriginAttributes* aOriginAttributes)
     : mOriginAttributes(aOriginAttributes)
   {
     MOZ_ASSERT(aOriginAttributes);
     // If mPrivateBrowsingId is passed in as >0 and is not present in the suffix,
     // then it will remain >0 when it should be 0 according to the suffix. Set to 0 before
     // iterating to fix this.
     mOriginAttributes->mPrivateBrowsingId = 0;
   }
 
-  bool URLParamsIterator(const nsAString& aName,
-                         const nsAString& aValue) override
+  bool Process(const nsAString& aName, const nsAString& aValue) override
   {
     if (aName.EqualsLiteral("appId")) {
       nsresult rv;
       int64_t val  = aValue.ToInteger64(&rv);
       NS_ENSURE_SUCCESS(rv, false);
       NS_ENSURE_TRUE(val <= UINT32_MAX, false);
       mOriginAttributes->mAppId = static_cast<uint32_t>(val);
 
@@ -247,17 +247,17 @@ OriginAttributes::PopulateFromSuffix(con
     return true;
   }
 
   if (aStr[0] != '^') {
     return false;
   }
 
   PopulateFromSuffixIterator iterator(this);
-  return URLParams::Parse(Substring(aStr, 1, aStr.Length() - 1), iterator);
+  return MozURL::ParseFormUrlencoded(Substring(aStr, 1, aStr.Length() - 1), iterator);
 }
 
 bool
 OriginAttributes::PopulateFromOrigin(const nsACString& aOrigin,
                                      nsACString& aOriginNoSuffix)
 {
   // RFindChar is only available on nsCString.
   nsCString origin(aOrigin);
--- a/dom/base/BodyUtil.cpp
+++ b/dom/base/BodyUtil.cpp
@@ -20,17 +20,17 @@
 
 #include "mozilla/ErrorResult.h"
 #include "mozilla/dom/Exceptions.h"
 #include "mozilla/dom/FetchUtil.h"
 #include "mozilla/dom/File.h"
 #include "mozilla/dom/FormData.h"
 #include "mozilla/dom/Headers.h"
 #include "mozilla/dom/Promise.h"
-#include "mozilla/dom/URLSearchParams.h"
+#include "mozilla/net/MozURL.h"
 
 namespace mozilla {
 namespace dom {
 
 namespace {
 
 // Reads over a CRLF and positions start after it.
 static bool
@@ -41,27 +41,26 @@ PushOverLine(nsACString::const_iterator&
     ++aStart; // advance to after CRLF
     return true;
   }
 
   return false;
 }
 
 class MOZ_STACK_CLASS FillFormIterator final
-  : public URLParams::ForEachIterator
+  : public net::MozURL::ForEachFormUrlencoded
 {
 public:
   explicit FillFormIterator(FormData* aFormData)
     : mFormData(aFormData)
   {
     MOZ_ASSERT(aFormData);
   }
 
-  bool URLParamsIterator(const nsAString& aName,
-                         const nsAString& aValue) override
+  bool Process(const nsAString& aName, const nsAString& aValue) override
   {
     ErrorResult rv;
     mFormData->Append(aName, aValue, rv);
     MOZ_ASSERT(!rv.Failed());
     return true;
   }
 
 private:
@@ -466,17 +465,17 @@ BodyUtil::ConsumeFormData(nsIGlobalObjec
 
   if (isValidUrlEncodedMimeType && aMimeType.Length() > urlDataMimeType.Length()) {
     isValidUrlEncodedMimeType = aMimeType[urlDataMimeType.Length()] == ';';
   }
 
   if (isValidUrlEncodedMimeType) {
     RefPtr<FormData> fd = new FormData(aParent);
     FillFormIterator iterator(fd);
-    DebugOnly<bool> status = URLParams::Parse(aStr, iterator);
+    DebugOnly<bool> status = net::MozURL::ParseFormUrlencoded(aStr, iterator);
     MOZ_ASSERT(status);
 
     return fd.forget();
   }
 
   aRv.ThrowTypeError<MSG_BAD_FORMDATA>();
   return nullptr;
 }
--- a/dom/url/URLSearchParams.cpp
+++ b/dom/url/URLSearchParams.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "URLSearchParams.h"
 #include "mozilla/dom/URLSearchParamsBinding.h"
+#include "mozilla/net/MozURL.h"
 #include "mozilla/Encoding.h"
 #include "nsDOMString.h"
 #include "nsIInputStream.h"
 #include "nsStringStream.h"
 
 namespace mozilla {
 namespace dom {
 
@@ -93,204 +94,44 @@ URLParams::Delete(const nsAString& aName
     if (mParams[i].mKey.Equals(aName)) {
       mParams.RemoveElementAt(i);
     } else {
       ++i;
     }
   }
 }
 
-/* static */ void
-URLParams::ConvertString(const nsACString& aInput, nsAString& aOutput)
-{
-  if (NS_FAILED(UTF_8_ENCODING->DecodeWithoutBOMHandling(aInput, aOutput))) {
-    MOZ_CRASH("Out of memory when converting URL params.");
-  }
-}
-
-/* static */ void
-URLParams::DecodeString(const nsACString& aInput, nsAString& aOutput)
-{
-  nsACString::const_iterator start, end;
-  aInput.BeginReading(start);
-  aInput.EndReading(end);
-
-  nsCString unescaped;
-
-  while (start != end) {
-    // replace '+' with U+0020
-    if (*start == '+') {
-      unescaped.Append(' ');
-      ++start;
-      continue;
-    }
-
-    // Percent decode algorithm
-    if (*start == '%') {
-      nsACString::const_iterator first(start);
-      ++first;
-
-      nsACString::const_iterator second(first);
-      ++second;
-
-#define ASCII_HEX_DIGIT( x )    \
-  ((x >= 0x41 && x <= 0x46) ||  \
-   (x >= 0x61 && x <= 0x66) ||  \
-   (x >= 0x30 && x <= 0x39))
-
-#define HEX_DIGIT( x )              \
-   (*x >= 0x30 && *x <= 0x39        \
-     ? *x - 0x30                    \
-     : (*x >= 0x41 && *x <= 0x46    \
-        ? *x - 0x37                 \
-        : *x - 0x57))
-
-      if (first != end && second != end &&
-          ASCII_HEX_DIGIT(*first) && ASCII_HEX_DIGIT(*second)) {
-        unescaped.Append(HEX_DIGIT(first) * 16 + HEX_DIGIT(second));
-        start = ++second;
-        continue;
-
-      } else {
-        unescaped.Append('%');
-        ++start;
-        continue;
-      }
-    }
-
-    unescaped.Append(*start);
-    ++start;
-  }
-
-  ConvertString(unescaped, aOutput);
-}
-
-/* static */ bool
-URLParams::Parse(const nsACString& aInput, ForEachIterator& aIterator)
-{
-  nsACString::const_iterator start, end;
-  aInput.BeginReading(start);
-  aInput.EndReading(end);
-  nsACString::const_iterator iter(start);
-
-  while (start != end) {
-    nsAutoCString string;
-
-    if (FindCharInReadable('&', iter, end)) {
-      string.Assign(Substring(start, iter));
-      start = ++iter;
-    } else {
-      string.Assign(Substring(start, end));
-      start = end;
-    }
-
-    if (string.IsEmpty()) {
-      continue;
-    }
-
-    nsACString::const_iterator eqStart, eqEnd;
-    string.BeginReading(eqStart);
-    string.EndReading(eqEnd);
-    nsACString::const_iterator eqIter(eqStart);
-
-    nsAutoCString name;
-    nsAutoCString value;
-
-    if (FindCharInReadable('=', eqIter, eqEnd)) {
-      name.Assign(Substring(eqStart, eqIter));
-
-      ++eqIter;
-      value.Assign(Substring(eqIter, eqEnd));
-    } else {
-      name.Assign(string);
-    }
-
-    nsAutoString decodedName;
-    DecodeString(name, decodedName);
-
-    nsAutoString decodedValue;
-    DecodeString(value, decodedValue);
-
-    if (!aIterator.URLParamsIterator(decodedName, decodedValue)) {
-      return false;
-    }
-  }
-  return true;
-}
-
-class MOZ_STACK_CLASS ExtractURLParam final
-  : public URLParams::ForEachIterator
-{
-public:
-  explicit ExtractURLParam(const nsAString& aName, nsAString& aValue)
-    : mName(aName), mValue(aValue)
-  {}
-
-  bool URLParamsIterator(const nsAString& aName,
-                         const nsAString& aValue) override
-  {
-    if (mName == aName) {
-      mValue = aValue;
-      return false;
-    }
-    return true;
-  }
-
-private:
-  const nsAString& mName;
-  nsAString& mValue;
-};
-
-
-/**
- * Extracts the first form-urlencoded parameter named `aName` from `aInput`.
- * @param aRange The input to parse.
- * @param aName The name of the parameter to extract.
- * @param aValue The value of the extracted parameter, void if not found.
- * @return Whether the parameter was found in the form-urlencoded.
- */
-/* static */ bool
-URLParams::Extract(const nsACString& aInput,
-                   const nsAString& aName,
-                   nsAString& aValue)
-{
-  aValue.SetIsVoid(true);
-  ExtractURLParam iterator(aName, aValue);
-  return !URLParams::Parse(aInput, iterator);
-}
-
 class MOZ_STACK_CLASS PopulateIterator final
-  : public URLParams::ForEachIterator
+  : public net::MozURL::ForEachFormUrlencoded
 {
 public:
   explicit PopulateIterator(URLParams* aParams)
     : mParams(aParams)
   {
     MOZ_ASSERT(aParams);
   }
 
-  bool URLParamsIterator(const nsAString& aName,
-                         const nsAString& aValue) override
+  bool Process(const nsAString& aName, const nsAString& aValue) override
   {
     mParams->Append(aName, aValue);
     return true;
   }
 
 private:
   URLParams* mParams;
 };
 
 void
 URLParams::ParseInput(const nsACString& aInput)
 {
   // Remove all the existing data before parsing a new input.
   DeleteAll();
 
   PopulateIterator iter(this);
-  URLParams::Parse(aInput, iter);
+  net::MozURL::ParseFormUrlencoded(aInput, iter);
 }
 
 namespace {
 
 void SerializeString(const nsCString& aInput, nsAString& aValue)
 {
   const unsigned char* p = (const unsigned char*) aInput.get();
   const unsigned char* end = p + aInput.Length();
--- a/dom/url/URLSearchParams.h
+++ b/dom/url/URLSearchParams.h
@@ -38,29 +38,16 @@ class URLParams final
 public:
   URLParams() {}
 
   ~URLParams()
   {
     DeleteAll();
   }
 
-  class ForEachIterator
-  {
-  public:
-    virtual bool
-    URLParamsIterator(const nsAString& aName, const nsAString& aValue) = 0;
-  };
-
-  static bool
-  Parse(const nsACString& aInput, ForEachIterator& aIterator);
-
-  static bool
-  Extract(const nsACString& aInput, const nsAString& aName, nsAString& aValue);
-
   void
   ParseInput(const nsACString& aInput);
 
   void Serialize(nsAString& aValue) const;
 
   void Get(const nsAString& aName, nsString& aRetval);
 
   void GetAll(const nsAString& aName, nsTArray<nsString>& aRetval);
@@ -99,19 +86,16 @@ public:
 
   bool
   ReadStructuredClone(JSStructuredCloneReader* aReader);
 
   bool
   WriteStructuredClone(JSStructuredCloneWriter* aWriter) const;
 
 private:
-  static void DecodeString(const nsACString& aInput, nsAString& aOutput);
-  static void ConvertString(const nsACString& aInput, nsAString& aOutput);
-
   struct Param
   {
     nsString mKey;
     nsString mValue;
   };
 
   nsTArray<Param> mParams;
 };
--- a/netwerk/base/MozURL.cpp
+++ b/netwerk/base/MozURL.cpp
@@ -1,13 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "MozURL.h"
+#include "mozilla/Encoding.h"
+#include "nsReadableUtils.h"
 #include "rust-url-capi/src/rust-url-capi.h"
 
 namespace mozilla {
 namespace net {
 
 NS_IMPL_ADDREF(MozURL)
 NS_IMPL_RELEASE(MozURL)
 
@@ -101,16 +103,176 @@ MozURL::GetRef(nsACString& aRef)
 }
 
 nsresult
 MozURL::GetOrigin(nsACString& aOrigin)
 {
   return rusturl_get_origin(mURL.get(), &aOrigin);
 }
 
+static void
+ConvertString(const nsACString& aInput, nsAString& aOutput)
+{
+  if (NS_FAILED(UTF_8_ENCODING->DecodeWithoutBOMHandling(aInput, aOutput))) {
+    MOZ_CRASH("Out of memory when converting URL params.");
+  }
+}
+
+static void
+DecodeString(const nsACString& aInput, nsAString& aOutput)
+{
+  nsACString::const_iterator start, end;
+  aInput.BeginReading(start);
+  aInput.EndReading(end);
+
+  nsCString unescaped;
+
+  while (start != end) {
+    // replace '+' with U+0020
+    if (*start == '+') {
+      unescaped.Append(' ');
+      ++start;
+      continue;
+    }
+
+    // Percent decode algorithm
+    if (*start == '%') {
+      nsACString::const_iterator first(start);
+      ++first;
+
+      nsACString::const_iterator second(first);
+      ++second;
+
+#define ASCII_HEX_DIGIT( x )    \
+  ((x >= 0x41 && x <= 0x46) ||  \
+   (x >= 0x61 && x <= 0x66) ||  \
+   (x >= 0x30 && x <= 0x39))
+
+#define HEX_DIGIT( x )              \
+   (*x >= 0x30 && *x <= 0x39        \
+     ? *x - 0x30                    \
+     : (*x >= 0x41 && *x <= 0x46    \
+        ? *x - 0x37                 \
+        : *x - 0x57))
+
+      if (first != end && second != end &&
+          ASCII_HEX_DIGIT(*first) && ASCII_HEX_DIGIT(*second)) {
+        unescaped.Append(HEX_DIGIT(first) * 16 + HEX_DIGIT(second));
+        start = ++second;
+        continue;
+
+      } else {
+        unescaped.Append('%');
+        ++start;
+        continue;
+      }
+    }
+
+    unescaped.Append(*start);
+    ++start;
+  }
+
+  ConvertString(unescaped, aOutput);
+}
+
+/* static */ bool
+MozURL::ParseFormUrlencoded(const nsACString& aInput,
+                            ForEachFormUrlencoded& aProcessor)
+{
+  nsACString::const_iterator start, end;
+  aInput.BeginReading(start);
+  aInput.EndReading(end);
+  nsACString::const_iterator iter(start);
+
+  while (start != end) {
+    nsAutoCString string;
+
+    if (FindCharInReadable('&', iter, end)) {
+      string.Assign(Substring(start, iter));
+      start = ++iter;
+    } else {
+      string.Assign(Substring(start, end));
+      start = end;
+    }
+
+    if (string.IsEmpty()) {
+      continue;
+    }
+
+    nsACString::const_iterator eqStart, eqEnd;
+    string.BeginReading(eqStart);
+    string.EndReading(eqEnd);
+    nsACString::const_iterator eqIter(eqStart);
+
+    nsAutoCString name;
+    nsAutoCString value;
+
+    if (FindCharInReadable('=', eqIter, eqEnd)) {
+      name.Assign(Substring(eqStart, eqIter));
+
+      ++eqIter;
+      value.Assign(Substring(eqIter, eqEnd));
+    } else {
+      name.Assign(string);
+    }
+
+    nsAutoString decodedName;
+    DecodeString(name, decodedName);
+
+    nsAutoString decodedValue;
+    DecodeString(value, decodedValue);
+
+    if (!aProcessor.Process(decodedName, decodedValue)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+class MOZ_STACK_CLASS ExtractURLParam final
+  : public MozURL::ForEachFormUrlencoded
+{
+public:
+  explicit ExtractURLParam(const nsAString& aName, nsAString& aValue)
+    : mName(aName)
+    , mValue(aValue)
+  {
+  }
+
+  bool Process(const nsAString& aName, const nsAString& aValue) override
+  {
+    if (mName == aName) {
+      mValue = aValue;
+      return false;
+    }
+    return true;
+  }
+
+private:
+  const nsAString& mName;
+  nsAString& mValue;
+};
+
+/**
+ * Extracts the first form-urlencoded parameter named `aName` from `aInput`.
+ * @param aInput The input to parse.
+ * @param aName The name of the parameter to extract.
+ * @param aValue The value of the extracted parameter, void if not found.
+ * @return Whether the parameter was found in the form-urlencoded.
+ */
+/* static */ bool
+MozURL::Extract(const nsACString& aInput,
+                const nsAString& aName,
+                nsAString& aValue)
+{
+  aValue.SetIsVoid(true);
+  ExtractURLParam processor(aName, aValue);
+  return !MozURL::ParseFormUrlencoded(aInput, processor);
+}
+
 // MozURL::Mutator
 
 MozURL::Mutator::Mutator(MozURL* url)
   : mURL(rusturl_clone(url->mURL.get()))
   , mFinalized(false)
   , mStatus(NS_OK)
 {
 }
--- a/netwerk/base/MozURL.h
+++ b/netwerk/base/MozURL.h
@@ -52,16 +52,29 @@ public:
   nsresult GetHostPort(nsACString& aHostPort);
   // Will return the port number, if specified, or -1
   nsresult GetPort(int32_t* aPort);
   nsresult GetFilePath(nsACString& aPath);
   nsresult GetQuery(nsACString& aQuery);
   nsresult GetRef(nsACString& aRef);
   nsresult GetOrigin(nsACString& aOrigin);
 
+  class ForEachFormUrlencoded
+  {
+  public:
+    virtual bool Process(const nsAString& aName, const nsAString& aValue) = 0;
+  };
+
+  static bool ParseFormUrlencoded(const nsACString& aInput,
+                                  ForEachFormUrlencoded& aProcessor);
+
+  static bool Extract(const nsACString& aInput,
+                      const nsAString& aName,
+                      nsAString& aValue);
+
 private:
   explicit MozURL(rusturl* rawPtr)
     : mURL(rawPtr)
   {
   }
   virtual ~MozURL() {}
   struct FreeRustURL
   {
--- a/toolkit/components/thumbnails/PageThumbsProtocol.cpp
+++ b/toolkit/components/thumbnails/PageThumbsProtocol.cpp
@@ -12,19 +12,21 @@
 #include "PageThumbsProtocol.h"
 #include "nsIURI.h"
 #include "nsIFileURL.h"
 #include "nsIFile.h"
 #include "nsIChannel.h"
 #include "nsComponentManagerUtils.h"
 #include "nsNetUtil.h"
 #include "mozilla/dom/URLSearchParams.h"
+#include "mozilla/net/MozURL.h"
 #include "nsStandardURL.h"
 
 using mozilla::dom::URLParams;
+using mozilla::net::MozURL;
 using mozilla::net::nsStandardURL;
 
 NS_IMPL_ISUPPORTS(PageThumbsProtocol, nsIProtocolHandler);
 
 // PageThumbsProtocol::GetScheme
 
 NS_IMETHODIMP
 PageThumbsProtocol::GetScheme(nsACString& aScheme)
@@ -133,19 +135,19 @@ PageThumbsProtocol::ParseProtocolURL(nsI
 
   // Since this is a protocol URI and it doesn't parse nicely, we split on where
   // the start of the query is and parse it from there
   int32_t queryBegins = path.FindChar('?');
   if (queryBegins <= 0) {
     return NS_ERROR_MALFORMED_URI;
   }
 
-  URLParams::Extract(Substring(path, queryBegins + 1),
-                     NS_LITERAL_STRING("url"),
-                     aParsedURL);
+  MozURL::Extract(Substring(path, queryBegins + 1),
+                  NS_LITERAL_STRING("url"),
+                  aParsedURL);
 
   // If there's no URL as part of the query params, there will be no thumbnail
   if (aParsedURL.IsVoid()) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   return NS_OK;
 }