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 350704 6bed7eb94f82c7f1bb28604c817d8aa3acdd44b5
parent 350703 4b1f9598c7e13033a550f7a138f51cbb83203bd5
child 350705 5ffa4de2f3437676a6b54f5cae4ab3af10a6aad6
push id1230
push userjlund@mozilla.com
push dateMon, 31 Oct 2016 18:13:35 +0000
treeherdermozilla-release@5e06e3766db2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange, ritu
bugs1307749
milestone50.0
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
@@ -2704,16 +2704,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
@@ -1070,16 +1070,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;