Reviewed by Adele and Tim Omernick.
authormjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 22 Jul 2006 05:31:07 +0000 (05:31 +0000)
committermjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 22 Jul 2006 05:31:07 +0000 (05:31 +0000)
        <rdar://problem/4641004> 9A224: Safari crashes in WebCore::RenderMenuList::showPopup when changing a input select field to input text field

        Couldn't figure out how to make layout test, here's a manual test:
        * manual-tests/remove-select-onchange.html: Added.

        * rendering/RenderMenuList.cpp:
        (WebCore::RenderMenuList::showPopup): Don't add the RenderPopupMenu to the render
        tree so it doesn't get destroyed if we do.

        The remaining changes are to let the RenderPopupMenu know its menu list w/o having
        to be in the render tree:

        * rendering/RenderPopupMenu.cpp:
        (WebCore::RenderPopupMenu::RenderPopupMenu):
        * rendering/RenderPopupMenu.h:
        (WebCore::RenderPopupMenu::menuList):
        * rendering/RenderPopupMenuMac.h:
        * rendering/RenderPopupMenuMac.mm:
        (WebCore::RenderPopupMenuMac::RenderPopupMenuMac):
        * rendering/RenderPopupMenuWin.h:
        (WebCore::RenderPopupMenuWin::RenderPopupMenuWin):
        * rendering/RenderTheme.h:
        * rendering/RenderThemeMac.h:
        * rendering/RenderThemeMac.mm:
        (WebCore::RenderThemeMac::createPopupMenu):
        * rendering/RenderThemeWin.cpp:
        (WebCore::RenderThemeWin::createPopupMenu):
        * rendering/RenderThemeWin.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@15571 268f45cc-cd09-0410-ab3c-d52691b4dbfc

13 files changed:
WebCore/ChangeLog
WebCore/manual-tests/remove-select-onchange.html [new file with mode: 0644]
WebCore/rendering/RenderMenuList.cpp
WebCore/rendering/RenderPopupMenu.cpp
WebCore/rendering/RenderPopupMenu.h
WebCore/rendering/RenderPopupMenuMac.h
WebCore/rendering/RenderPopupMenuMac.mm
WebCore/rendering/RenderPopupMenuWin.h
WebCore/rendering/RenderTheme.h
WebCore/rendering/RenderThemeMac.h
WebCore/rendering/RenderThemeMac.mm
WebCore/rendering/RenderThemeWin.cpp
WebCore/rendering/RenderThemeWin.h

index 591e7b95c58787869a22f3fe708b091ce4ef615a..4be3dc1fef0ec202ada66e24c0a8b804fe74ff87 100644 (file)
@@ -1,3 +1,36 @@
+2006-07-21  Maciej Stachowiak  <mjs@apple.com>
+
+        Reviewed by Adele and Tim Omernick.
+
+        <rdar://problem/4641004> 9A224: Safari crashes in WebCore::RenderMenuList::showPopup when changing a input select field to input text field
+
+        Couldn't figure out how to make layout test, here's a manual test:
+        * manual-tests/remove-select-onchange.html: Added.
+        
+        * rendering/RenderMenuList.cpp:
+        (WebCore::RenderMenuList::showPopup): Don't add the RenderPopupMenu to the render
+        tree so it doesn't get destroyed if we do.
+        
+        The remaining changes are to let the RenderPopupMenu know its menu list w/o having
+        to be in the render tree:
+        
+        * rendering/RenderPopupMenu.cpp:
+        (WebCore::RenderPopupMenu::RenderPopupMenu):
+        * rendering/RenderPopupMenu.h:
+        (WebCore::RenderPopupMenu::menuList):
+        * rendering/RenderPopupMenuMac.h:
+        * rendering/RenderPopupMenuMac.mm:
+        (WebCore::RenderPopupMenuMac::RenderPopupMenuMac):
+        * rendering/RenderPopupMenuWin.h:
+        (WebCore::RenderPopupMenuWin::RenderPopupMenuWin):
+        * rendering/RenderTheme.h:
+        * rendering/RenderThemeMac.h:
+        * rendering/RenderThemeMac.mm:
+        (WebCore::RenderThemeMac::createPopupMenu):
+        * rendering/RenderThemeWin.cpp:
+        (WebCore::RenderThemeWin::createPopupMenu):
+        * rendering/RenderThemeWin.h:
+
 2006-07-21  Adele Peterson  <adele@apple.com>
 
         Reviewed by Darin.
diff --git a/WebCore/manual-tests/remove-select-onchange.html b/WebCore/manual-tests/remove-select-onchange.html
new file mode 100644 (file)
index 0000000..51004b5
--- /dev/null
@@ -0,0 +1,9 @@
+<p>This test shouldn't crash when you pick something from select, even though it removes itself.
+</p>
+<select id="foo" onchange='sel.parentNode.removeChild(sel)'>
+<option>Boom</option>
+<option>Shouldn't crash when you pick this.</option>
+</select>
+<script>
+var sel = document.getElementById("foo");
+</script>
\ No newline at end of file
index b4280e802819774aa8d76dcad2e1c05c5229b75b..373829faea56f0204716970a85da6de031b0ff2a 100644 (file)
@@ -198,11 +198,10 @@ void RenderMenuList::showPopup()
     // This is important because otherwise we might try to create m_innerBlock
     // inside the showPopup call and it would fail.
     createInnerBlock();
-    RenderPopupMenu* menu = theme()->createPopupMenu(renderArena(), document());
+    RenderPopupMenu* menu = theme()->createPopupMenu(renderArena(), document(), this);
     RenderStyle* newStyle = new (renderArena()) RenderStyle;
     newStyle->inheritFrom(style());
     menu->setStyle(newStyle);
-    RenderFlexibleBox::addChild(menu);
     HTMLSelectElement* select = static_cast<HTMLSelectElement*>(node());
     menu->showPopup(absoluteBoundingBoxRect(), document()->view(),
         select->optionToListIndex(select->selectedIndex()));
index 0d58143b44e5521eb57ad590ec24d18ab990651e..80c69f34f4fd532eba51be623d23f9c248dd4ebb 100644 (file)
@@ -31,8 +31,9 @@ namespace WebCore {
 
 using namespace HTMLNames;
 
-RenderPopupMenu::RenderPopupMenu(Node* element)
+RenderPopupMenu::RenderPopupMenu(Node* element, RenderMenuList* menuList)
     : RenderBlock(element)
+    , m_menuList(menuList)
 {
 }
 
index cfeb2fcac21f97a8774c897b9e1e854e4daa0524..dc8f0e55659069dc9cf05d294f6869d630d16a60 100644 (file)
@@ -33,7 +33,7 @@ class HTMLOptGroupElement;
 
 class RenderPopupMenu : public RenderBlock {
 public:
-    RenderPopupMenu(Node*);
+    RenderPopupMenu(Node*, RenderMenuList* menuList);
     
     virtual const char* renderName() const { return "RenderPopupMenu"; }
 
@@ -41,12 +41,15 @@ public:
     virtual void populate();
     virtual void showPopup(const IntRect&, FrameView*, int index) = 0;
     
-    RenderMenuList* menuList() { return static_cast<RenderMenuList*>(parent() ? parent()->parent() : 0); }
+    RenderMenuList* menuList() { return m_menuList; }
 
 protected:
     virtual void addSeparator() = 0;
     virtual void addGroupLabel(HTMLOptGroupElement*) = 0;
     virtual void addOption(HTMLOptionElement*) = 0;
+
+ private:
+    RenderMenuList* m_menuList;
 };
 
 }
index ed4387c0c1babded10cde66907d400d4e7968769..498fb24588201858673ad2eaedb003049b56bdd1 100644 (file)
@@ -30,7 +30,7 @@ namespace WebCore {
 
 class RenderPopupMenuMac : public RenderPopupMenu {
 public:
-    RenderPopupMenuMac(Node*);
+    RenderPopupMenuMac(Node*, RenderMenuList*);
     ~RenderPopupMenuMac();
     
     virtual void clear();
@@ -48,4 +48,4 @@ protected:
 
 }
 
-#endif
\ No newline at end of file
+#endif
index 072bb3158dff449c8c953d848caf775a603181a7..dcbefa1dc0eb93d63ed80614f0b4e1f86424c349 100644 (file)
@@ -34,8 +34,8 @@ namespace WebCore {
 
 using namespace HTMLNames;
 
-RenderPopupMenuMac::RenderPopupMenuMac(Node* element)
-    : RenderPopupMenu(element)
+RenderPopupMenuMac::RenderPopupMenuMac(Node* element, RenderMenuList* menuList)
+    : RenderPopupMenu(element, menuList)
     , popup(nil)
 {
 }
index cb5ba996f2ed0a52ebf978b6d24a511f6d591e25..f75d66991c44ce6b0531dd8aebe2fe55d1460537 100644 (file)
@@ -32,7 +32,7 @@ class HTMLOptGroupElement;
 
 class RenderPopupMenuWin : public RenderPopupMenu {
 public:
-    RenderPopupMenuWin(Node* n) : RenderPopupMenu(n) {}
+    RenderPopupMenuWin(Node* n, RenderMenuList* m) : RenderPopupMenu(n, m) {}
     ~RenderPopupMenuWin();
 
     virtual void clear();
index 47da0a0e23b8f5730794e3d071dd775a40cdd34d..3ab582d78b808d4361adef5545f4b145f69cf55b 100644 (file)
@@ -29,6 +29,7 @@ namespace WebCore {
 
 class Element;
 class RenderPopupMenu;
+class RenderMenuList;
 
 enum ControlState { HoverState, PressedState, FocusState, EnabledState, CheckedState, ReadOnlyState };
 
@@ -101,7 +102,7 @@ public:
     virtual Color platformInactiveSelectionForegroundColor() const;
 
     virtual int minimumTextSize(RenderStyle*) const { return 0; }
-    virtual RenderPopupMenu* createPopupMenu(RenderArena*, Document*) = 0;
+    virtual RenderPopupMenu* createPopupMenu(RenderArena*, Document*, RenderMenuList*) = 0;
 
 protected:
     // Methods for state querying
index b04850ebb9c4af44d6083c2d12d76f25e0dced13..ae8fdc3b45af8cb1b94b41c688beb43be61a10e0 100644 (file)
@@ -57,7 +57,7 @@ public:
     virtual Color platformInactiveSelectionBackgroundColor() const;
     
     virtual int minimumTextSize(RenderStyle*) const;
-    virtual RenderPopupMenu* createPopupMenu(RenderArena*, Document*);
+    virtual RenderPopupMenu* createPopupMenu(RenderArena*, Document*, RenderMenuList*);
 
 protected:
     // Methods for each appearance value.
index a0f64c00a58a0b36c7b611308b62588b12225edc..fda0ce018fb68c543ffca3345f973fe7acb40bb2 100644 (file)
@@ -690,9 +690,9 @@ void RenderThemeMac::setPopupButtonCellState(const RenderObject* o, const IntRec
     updateFocusedState(popupButton, o);
 }
 
-RenderPopupMenu* RenderThemeMac::createPopupMenu(RenderArena* arena, Document* doc)
+RenderPopupMenu* RenderThemeMac::createPopupMenu(RenderArena* arena, Document* doc, RenderMenuList* menuList)
 {
-    return new (arena) RenderPopupMenuMac(doc);
+    return new (arena) RenderPopupMenuMac(doc, menuList);
 }
 
 int RenderThemeMac::minimumTextSize(RenderStyle* style) const
index 1ba702d7150b964e00533e2c5d1a5ffb00f93572..30bb39de24acaee00f0fae8c8f486a7ccba9883c 100644 (file)
@@ -359,9 +359,9 @@ bool RenderThemeWin::paintTextArea(RenderObject* o, const RenderObject::PaintInf
     return paintTextField(o, i, r);
 }
 
-RenderPopupMenu* RenderThemeWin::createPopupMenu(RenderArena* arena, Document* doc)
+RenderPopupMenu* RenderThemeWin::createPopupMenu(RenderArena* arena, Document* doc, RenderMenuList* menuList)
 {
-    return new (arena) RenderPopupMenuWin(doc);
+    return new (arena) RenderPopupMenuWin(doc, menuList);
 }
 
 }
index a30f13c8c21a28804cb197ef577baff6bb671c39..ec0af9b0f8f6421c7bb91edc6a21f2e633eaf8d6 100644 (file)
@@ -72,7 +72,7 @@ public:
 
     virtual bool paintMenuList(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
     virtual void adjustMenuListStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
-    virtual RenderPopupMenu* createPopupMenu(RenderArena*, Document*);
+    virtual RenderPopupMenu* createPopupMenu(RenderArena*, Document*, RenderMenuList*);
 
 private:
     void addIntrinsicMargins(RenderStyle*) const;
@@ -90,4 +90,4 @@ private:
 
 };
 
-#endif
\ No newline at end of file
+#endif