[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.19-706-ge5415e9

bweinstein at apple.com bweinstein at apple.com
Thu Feb 4 21:28:22 UTC 2010


The following commit has been merged in the webkit-1.1 branch:
commit a50eb0666b174d979e2760d66d279be49419fd80
Author: bweinstein at apple.com <bweinstein at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Tue Jan 26 22:45:38 2010 +0000

    Crash in WebKit!WebCore::RenderMenuList::itemStyle
    https://bugs.webkit.org/show_bug.cgi?id=34182
    <rdar://7087757>
    
    Reviewed by Jon Honeycutt.
    
    Added bounds checks in RenderMenuList to make sure we are
    not making an out of bounds check in a vector once an option
    element has been deleted. If we are out of bounds, we fall back to
    a default value and return early, and in the case of itemStyle, we use a
    previous option's style, if it is available.
    
    * manual-tests/select-delete-item.html: Added.
    * rendering/RenderMenuList.cpp:
    (WebCore::RenderMenuList::itemText): If out of bounds check, return early.
    (WebCore::RenderMenuList::itemToolTip): Ditto.
    (WebCore::RenderMenuList::itemIsEnabled): Ditto.
    (WebCore::RenderMenuList::itemStyle): If out of bounds check, try using the 0th index
        option style, then fall back to the select's style if that option doesn't exist.
    (WebCore::RenderMenuList::itemBackgroundColor): If out of bounds check, return early.
    (WebCore::RenderMenuList::itemIsSeparator): Ditto.
    (WebCore::RenderMenuList::itemIsLabel): Ditto.
    (WebCore::RenderMenuList::itemIsSelected): Ditto.
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@53867 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 1db5c9e..c972ac4 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,29 @@
+2010-01-26  Brian Weinstein  <bweinstein at apple.com>
+
+        Reviewed by Jon Honeycutt.
+
+        Crash in WebKit!WebCore::RenderMenuList::itemStyle
+        https://bugs.webkit.org/show_bug.cgi?id=34182
+        <rdar://7087757>
+        
+        Added bounds checks in RenderMenuList to make sure we are
+        not making an out of bounds check in a vector once an option
+        element has been deleted. If we are out of bounds, we fall back to
+        a default value and return early, and in the case of itemStyle, we use a 
+        previous option's style, if it is available.
+
+        * manual-tests/select-delete-item.html: Added.
+        * rendering/RenderMenuList.cpp:
+        (WebCore::RenderMenuList::itemText): If out of bounds check, return early.
+        (WebCore::RenderMenuList::itemToolTip): Ditto.
+        (WebCore::RenderMenuList::itemIsEnabled): Ditto.
+        (WebCore::RenderMenuList::itemStyle): If out of bounds check, try using the 0th index
+            option style, then fall back to the select's style if that option doesn't exist.
+        (WebCore::RenderMenuList::itemBackgroundColor): If out of bounds check, return early.
+        (WebCore::RenderMenuList::itemIsSeparator): Ditto.
+        (WebCore::RenderMenuList::itemIsLabel): Ditto.
+        (WebCore::RenderMenuList::itemIsSelected): Ditto.
+
 2010-01-25  Gavin Barraclough  <barraclough at apple.com>
 
         Reviewed by Anders Carlsson.
diff --git a/WebCore/manual-tests/select-delete-item.html b/WebCore/manual-tests/select-delete-item.html
new file mode 100644
index 0000000..43ca0c3
--- /dev/null
+++ b/WebCore/manual-tests/select-delete-item.html
@@ -0,0 +1,21 @@
+<html>
+<head>
+    <title>RenderMenuList::itemStyle Select Element Crash</title>
+    <script>
+        function removeItem() {
+            var select = document.getElementById("dropDown");
+            select.removeChild(document.getElementsByTagName("option")[2]);
+        }
+    </script>
+</head>
+<body>
+    <select id="dropDown" onfocus="setTimeout('removeItem();', 2000);">
+        <option>Option 1</option>
+        <option>Option 2</option>
+        <option>Option 3</option>
+    </select>
+    <p>This is a test for bug <a href="http://webkit.org/b/34182">34182</a> Crash in WebKit!WebCore::RenderMenuList::itemStyle.
+    Once the select gets focus, in 2 seconds it will delete an item. This test passes
+    if you have the select open when it deletes an item, and doesn't crash.</p>
+</body>
+</html>
diff --git a/WebCore/rendering/RenderMenuList.cpp b/WebCore/rendering/RenderMenuList.cpp
index bea250d..05a9873 100644
--- a/WebCore/rendering/RenderMenuList.cpp
+++ b/WebCore/rendering/RenderMenuList.cpp
@@ -323,7 +323,10 @@ void RenderMenuList::didSetSelectedIndex()
 String RenderMenuList::itemText(unsigned listIndex) const
 {
     SelectElement* select = toSelectElement(static_cast<Element*>(node()));
-    Element* element = select->listItems()[listIndex];
+    const Vector<Element*>& listItems = select->listItems();
+    if (listIndex >= listItems.size())
+        return String();
+    Element* element = listItems[listIndex];
     if (OptionGroupElement* optionGroupElement = toOptionGroupElement(element))
         return optionGroupElement->groupLabelText();
     else if (OptionElement* optionElement = toOptionElement(element))
@@ -334,14 +337,20 @@ String RenderMenuList::itemText(unsigned listIndex) const
 String RenderMenuList::itemToolTip(unsigned listIndex) const
 {
     SelectElement* select = toSelectElement(static_cast<Element*>(node()));
-    Element* element = select->listItems()[listIndex];
+    const Vector<Element*>& listItems = select->listItems();
+    if (listIndex >= listItems.size())
+        return String();
+    Element* element = listItems[listIndex];
     return element->title();
 }
 
 bool RenderMenuList::itemIsEnabled(unsigned listIndex) const
 {
     SelectElement* select = toSelectElement(static_cast<Element*>(node()));
-    Element* element = select->listItems()[listIndex];
+    const Vector<Element*>& listItems = select->listItems();
+    if (listIndex >= listItems.size())
+        return false;
+    Element* element = listItems[listIndex];
     if (!isOptionElement(element))
         return false;
 
@@ -359,7 +368,18 @@ bool RenderMenuList::itemIsEnabled(unsigned listIndex) const
 PopupMenuStyle RenderMenuList::itemStyle(unsigned listIndex) const
 {
     SelectElement* select = toSelectElement(static_cast<Element*>(node()));
-    Element* element = select->listItems()[listIndex];
+    const Vector<Element*>& listItems = select->listItems();
+    if (listIndex >= listItems.size()) {
+        // If we are making an out of bounds access, then we want to use the style
+        // of a different option element (index 0). However, if there isn't an option element
+        // before at index 0, we fall back to the menu's style.
+        if (!listIndex)
+            return menuStyle();
+
+        // Try to retrieve the style of an option element we know exists (index 0).
+        listIndex = 0;
+    }
+    Element* element = listItems[listIndex];
     
     RenderStyle* style = element->renderStyle() ? element->renderStyle() : element->computedStyle();
     return style ? PopupMenuStyle(style->color(), itemBackgroundColor(listIndex), style->font(), style->visibility() == VISIBLE, style->textIndent(), style->direction()) : menuStyle();
@@ -368,7 +388,10 @@ PopupMenuStyle RenderMenuList::itemStyle(unsigned listIndex) const
 Color RenderMenuList::itemBackgroundColor(unsigned listIndex) const
 {
     SelectElement* select = toSelectElement(static_cast<Element*>(node()));
-    Element* element = select->listItems()[listIndex];
+    const Vector<Element*>& listItems = select->listItems();
+    if (listIndex >= listItems.size())
+        return style()->backgroundColor();
+    Element* element = listItems[listIndex];
 
     Color backgroundColor;
     if (element->renderStyle())
@@ -459,21 +482,30 @@ void RenderMenuList::popupDidHide()
 bool RenderMenuList::itemIsSeparator(unsigned listIndex) const
 {
     SelectElement* select = toSelectElement(static_cast<Element*>(node()));
-    Element* element = select->listItems()[listIndex];
+    const Vector<Element*>& listItems = select->listItems();
+    if (listIndex >= listItems.size())
+        return false;
+    Element* element = listItems[listIndex];
     return element->hasTagName(hrTag);
 }
 
 bool RenderMenuList::itemIsLabel(unsigned listIndex) const
 {
     SelectElement* select = toSelectElement(static_cast<Element*>(node()));
-    Element* element = select->listItems()[listIndex];
+    const Vector<Element*>& listItems = select->listItems();
+    if (listIndex >= listItems.size())
+        return false;
+    Element* element = listItems[listIndex];
     return isOptionGroupElement(element);
 }
 
 bool RenderMenuList::itemIsSelected(unsigned listIndex) const
 {
     SelectElement* select = toSelectElement(static_cast<Element*>(node()));
-    Element* element = select->listItems()[listIndex];
+    const Vector<Element*>& listItems = select->listItems();
+    if (listIndex >= listItems.size())
+        return false;
+    Element* element = listItems[listIndex];
     if (OptionElement* optionElement = toOptionElement(element))
         return optionElement->selected();
     return false;

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list