From 224a88a802d0daf254004b226aaee60033552098 Mon Sep 17 00:00:00 2001 From: Tom Schuster Date: Wed, 5 Jan 2022 19:31:04 +0000 Subject: [PATCH] Bug 1734239 - Implement the CountQueuingStrategy size function. r=smaug Differential Revision: https://phabricator.services.mozilla.com/D134916 --- dom/base/nsIGlobalObject.cpp | 18 +++++++++ dom/base/nsIGlobalObject.h | 14 +++++++ dom/streams/CountQueuingStrategy.cpp | 55 ++++++++++++++++++++++++++++ dom/streams/CountQueuingStrategy.h | 2 +- dom/webidl/QueuingStrategy.webidl | 6 +-- 5 files changed, 90 insertions(+), 5 deletions(-) diff --git a/dom/base/nsIGlobalObject.cpp b/dom/base/nsIGlobalObject.cpp index 6bf3f10b54eab..fd8fb47d38468 100644 --- a/dom/base/nsIGlobalObject.cpp +++ b/dom/base/nsIGlobalObject.cpp @@ -134,6 +134,9 @@ void nsIGlobalObject::UnlinkObjectsInGlobal() { mReportRecords.Clear(); mReportingObservers.Clear(); +#ifdef MOZ_DOM_STREAMS + mCountQueuingStrategySizeFunction = nullptr; +#endif } void nsIGlobalObject::TraverseObjectsInGlobal( @@ -149,6 +152,9 @@ void nsIGlobalObject::TraverseObjectsInGlobal( nsIGlobalObject* tmp = this; NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mReportRecords) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mReportingObservers) +#ifdef MOZ_DOM_STREAMS + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCountQueuingStrategySizeFunction) +#endif } void nsIGlobalObject::AddEventTargetObject(DOMEventTargetHelper* aObject) { @@ -349,6 +355,18 @@ void nsIGlobalObject::RemoveReportRecords() { } } +#ifdef MOZ_DOM_STREAMS +already_AddRefed +nsIGlobalObject::GetCountQueuingStrategySizeFunction() { + return do_AddRef(mCountQueuingStrategySizeFunction); +} + +void nsIGlobalObject::SetCountQueuingStrategySizeFunction( + mozilla::dom::Function* aFunction) { + mCountQueuingStrategySizeFunction = aFunction; +} +#endif + bool nsIGlobalObject::ShouldResistFingerprinting() const { return nsContentUtils::ShouldResistFingerprinting(); } diff --git a/dom/base/nsIGlobalObject.h b/dom/base/nsIGlobalObject.h index 7163304be932c..1029afdecca5c 100644 --- a/dom/base/nsIGlobalObject.h +++ b/dom/base/nsIGlobalObject.h @@ -37,6 +37,7 @@ enum class StorageAccess; namespace dom { class VoidFunction; class DebuggerNotificationManager; +class Function; class Report; class ReportBody; class ReportingObserver; @@ -212,6 +213,14 @@ class nsIGlobalObject : public nsISupports, void RemoveReportRecords(); +#ifdef MOZ_DOM_STREAMS + // https://streams.spec.whatwg.org/#count-queuing-strategy-size-function + // This function is set once by CountQueuingStrategy::GetSize. + already_AddRefed + GetCountQueuingStrategySizeFunction(); + void SetCountQueuingStrategySizeFunction(mozilla::dom::Function* aFunction); +#endif + /** * Check whether we should avoid leaking distinguishing information to JS/CSS. * https://w3c.github.io/fingerprinting-guidance/ @@ -240,6 +249,11 @@ class nsIGlobalObject : public nsISupports, // List of Report objects for ReportingObservers. nsTArray> mReportingObservers; nsTArray> mReportRecords; + +#ifdef MOZ_DOM_STREAMS + // https://streams.spec.whatwg.org/#count-queuing-strategy-size-function + RefPtr mCountQueuingStrategySizeFunction; +#endif }; NS_DEFINE_STATIC_IID_ACCESSOR(nsIGlobalObject, NS_IGLOBALOBJECT_IID) diff --git a/dom/streams/CountQueuingStrategy.cpp b/dom/streams/CountQueuingStrategy.cpp index 8c5b6028e1fe7..96cd1bef597f6 100644 --- a/dom/streams/CountQueuingStrategy.cpp +++ b/dom/streams/CountQueuingStrategy.cpp @@ -5,6 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/dom/CountQueuingStrategy.h" +#include "mozilla/dom/FunctionBinding.h" #include "mozilla/dom/QueuingStrategyBinding.h" #include "nsCOMPtr.h" @@ -37,5 +38,59 @@ JSObject* CountQueuingStrategy::WrapObject(JSContext* aCx, return CountQueuingStrategy_Binding::Wrap(aCx, this, aGivenProto); } +// https://streams.spec.whatwg.org/#count-queuing-strategy-size-function +static bool CountQueuingStrategySize(JSContext* aCx, unsigned aArgc, + JS::Value* aVp) { + JS::CallArgs args = CallArgsFromVp(aArgc, aVp); + + // Step 1.1. Return 1. + args.rval().setInt32(1); + return true; +} + +// https://streams.spec.whatwg.org/#cqs-size +already_AddRefed CountQueuingStrategy::GetSize(ErrorResult& aRv) { + // Step 1. Return this's relevant global object's count queuing strategy + // size function. + if (RefPtr fun = mGlobal->GetCountQueuingStrategySizeFunction()) { + return fun.forget(); + } + + // Note: Instead of eagerly allocating a size function for every global object + // we do it lazily once in this getter. + // After this point the steps refer to: + // https://streams.spec.whatwg.org/#count-queuing-strategy-size-function. + + AutoJSAPI jsapi; + if (!jsapi.Init(mGlobal)) { + aRv.ThrowUnknownError("Internal error"); + return nullptr; + } + JSContext* cx = jsapi.cx(); + + // Step 1. Let steps be the following steps: + // Note: See CountQueuingStrategySize instead. + + // Step 2. Let F be + // ! CreateBuiltinFunction(steps, 0, "size", « », + // globalObject’s relevant Realm). + JS::Rooted sizeFunction( + cx, JS_NewFunction(cx, CountQueuingStrategySize, 0, 0, "size")); + if (!sizeFunction) { + aRv.StealExceptionFromJSContext(cx); + return nullptr; + } + + // Step 3. Set globalObject’s count queuing strategy size function to + // a Function that represents a reference to F, + // with callback context equal to globalObject’s relevant settings object. + JS::Rooted funObj(cx, JS_GetFunctionObject(sizeFunction)); + JS::Rooted global(cx, mGlobal->GetGlobalJSObject()); + RefPtr function = new Function(cx, funObj, global, mGlobal); + mGlobal->SetCountQueuingStrategySizeFunction(function); + + return function.forget(); +} + } // namespace dom } // namespace mozilla diff --git a/dom/streams/CountQueuingStrategy.h b/dom/streams/CountQueuingStrategy.h index 55b312be564f5..e102c6e9db7e0 100644 --- a/dom/streams/CountQueuingStrategy.h +++ b/dom/streams/CountQueuingStrategy.h @@ -52,7 +52,7 @@ class CountQueuingStrategy final : public nsISupports, public nsWrapperCache { double HighWaterMark() const { return mHighWaterMark; } - already_AddRefed Size() const; + already_AddRefed GetSize(ErrorResult& aRv); private: double mHighWaterMark = 0.0; diff --git a/dom/webidl/QueuingStrategy.webidl b/dom/webidl/QueuingStrategy.webidl index 400a5ee7a070f..90f665b1f0124 100644 --- a/dom/webidl/QueuingStrategy.webidl +++ b/dom/webidl/QueuingStrategy.webidl @@ -16,8 +16,6 @@ interface CountQueuingStrategy { readonly attribute unrestricted double highWaterMark; - // This is currently inlined, but will need to be implemented - // See Bug 1734239 - // - // readonly attribute Function size; + [Throws] + readonly attribute Function size; };