Implement the HTML5 canvas tainting rules to prevent potential data leakage
[WebKit-https.git] / WebCore / html / CanvasPattern.cpp
index ae0dfc7d2b4fa135fd7b84158d2d5411ee4bab2f..2cda91783103a484649b9d4cb9cb889b2cfb2d00 100644 (file)
@@ -65,25 +65,39 @@ void CanvasPattern::parseRepetitionType(const String& type, bool& repeatX, bool&
 
 #if PLATFORM(CG)
 
-CanvasPattern::CanvasPattern(CGImageRef image, bool repeatX, bool repeatY)
-    : m_platformImage(image)
+CanvasPattern::CanvasPattern(CGImageRef image, bool repeatX, bool repeatY, bool originClean)
+    : RefCounted<CanvasPattern>(0)
+    , m_platformImage(image)
     , m_cachedImage(0)
     , m_repeatX(repeatX)
     , m_repeatY(repeatY)
+    , m_originClean(originClean)
+{
+}
+
+#elif PLATFORM(CAIRO)
+
+CanvasPattern::CanvasPattern(cairo_surface_t* surface, bool repeatX, bool repeatY, bool originClean)
+    : RefCounted<CanvasPattern>(0)
+    , m_platformImage(cairo_surface_reference(surface))
+    , m_cachedImage(0)
+    , m_repeatX(repeatX)
+    , m_repeatY(repeatY)
+    , m_originClean(originClean)
 {
 }
 
 #endif
 
-CanvasPattern::CanvasPattern(CachedImage* cachedImage, bool repeatX, bool repeatY)
-    :
-#if PLATFORM(CG)
-      m_platformImage(0)
-    ,
+CanvasPattern::CanvasPattern(CachedImage* cachedImage, bool repeatX, bool repeatY, bool originClean)
+    : RefCounted<CanvasPattern>(0)
+#if PLATFORM(CG) || PLATFORM(CAIRO)
+    , m_platformImage(0)
 #endif
-      m_cachedImage(cachedImage)
+    , m_cachedImage(cachedImage)
     , m_repeatX(repeatX)
     , m_repeatY(repeatY)
+    , m_originClean(originClean)
 {
     if (cachedImage)
         cachedImage->ref(this);
@@ -91,6 +105,10 @@ CanvasPattern::CanvasPattern(CachedImage* cachedImage, bool repeatX, bool repeat
 
 CanvasPattern::~CanvasPattern()
 {
+#if PLATFORM(CAIRO)
+    if (m_platformImage)
+        cairo_surface_destroy(m_platformImage);
+#endif
     if (m_cachedImage)
         m_cachedImage->deref(this);
 }
@@ -168,6 +186,32 @@ CGPatternRef CanvasPattern::createPattern(const CGAffineTransform& transform)
         kCGPatternTilingConstantSpacing, TRUE, &patternCallbacks);
 }
 
+#elif PLATFORM(CAIRO)
+
+cairo_pattern_t* CanvasPattern::createPattern(const cairo_matrix_t& m)
+{
+    cairo_surface_t* surface = 0;
+    if (m_platformImage) {
+        surface = m_platformImage;
+    } else {
+        if (!m_cachedImage)
+            return 0;
+        Image* image = m_cachedImage->image();
+        if (!image)
+            return 0;
+        surface = image->nativeImageForCurrentFrame();
+    }
+
+    if (!surface)
+        return 0;
+
+    cairo_pattern_t* pattern = cairo_pattern_create_for_surface(surface);
+    cairo_pattern_set_matrix(pattern, &m);
+    if (m_repeatX || m_repeatY)
+        cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT);
+    return pattern;
+}
+
 #endif
 
 }