Bug 1307749 - Ensure that we still set filterSourceGraphicTainted and an empty filter when updating our filter in CanvasRenderingContext2D r=mstange a=ritu
authorGeorge Wright <george@mozilla.com>
Tue, 11 Oct 2016 15:18:45 -0400
changeset 340612 e4fc494c0e47738aef345a975a477821ddbb0727
parent 340611 59bf767c449d963a3506c7e33128ca6a710210ec
child 340613 e97d9eb2849add1f7a145e0249e369ad824101e3
push id10156
push userkwierso@gmail.com
push dateMon, 17 Oct 2016 20:08:56 +0000
treeherdermozilla-aurora@be9b2b04f7e3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange, ritu
bugs1307749
milestone51.0a2
Bug 1307749 - Ensure that we still set filterSourceGraphicTainted and an empty filter when updating our filter in CanvasRenderingContext2D r=mstange a=ritu
dom/canvas/CanvasRenderingContext2D.cpp
dom/canvas/CanvasRenderingContext2D.h
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -2834,16 +2834,21 @@ private:
   nsPresContext* mPresContext;
 };
 
 void
 CanvasRenderingContext2D::UpdateFilter()
 {
   nsCOMPtr<nsIPresShell> presShell = GetPresShell();
   if (!presShell || presShell->IsDestroying()) {
+    // Ensure we set an empty filter and update the state to
+    // reflect the current "taint" status of the canvas
+    CurrentState().filter = FilterDescription();
+    CurrentState().filterSourceGraphicTainted =
+      (mCanvasElement && mCanvasElement->IsWriteOnly());
     return;
   }
 
   // The filter might reference an SVG filter that is declared inside this
   // document. Flush frames so that we'll have an nsSVGFilterFrame to work
   // with.
   presShell->FlushPendingNotifications(Flush_Frames);
 
--- a/dom/canvas/CanvasRenderingContext2D.h
+++ b/dom/canvas/CanvasRenderingContext2D.h
@@ -1087,16 +1087,28 @@ protected:
     mozilla::gfx::CapStyle lineCap;
     mozilla::gfx::JoinStyle lineJoin;
 
     nsString filterString;
     nsTArray<nsStyleFilter> filterChain;
     RefPtr<nsSVGFilterChainObserver> filterChainObserver;
     mozilla::gfx::FilterDescription filter;
     nsTArray<RefPtr<mozilla::gfx::SourceSurface>> filterAdditionalImages;
+
+    // This keeps track of whether the canvas was "tainted" or not when
+    // we last used a filter. This is a security measure, whereby the
+    // canvas is flipped to write-only if a cross-origin image is drawn to it.
+    // This is to stop bad actors from reading back data they shouldn't have
+    // access to.
+    //
+    // This also limits what filters we can apply to the context; in particular
+    // feDisplacementMap is restricted.
+    //
+    // We keep track of this to ensure that if this gets out of sync with the
+    // tainted state of the canvas itself, we update our filters accordingly.
     bool filterSourceGraphicTainted;
 
     bool imageSmoothingEnabled;
     bool fontExplicitLanguage;
   };
 
   AutoTArray<ContextState, 3> mStyleStack;