summaryrefslogtreecommitdiffstats
path: root/dom/html/HTMLCanvasElement.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/html/HTMLCanvasElement.cpp')
-rw-r--r--dom/html/HTMLCanvasElement.cpp43
1 files changed, 35 insertions, 8 deletions
diff --git a/dom/html/HTMLCanvasElement.cpp b/dom/html/HTMLCanvasElement.cpp
index 0417a30..3a4d67a 100644
--- a/dom/html/HTMLCanvasElement.cpp
+++ b/dom/html/HTMLCanvasElement.cpp
@@ -586,9 +586,8 @@ bool HTMLCanvasElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
void HTMLCanvasElement::ToDataURL(JSContext* aCx, const nsAString& aType,
JS::Handle<JS::Value> aParams,
nsAString& aDataURL, ErrorResult& aRv) {
- // do a trust check if this is a write-only canvas
- if (mWriteOnly && !nsContentUtils::CallerHasPermission(
- aCx, nsGkAtoms::all_urlsPermission)) {
+ // mWriteOnly check is redundant, but optimizes for the common case.
+ if (mWriteOnly && !CallerCanRead(aCx)) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return;
}
@@ -761,9 +760,8 @@ void HTMLCanvasElement::ToBlob(JSContext* aCx, BlobCallback& aCallback,
const nsAString& aType,
JS::Handle<JS::Value> aParams,
ErrorResult& aRv) {
- // do a trust check if this is a write-only canvas
- if (mWriteOnly && !nsContentUtils::CallerHasPermission(
- aCx, nsGkAtoms::all_urlsPermission)) {
+ // mWriteOnly check is redundant, but optimizes for the common case.
+ if (mWriteOnly && !CallerCanRead(aCx)) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return;
}
@@ -939,9 +937,38 @@ already_AddRefed<nsISupports> HTMLCanvasElement::MozGetIPCContext(
nsIntSize HTMLCanvasElement::GetSize() { return GetWidthHeight(); }
-bool HTMLCanvasElement::IsWriteOnly() { return mWriteOnly; }
+bool HTMLCanvasElement::IsWriteOnly() const { return mWriteOnly; }
+
+void HTMLCanvasElement::SetWriteOnly() {
+ mExpandedReader = nullptr;
+ mWriteOnly = true;
+}
+
+void
+HTMLCanvasElement::SetWriteOnly(nsIPrincipal* aExpandedReader)
+{
+ mExpandedReader = aExpandedReader;
+ mWriteOnly = true;
+}
+
+bool
+HTMLCanvasElement::CallerCanRead(JSContext* aCx)
+{
+ if (!mWriteOnly) {
+ return true;
+ }
-void HTMLCanvasElement::SetWriteOnly() { mWriteOnly = true; }
+ nsIPrincipal* prin = nsContentUtils::SubjectPrincipal(aCx);
+
+ // If mExpandedReader is set, this canvas was tainted only by
+ // mExpandedReader's resources. So allow reading if the subject
+ // principal subsumes mExpandedReader.
+ if (mExpandedReader && prin->Subsumes(mExpandedReader)) {
+ return true;
+ }
+
+ return nsContentUtils::PrincipalHasPermission(prin, nsGkAtoms::all_urlsPermission);
+}
void HTMLCanvasElement::InvalidateCanvasContent(const gfx::Rect* damageRect) {
// We don't need to flush anything here; if there's no frame or if