Title: [129962] trunk
Revision
129962
Author
[email protected]
Date
2012-09-28 16:58:22 -0700 (Fri, 28 Sep 2012)

Log Message

REGRESSION(r122215) - CachedImage::likelyToBeUsedSoon crashes on accessing a deleted CachedImageClient
https://bugs.webkit.org/show_bug.cgi?id=97749

Reviewed by James Robinson.

.:

Added a manual test to demonstrate drag image and crashing.

* ManualTests/drag-image-no-crash.html: Added.

Source/WebCore:

All implementations of Clipboard set themselves as clients to CachedImage
through the JS API setDrageImage() but they do not detach during destruction.
This causes memory corruption when CachedImage tries to access a deleted client
when MemoryCache prunes and calls CachedImage::likelyToUsedSoon().

Manual test added: ManualTests/drag-image-no-crash.html

* platform/chromium/ClipboardChromium.cpp:
(WebCore::ClipboardChromium::~ClipboardChromium):
* platform/gtk/ClipboardGtk.cpp:
(WebCore::ClipboardGtk::~ClipboardGtk):
* platform/mac/ClipboardMac.mm:
(WebCore::ClipboardMac::~ClipboardMac):
* platform/win/ClipboardWin.cpp:
(WebCore::ClipboardWin::~ClipboardWin):

Modified Paths

Added Paths

Diff

Modified: trunk/ChangeLog (129961 => 129962)


--- trunk/ChangeLog	2012-09-28 23:41:58 UTC (rev 129961)
+++ trunk/ChangeLog	2012-09-28 23:58:22 UTC (rev 129962)
@@ -1,3 +1,14 @@
+2012-09-28  Alpha Lam  <[email protected]>
+
+        REGRESSION(r122215) - CachedImage::likelyToBeUsedSoon crashes on accessing a deleted CachedImageClient
+        https://bugs.webkit.org/show_bug.cgi?id=97749
+
+        Reviewed by James Robinson.
+
+        Added a manual test to demonstrate drag image and crashing.
+
+        * ManualTests/drag-image-no-crash.html: Added.
+
 2012-09-27  Keishi Hattori  <[email protected]>
 
         SuggestionPicker should support rtl

Added: trunk/ManualTests/drag-image-no-crash.html (0 => 129962)


--- trunk/ManualTests/drag-image-no-crash.html	                        (rev 0)
+++ trunk/ManualTests/drag-image-no-crash.html	2012-09-28 23:58:22 UTC (rev 129962)
@@ -0,0 +1,87 @@
+<html>
+<body>
+<script>
+// This is a 10x10 24-bits RGB BMP image in white.
+var imageString =
+"Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAAAAA" +
+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
+
+// Raw image byets.
+var imageRaw = window.atob(imageString).split("");
+
+// 10x10x3 bytes are image data.
+var pixelBytes = 300;
+var beginByte = imageRaw.length - pixelBytes;
+
+function generateNewImage()
+{
+    // Add 1 to image data.
+    for (var i = beginByte; i < imageRaw.length; ++i) {
+        var c = imageRaw[i].charCodeAt(0);
+        if (c == 255) {
+            imageRaw[i] = String.fromCharCode(0);
+        } else {
+            imageRaw[i] = String.fromCharCode(c+1);
+            break;
+        }
+    }
+
+    var bmpImage = new Image();
+    bmpImage.src = "" + window.btoa(imageRaw.join(""));
+    return bmpImage;
+}
+
+var imageCount = 0;
+function addImage()
+{
+    if (imageCount >= 1000 * 1000)
+        return;
+    document.getElementById("imageCanvas").appendChild(generateNewImage());
+    window.setTimeout("addImage()", 1);
+}
+
+function runTest()
+{
+    document.getElementById("dragFrame").contentWindow.location.href =
+        "about:blank";
+    addImage();
+}
+</script>
+<p>To run this test:</p>
+<p>1. Drag this text 10 times:
+   <iframe id="dragFrame" width="50" height="30">.</iframe></p>
+<p>2. Click this <button _onclick_="runTest();">Start</button> button.</p>
+<p>3. Let it run for 5 minutes and browser shouldn't crash.</p>
+<div id="imageCanvas"></div>
+
+<script>
+// Write this content to the iframe.
+var content =
+    "<" + "body" + ">" +
+    "<" + "script" + ">" +
+    "function dragStartHandler()" +
+    "{" +
+    "    var img = new Image();" +
+    "    img.src = '';" +
+    "    event.dataTransfer.setDragImage(img, 10, 10);" +
+    "}" +
+    "</" + "script" + ">" +
+    "<span _ondragstart_='dragStartHandler()'" +
+    "      style='-webkit-user-select:none;" +
+    "             -webkit-user-drag: element;" +
+    "             position: absolute; top: 0; left: 0;" +
+    "             background-color: blue;'>HERE</span>" +
+    "</" + "body" + ">";
+
+var doc = document.getElementById("dragFrame");
+doc.contentDocument.open();
+doc.contentDocument.write(content);
+doc.contentDocument.close();
+</script>
+</body>
+</html>
Property changes on: trunk/ManualTests/drag-image-no-crash.html
___________________________________________________________________

Added: svn:eol-style

Modified: trunk/Source/WebCore/ChangeLog (129961 => 129962)


--- trunk/Source/WebCore/ChangeLog	2012-09-28 23:41:58 UTC (rev 129961)
+++ trunk/Source/WebCore/ChangeLog	2012-09-28 23:58:22 UTC (rev 129962)
@@ -1,3 +1,26 @@
+2012-09-27  Alpha Lam  <[email protected]>
+
+        REGRESSION(r122215) - CachedImage::likelyToBeUsedSoon crashes on accessing a deleted CachedImageClient
+        https://bugs.webkit.org/show_bug.cgi?id=97749
+
+        Reviewed by James Robinson.
+
+        All implementations of Clipboard set themselves as clients to CachedImage
+        through the JS API setDrageImage() but they do not detach during destruction.
+        This causes memory corruption when CachedImage tries to access a deleted client
+        when MemoryCache prunes and calls CachedImage::likelyToUsedSoon().
+
+        Manual test added: ManualTests/drag-image-no-crash.html
+
+        * platform/chromium/ClipboardChromium.cpp:
+        (WebCore::ClipboardChromium::~ClipboardChromium):
+        * platform/gtk/ClipboardGtk.cpp:
+        (WebCore::ClipboardGtk::~ClipboardGtk):
+        * platform/mac/ClipboardMac.mm:
+        (WebCore::ClipboardMac::~ClipboardMac):
+        * platform/win/ClipboardWin.cpp:
+        (WebCore::ClipboardWin::~ClipboardWin):
+
 2012-09-28  Anders Carlsson  <[email protected]>
 
         Remove Instance::setDidExecuteFunction

Modified: trunk/Source/WebCore/platform/chromium/ClipboardChromium.cpp (129961 => 129962)


--- trunk/Source/WebCore/platform/chromium/ClipboardChromium.cpp	2012-09-28 23:41:58 UTC (rev 129961)
+++ trunk/Source/WebCore/platform/chromium/ClipboardChromium.cpp	2012-09-28 23:58:22 UTC (rev 129962)
@@ -226,6 +226,8 @@
 
 ClipboardChromium::~ClipboardChromium()
 {
+    if (m_dragImage)
+        m_dragImage->removeClient(this);
 }
 
 PassRefPtr<ClipboardChromium> ClipboardChromium::create(ClipboardType clipboardType,

Modified: trunk/Source/WebCore/platform/gtk/ClipboardGtk.cpp (129961 => 129962)


--- trunk/Source/WebCore/platform/gtk/ClipboardGtk.cpp	2012-09-28 23:41:58 UTC (rev 129961)
+++ trunk/Source/WebCore/platform/gtk/ClipboardGtk.cpp	2012-09-28 23:58:22 UTC (rev 129962)
@@ -74,6 +74,8 @@
 
 ClipboardGtk::~ClipboardGtk()
 {
+    if (m_dragImage)
+        m_dragImage->removeClient(this);
 }
 
 static ClipboardDataType dataObjectTypeFromHTMLClipboardType(const String& rawType)

Modified: trunk/Source/WebCore/platform/mac/ClipboardMac.mm (129961 => 129962)


--- trunk/Source/WebCore/platform/mac/ClipboardMac.mm	2012-09-28 23:41:58 UTC (rev 129961)
+++ trunk/Source/WebCore/platform/mac/ClipboardMac.mm	2012-09-28 23:58:22 UTC (rev 129962)
@@ -65,6 +65,8 @@
 
 ClipboardMac::~ClipboardMac()
 {
+    if (m_dragImage)
+        m_dragImage->removeClient(this);
 }
 
 bool ClipboardMac::hasData()

Modified: trunk/Source/WebCore/platform/win/ClipboardWin.cpp (129961 => 129962)


--- trunk/Source/WebCore/platform/win/ClipboardWin.cpp	2012-09-28 23:41:58 UTC (rev 129961)
+++ trunk/Source/WebCore/platform/win/ClipboardWin.cpp	2012-09-28 23:58:22 UTC (rev 129962)
@@ -355,6 +355,8 @@
 
 ClipboardWin::~ClipboardWin()
 {
+    if (m_dragImage)
+        m_dragImage->removeClient(this);
 }
 
 static bool writeURL(WCDataObject *data, const KURL& url, String title, bool withPlainText, bool withHTML)
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to