• ch.dumez@samsung.com's avatar
    Do not fire a DOMSubtreeModified event when Attr.value attribute is set · 9ba82696
    ch.dumez@samsung.com authored
    Do not fire a DOMSubtreeModified event when Attr.value attribute is set. This
    event is deprecated and both Firefox 31 and IE 11 do not fire it in this case.
    
    Firing a DOMSubtreeModified event is problematic because it is synchronous and
    it can lead to calling Attr::setValueInternal() recursively if the JS callback
    sets Attr.value again. This can lead to serious problems as setValueInternal()
    calls:
    1. Element::willModifyAttribute(oldValue, newValue)
    2. Attr::setValue(newValue);
    3. Element::didModifyAttribute(newValue)
    
    Due to recursivity, we can end up with the following call stack:
    1. Element::willModifyAttribute("old-id", "new-id")
    2. Attr::setValue("new-id");
    3. Element::willModifyAttribute("new-id", "id-from-callback")
    4. Attr::setValue("id-from-callback");
    5. Element::didModifyAttribute("id-from-callback")
    6. Element::didModifyAttribute("new-id")
    
    After this, the Element's id is "new-id" because the id attribute is updated
    in Element::didModifyAttribute(). However, the id in the DocumentOrderedMap
    is "id-from-callback" because the id DocumentOrderedMap is updated in
    Element::willModifyAttribute(). This mismatch between the DocumentOrderedMap
    and the actual Element id can cause getElementById() to return incorrect
    result. Even worse, it can result in a use-after-free (as in Bug 402255)
    because the DocumentOrderedMap does not hold a reference to the StringImpl
    used as key, assuming the StringImpl will be kept alive as it is used as 'id'
    for an Element.
    
    BUG=402255
    TEST=fast/dom/Attr/set-attr-value-no-DOMSubtreeModified.html
    
    Review URL: https://codereview.chromium.org/452093003
    
    git-svn-id: svn://svn.chromium.org/blink/trunk@180380 bbb929c8-8fbe-4397-9dbb-9b2b20218538
    9ba82696
set-attr-value-no-DOMSubtreeModified.html 586 Bytes