Bug 1034584 - Prevent invalid sources to contaminate cairo DrawTargets during painting operations. r=Bas, a=sledru
authorNicolas Silva <nsilva@mozilla.com>
Fri, 04 Jul 2014 16:55:04 +0200
changeset 207703 48c49053a2e679e61e65c9a576bd39b99493cbff
parent 207702 acaa7b80c21bde072448592b2e660dfd6281f99d
child 207704 753c99efdb0dfd6bdd42604902dbb47532507e43
push id3741
push userasasaki@mozilla.com
push dateMon, 21 Jul 2014 20:25:18 +0000
treeherdermozilla-beta@4d6f46f5af68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersBas, sledru
bugs1034584
milestone32.0a2
Bug 1034584 - Prevent invalid sources to contaminate cairo DrawTargets during painting operations. r=Bas, a=sledru
gfx/2d/DrawTargetCairo.cpp
--- a/gfx/2d/DrawTargetCairo.cpp
+++ b/gfx/2d/DrawTargetCairo.cpp
@@ -591,18 +591,24 @@ DrawTargetCairo::DrawPattern(const Patte
 {
   if (!PatternIsCompatible(aPattern)) {
     return;
   }
 
   AutoClearDeviceOffset clear(aPattern);
 
   cairo_pattern_t* pat = GfxPatternToCairoPattern(aPattern, aOptions.mAlpha);
-  if (!pat)
+  if (!pat) {
     return;
+  }
+  if (cairo_pattern_status(pat)) {
+    cairo_pattern_destroy(pat);
+    gfxWarning() << "Invalid pattern";
+    return;
+  }
 
   cairo_set_source(mContext, pat);
 
   cairo_set_antialias(mContext, GfxAntialiasToCairoAntialias(aOptions.mAntialiasMode));
 
   if (NeedIntermediateSurface(aPattern, aOptions) ||
       (!IsOperatorBoundByMask(aOptions.mCompositionOp) && !aPathBoundsClip)) {
     cairo_push_group_with_content(mContext, CAIRO_CONTENT_COLOR_ALPHA);
@@ -655,16 +661,21 @@ DrawTargetCairo::FillRect(const Rect &aR
   DrawPattern(aPattern, StrokeOptions(), aOptions, DRAW_FILL, pathBoundsClip);
 }
 
 void
 DrawTargetCairo::CopySurfaceInternal(cairo_surface_t* aSurface,
                                      const IntRect &aSource,
                                      const IntPoint &aDest)
 {
+  if (cairo_surface_status(aSurface)) {
+    gfxWarning() << "Invalid surface";
+    return;
+  }
+
   cairo_identity_matrix(mContext);
 
   cairo_set_source_surface(mContext, aSurface, aDest.x - aSource.x, aDest.y - aSource.y);
   cairo_set_operator(mContext, CAIRO_OPERATOR_SOURCE);
   cairo_set_antialias(mContext, CAIRO_ANTIALIAS_NONE);
 
   cairo_reset_clip(mContext);
   cairo_new_path(mContext);
@@ -854,25 +865,33 @@ DrawTargetCairo::Mask(const Pattern &aSo
 {
   AutoPrepareForDrawing prep(this, mContext);
   AutoClearDeviceOffset clearSource(aSource);
   AutoClearDeviceOffset clearMask(aMask);
 
   cairo_set_antialias(mContext, GfxAntialiasToCairoAntialias(aOptions.mAntialiasMode));
 
   cairo_pattern_t* source = GfxPatternToCairoPattern(aSource, aOptions.mAlpha);
-  if (!source)
+  if (!source) {
     return;
+  }
 
   cairo_pattern_t* mask = GfxPatternToCairoPattern(aMask, aOptions.mAlpha);
   if (!mask) {
     cairo_pattern_destroy(source);
     return;
   }
 
+  if (cairo_pattern_status(source) || cairo_pattern_status(mask)) {
+    cairo_pattern_destroy(source);
+    cairo_pattern_destroy(mask);
+    gfxWarning() << "Invalid pattern";
+    return;
+  }
+
   cairo_set_source(mContext, source);
   cairo_mask(mContext, mask);
 
   cairo_pattern_destroy(mask);
   cairo_pattern_destroy(source);
 }
 
 void
@@ -887,18 +906,25 @@ DrawTargetCairo::MaskSurface(const Patte
 
   if (!PatternIsCompatible(aSource)) {
     return;
   }
 
   cairo_set_antialias(mContext, GfxAntialiasToCairoAntialias(aOptions.mAntialiasMode));
 
   cairo_pattern_t* pat = GfxPatternToCairoPattern(aSource, aOptions.mAlpha);
-  if (!pat)
+  if (!pat) {
     return;
+  }
+
+  if (cairo_pattern_status(pat)) {
+    cairo_pattern_destroy(pat);
+    gfxWarning() << "Invalid pattern";
+    return;
+  }
 
   cairo_set_source(mContext, pat);
 
   if (NeedIntermediateSurface(aSource, aOptions)) {
     cairo_push_group_with_content(mContext, CAIRO_CONTENT_COLOR_ALPHA);
 
     // Don't want operators to be applied twice
     cairo_set_operator(mContext, CAIRO_OPERATOR_OVER);