Bug 1746750 - Part 2. Add new WebIDL method variants to support OffscreenCanvasRenderingContext2D. r=lsalzman

This patch is a non-functional change. It overloads some WebIDL methods
of CanvasRenderingContext2D to account for the difference between the
main thread and worker prototypes.

Differential Revision: https://phabricator.services.mozilla.com/D135353
This commit is contained in:
Andrew Osmond 2022-02-02 16:41:26 +00:00
Родитель 1e00358fd7
Коммит 94c44e84c9
5 изменённых файлов: 72 добавлений и 13 удалений

Просмотреть файл

@ -4271,6 +4271,12 @@ bool CanvasRenderingContext2D::IsPointInPath(JSContext* aCx, double aX,
double aY,
const CanvasWindingRule& aWinding,
nsIPrincipal& aSubjectPrincipal) {
return IsPointInPath(aCx, aX, aY, aWinding, Some(&aSubjectPrincipal));
}
bool CanvasRenderingContext2D::IsPointInPath(
JSContext* aCx, double aX, double aY, const CanvasWindingRule& aWinding,
Maybe<nsIPrincipal*> aSubjectPrincipal) {
if (!FloatValidate(aX, aY)) {
return false;
}
@ -4282,6 +4288,9 @@ bool CanvasRenderingContext2D::IsPointInPath(JSContext* aCx, double aX,
aSubjectPrincipal)) {
return false;
}
} else if (mOffscreenCanvas &&
mOffscreenCanvas->ShouldResistFingerprinting()) {
return false;
}
EnsureUserSpacePath(aWinding);
@ -4300,7 +4309,15 @@ bool CanvasRenderingContext2D::IsPointInPath(JSContext* aCx,
const CanvasPath& aPath, double aX,
double aY,
const CanvasWindingRule& aWinding,
nsIPrincipal&) {
nsIPrincipal& aSubjectPrincipal) {
return IsPointInPath(aCx, aPath, aX, aY, aWinding, Some(&aSubjectPrincipal));
}
bool CanvasRenderingContext2D::IsPointInPath(JSContext* aCx,
const CanvasPath& aPath, double aX,
double aY,
const CanvasWindingRule& aWinding,
Maybe<nsIPrincipal*>) {
if (!FloatValidate(aX, aY)) {
return false;
}
@ -4317,6 +4334,12 @@ bool CanvasRenderingContext2D::IsPointInPath(JSContext* aCx,
bool CanvasRenderingContext2D::IsPointInStroke(
JSContext* aCx, double aX, double aY, nsIPrincipal& aSubjectPrincipal) {
return IsPointInStroke(aCx, aX, aY, Some(&aSubjectPrincipal));
}
bool CanvasRenderingContext2D::IsPointInStroke(
JSContext* aCx, double aX, double aY,
Maybe<nsIPrincipal*> aSubjectPrincipal) {
if (!FloatValidate(aX, aY)) {
return false;
}
@ -4328,6 +4351,9 @@ bool CanvasRenderingContext2D::IsPointInStroke(
aSubjectPrincipal)) {
return false;
}
} else if (mOffscreenCanvas &&
mOffscreenCanvas->ShouldResistFingerprinting()) {
return false;
}
EnsureUserSpacePath();
@ -4348,10 +4374,16 @@ bool CanvasRenderingContext2D::IsPointInStroke(
mTarget->GetTransform());
}
bool CanvasRenderingContext2D::IsPointInStroke(
JSContext* aCx, const CanvasPath& aPath, double aX, double aY,
nsIPrincipal& aSubjectPrincipal) {
return IsPointInStroke(aCx, aPath, aX, aY, Some(&aSubjectPrincipal));
}
bool CanvasRenderingContext2D::IsPointInStroke(JSContext* aCx,
const CanvasPath& aPath,
double aX, double aY,
nsIPrincipal&) {
Maybe<nsIPrincipal*>) {
if (!FloatValidate(aX, aY)) {
return false;
}
@ -5050,7 +5082,14 @@ void CanvasRenderingContext2D::DrawWindow(nsGlobalWindowInner& aWindow,
already_AddRefed<ImageData> CanvasRenderingContext2D::GetImageData(
JSContext* aCx, int32_t aSx, int32_t aSy, int32_t aSw, int32_t aSh,
nsIPrincipal& aSubjectPrincipal, ErrorResult& aError) {
if (!mCanvasElement && !mDocShell) {
return GetImageData(aCx, aSx, aSy, aSw, aSh, Some(&aSubjectPrincipal),
aError);
}
already_AddRefed<ImageData> CanvasRenderingContext2D::GetImageData(
JSContext* aCx, int32_t aSx, int32_t aSy, int32_t aSw, int32_t aSh,
Maybe<nsIPrincipal*> aSubjectPrincipal, ErrorResult& aError) {
if (!mCanvasElement && !mDocShell && !mOffscreenCanvas) {
NS_ERROR("No canvas element and no docshell in GetImageData!!!");
aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
return nullptr;
@ -5058,6 +5097,7 @@ already_AddRefed<ImageData> CanvasRenderingContext2D::GetImageData(
// Check only if we have a canvas element; if we were created with a docshell,
// then it's special internal use.
// FIXME(aosmond): OffscreenCanvas security check??!
if (IsWriteOnly() ||
(mCanvasElement && !mCanvasElement->CallerCanRead(aCx))) {
// XXX ERRMSG we need to report an error to developers here! (bug 329026)
@ -5105,7 +5145,7 @@ already_AddRefed<ImageData> CanvasRenderingContext2D::GetImageData(
nsresult CanvasRenderingContext2D::GetImageDataArray(
JSContext* aCx, int32_t aX, int32_t aY, uint32_t aWidth, uint32_t aHeight,
nsIPrincipal& aSubjectPrincipal, JSObject** aRetval) {
Maybe<nsIPrincipal*> aSubjectPrincipal, JSObject** aRetval) {
MOZ_ASSERT(aWidth && aHeight);
// Restrict the typed array length to INT32_MAX because that's all we support
@ -5170,6 +5210,8 @@ nsresult CanvasRenderingContext2D::GetImageDataArray(
nsCOMPtr<Document> ownerDoc = mCanvasElement->OwnerDoc();
usePlaceholder = !CanvasUtils::IsImageExtractionAllowed(ownerDoc, aCx,
aSubjectPrincipal);
} else if (mOffscreenCanvas) {
usePlaceholder = mOffscreenCanvas->ShouldResistFingerprinting();
}
do {

Просмотреть файл

@ -15,6 +15,7 @@
#include "mozilla/Atomics.h"
#include "mozilla/Attributes.h"
#include "mozilla/EnumeratedArray.h"
#include "mozilla/Maybe.h"
#include "mozilla/RefPtr.h"
#include "mozilla/SurfaceFromElementResult.h"
#include "mozilla/UniquePtr.h"
@ -208,13 +209,23 @@ class CanvasRenderingContext2D : public nsICanvasRenderingContextInternal,
bool IsPointInPath(JSContext* aCx, double aX, double aY,
const CanvasWindingRule& aWinding,
nsIPrincipal& aSubjectPrincipal);
bool IsPointInPath(JSContext* aCx, double aX, double aY,
const CanvasWindingRule& aWinding,
Maybe<nsIPrincipal*> aSubjectPrincipal);
bool IsPointInPath(JSContext* aCx, const CanvasPath& aPath, double aX,
double aY, const CanvasWindingRule& aWinding,
nsIPrincipal&);
bool IsPointInPath(JSContext* aCx, const CanvasPath& aPath, double aX,
double aY, const CanvasWindingRule& aWinding,
Maybe<nsIPrincipal*>);
bool IsPointInStroke(JSContext* aCx, double aX, double aY,
nsIPrincipal& aSubjectPrincipal);
bool IsPointInStroke(JSContext* aCx, double aX, double aY,
Maybe<nsIPrincipal*> aSubjectPrincipal);
bool IsPointInStroke(JSContext* aCx, const CanvasPath& aPath, double aX,
double aY, nsIPrincipal&);
bool IsPointInStroke(JSContext* aCx, const CanvasPath& aPath, double aX,
double aY, Maybe<nsIPrincipal*>);
void FillText(const nsAString& aText, double aX, double aY,
const Optional<double>& aMaxWidth,
mozilla::ErrorResult& aError);
@ -254,6 +265,9 @@ class CanvasRenderingContext2D : public nsICanvasRenderingContextInternal,
int32_t aSw, int32_t aSh,
nsIPrincipal& aSubjectPrincipal,
ErrorResult&);
already_AddRefed<ImageData> GetImageData(
JSContext*, int32_t aSx, int32_t aSy, int32_t aSw, int32_t aSh,
Maybe<nsIPrincipal*> aSubjectPrincipal, ErrorResult&);
void PutImageData(ImageData&, int32_t aDx, int32_t aDy, ErrorResult&);
void PutImageData(ImageData&, int32_t aDx, int32_t aDy, int32_t aDirtyX,
int32_t aDirtyY, int32_t aDirtyWidth, int32_t aDirtyHeight,
@ -516,7 +530,7 @@ class CanvasRenderingContext2D : public nsICanvasRenderingContextInternal,
protected:
nsresult GetImageDataArray(JSContext* aCx, int32_t aX, int32_t aY,
uint32_t aWidth, uint32_t aHeight,
nsIPrincipal& aSubjectPrincipal,
Maybe<nsIPrincipal*> aSubjectPrincipal,
JSObject** aRetval);
void PutImageData_explicit(int32_t aX, int32_t aY, ImageData&,

Просмотреть файл

@ -51,24 +51,26 @@ using namespace mozilla::gfx;
namespace mozilla::CanvasUtils {
bool IsImageExtractionAllowed(dom::Document* aDocument, JSContext* aCx,
nsIPrincipal& aPrincipal) {
Maybe<nsIPrincipal*> aPrincipal) {
// Do the rest of the checks only if privacy.resistFingerprinting is on.
if (!nsContentUtils::ShouldResistFingerprinting(aDocument)) {
return true;
}
// Don't proceed if we don't have a document or JavaScript context.
if (!aDocument || !aCx) {
if (!aDocument || !aCx || !aPrincipal) {
return false;
}
nsIPrincipal& subjectPrincipal = *aPrincipal.ref();
// The system principal can always extract canvas data.
if (aPrincipal.IsSystemPrincipal()) {
if (subjectPrincipal.IsSystemPrincipal()) {
return true;
}
// Allow extension principals.
auto principal = BasePrincipal::Cast(&aPrincipal);
auto* principal = BasePrincipal::Cast(&subjectPrincipal);
if (principal->AddonPolicy() || principal->ContentScriptAddonPolicy()) {
return true;
}

Просмотреть файл

@ -56,7 +56,7 @@ bool IsOffscreenCanvasEnabled(JSContext* aCx, JSObject* aObj);
// Check site-specific permission and display prompt if appropriate.
bool IsImageExtractionAllowed(dom::Document* aDocument, JSContext* aCx,
nsIPrincipal& aPrincipal);
Maybe<nsIPrincipal*> aPrincipal);
// Make a double out of |v|, treating undefined values as 0.0 (for
// the sake of sparse arrays). Return true iff coercion

Просмотреть файл

@ -800,7 +800,8 @@ already_AddRefed<CanvasCaptureMediaStream> HTMLCanvasElement::CaptureStream(
// If no permission, arrange for the frame capture listener to return
// all-white, opaque image data.
bool usePlaceholder = !CanvasUtils::IsImageExtractionAllowed(
OwnerDoc(), nsContentUtils::GetCurrentJSContext(), aSubjectPrincipal);
OwnerDoc(), nsContentUtils::GetCurrentJSContext(),
Some(&aSubjectPrincipal));
rv = RegisterFrameCaptureListener(stream->FrameCaptureListener(),
usePlaceholder);
@ -820,7 +821,7 @@ nsresult HTMLCanvasElement::ExtractData(JSContext* aCx,
// Check site-specific permission and display prompt if appropriate.
// If no permission, return all-white, opaque image data.
bool usePlaceholder = !CanvasUtils::IsImageExtractionAllowed(
OwnerDoc(), aCx, aSubjectPrincipal);
OwnerDoc(), aCx, Some(&aSubjectPrincipal));
return ImageEncoder::ExtractData(aType, aOptions, GetSize(), usePlaceholder,
mCurrentContext, mCanvasRenderer, aStream);
}
@ -904,7 +905,7 @@ void HTMLCanvasElement::ToBlob(JSContext* aCx, BlobCallback& aCallback,
// Check site-specific permission and display prompt if appropriate.
// If no permission, return all-white, opaque image data.
bool usePlaceholder = !CanvasUtils::IsImageExtractionAllowed(
OwnerDoc(), aCx, aSubjectPrincipal);
OwnerDoc(), aCx, Some(&aSubjectPrincipal));
CanvasRenderingContextHelper::ToBlob(aCx, global, aCallback, aType, aParams,
usePlaceholder, aRv);
}