[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