summaryrefslogtreecommitdiffstats
path: root/dom/canvas/CanvasRenderingContext2D.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/canvas/CanvasRenderingContext2D.cpp')
-rw-r--r--dom/canvas/CanvasRenderingContext2D.cpp44
1 files changed, 30 insertions, 14 deletions
diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp
index eee73e5..73cd347 100644
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -1080,7 +1080,8 @@ CanvasRenderingContext2D::CanvasRenderingContext2D(
mPredictManyRedrawCalls(false),
mIsCapturedFrameInvalid(false),
mPathTransformWillUpdate(false),
- mInvalidateCount(0) {
+ mInvalidateCount(0),
+ mWriteOnly(false) {
if (!sMaxContextsInitialized) {
sMaxContexts = gfxPrefs::CanvasAzureAcceleratedLimit();
sMaxContextsInitialized = true;
@@ -2346,7 +2347,11 @@ void CanvasRenderingContext2D::SetStyleFromUnion(
}
if (aValue.IsCanvasPattern()) {
- SetStyleFromPattern(aValue.GetAsCanvasPattern(), aWhichStyle);
+ CanvasPattern& pattern = aValue.GetAsCanvasPattern();
+ SetStyleFromPattern(pattern, aWhichStyle);
+ if (pattern.mForceWriteOnly) {
+ SetWriteOnly();
+ }
return;
}
@@ -2497,7 +2502,7 @@ already_AddRefed<CanvasPattern> CanvasRenderingContext2D::CreatePattern(
// nullptr and set CORSUsed to true for passing the security check in
// CanvasUtils::DoDrawImageSecurityCheck().
RefPtr<CanvasPattern> pat =
- new CanvasPattern(this, srcSurf, repeatMode, nullptr, false, true);
+ new CanvasPattern(this, srcSurf, repeatMode, nullptr, imgBitmap.IsWriteOnly(), true);
return pat.forget();
}
@@ -2514,13 +2519,14 @@ already_AddRefed<CanvasPattern> CanvasRenderingContext2D::CreatePattern(
nsLayoutUtils::SurfaceFromElement(
element, nsLayoutUtils::SFE_WANT_FIRST_FRAME_IF_IMAGE, mTarget);
- if (!res.GetSourceSurface()) {
+ RefPtr<SourceSurface> surface = res.GetSourceSurface();
+ if (!surface) {
return nullptr;
}
RefPtr<CanvasPattern> pat =
- new CanvasPattern(this, res.GetSourceSurface(), repeatMode,
- res.mPrincipal, res.mIsWriteOnly, res.mCORSUsed);
+ new CanvasPattern(this, surface, repeatMode, res.mPrincipal,
+ res.mIsWriteOnly, res.mCORSUsed);
return pat.forget();
}
@@ -4848,8 +4854,8 @@ CanvasRenderingContext2D::CachedSurfaceFromElement(Element* aElement) {
res.mSize = res.mSourceSurface->GetSize();
res.mPrincipal = principal.forget();
- res.mIsWriteOnly = false;
res.mImageRequest = imgRequest.forget();
+ res.mIsWriteOnly = CheckWriteOnlySecurity(res.mCORSUsed, res.mPrincipal);
return res;
}
@@ -4908,6 +4914,10 @@ void CanvasRenderingContext2D::DrawImage(const CanvasImageSource& aImage,
aError.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
}
+
+ if (canvas->IsWriteOnly()) {
+ SetWriteOnly();
+ }
} else if (aImage.IsImageBitmap()) {
ImageBitmap& imageBitmap = aImage.GetAsImageBitmap();
srcSurf = imageBitmap.PrepareForDrawTarget(mTarget);
@@ -4916,6 +4926,10 @@ void CanvasRenderingContext2D::DrawImage(const CanvasImageSource& aImage,
return;
}
+ if (imageBitmap.IsWriteOnly()) {
+ SetWriteOnly();
+ }
+
imgSize = gfx::IntSize(imageBitmap.Width(), imageBitmap.Height());
} else {
if (aImage.IsHTMLImageElement()) {
@@ -5421,13 +5435,8 @@ 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.
- if (mCanvasElement && mCanvasElement->IsWriteOnly() &&
- // We could ask bindings for the caller type, but they already hand us a
- // JSContext, and we're at least _somewhat_ perf-sensitive (so may not
- // want to compute the caller type in the common non-write-only case), so
- // let's just use what we have.
- !nsContentUtils::CallerHasPermission(aCx,
- nsGkAtoms::all_urlsPermission)) {
+ if (IsWriteOnly() ||
+ (mCanvasElement && !mCanvasElement->CallerCanRead(aCx))) {
// XXX ERRMSG we need to report an error to developers here! (bug 329026)
aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
return nullptr;
@@ -6029,6 +6038,13 @@ bool CanvasRenderingContext2D::ShouldForceInactiveLayer(
return !aManager->CanUseCanvasLayerForSize(GetSize());
}
+void CanvasRenderingContext2D::SetWriteOnly() {
+ mWriteOnly = true;
+ if (mCanvasElement) {
+ mCanvasElement->SetWriteOnly();
+ }
+}
+
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(CanvasPath, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(CanvasPath, Release)