[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.21-584-g1e41756

ap at apple.com ap at apple.com
Fri Feb 26 22:17:10 UTC 2010


The following commit has been merged in the webkit-1.1 branch:
commit b86c03c027eaeaea38a5a201db25d1fff8aa7076
Author: ap at apple.com <ap at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Wed Feb 10 21:14:24 2010 +0000

            Reviewed by Geoffrey Garen.
    
            https://bugs.webkit.org/show_bug.cgi?id=34490
            WebCore::ImageEventSender::dispatchPendingEvents() crashes in certain conditions
    
            Test: fast/images/destroyed-image-load-event.html
    
            * ForwardingHeaders/wtf/ValueCheck.h: Added.
    
            * loader/ImageLoader.cpp:
            (WTF::ValueCheck): Special case value check for ImageLoader - it's allocated inside elements,
            so check the owner instead.
            (WebCore::ImageEventSender::hasPendingEvents): Added a debugging aid for ImageLoader destructor.
            (WebCore::ImageLoader::~ImageLoader): Assert that we're not going to leave dangling pointers
            in ImageEventSender.
            (WebCore::ImageLoader::setImage): Cancel events that could be dispatched for the previous
            image. The only client using this method that I could find was DeleteButton, which doesn't
            care about load events for the new image, so I didn't add any code for firing those.
            (WebCore::ImageLoader::setLoadingImage): This method only existed to confuse readers -
            there wasn't any meaningful code shared (callers just undid most assignments made there).
            Merged the logic into callers.
            (WebCore::ImageLoader::updateFromElement): We're forgetting the old image, so forget its
            old events, too.
            (WebCore::ImageLoader::notifyFinished): This can be called from setImage(), in which case
            no one is going to dispatch the event "soon". So, don't queue it.
            (WebCore::ImageEventSender::dispatchPendingEvents): Call checkConsistency(). This didn't
            help catch this particuar bug, but seems like a useful check anyway.
    
            * loader/ImageLoader.h: Removed setLoadingImage().
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@54618 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index fafceca..68354da 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,29 @@
+2010-02-09  Alexey Proskuryakov  <ap at apple.com>
+
+        Reviewed by Geoffrey Garen.
+
+        https://bugs.webkit.org/show_bug.cgi?id=34490
+        WebCore::ImageEventSender::dispatchPendingEvents() crashes in certain conditions
+
+        * GNUmakefile.am:
+        * JavaScriptCore.gypi:
+        * JavaScriptCore.vcproj/WTF/WTF.vcproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        Added ValueCheck.h.
+
+        * wtf/ValueCheck.h: Added. Moved code out of HashTraits, since it would be awkward to
+        include that from Vector.h.
+        (WTF::ValueCheck::checkConsistency): Allow null pointers, those are pretty consistent.
+
+        * wtf/HashTraits.h: Moved value checking code out of here.
+
+        * wtf/HashTable.h: (WTF::::checkTableConsistencyExceptSize): Updated for the above changes.
+
+        * wtf/Vector.h:
+        (WTF::::checkConsistency): Check all vector elements.
+        (WTF::ValueCheck): Support checking a Vector as an element in other containers. Currently
+        unused.
+
 2010-02-10  Jedrzej Nowacki  <jedrzej.nowacki at nokia.com>
 
         Reviewed by Simon Hausmann.
diff --git a/JavaScriptCore/GNUmakefile.am b/JavaScriptCore/GNUmakefile.am
index 278341a..4ac89d9 100644
--- a/JavaScriptCore/GNUmakefile.am
+++ b/JavaScriptCore/GNUmakefile.am
@@ -289,6 +289,7 @@ javascriptcore_sources += \
 	JavaScriptCore/wtf/TypeTraits.cpp \
 	JavaScriptCore/wtf/TypeTraits.h \
 	JavaScriptCore/wtf/UnusedParam.h \
+	JavaScriptCore/wtf/ValueCheck.h \
 	JavaScriptCore/wtf/Vector.h \
 	JavaScriptCore/wtf/VectorTraits.h \
 	JavaScriptCore/wtf/gtk/GOwnPtr.cpp \
diff --git a/JavaScriptCore/JavaScriptCore.gypi b/JavaScriptCore/JavaScriptCore.gypi
index 24577da..c67b6a8 100644
--- a/JavaScriptCore/JavaScriptCore.gypi
+++ b/JavaScriptCore/JavaScriptCore.gypi
@@ -441,6 +441,7 @@
             'wtf/unicode/UTF8.cpp',
             'wtf/unicode/UTF8.h',
             'wtf/UnusedParam.h',
+            'wtf/ValueCheck.h',
             'wtf/Vector.h',
             'wtf/VectorTraits.h',
             'wtf/VMTags.h',
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj b/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj
index 7a93632..c5b826c 100644
--- a/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj
+++ b/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj
@@ -545,6 +545,10 @@
 			>
 		</File>
 		<File
+			RelativePath="..\..\wtf\ValueCheck.h"
+			>
+		</File>
+		<File
 			RelativePath="..\..\wtf\Vector.h"
 			>
 		</File>
diff --git a/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
index b5ac555..5f904ce 100644
--- a/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
+++ b/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
@@ -475,6 +475,7 @@
 		E124A8F70E555775003091F1 /* OpaqueJSString.h in Headers */ = {isa = PBXBuildFile; fileRef = E124A8F50E555775003091F1 /* OpaqueJSString.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E124A8F80E555775003091F1 /* OpaqueJSString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E124A8F60E555775003091F1 /* OpaqueJSString.cpp */; };
 		E178636D0D9BEEC300D74E75 /* InitializeThreading.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E178636C0D9BEEC300D74E75 /* InitializeThreading.cpp */; };
+		E17FF771112131D200076A19 /* ValueCheck.h in Headers */ = {isa = PBXBuildFile; fileRef = E17FF770112131D200076A19 /* ValueCheck.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E18E3A590DF9278C00D90B34 /* JSGlobalData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E18E3A570DF9278C00D90B34 /* JSGlobalData.cpp */; };
 		E1A862A90D7EBB76001EC6AA /* CollatorICU.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1A862A80D7EBB76001EC6AA /* CollatorICU.cpp */; settings = {COMPILER_FLAGS = "-fno-strict-aliasing"; }; };
 		E1A862D60D7F2B5C001EC6AA /* CollatorDefault.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1A862D50D7F2B5C001EC6AA /* CollatorDefault.cpp */; };
@@ -979,6 +980,7 @@
 		E124A8F60E555775003091F1 /* OpaqueJSString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpaqueJSString.cpp; sourceTree = "<group>"; };
 		E178633F0D9BEC0000D74E75 /* InitializeThreading.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InitializeThreading.h; sourceTree = "<group>"; };
 		E178636C0D9BEEC300D74E75 /* InitializeThreading.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InitializeThreading.cpp; sourceTree = "<group>"; };
+		E17FF770112131D200076A19 /* ValueCheck.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValueCheck.h; sourceTree = "<group>"; };
 		E18E3A560DF9278C00D90B34 /* JSGlobalData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGlobalData.h; sourceTree = "<group>"; };
 		E18E3A570DF9278C00D90B34 /* JSGlobalData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSGlobalData.cpp; sourceTree = "<group>"; };
 		E195678F09E7CF1200B89D13 /* UnicodeIcu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnicodeIcu.h; sourceTree = "<group>"; };
@@ -1386,6 +1388,7 @@
 				0B330C260F38C62300692DE3 /* TypeTraits.cpp */,
 				0B4D7E620F319AC800AD7E58 /* TypeTraits.h */,
 				935AF46B09E9D9DB00ACD1D8 /* UnusedParam.h */,
+				E17FF770112131D200076A19 /* ValueCheck.h */,
 				6592C316098B7DE10003D4F6 /* Vector.h */,
 				6592C317098B7DE10003D4F6 /* VectorTraits.h */,
 				96DD73780F9DA3100027FBCC /* VMTags.h */,
@@ -2054,6 +2057,7 @@
 				1429DABF0ED263E700B89619 /* WRECParser.h in Headers */,
 				9688CB160ED12B4E001D649F /* X86Assembler.h in Headers */,
 				86E85539111B9968001AF51E /* JSStringBuilder.h in Headers */,
+				E17FF771112131D200076A19 /* ValueCheck.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
diff --git a/JavaScriptCore/wtf/HashTable.h b/JavaScriptCore/wtf/HashTable.h
index f1473e3..ceb8963 100644
--- a/JavaScriptCore/wtf/HashTable.h
+++ b/JavaScriptCore/wtf/HashTable.h
@@ -24,6 +24,7 @@
 
 #include "FastMalloc.h"
 #include "HashTraits.h"
+#include "ValueCheck.h"
 #include <wtf/Assertions.h>
 #include <wtf/Threading.h>
 
@@ -1021,7 +1022,7 @@ namespace WTF {
             ASSERT(entry == it.m_position);
             ++count;
 
-            KeyTraits::checkValueConsistency(it->first);
+            ValueCheck<Key>::checkConsistency(it->first);
         }
 
         ASSERT(count == m_keyCount);
diff --git a/JavaScriptCore/wtf/HashTraits.h b/JavaScriptCore/wtf/HashTraits.h
index 96ecac9..c8d40f7 100644
--- a/JavaScriptCore/wtf/HashTraits.h
+++ b/JavaScriptCore/wtf/HashTraits.h
@@ -26,13 +26,6 @@
 #include <utility>
 #include <limits>
 
-// For malloc_size and _msize.
-#if OS(DARWIN)
-#include <malloc/malloc.h>
-#elif COMPILER(MSVC)
-#include <malloc.h>
-#endif
-
 namespace WTF {
 
     using std::pair;
@@ -58,7 +51,6 @@ namespace WTF {
     template<typename T> struct GenericHashTraits : GenericHashTraitsBase<IsInteger<T>::value, T> {
         typedef T TraitType;
         static T emptyValue() { return T(); }
-        static void checkValueConsistency(const T&) { }
     };
 
     template<typename T> struct HashTraits : GenericHashTraits<T> { };
@@ -87,19 +79,6 @@ namespace WTF {
         static const bool needsDestruction = false;
         static void constructDeletedValue(P*& slot) { slot = reinterpret_cast<P*>(-1); }
         static bool isDeletedValue(P* value) { return value == reinterpret_cast<P*>(-1); }
-#if !ASSERT_DISABLED
-        static void checkValueConsistency(const P* p)
-        {
-#if (defined(USE_SYSTEM_MALLOC) && USE_SYSTEM_MALLOC) || !defined(NDEBUG)
-#if OS(DARWIN)
-            ASSERT(malloc_size(p));
-#elif COMPILER(MSVC)
-            ASSERT(_msize(const_cast<P*>(p)));
-#endif
-#endif
-            HashTraits<P>::checkValueConsistency(*p);
-        }
-#endif
     };
 
     template<typename P> struct HashTraits<RefPtr<P> > : GenericHashTraits<RefPtr<P> > {
diff --git a/JavaScriptCore/wtf/ValueCheck.h b/JavaScriptCore/wtf/ValueCheck.h
new file mode 100644
index 0000000..2ab6925
--- /dev/null
+++ b/JavaScriptCore/wtf/ValueCheck.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef ValueTraits_h
+#define ValueTraits_h
+
+// For malloc_size and _msize.
+#if OS(DARWIN)
+#include <malloc/malloc.h>
+#elif COMPILER(MSVC)
+#include <malloc.h>
+#endif
+
+namespace WTF {
+
+template<typename T> struct ValueCheck {
+    typedef T TraitType;
+    static void checkConsistency(const T&) { }
+};
+
+#if !ASSERT_DISABLED
+template<typename P> struct ValueCheck<P*> {
+    typedef P* TraitType;
+    static void checkConsistency(const P* p)
+    {
+        if (!p)
+            return;
+#if (defined(USE_SYSTEM_MALLOC) && USE_SYSTEM_MALLOC) || !defined(NDEBUG)
+#if OS(DARWIN)
+        ASSERT(malloc_size(p));
+#elif COMPILER(MSVC)
+        ASSERT(_msize(const_cast<P*>(p)));
+#endif
+#endif
+        ValueCheck<P>::checkConsistency(*p);
+    }
+};
+#endif
+
+}
+
+#endif // ValueTraits_h
diff --git a/JavaScriptCore/wtf/Vector.h b/JavaScriptCore/wtf/Vector.h
index decc9c9..ad0e5d7 100644
--- a/JavaScriptCore/wtf/Vector.h
+++ b/JavaScriptCore/wtf/Vector.h
@@ -24,6 +24,7 @@
 #include "FastAllocBase.h"
 #include "Noncopyable.h"
 #include "NotFound.h"
+#include "ValueCheck.h"
 #include "VectorTraits.h"
 #include <limits>
 #include <utility>
@@ -586,6 +587,8 @@ namespace WTF {
             m_buffer.swap(other.m_buffer);
         }
 
+        void checkConsistency();
+
     private:
         void expandCapacity(size_t newMinCapacity);
         const T* expandCapacity(size_t newMinCapacity, const T*);
@@ -987,6 +990,16 @@ namespace WTF {
     }
 
     template<typename T, size_t inlineCapacity>
+    inline void Vector<T, inlineCapacity>::checkConsistency()
+    {
+#if !ASSERT_DISABLED
+        for (size_t i = 0; i < size(); ++i) {
+            ValueCheck<T>::checkConsistency(at(i));
+        }
+#endif
+    }
+
+    template<typename T, size_t inlineCapacity>
     void deleteAllValues(const Vector<T, inlineCapacity>& collection)
     {
         typedef typename Vector<T, inlineCapacity>::const_iterator iterator;
@@ -1016,6 +1029,15 @@ namespace WTF {
         return !(a == b);
     }
 
+#if !ASSERT_DISABLED
+    template<typename T> struct ValueCheck<Vector<T> > {
+        typedef Vector<T> TraitType;
+        static void checkConsistency(const Vector<T>& v)
+        {
+            v.checkConsistency();
+        }
+    };
+#endif
 
 } // namespace WTF
 
diff --git a/JavaScriptGlue/ChangeLog b/JavaScriptGlue/ChangeLog
index 4f00b0a..df8b3ec 100644
--- a/JavaScriptGlue/ChangeLog
+++ b/JavaScriptGlue/ChangeLog
@@ -1,3 +1,12 @@
+2010-02-09  Alexey Proskuryakov  <ap at apple.com>
+
+        Reviewed by Geoffrey Garen.
+
+        https://bugs.webkit.org/show_bug.cgi?id=34490
+        WebCore::ImageEventSender::dispatchPendingEvents() crashes in certain conditions
+
+        * ForwardingHeaders/wtf/ValueCheck.h: Added.
+
 2010-02-04  Mark Rowe  <mrowe at apple.com>
 
         Reviewed by Timothy Hatcher.
diff --git a/JavaScriptGlue/ForwardingHeaders/wtf/ValueCheck.h b/JavaScriptGlue/ForwardingHeaders/wtf/ValueCheck.h
new file mode 100644
index 0000000..904b15d
--- /dev/null
+++ b/JavaScriptGlue/ForwardingHeaders/wtf/ValueCheck.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/ValueCheck.h>
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index d2bf0fa..1e1f0f8 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,13 @@
+2010-02-09  Alexey Proskuryakov  <ap at apple.com>
+
+        Reviewed by Geoffrey Garen.
+
+        https://bugs.webkit.org/show_bug.cgi?id=34490
+        WebCore::ImageEventSender::dispatchPendingEvents() crashes in certain conditions
+
+        * fast/images/destroyed-image-load-event-expected.txt: Added.
+        * fast/images/destroyed-image-load-event.html: Added.
+
 2010-02-08  Jon Honeycutt  <jhoneycutt at apple.com>
 
         <rdar://problem/7436875> Crash in Flash when visiting
diff --git a/LayoutTests/fast/images/destroyed-image-load-event-expected.txt b/LayoutTests/fast/images/destroyed-image-load-event-expected.txt
new file mode 100644
index 0000000..ec05c97
--- /dev/null
+++ b/LayoutTests/fast/images/destroyed-image-load-event-expected.txt
@@ -0,0 +1,4 @@
+Test for bug 34490: WebCore::ImageEventSender::dispatchPendingEvents() crashes in certain conditions.
+
+PASS
+
diff --git a/LayoutTests/fast/images/destroyed-image-load-event.html b/LayoutTests/fast/images/destroyed-image-load-event.html
new file mode 100644
index 0000000..a4ad997
--- /dev/null
+++ b/LayoutTests/fast/images/destroyed-image-load-event.html
@@ -0,0 +1,55 @@
+<body onload="test()">
+<p>Test for <a href="https://bugs.webkit.org/show_bug.cgi?id=34490">bug 34490<a/>:
+WebCore::ImageEventSender::dispatchPendingEvents() crashes in certain conditions.</p>
+<div id="testRun"></div>
+<div id="container"></div>
+<script>
+if (window.layoutTestController) {
+    layoutTestController.waitUntilDone();
+    layoutTestController.dumpAsText();
+}
+
+function gc()
+{
+    if (window.GCController)
+        return GCController.collect();
+
+    for (var i = 0; i < 10000; i++) { // > force garbage collection (FF requires about 9K allocations before a collect)
+        var s = new String("abc");
+    }
+}
+
+var container = document.getElementById("container");
+var testRunDiv = document.getElementById("testRun");
+var remainingTestRuns = 30;
+
+function test()
+{
+    testRunDiv.innerHTML = remainingTestRuns;
+
+    if (--remainingTestRuns < 0) {
+        testRunDiv.innerHTML = "PASS";
+        if (window.layoutTestController)
+            layoutTestController.notifyDone();
+        return;
+    }
+
+    container.innerHTML = '<img src="resources/boston.gif" onload="loaded1()">' +
+        '<img src="resources/boston.gif" onload="loaded2()">';
+}
+
+function loaded1()
+{
+    var img2 = document.getElementsByTagName("img")[1];
+    img2.src = "";
+    container.removeChild(img2);
+    img2 = null;
+    gc();
+    setTimeout(test, 0);
+}
+
+function loaded2()
+{
+}
+</script>
+</body>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 00291ed..9ea9bef 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,35 @@
+2010-02-09  Alexey Proskuryakov  <ap at apple.com>
+
+        Reviewed by Geoffrey Garen.
+
+        https://bugs.webkit.org/show_bug.cgi?id=34490
+        WebCore::ImageEventSender::dispatchPendingEvents() crashes in certain conditions
+
+        Test: fast/images/destroyed-image-load-event.html
+
+        * ForwardingHeaders/wtf/ValueCheck.h: Added.
+
+        * loader/ImageLoader.cpp:
+        (WTF::ValueCheck): Special case value check for ImageLoader - it's allocated inside elements,
+        so check the owner instead.
+        (WebCore::ImageEventSender::hasPendingEvents): Added a debugging aid for ImageLoader destructor.
+        (WebCore::ImageLoader::~ImageLoader): Assert that we're not going to leave dangling pointers
+        in ImageEventSender.
+        (WebCore::ImageLoader::setImage): Cancel events that could be dispatched for the previous
+        image. The only client using this method that I could find was DeleteButton, which doesn't
+        care about load events for the new image, so I didn't add any code for firing those.
+        (WebCore::ImageLoader::setLoadingImage): This method only existed to confuse readers -
+        there wasn't any meaningful code shared (callers just undid most assignments made there).
+        Merged the logic into callers.
+        (WebCore::ImageLoader::updateFromElement): We're forgetting the old image, so forget its
+        old events, too.
+        (WebCore::ImageLoader::notifyFinished): This can be called from setImage(), in which case
+        no one is going to dispatch the event "soon". So, don't queue it.
+        (WebCore::ImageEventSender::dispatchPendingEvents): Call checkConsistency(). This didn't
+        help catch this particuar bug, but seems like a useful check anyway.
+
+        * loader/ImageLoader.h: Removed setLoadingImage().
+
 2010-02-10  Jon Honeycutt  <jhoneycutt at apple.com>
 
         Mac build fix. Unreviewed.
diff --git a/WebCore/ForwardingHeaders/wtf/ValueCheck.h b/WebCore/ForwardingHeaders/wtf/ValueCheck.h
new file mode 100644
index 0000000..4667674
--- /dev/null
+++ b/WebCore/ForwardingHeaders/wtf/ValueCheck.h
@@ -0,0 +1,4 @@
+#ifndef WebCore_FWD_ValueCheck_h
+#define WebCore_FWD_ValueCheck_h
+#include <JavaScriptCore/ValueCheck.h>
+#endif
diff --git a/WebCore/loader/ImageLoader.cpp b/WebCore/loader/ImageLoader.cpp
index 9c237cd..c61d133 100644
--- a/WebCore/loader/ImageLoader.cpp
+++ b/WebCore/loader/ImageLoader.cpp
@@ -29,6 +29,24 @@
 #include "Element.h"
 #include "RenderImage.h"
 
+#if !ASSERT_DISABLED
+// ImageLoader objects are allocated as members of other objects, so generic pointer check would always fail.
+namespace WTF {
+
+template<> struct ValueCheck<WebCore::ImageLoader*> {
+    typedef WebCore::ImageLoader* TraitType;
+    static void checkConsistency(const WebCore::ImageLoader* p)
+    {
+        if (!p)
+            return;
+        ASSERT(p->element());
+        ValueCheck<WebCore::Element*>::checkConsistency(p->element());
+    }
+};
+
+}
+#endif
+
 namespace WebCore {
 
 class ImageEventSender : public Noncopyable {
@@ -40,6 +58,10 @@ public:
 
     void dispatchPendingEvents();
 
+#if !ASSERT_DISABLED
+    bool hasPendingEvents(ImageLoader* loader) { return m_dispatchSoonList.find(loader) != notFound; }
+#endif
+
 private:
     void timerFired(Timer<ImageEventSender>*);
 
@@ -75,8 +97,12 @@ ImageLoader::~ImageLoader()
 {
     if (m_image)
         m_image->removeClient(this);
+
+    ASSERT(!m_firedBeforeLoad || !beforeLoadEventSender().hasPendingEvents(this));
     if (!m_firedBeforeLoad)
         beforeLoadEventSender().cancelEvent(this);
+
+    ASSERT(!m_firedLoad || !loadEventSender().hasPendingEvents(this));
     if (!m_firedLoad)
         loadEventSender().cancelEvent(this);
 }
@@ -86,9 +112,15 @@ void ImageLoader::setImage(CachedImage* newImage)
     ASSERT(m_failedLoadURL.isEmpty());
     CachedImage* oldImage = m_image.get();
     if (newImage != oldImage) {
-        setLoadingImage(newImage);
-        m_firedBeforeLoad = true;
-        m_firedLoad = true;
+        m_image = newImage;
+        if (!m_firedBeforeLoad) {
+            beforeLoadEventSender().cancelEvent(this);
+            m_firedBeforeLoad = true;
+        }
+        if (!m_firedLoad) {
+            loadEventSender().cancelEvent(this);
+            m_firedLoad = true;
+        }
         m_imageComplete = true;
         if (newImage)
             newImage->addClient(this);
@@ -103,14 +135,6 @@ void ImageLoader::setImage(CachedImage* newImage)
     }
 }
 
-void ImageLoader::setLoadingImage(CachedImage* loadingImage)
-{
-    m_image = loadingImage;
-    m_firedBeforeLoad = !loadingImage;
-    m_firedLoad = !loadingImage;
-    m_imageComplete = !loadingImage;
-}
-
 void ImageLoader::updateFromElement()
 {
     // If we're not making renderers for the page, then don't load images.  We don't want to slow
@@ -146,7 +170,16 @@ void ImageLoader::updateFromElement()
     
     CachedImage* oldImage = m_image.get();
     if (newImage != oldImage) {
-        setLoadingImage(newImage);
+        if (!m_firedBeforeLoad)
+            beforeLoadEventSender().cancelEvent(this);
+        if (!m_firedLoad)
+            loadEventSender().cancelEvent(this);
+
+        m_image = newImage;
+        m_firedBeforeLoad = !newImage;
+        m_firedLoad = !newImage;
+        m_imageComplete = !newImage;
+
         if (newImage) {
             newImage->addClient(this);
             if (!m_element->document()->hasListenerType(Document::BEFORELOAD_LISTENER))
@@ -180,6 +213,9 @@ void ImageLoader::notifyFinished(CachedResource*)
     if (haveFiredBeforeLoadEvent())
         updateRenderer();
 
+    if (m_firedLoad)
+        return;
+
     loadEventSender().dispatchEventSoon(this);
 }
 
@@ -282,6 +318,8 @@ void ImageEventSender::dispatchPendingEvents()
 
     m_timer.stop();
 
+    m_dispatchSoonList.checkConsistency();
+
     m_dispatchingList.swap(m_dispatchSoonList);
     size_t size = m_dispatchingList.size();
     for (size_t i = 0; i < size; ++i) {
diff --git a/WebCore/loader/ImageLoader.h b/WebCore/loader/ImageLoader.h
index e7463d5..44fe98e 100644
--- a/WebCore/loader/ImageLoader.h
+++ b/WebCore/loader/ImageLoader.h
@@ -49,7 +49,7 @@ public:
     bool imageComplete() const { return m_imageComplete; }
 
     CachedImage* image() const { return m_image.get(); }
-    void setImage(CachedImage*);
+    void setImage(CachedImage*); // Cancels pending beforeload and load events, and doesn't dispatch new ones.
 
     void setLoadManually(bool loadManually) { m_loadManually = loadManually; }
 
@@ -70,8 +70,6 @@ private:
     void dispatchPendingBeforeLoadEvent();
     void dispatchPendingLoadEvent();
 
-    void setLoadingImage(CachedImage*);
-
     void updateRenderer();
 
     Element* m_element;
diff --git a/WebKit/mac/ChangeLog b/WebKit/mac/ChangeLog
index e9fe585..ec77e77 100644
--- a/WebKit/mac/ChangeLog
+++ b/WebKit/mac/ChangeLog
@@ -1,3 +1,12 @@
+2010-02-09  Alexey Proskuryakov  <ap at apple.com>
+
+        Reviewed by Geoffrey Garen.
+
+        https://bugs.webkit.org/show_bug.cgi?id=34490
+        WebCore::ImageEventSender::dispatchPendingEvents() crashes in certain conditions
+
+        * ForwardingHeaders/wtf/ValueCheck.h: Added.
+
 2010-02-10  Jesus Sanchez-Palencia  <jesus.palencia at openbossa.org>
 
         Reviewed by Kenneth Rohde Christiansen.
diff --git a/WebKit/mac/ForwardingHeaders/wtf/ValueCheck.h b/WebKit/mac/ForwardingHeaders/wtf/ValueCheck.h
new file mode 100644
index 0000000..7a067ff
--- /dev/null
+++ b/WebKit/mac/ForwardingHeaders/wtf/ValueCheck.h
@@ -0,0 +1 @@
+#import <JavaScriptCore/ValueCheck.h>

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list