[CSSRegions]Use RefPtr's instead of weak references on DOMNamedFlowCollection
https://bugs.webkit.org/show_bug.cgi?id=95311

Patch by Andrei Onea <onea@adobe.com> on 2012-09-12
Reviewed by Andreas Kling.

Source/WebCore:

Currently, DOMNamedFlowCollection holds a collection of raw pointers to WebKitNamedFlow.
This causes a crash when there is a JS instance of a NamedFlowCollection snapshot taken
before the NamedFlow is deleted, since the memory previously occupied by the NamedFlow
can be accessed. Because of this, we need to use RefPtr's for the snapshot, so that such
dangling references extend the lifetime of the NamedFlow objects.

Test: fast/regions/webkit-named-flow-collection-crash.html

* dom/DOMNamedFlowCollection.cpp:
(WebCore::DOMNamedFlowCollection::DOMNamedFlowCollection):
(WebCore::DOMNamedFlowCollection::item):
(WebCore::DOMNamedFlowCollection::namedItem):
(WebCore):
(WebCore::DOMNamedFlowCollection::DOMNamedFlowHashFunctions::hash):
(WebCore::DOMNamedFlowCollection::DOMNamedFlowHashFunctions::equal):
(DOMNamedFlowCollection::DOMNamedFlowHashFunctions):
(WebCore::DOMNamedFlowCollection::DOMNamedFlowHashTranslator::hash):
(WebCore::DOMNamedFlowCollection::DOMNamedFlowHashTranslator::equal):
Create new internal ListHashSet for RefPtr<WebKitNamedFlow>.
* dom/DOMNamedFlowCollection.h:
(WebCore::DOMNamedFlowCollection::create):
(DOMNamedFlowCollection):
* dom/NamedFlowCollection.cpp:
(WebCore::NamedFlowCollection::createCSSOMSnapshot):
(WebCore):
(WebCore::NamedFlowCollection::NamedFlowHashFunctions::hash):
(WebCore::NamedFlowCollection::NamedFlowHashFunctions::equal):
(NamedFlowCollection::NamedFlowHashFunctions):
(WebCore::NamedFlowCollection::NamedFlowHashTranslator::hash):
(WebCore::NamedFlowCollection::NamedFlowHashTranslator::equal):
Move back the definitions for NamedFlowHashFunctions and NamedFlowHashTranslator
to the .cpp file.
* dom/NamedFlowCollection.h:
(NamedFlowCollection):

LayoutTests:

Added test for crash which occurs when there is a raw pointer to a NamedFlow
(in a NamedFlowCollection) which has been freed.

* fast/regions/webkit-named-flow-collection-crash-expected.txt: Added.
* fast/regions/webkit-named-flow-collection-crash.html: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@128325 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/dom/NamedFlowCollection.cpp b/Source/WebCore/dom/NamedFlowCollection.cpp
index 5547506..4cbefe5 100644
--- a/Source/WebCore/dom/NamedFlowCollection.cpp
+++ b/Source/WebCore/dom/NamedFlowCollection.cpp
@@ -106,11 +106,25 @@
 }
 PassRefPtr<DOMNamedFlowCollection> NamedFlowCollection::createCSSOMSnapshot()
 {
-    NamedFlowSet createdFlows;
+    Vector<WebKitNamedFlow*> createdFlows;
     for (NamedFlowSet::iterator it = m_namedFlows.begin(); it != m_namedFlows.end(); ++it)
         if ((*it)->flowState() == WebKitNamedFlow::FlowStateCreated)
-            createdFlows.add(*it);
+            createdFlows.append(*it);
     return DOMNamedFlowCollection::create(createdFlows);
 }
 
+// The HashFunctions object used by the HashSet to compare between NamedFlows.
+// It is safe to set safeToCompareToEmptyOrDeleted because the HashSet will never contain null pointers or deleted values.
+struct NamedFlowCollection::NamedFlowHashFunctions {
+    static unsigned hash(WebKitNamedFlow* key) { return DefaultHash<String>::Hash::hash(key->name()); }
+    static bool equal(WebKitNamedFlow* a, WebKitNamedFlow* b) { return a->name() == b->name(); }
+    static const bool safeToCompareToEmptyOrDeleted = true;
+};
+
+// The HashTranslator is used to lookup a NamedFlow in the set using a name.
+struct NamedFlowCollection::NamedFlowHashTranslator {
+    static unsigned hash(const String& key) { return DefaultHash<String>::Hash::hash(key); }
+    static bool equal(WebKitNamedFlow* a, const String& b) { return a->name() == b; }
+};
+
 } // namespace WebCore