Bug 1866220 - Prevent refcounted non-WrapperCached DOM objects. r=farre,extension-reviewers,rpl

Differential Revision: https://phabricator.services.mozilla.com/D194469
This commit is contained in:
Peter Van der Beken 2023-11-24 10:38:18 +00:00
parent e3989e26b1
commit a86f38d65b
7 changed files with 25 additions and 49 deletions

View file

@ -36,11 +36,9 @@ using mozilla::dom::GlobalObject;
using mozilla::dom::Optional;
// static
already_AddRefed<FileReaderSync> FileReaderSync::Constructor(
UniquePtr<FileReaderSync> FileReaderSync::Constructor(
const GlobalObject& aGlobal) {
RefPtr<FileReaderSync> frs = new FileReaderSync();
return frs.forget();
return MakeUnique<FileReaderSync>();
}
bool FileReaderSync::WrapObject(JSContext* aCx,

View file

@ -8,7 +8,7 @@
#define mozilla_dom_filereadersync_h__
#include "mozilla/dom/WorkerCommon.h"
#include "nsISupports.h"
#include "mozilla/dom/NonRefcountedDOMObject.h"
class nsIInputStream;
@ -21,13 +21,8 @@ class GlobalObject;
template <typename>
class Optional;
class FileReaderSync final {
NS_INLINE_DECL_REFCOUNTING(FileReaderSync)
class FileReaderSync final : public NonRefcountedDOMObject {
private:
// Private destructor, to discourage deletion outside of Release():
~FileReaderSync() = default;
nsresult ConvertStream(nsIInputStream* aStream, const char* aCharset,
nsAString& aResult);
@ -39,8 +34,7 @@ class FileReaderSync final {
uint32_t aBufferSize, uint32_t* aTotalBytesRead);
public:
static already_AddRefed<FileReaderSync> Constructor(
const GlobalObject& aGlobal);
static UniquePtr<FileReaderSync> Constructor(const GlobalObject& aGlobal);
bool WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto,
JS::MutableHandle<JSObject*> aReflector);

View file

@ -23,21 +23,21 @@ using namespace mozilla;
using namespace mozilla::dom;
// static
already_AddRefed<ClonedErrorHolder> ClonedErrorHolder::Constructor(
UniquePtr<ClonedErrorHolder> ClonedErrorHolder::Constructor(
const GlobalObject& aGlobal, JS::Handle<JSObject*> aError,
ErrorResult& aRv) {
return Create(aGlobal.Context(), aError, aRv);
}
// static
already_AddRefed<ClonedErrorHolder> ClonedErrorHolder::Create(
UniquePtr<ClonedErrorHolder> ClonedErrorHolder::Create(
JSContext* aCx, JS::Handle<JSObject*> aError, ErrorResult& aRv) {
RefPtr<ClonedErrorHolder> ceh = new ClonedErrorHolder();
UniquePtr<ClonedErrorHolder> ceh(new ClonedErrorHolder());
ceh->Init(aCx, aError, aRv);
if (aRv.Failed()) {
return nullptr;
}
return ceh.forget();
return ceh;
}
ClonedErrorHolder::ClonedErrorHolder()
@ -224,7 +224,7 @@ JSObject* ClonedErrorHolder::ReadStructuredClone(
// to avoid a potential rooting hazard.
JS::Rooted<JS::Value> errorVal(aCx);
{
RefPtr<ClonedErrorHolder> ceh = new ClonedErrorHolder();
UniquePtr<ClonedErrorHolder> ceh(new ClonedErrorHolder());
if (!ceh->Init(aCx, aReader) || !ceh->ToErrorValue(aCx, &errorVal)) {
return nullptr;
}

View file

@ -7,6 +7,7 @@
#ifndef mozilla_dom_ClonedErrorHolder_h
#define mozilla_dom_ClonedErrorHolder_h
#include "mozilla/dom/NonRefcountedDOMObject.h"
#include "nsISupportsImpl.h"
#include "js/ColumnNumber.h" // JS::ColumnNumberOneOrigin
#include "js/ErrorReport.h"
@ -23,16 +24,15 @@ class ErrorResult;
namespace dom {
class ClonedErrorHolder final {
NS_INLINE_DECL_REFCOUNTING(ClonedErrorHolder)
class ClonedErrorHolder final : public NonRefcountedDOMObject {
public:
static already_AddRefed<ClonedErrorHolder> Constructor(
const GlobalObject& aGlobal, JS::Handle<JSObject*> aError,
ErrorResult& aRv);
static UniquePtr<ClonedErrorHolder> Constructor(const GlobalObject& aGlobal,
JS::Handle<JSObject*> aError,
ErrorResult& aRv);
static already_AddRefed<ClonedErrorHolder> Create(
JSContext* aCx, JS::Handle<JSObject*> aError, ErrorResult& aRv);
static UniquePtr<ClonedErrorHolder> Create(JSContext* aCx,
JS::Handle<JSObject*> aError,
ErrorResult& aRv);
enum class Type : uint8_t {
Uninitialized,
@ -57,7 +57,6 @@ class ClonedErrorHolder final {
private:
ClonedErrorHolder();
~ClonedErrorHolder() = default;
void Init(JSContext* aCx, JS::Handle<JSObject*> aError, ErrorResult& aRv);

View file

@ -12,7 +12,6 @@
#include "mozilla/FunctionRef.h"
#include "mozilla/dom/AutoEntryScript.h"
#include "mozilla/dom/ClonedErrorHolder.h"
#include "mozilla/dom/ClonedErrorHolderBinding.h"
#include "mozilla/dom/DOMException.h"
#include "mozilla/dom/DOMExceptionBinding.h"
#include "mozilla/dom/JSActorManager.h"
@ -407,14 +406,9 @@ void JSActor::QueryHandler::RejectedCallback(JSContext* aCx,
JS::Rooted<JS::Value> value(aCx, aValue);
if (value.isObject()) {
JS::Rooted<JSObject*> error(aCx, &value.toObject());
if (RefPtr<ClonedErrorHolder> ceh =
if (UniquePtr<ClonedErrorHolder> ceh =
ClonedErrorHolder::Create(aCx, error, IgnoreErrors())) {
JS::RootedObject obj(aCx);
// Note: We can't use `ToJSValue` here because ClonedErrorHolder isn't
// wrapper cached.
if (ceh->WrapObject(aCx, nullptr, &obj)) {
value.setObject(*obj);
} else {
if (!ToJSValue(aCx, std::move(ceh), &value)) {
JS_ClearPendingException(aCx);
}
} else {

View file

@ -12,7 +12,6 @@
#include "mozilla/dom/Client.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/dom/ClonedErrorHolder.h"
#include "mozilla/dom/ClonedErrorHolderBinding.h"
#include "mozilla/dom/ExtensionBrowserBinding.h"
#include "mozilla/dom/FunctionBinding.h"
#include "mozilla/dom/WorkerScope.h"
@ -264,7 +263,7 @@ bool ExtensionAPIRequestStructuredCloneWrite(JSContext* aCx,
// Try to serialize the object as a CloneErrorHolder, if it fails then
// the object wasn't an error.
IgnoredErrorResult rv;
RefPtr<dom::ClonedErrorHolder> ceh =
UniquePtr<dom::ClonedErrorHolder> ceh =
dom::ClonedErrorHolder::Create(aCx, aObj, rv);
if (NS_WARN_IF(rv.Failed()) || !ceh) {
return false;
@ -503,14 +502,10 @@ bool RequestWorkerRunnable::HandleAPIRequest(
// runtime.lastError).
JS::Rooted<JSObject*> errObj(aCx, &aRetval.toObject());
IgnoredErrorResult rv;
RefPtr<dom::ClonedErrorHolder> ceh =
UniquePtr<dom::ClonedErrorHolder> ceh =
dom::ClonedErrorHolder::Create(aCx, errObj, rv);
if (!rv.Failed() && ceh) {
JS::Rooted<JSObject*> obj(aCx);
// Note: `ToJSValue` cannot be used because ClonedErrorHolder isn't
// wrapper cached.
okSerializedError = ceh->WrapObject(aCx, nullptr, &obj);
aRetval.setObject(*obj);
okSerializedError = ToJSValue(aCx, std::move(ceh), aRetval);
} else {
okSerializedError = false;
}

View file

@ -595,14 +595,10 @@ void ExtensionListenerCallPromiseResultHandler::WorkerRunCallback(
// in case the value is an Error object.
IgnoredErrorResult rv;
JS::Rooted<JSObject*> errObj(aCx, &retval.toObject());
RefPtr<dom::ClonedErrorHolder> ceh =
UniquePtr<dom::ClonedErrorHolder> ceh =
dom::ClonedErrorHolder::Create(aCx, errObj, rv);
if (!rv.Failed() && ceh) {
JS::Rooted<JSObject*> obj(aCx);
// Note: `ToJSValue` cannot be used because ClonedErrorHolder isn't
// wrapped cached.
Unused << NS_WARN_IF(!ceh->WrapObject(aCx, nullptr, &obj));
retval.setObject(*obj);
Unused << NS_WARN_IF(!ToJSValue(aCx, std::move(ceh), &retval));
}
}