Bug 1841314 - Part 7: Add char and uint8_t overloads for NewArrayBufferWithContents. r=sfink

Depends on D182644

Differential Revision: https://phabricator.services.mozilla.com/D182645
This commit is contained in:
André Bargull 2023-07-06 11:41:18 +00:00
parent f085eb761c
commit 664cf60824
8 changed files with 46 additions and 15 deletions

View File

@ -356,10 +356,9 @@ void BodyUtil::ConsumeArrayBuffer(JSContext* aCx,
uint32_t aInputLength,
UniquePtr<uint8_t[], JS::FreePolicy> aInput,
ErrorResult& aRv) {
UniquePtr<void, JS::FreePolicy> dataPtr{aInput.release()};
JS::Rooted<JSObject*> arrayBuffer(aCx);
arrayBuffer =
JS::NewArrayBufferWithContents(aCx, aInputLength, std::move(dataPtr));
JS::NewArrayBufferWithContents(aCx, aInputLength, std::move(aInput));
if (!arrayBuffer) {
JS_ClearPendingException(aCx);
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);

View File

@ -189,9 +189,8 @@ bool nsJSUtils::DumpEnabled() {
JSObject* nsJSUtils::MoveBufferAsUint8Array(
JSContext* aCx, size_t aSize,
UniquePtr<uint8_t[], JS::FreePolicy> aBuffer) {
UniquePtr<void, JS::FreePolicy> dataPtr{aBuffer.release()};
JS::Rooted<JSObject*> arrayBuffer(
aCx, JS::NewArrayBufferWithContents(aCx, aSize, std::move(dataPtr)));
aCx, JS::NewArrayBufferWithContents(aCx, aSize, std::move(aBuffer)));
if (!arrayBuffer) {
return nullptr;
}

View File

@ -98,9 +98,8 @@ static void EncodeNative(JSContext* aCx, mozilla::Decoder* aDecoder,
// https://encoding.spec.whatwg.org/#encode-and-enqueue-a-chunk
// Step 4.2.2.1. Let chunk be a Uint8Array object wrapping an ArrayBuffer
// containing output.
UniquePtr<void, JS::FreePolicy> dataPtr{buffer.release()};
JS::Rooted<JSObject*> arrayBuffer(
aCx, JS::NewArrayBufferWithContents(aCx, written, std::move(dataPtr)));
aCx, JS::NewArrayBufferWithContents(aCx, written, std::move(buffer)));
if (!arrayBuffer.get()) {
JS_ClearPendingException(aCx);
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);

View File

@ -84,9 +84,8 @@ void FileReaderSync::ReadAsArrayBuffer(JSContext* aCx,
return;
}
UniquePtr<void, JS::FreePolicy> dataPtr{bufferData.release()};
JSObject* arrayBuffer =
JS::NewArrayBufferWithContents(aCx, blobSize, std::move(dataPtr));
JS::NewArrayBufferWithContents(aCx, blobSize, std::move(bufferData));
if (!arrayBuffer) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return;

View File

@ -32,9 +32,8 @@ bool DeserializeArrayBuffer(JSContext* cx, const nsTArray<uint8_t>& aBuffer,
if (!data) return false;
memcpy(data.get(), aBuffer.Elements(), aBuffer.Length());
mozilla::UniquePtr<void, JS::FreePolicy> dataPtr{data.release()};
JSObject* obj =
JS::NewArrayBufferWithContents(cx, aBuffer.Length(), std::move(dataPtr));
JS::NewArrayBufferWithContents(cx, aBuffer.Length(), std::move(data));
if (!obj) return false;
aVal.setObject(*obj);

View File

@ -2708,11 +2708,10 @@ JSObject* IOUtils::JsBuffer::IntoUint8Array(JSContext* aCx, JsBuffer aBuffer) {
return JS_NewUint8Array(aCx, 0);
}
UniquePtr<void, JS::FreePolicy> rawBuffer{aBuffer.mBuffer.release()};
MOZ_RELEASE_ASSERT(rawBuffer);
MOZ_RELEASE_ASSERT(aBuffer.mBuffer);
JS::Rooted<JSObject*> arrayBuffer(
aCx, JS::NewArrayBufferWithContents(aCx, aBuffer.mLength,
std::move(rawBuffer)));
std::move(aBuffer.mBuffer)));
if (!arrayBuffer) {
// aBuffer will be destructed at end of scope, but its destructor does not

View File

@ -46,6 +46,44 @@ extern JS_PUBLIC_API JSObject* NewArrayBufferWithContents(
JSContext* cx, size_t nbytes,
mozilla::UniquePtr<void, JS::FreePolicy> contents);
/**
* Create a new ArrayBuffer with the given |contents|, which may be null only
* if |nbytes == 0|. |contents| must be allocated compatible with deallocation
* by |JS_free|.
*
* Care must be taken that |nbytes| bytes of |contents| remain valid for the
* duration of this call. In particular, passing the length/pointer of existing
* typed array or ArrayBuffer data is generally unsafe: if a GC occurs during a
* call to this function, it could move those contents to a different location
* and invalidate the provided pointer.
*/
inline JS_PUBLIC_API JSObject* NewArrayBufferWithContents(
JSContext* cx, size_t nbytes,
mozilla::UniquePtr<char[], JS::FreePolicy> contents) {
// As a convenience, provide an overload for UniquePtr<char[]>.
mozilla::UniquePtr<void, JS::FreePolicy> ptr{contents.release()};
return NewArrayBufferWithContents(cx, nbytes, std::move(ptr));
}
/**
* Create a new ArrayBuffer with the given |contents|, which may be null only
* if |nbytes == 0|. |contents| must be allocated compatible with deallocation
* by |JS_free|.
*
* Care must be taken that |nbytes| bytes of |contents| remain valid for the
* duration of this call. In particular, passing the length/pointer of existing
* typed array or ArrayBuffer data is generally unsafe: if a GC occurs during a
* call to this function, it could move those contents to a different location
* and invalidate the provided pointer.
*/
inline JS_PUBLIC_API JSObject* NewArrayBufferWithContents(
JSContext* cx, size_t nbytes,
mozilla::UniquePtr<uint8_t[], JS::FreePolicy> contents) {
// As a convenience, provide an overload for UniquePtr<uint8_t[]>.
mozilla::UniquePtr<void, JS::FreePolicy> ptr{contents.release()};
return NewArrayBufferWithContents(cx, nbytes, std::move(ptr));
}
/**
* Marker enum to notify callers that the buffer contents must be freed manually
* when the ArrayBuffer allocation failed.

View File

@ -4989,9 +4989,8 @@ class CloneBufferObject : public NativeObject {
return false;
}
UniquePtr<void, JS::FreePolicy> dataBuffer{buffer.release()};
JSObject* arrayBuffer =
JS::NewArrayBufferWithContents(cx, size, std::move(dataBuffer));
JS::NewArrayBufferWithContents(cx, size, std::move(buffer));
if (!arrayBuffer) {
return false;
}