Changeset 21447 in webkit


Ignore:
Timestamp:
May 13, 2007 8:28:01 AM (17 years ago)
Author:
beidson
Message:

Reviewed by Mitz

http://bugs.webkit.org/show_bug.cgi?id=13701

Since HTMLInputElements register themselves with their Document for special handling, if their document
ever changes then bad things can happen.

Unfortunately, with adoptNode, the document can change. This has been a long standing crasher with all
input fields but was given recent high visibility by r21430

The solution is to add functionality for a Node to react to its owner document changing via a pair of
virtual callbacks. Then we can tap into those callbacks in HTMLInputElement.

No layout test possible until http://bugs.webkit.org/show_bug.cgi?id=13672 is resolved

  • dom/Node.cpp: (WebCore::Node::setDocument): Call willMoveToNewOwnerDocument and didMoveToNewOwnerDocument
  • dom/Node.h: (WebCore::Node::willMoveToNewOwnerDocument): Virtual callback to a node for before an owner document change (WebCore::Node::didMoveToNewOwnerDocument): Virtual callback to a node for after an owner document change
  • html/HTMLInputElement.cpp: (WebCore::HTMLInputElement::~HTMLInputElement): Unconditionally unregister both for both form state and the cache restoration callback (WebCore::HTMLInputElement::setInputType): Change registration with the document only if we're in one (WebCore::HTMLInputElement::attach): Don't bother registering for the callback here - that will be handled by setInputType() or by a change in owner document (WebCore::HTMLInputElement::willMoveToNewOwnerDocument): Unregister with the old owner document (WebCore::HTMLInputElement::didMoveToNewOwnerDocument): Register with the new owner document
  • html/HTMLInputElement.h:
Location:
trunk/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r21446 r21447  
     12007-05-13  Brady Eidson  <beidson@apple.com>
     2
     3        Reviewed by Mitz
     4
     5        http://bugs.webkit.org/show_bug.cgi?id=13701
     6
     7        Since HTMLInputElements register themselves with their Document for special handling, if their document
     8        ever changes then bad things can happen.
     9
     10        Unfortunately, with adoptNode, the document can change.  This has been a long standing crasher with all
     11        input fields but was given recent high visibility by r21430
     12
     13        The solution is to add functionality for a Node to react to its owner document changing via a pair of
     14        virtual callbacks.  Then we can tap into those callbacks in HTMLInputElement.
     15
     16        No layout test possible until http://bugs.webkit.org/show_bug.cgi?id=13672 is resolved
     17
     18        * dom/Node.cpp:
     19        (WebCore::Node::setDocument): Call willMoveToNewOwnerDocument and didMoveToNewOwnerDocument
     20
     21        * dom/Node.h:
     22        (WebCore::Node::willMoveToNewOwnerDocument): Virtual callback to a node for before an owner document change
     23        (WebCore::Node::didMoveToNewOwnerDocument): Virtual callback to a node for after an owner document change
     24
     25        * html/HTMLInputElement.cpp:
     26        (WebCore::HTMLInputElement::~HTMLInputElement): Unconditionally unregister both for both form state
     27          and the cache restoration callback
     28        (WebCore::HTMLInputElement::setInputType): Change registration with the document only if we're in one
     29        (WebCore::HTMLInputElement::attach): Don't bother registering for the callback here - that will be
     30          handled by setInputType() or by a change in owner document
     31        (WebCore::HTMLInputElement::willMoveToNewOwnerDocument): Unregister with the old owner document
     32        (WebCore::HTMLInputElement::didMoveToNewOwnerDocument): Register with the new owner document
     33        * html/HTMLInputElement.h:
     34
    1352007-05-13  Darin Adler  <darin@apple.com>
    236
  • trunk/WebCore/dom/Node.cpp

    r21405 r21447  
    169169        return;
    170170
     171    willMoveToNewOwnerDocument();
     172
    171173    {
    172174        KJS::JSLock lock;
    173175        KJS::ScriptInterpreter::updateDOMNodeDocument(this, m_document.get(), doc);
    174     }
     176    }   
    175177    m_document = doc;
     178
     179    didMoveToNewOwnerDocument();
    176180}
    177181
  • trunk/WebCore/dom/Node.h

    r21278 r21447  
    456456
    457457protected:
     458    virtual void willMoveToNewOwnerDocument() { }
     459    virtual void didMoveToNewOwnerDocument() { }
     460   
    458461    NodeListsNodeData* m_nodeLists;
    459462
  • trunk/WebCore/html/HTMLInputElement.cpp

    r21445 r21447  
    137137HTMLInputElement::~HTMLInputElement()
    138138{
    139     document()->unregisterFormElementWithState(this);
    140     document()->unregisterForDidRestoreFromCacheCallback(this);
     139    ownerDocument()->unregisterFormElementWithState(this);
     140    ownerDocument()->unregisterForDidRestoreFromCacheCallback(this);
    141141    delete m_imageLoader;
    142142}
     
    324324
    325325            if (wasPasswordField && !isPasswordField) {
    326                 document()->registerFormElementWithState(this);
    327                 document()->unregisterForDidRestoreFromCacheCallback(this);
     326                ownerDocument()->registerFormElementWithState(this);
     327                ownerDocument()->unregisterForDidRestoreFromCacheCallback(this);
    328328            } else if (!wasPasswordField && isPasswordField) {
    329                 document()->unregisterFormElementWithState(this);
    330                 document()->registerForDidRestoreFromCacheCallback(this);
     329                ownerDocument()->unregisterFormElementWithState(this);
     330                ownerDocument()->registerForDidRestoreFromCacheCallback(this);
    331331            }
    332332
     
    762762        }
    763763    }
    764 
    765     if (inputType() == PASSWORD)
    766         document()->registerForDidRestoreFromCacheCallback(this);
    767764}
    768765
     
    14791476    reset();
    14801477}
     1478
     1479void HTMLInputElement::willMoveToNewOwnerDocument()
     1480{
     1481    if (inputType() == PASSWORD)
     1482        ownerDocument()->unregisterForDidRestoreFromCacheCallback(this);
     1483    else
     1484        ownerDocument()->unregisterFormElementWithState(this);
     1485       
     1486    HTMLGenericFormElement::willMoveToNewOwnerDocument();
     1487}
     1488
     1489void HTMLInputElement::didMoveToNewOwnerDocument()
     1490{
     1491    if (inputType() == PASSWORD)
     1492        document()->registerForDidRestoreFromCacheCallback(this);
     1493    else
     1494        document()->registerFormElementWithState(this);
     1495       
     1496    HTMLGenericFormElement::didMoveToNewOwnerDocument();
     1497}
    14811498   
    14821499} // namespace
  • trunk/WebCore/html/HTMLInputElement.h

    r21430 r21447  
    187187   
    188188protected:
     189    virtual void willMoveToNewOwnerDocument();
     190    virtual void didMoveToNewOwnerDocument();
     191   
    189192    AtomicString m_name;
    190193
Note: See TracChangeset for help on using the changeset viewer.