Bug 1267021 - Use fallible allocation and move semantics for Push events. r=wchen

MozReview-Commit-ID: H43zrz5fhvU

--HG--
extra : rebase_source : 63631f3c2f4a3389e8e0365cd9a770a537162762
This commit is contained in:
Kit Cambridge 2016-04-22 20:54:22 -07:00
parent d2cd761b35
commit c6e8720d75
5 changed files with 47 additions and 40 deletions

View File

@ -98,8 +98,8 @@ CopySubscriptionKeyToArray(nsIPushSubscription* aSubscription,
if (NS_FAILED(rv)) {
return rv;
}
if (!aKey.SetLength(keyLen, fallible) ||
!aKey.ReplaceElementsAt(0, keyLen, keyBuffer, keyLen, fallible)) {
if (!aKey.SetCapacity(keyLen, fallible) ||
!aKey.InsertElementsAt(0, keyBuffer, keyLen, fallible)) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;

View File

@ -11,10 +11,20 @@ namespace dom {
PushUtil::CopyArrayBufferToArray(const ArrayBuffer& aBuffer,
nsTArray<uint8_t>& aArray)
{
MOZ_ASSERT(aArray.IsEmpty());
aBuffer.ComputeLengthAndData();
return aArray.SetLength(aBuffer.Length(), fallible) &&
aArray.ReplaceElementsAt(0, aBuffer.Length(), aBuffer.Data(),
aBuffer.Length(), fallible);
return aArray.SetCapacity(aBuffer.Length(), fallible) &&
aArray.InsertElementsAt(0, aBuffer.Data(), aBuffer.Length(), fallible);
}
/* static */ bool
PushUtil::CopyArrayBufferViewToArray(const ArrayBufferView& aView,
nsTArray<uint8_t>& aArray)
{
MOZ_ASSERT(aArray.IsEmpty());
aView.ComputeLengthAndData();
return aArray.SetCapacity(aView.Length(), fallible) &&
aArray.InsertElementsAt(0, aView.Data(), aView.Length(), fallible);
}
/* static */ bool
@ -25,11 +35,7 @@ PushUtil::CopyBufferSourceToArray(
return CopyArrayBufferToArray(aSource.GetAsArrayBuffer(), aArray);
}
if (aSource.IsArrayBufferView()) {
const ArrayBufferView& view = aSource.GetAsArrayBufferView();
view.ComputeLengthAndData();
return aArray.SetLength(view.Length(), fallible) &&
aArray.ReplaceElementsAt(0, view.Length(), view.Data(),
view.Length(), fallible);
return CopyArrayBufferViewToArray(aSource.GetAsArrayBufferView(), aArray);
}
MOZ_CRASH("Uninitialized union: expected buffer or view");
}

View File

@ -5,6 +5,10 @@
#ifndef mozilla_dom_PushUtil_h
#define mozilla_dom_PushUtil_h
#include "nsTArray.h"
#include "mozilla/dom/TypedArray.h"
namespace mozilla {
namespace dom {
@ -20,6 +24,10 @@ public:
CopyArrayBufferToArray(const ArrayBuffer& aBuffer,
nsTArray<uint8_t>& aArray);
static bool
CopyArrayBufferViewToArray(const ArrayBufferView& aView,
nsTArray<uint8_t>& aArray);
static bool
CopyBufferSourceToArray(const OwningArrayBufferViewOrArrayBuffer& aSource,
nsTArray<uint8_t>& aArray);

View File

@ -45,6 +45,7 @@
#include "mozilla/dom/BodyUtil.h"
#include "mozilla/dom/EncodingUtils.h"
#include "mozilla/dom/PushUtil.h"
#include "mozilla/dom/TypedArray.h"
#endif
@ -956,30 +957,12 @@ NS_IMPL_CYCLE_COLLECTION_INHERITED(ExtendableEvent, Event, mPromises)
#ifndef MOZ_SIMPLEPUSH
namespace {
nsresult
ExtractBytesFromArrayBufferView(const ArrayBufferView& aView, nsTArray<uint8_t>& aBytes)
{
MOZ_ASSERT(aBytes.IsEmpty());
aView.ComputeLengthAndData();
aBytes.InsertElementsAt(0, aView.Data(), aView.Length());
return NS_OK;
}
nsresult
ExtractBytesFromArrayBuffer(const ArrayBuffer& aBuffer, nsTArray<uint8_t>& aBytes)
{
MOZ_ASSERT(aBytes.IsEmpty());
aBuffer.ComputeLengthAndData();
aBytes.InsertElementsAt(0, aBuffer.Data(), aBuffer.Length());
return NS_OK;
}
nsresult
ExtractBytesFromUSVString(const nsAString& aStr, nsTArray<uint8_t>& aBytes)
{
MOZ_ASSERT(aBytes.IsEmpty());
nsCOMPtr<nsIUnicodeEncoder> encoder = EncodingUtils::EncoderForEncoding("UTF-8");
if (!encoder) {
if (NS_WARN_IF(!encoder)) {
return NS_ERROR_OUT_OF_MEMORY;
}
@ -990,17 +973,19 @@ ExtractBytesFromUSVString(const nsAString& aStr, nsTArray<uint8_t>& aBytes)
return rv;
}
aBytes.SetLength(destBufferLen);
if (NS_WARN_IF(!aBytes.SetLength(destBufferLen, fallible))) {
return NS_ERROR_OUT_OF_MEMORY;
}
char* destBuffer = reinterpret_cast<char*>(aBytes.Elements());
int32_t outLen = destBufferLen;
rv = encoder->Convert(aStr.BeginReading(), &srcLen, destBuffer, &outLen);
if (NS_WARN_IF(NS_FAILED(rv))) {
aBytes.Clear();
return rv;
}
MOZ_ASSERT(outLen <= destBufferLen);
aBytes.SetLength(outLen);
aBytes.TruncateLength(outLen);
return NS_OK;
}
@ -1010,11 +995,19 @@ ExtractBytesFromData(const OwningArrayBufferViewOrArrayBufferOrUSVString& aDataI
{
if (aDataInit.IsArrayBufferView()) {
const ArrayBufferView& view = aDataInit.GetAsArrayBufferView();
return ExtractBytesFromArrayBufferView(view, aBytes);
} else if (aDataInit.IsArrayBuffer()) {
if (NS_WARN_IF(!PushUtil::CopyArrayBufferViewToArray(view, aBytes))) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
if (aDataInit.IsArrayBuffer()) {
const ArrayBuffer& buffer = aDataInit.GetAsArrayBuffer();
return ExtractBytesFromArrayBuffer(buffer, aBytes);
} else if (aDataInit.IsUSVString()) {
if (NS_WARN_IF(!PushUtil::CopyArrayBufferToArray(buffer, aBytes))) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
if (aDataInit.IsUSVString()) {
return ExtractBytesFromUSVString(aDataInit.GetAsUSVString(), aBytes);
}
NS_NOTREACHED("Unexpected push message data");
@ -1023,8 +1016,8 @@ ExtractBytesFromData(const OwningArrayBufferViewOrArrayBufferOrUSVString& aDataI
}
PushMessageData::PushMessageData(nsISupports* aOwner,
const nsTArray<uint8_t>& aBytes)
: mOwner(aOwner), mBytes(aBytes) {}
nsTArray<uint8_t>&& aBytes)
: mOwner(aOwner), mBytes(Move(aBytes)) {}
PushMessageData::~PushMessageData()
{
@ -1142,7 +1135,7 @@ PushEvent::Constructor(mozilla::dom::EventTarget* aOwner,
aRv.Throw(rv);
return nullptr;
}
e->mData = new PushMessageData(aOwner, bytes);
e->mData = new PushMessageData(aOwner, Move(bytes));
}
return e.forget();
}

View File

@ -207,7 +207,7 @@ public:
ErrorResult& aRv);
already_AddRefed<mozilla::dom::Blob> Blob(ErrorResult& aRv);
PushMessageData(nsISupports* aOwner, const nsTArray<uint8_t>& aBytes);
PushMessageData(nsISupports* aOwner, nsTArray<uint8_t>&& aBytes);
private:
nsCOMPtr<nsISupports> mOwner;
nsTArray<uint8_t> mBytes;