Bug 1433624 - Do not convert to UTF-16 when calling ForEachFormUrlencoded::Process; r?bz
Most consumers don't actually need to handle the strings as UTF-16, so we can postpone
converting them from UTF-8 until it's actually needed.
MozReview-Commit-ID: 1H350679rt6
--- a/caps/OriginAttributes.cpp
+++ b/caps/OriginAttributes.cpp
@@ -162,101 +162,100 @@ OriginAttributes::CreateAnonymizedSuffix
}
namespace {
class MOZ_STACK_CLASS PopulateFromSuffixIterator final
: public MozURL::ForEachFormUrlencoded
{
public:
- explicit PopulateFromSuffixIterator(OriginAttributes* aOriginAttributes)
+ 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;
+ mOriginAttributes.mPrivateBrowsingId = 0;
}
- bool Process(const nsAString& aName, const nsAString& aValue) override
+ bool Process(const nsACString& aName, const nsACString& aValue) override
{
if (aName.EqualsLiteral("appId")) {
nsresult rv;
- int64_t val = aValue.ToInteger64(&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);
+ mOriginAttributes.mAppId = static_cast<uint32_t>(val);
return true;
}
if (aName.EqualsLiteral("inBrowser")) {
if (!aValue.EqualsLiteral("1")) {
return false;
}
- mOriginAttributes->mInIsolatedMozBrowser = true;
+ mOriginAttributes.mInIsolatedMozBrowser = true;
return true;
}
if (aName.EqualsLiteral("addonId")) {
// No longer supported. Silently ignore so that legacy origin strings
// don't cause failures.
return true;
}
if (aName.EqualsLiteral("userContextId")) {
nsresult rv;
- int64_t val = aValue.ToInteger64(&rv);
+ int64_t val = aValue.ToInteger64(&rv);
NS_ENSURE_SUCCESS(rv, false);
NS_ENSURE_TRUE(val <= UINT32_MAX, false);
- mOriginAttributes->mUserContextId = static_cast<uint32_t>(val);
+ mOriginAttributes.mUserContextId = static_cast<uint32_t>(val);
return true;
}
if (aName.EqualsLiteral("privateBrowsingId")) {
nsresult rv;
int64_t val = aValue.ToInteger64(&rv);
NS_ENSURE_SUCCESS(rv, false);
NS_ENSURE_TRUE(val >= 0 && val <= UINT32_MAX, false);
- mOriginAttributes->mPrivateBrowsingId = static_cast<uint32_t>(val);
+ mOriginAttributes.mPrivateBrowsingId = static_cast<uint32_t>(val);
return true;
}
if (aName.EqualsLiteral("firstPartyDomain")) {
- MOZ_RELEASE_ASSERT(mOriginAttributes->mFirstPartyDomain.IsEmpty());
- mOriginAttributes->mFirstPartyDomain.Assign(aValue);
+ MOZ_RELEASE_ASSERT(mOriginAttributes.mFirstPartyDomain.IsEmpty());
+ CopyUTF8toUTF16(aValue, mOriginAttributes.mFirstPartyDomain);
return true;
}
// No other attributes are supported.
return false;
}
private:
- OriginAttributes* mOriginAttributes;
+ OriginAttributes& mOriginAttributes;
};
} // namespace
bool
OriginAttributes::PopulateFromSuffix(const nsACString& aStr)
{
if (aStr.IsEmpty()) {
return true;
}
if (aStr[0] != '^') {
return false;
}
- PopulateFromSuffixIterator iterator(this);
+ PopulateFromSuffixIterator iterator(*this);
return MozURL::ParseFormUrlencoded(Substring(aStr, 1, aStr.Length() - 1), iterator);
}
bool
OriginAttributes::PopulateFromOrigin(const nsACString& aOrigin,
nsACString& aOriginNoSuffix)
{
// RFindChar is only available on nsCString.
--- a/dom/base/BodyUtil.cpp
+++ b/dom/base/BodyUtil.cpp
@@ -50,26 +50,30 @@ class MOZ_STACK_CLASS FillFormIterator f
{
public:
explicit FillFormIterator(FormData* aFormData)
: mFormData(aFormData)
{
MOZ_ASSERT(aFormData);
}
- bool Process(const nsAString& aName, const nsAString& aValue) override
+ bool Process(const nsACString& aName, const nsACString& aValue) override
{
ErrorResult rv;
- mFormData->Append(aName, aValue, rv);
+ CopyUTF8toUTF16(aName, mName);
+ CopyUTF8toUTF16(aValue, mValue);
+ mFormData->Append(mName, mValue, rv);
MOZ_ASSERT(!rv.Failed());
return true;
}
private:
FormData* mFormData;
+ nsAutoString mName;
+ nsAutoString mValue;
};
/**
* A simple multipart/form-data parser as defined in RFC 2388 and RFC 2046.
* This does not respect any encoding specified per entry, using UTF-8
* throughout. This is as the Fetch spec states in the consume body algorithm.
* Borrows some things from Necko's nsMultiMixedConv, but is simpler since
* unlike Necko we do not have to deal with receiving incomplete chunks of data.
--- a/dom/url/URLSearchParams.cpp
+++ b/dom/url/URLSearchParams.cpp
@@ -98,40 +98,42 @@ URLParams::Delete(const nsAString& aName
}
}
}
class MOZ_STACK_CLASS PopulateIterator final
: public net::MozURL::ForEachFormUrlencoded
{
public:
- explicit PopulateIterator(URLParams* aParams)
+ explicit PopulateIterator(URLParams& aParams)
: mParams(aParams)
+ {}
+
+ bool Process(const nsACString& aName, const nsACString& aValue) override
{
- MOZ_ASSERT(aParams);
- }
-
- bool Process(const nsAString& aName, const nsAString& aValue) override
- {
- mParams->Append(aName, aValue);
+ CopyUTF8toUTF16(aName, mName);
+ CopyUTF8toUTF16(aValue, mValue);
+ mParams.Append(mName, mValue);
return true;
}
private:
- URLParams* mParams;
+ URLParams& mParams;
+ nsAutoString mName;
+ nsAutoString mValue;
};
void
URLParams::ParseInput(const nsACString& aInput)
{
// Remove all the existing data before parsing a new input.
DeleteAll();
- PopulateIterator iter(this);
- net::MozURL::ParseFormUrlencoded(aInput, iter);
+ PopulateIterator processor(*this);
+ net::MozURL::ParseFormUrlencoded(aInput, processor);
}
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/netwerk/base/MozURL.cpp
+++ b/netwerk/base/MozURL.cpp
@@ -3,30 +3,21 @@
* 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"
extern "C" {
-struct ForEachWrapper
-{
- nsAutoString& mName;
- nsAutoString& mValue;
- mozilla::MozURL::ForEachFormUrlencoded& mProcessor;
-};
-
static bool
CallForEach(const nsACString* aName, const nsACString* aValue, void* aContext)
{
- auto wrapper = static_cast<ForEachWrapper*>(aContext);
- CopyUTF8toUTF16(*aName, wrapper->mName);
- CopyUTF8toUTF16(*aValue, wrapper->mValue);
- return wrapper->mProcessor.Process(wrapper->mName, wrapper->mValue);
+ auto wrapper = static_cast<mozilla::MozURL::ForEachFormUrlencoded*>(aContext);
+ return wrapper->Process(*aName, *aValue);
}
}
namespace mozilla {
namespace net {
NS_IMPL_ADDREF(MozURL)
NS_IMPL_RELEASE(MozURL)
@@ -121,65 +112,63 @@ MozURL::GetRef(nsACString& aRef)
}
nsresult
MozURL::GetOrigin(nsACString& aOrigin)
{
return rusturl_get_origin(mURL.get(), &aOrigin);
}
+/**
+ * Parses and decodes some form-urlencoded input.
+ * @param aInput The input, as a slice of bytes, lossily interpreted as UTF-8.
+ * @param aProcessor The processor, its `Process` method is called for each pair.
+ */
/* static */ bool
MozURL::ParseFormUrlencoded(const nsACString& aInput,
ForEachFormUrlencoded& aProcessor)
{
- nsAutoString name;
- nsAutoString value;
- ForEachWrapper wrapper = {
- name,
- value,
- aProcessor
- };
- return rusturl_parse_form_urlencoded(&aInput, CallForEach, &wrapper);
+ return rusturl_parse_form_urlencoded(&aInput, CallForEach, &aProcessor);
}
class MOZ_STACK_CLASS ExtractURLParam final
: public MozURL::ForEachFormUrlencoded
{
public:
- explicit ExtractURLParam(const nsAString& aName, nsAString& aValue)
+ explicit ExtractURLParam(const nsACString& aName, nsACString& aValue)
: mName(aName)
, mValue(aValue)
{
}
- bool Process(const nsAString& aName, const nsAString& aValue) override
+ bool Process(const nsACString& aName, const nsACString& aValue) override
{
if (mName == aName) {
mValue = aValue;
return false;
}
return true;
}
private:
- const nsAString& mName;
- nsAString& mValue;
+ const nsACString& mName;
+ nsACString& 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.
+ * Extracts the first form-urlencoded parameter named `aName` from the input.
+ * @param aInput The input, as in `ParseFormUrlencoded`.
+ * @param aName The name of the parameter, should be UTF-8 encoded.
+ * @param aValue The value of the parameter, if found, UTF-8 encoded.
+ * @return True if parameter was found, false otherwise.
*/
/* static */ bool
MozURL::Extract(const nsACString& aInput,
- const nsAString& aName,
- nsAString& aValue)
+ const nsACString& aName,
+ nsACString& aValue)
{
aValue.SetIsVoid(true);
ExtractURLParam processor(aName, aValue);
return !MozURL::ParseFormUrlencoded(aInput, processor);
}
// MozURL::Mutator
--- a/netwerk/base/MozURL.h
+++ b/netwerk/base/MozURL.h
@@ -55,25 +55,44 @@ public:
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;
+ /**
+ * Callback used to process each name-value pair of the form-urlencoded input.
+ * @param aName The name of the parameter, UTF-8 encoded.
+ * @param aValue The value of the parameter, UTF-8 encoded.
+ * @return Whether processing should continue after this pair.
+ */
+ virtual bool Process(const nsACString& aName, const nsACString& aValue) = 0;
};
+ /**
+ * Parses and decodes some form-urlencoded input.
+ * @param aInput The input, as a slice of bytes, lossily interpreted as UTF-8.
+ * @param aProcessor The processor, its `Process` method is called for each pair.
+ * @return False if `Process` returned false, true otherwise.
+ */
static bool ParseFormUrlencoded(const nsACString& aInput,
ForEachFormUrlencoded& aProcessor);
+ /**
+ * Extracts the first form-urlencoded parameter named `aName` from the input.
+ * @param aInput The input, as in `ParseFormUrlencoded`.
+ * @param aName The name of the parameter, should be UTF-8 encoded.
+ * @param aValue The value of the parameter, if found, UTF-8 encoded.
+ * @return True if parameter was found, false otherwise.
+ */
static bool Extract(const nsACString& aInput,
- const nsAString& aName,
- nsAString& aValue);
+ const nsACString& aName,
+ nsACString& aValue);
private:
explicit MozURL(rusturl* rawPtr)
: mURL(rawPtr)
{
}
virtual ~MozURL() {}
struct FreeRustURL
--- a/toolkit/components/thumbnails/PageThumbsProtocol.cpp
+++ b/toolkit/components/thumbnails/PageThumbsProtocol.cpp
@@ -135,25 +135,27 @@ 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;
}
+ nsAutoCString parsedURL;
MozURL::Extract(Substring(path, queryBegins + 1),
- NS_LITERAL_STRING("url"),
- aParsedURL);
+ NS_LITERAL_CSTRING("url"),
+ parsedURL);
// If there's no URL as part of the query params, there will be no thumbnail
- if (aParsedURL.IsVoid()) {
+ if (parsedURL.IsVoid()) {
return NS_ERROR_NOT_AVAILABLE;
}
+ CopyUTF8toUTF16(parsedURL, aParsedURL);
return NS_OK;
}
// PageThumbsProtocol::GetFilePathForURL
//
// Returns the thumbnail's file path for a given URL
nsresult