Changeset 145423 in webkit


Ignore:
Timestamp:
Mar 11, 2013, 4:18:44 PM (12 years ago)
Author:
schenney@chromium.org
Message:

HTMLInputElement can delete an ImageLoader while it's still needed
https://bugs.webkit.org/show_bug.cgi?id=110621

Reviewed by Darin Adler.

Source/WebCore:

ImageLoader objects may fire events for HTMLInputElements that are of
type ImageInputType that own the loader. These events may cause script
to run that changes the type of the input element and hence causes the
ImageLoader to be deleted, while the image loader is still processing
the event dispatch. Bad things ensue.

This change moves ownership of the ImageLoader from the ImageInputType
onto the HTMLImageElement which is already protected from deletion during
event processing.

Test: fast/forms/image/image-error-event-modifies-type-crash.html

  • html/HTMLInputElement.cpp:

(WebCore::HTMLInputElement::imageLoader): Method to return the

ImageLoader, creating it if not already created.

  • html/HTMLInputElement.h:

(WebCore::HTMLInputElement::hasImageLoader): Return true if the

ImageLoader has been created.

(HTMLInputElement): Define ImageLoader access methods and the OwnPtr

for the HTMLImageLoader.

  • html/ImageInputType.cpp:

(WebCore::ImageInputType::srcAttributeChanged): Use the element's ImageLoader.
(WebCore::ImageInputType::attach): Use the element's ImageLoader.
(WebCore::ImageInputType::willMoveToNewOwnerDocument): Use the element's ImageLoader.
(WebCore::ImageInputType::height): Use the element's ImageLoader.
(WebCore::ImageInputType::width): Use the element's ImageLoader.

  • html/ImageInputType.h:

(ImageInputType): Remove the declaration of the ImageLoader.

LayoutTests:

  • fast/forms/image/image-error-event-modifies-type-crash-expected.txt: Added.
  • fast/forms/image/image-error-event-modifies-type-crash.html: Added.
Location:
trunk
Files:
2 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r145422 r145423  
     12013-03-11  Stephen Chenney  <schenney@chromium.org>
     2
     3        HTMLInputElement can delete an ImageLoader while it's still needed
     4        https://bugs.webkit.org/show_bug.cgi?id=110621
     5
     6        Reviewed by Darin Adler.
     7
     8        * fast/forms/image/image-error-event-modifies-type-crash-expected.txt: Added.
     9        * fast/forms/image/image-error-event-modifies-type-crash.html: Added.
     10
    1112013-03-11  Alok Priyadarshi  <alokp@chromium.org>
    212
  • trunk/Source/WebCore/ChangeLog

    r145422 r145423  
     12013-03-11  Stephen Chenney  <schenney@chromium.org>
     2
     3        HTMLInputElement can delete an ImageLoader while it's still needed
     4        https://bugs.webkit.org/show_bug.cgi?id=110621
     5
     6        Reviewed by Darin Adler.
     7
     8        ImageLoader objects may fire events for HTMLInputElements that are of
     9        type ImageInputType that own the loader. These events may cause script
     10        to run that changes the type of the input element and hence causes the
     11        ImageLoader to be deleted, while the image loader is still processing
     12        the event dispatch. Bad things ensue.
     13
     14        This change moves ownership of the ImageLoader from the ImageInputType
     15        onto the HTMLImageElement which is already protected from deletion during
     16        event processing.
     17
     18        Test: fast/forms/image/image-error-event-modifies-type-crash.html
     19
     20        * html/HTMLInputElement.cpp:
     21        (WebCore::HTMLInputElement::imageLoader): Method to return the
     22          ImageLoader, creating it if not already created.
     23        * html/HTMLInputElement.h:
     24        (WebCore::HTMLInputElement::hasImageLoader): Return true if the
     25          ImageLoader has been created.
     26        (HTMLInputElement): Define ImageLoader access methods and the OwnPtr
     27          for the HTMLImageLoader.
     28        * html/ImageInputType.cpp:
     29        (WebCore::ImageInputType::srcAttributeChanged): Use the element's ImageLoader.
     30        (WebCore::ImageInputType::attach): Use the element's ImageLoader.
     31        (WebCore::ImageInputType::willMoveToNewOwnerDocument): Use the element's ImageLoader.
     32        (WebCore::ImageInputType::height): Use the element's ImageLoader.
     33        (WebCore::ImageInputType::width): Use the element's ImageLoader.
     34        * html/ImageInputType.h:
     35        (ImageInputType): Remove the declaration of the ImageLoader.
     36
    1372013-03-11  Alok Priyadarshi  <alokp@chromium.org>
    238
  • trunk/Source/WebCore/html/HTMLInputElement.cpp

    r145055 r145423  
    4848#include "HTMLDataListElement.h"
    4949#include "HTMLFormElement.h"
     50#include "HTMLImageLoader.h"
    5051#include "HTMLNames.h"
    5152#include "HTMLOptionElement.h"
     
    146147    inputElement->ensureUserAgentShadowRoot();
    147148    return inputElement.release();
     149}
     150
     151HTMLImageLoader* HTMLInputElement::imageLoader()
     152{
     153    if (!m_imageLoader)
     154        m_imageLoader = adoptPtr(new HTMLImageLoader(this));
     155    return m_imageLoader.get();
    148156}
    149157
     
    15141522void HTMLInputElement::didMoveToNewDocument(Document* oldDocument)
    15151523{
    1516     m_inputType->willMoveToNewOwnerDocument();
     1524    if (hasImageLoader())
     1525        imageLoader()->elementDidMoveToNewDocument();
     1526
    15171527    bool needsSuspensionCallback = this->needsSuspensionCallback();
    15181528    if (oldDocument) {
  • trunk/Source/WebCore/html/HTMLInputElement.h

    r145055 r145423  
    3636class FileList;
    3737class HTMLDataListElement;
     38class HTMLImageLoader;
    3839class HTMLOptionElement;
    3940class Icon;
     
    294295    virtual void setRangeText(const String& replacement, ExceptionCode&) OVERRIDE;
    295296    virtual void setRangeText(const String& replacement, unsigned start, unsigned end, const String& selectionMode, ExceptionCode&) OVERRIDE;
     297
     298    bool hasImageLoader() const { return m_imageLoader; }
     299    HTMLImageLoader* imageLoader();
    296300
    297301#if ENABLE(DATE_AND_TIME_INPUT_TYPES)
     
    431435#endif
    432436    OwnPtr<InputType> m_inputType;
     437    // The ImageLoader must be owned by this element because the loader code assumes
     438    // that it lives as long as its owning element lives. If we move the loader into
     439    // the ImageInput object we may delete the loader while this element lives on.
     440    OwnPtr<HTMLImageLoader> m_imageLoader;
    433441#if ENABLE(DATALIST_ELEMENT)
    434442    OwnPtr<ListAttributeTargetObserver> m_listAttributeTargetObserver;
  • trunk/Source/WebCore/html/ImageInputType.cpp

    r144568 r145423  
    121121    if (!element()->renderer())
    122122        return;
    123     if (!m_imageLoader)
    124         m_imageLoader = adoptPtr(new HTMLImageLoader(element()));
    125     m_imageLoader->updateFromElementIgnoringPreviousError();
     123    element()->imageLoader()->updateFromElementIgnoringPreviousError();
    126124}
    127125
     
    130128    BaseButtonInputType::attach();
    131129
    132     if (!m_imageLoader)
    133         m_imageLoader = adoptPtr(new HTMLImageLoader(element()));
    134     m_imageLoader->updateFromElement();
     130    HTMLImageLoader* imageLoader = element()->imageLoader();
     131    imageLoader->updateFromElement();
    135132
    136133    RenderImage* renderer = toRenderImage(element()->renderer());
     
    138135        return;
    139136
    140     if (m_imageLoader->hasPendingBeforeLoadEvent())
     137    if (imageLoader->hasPendingBeforeLoadEvent())
    141138        return;
    142139
    143140    RenderImageResource* imageResource = renderer->imageResource();
    144     imageResource->setCachedImage(m_imageLoader->image());
     141    imageResource->setCachedImage(imageLoader->image());
    145142
    146143    // If we have no image at all because we have no src attribute, set
    147144    // image height and width for the alt text instead.
    148     if (!m_imageLoader->image() && !imageResource->cachedImage())
     145    if (!imageLoader->image() && !imageResource->cachedImage())
    149146        renderer->setImageSizeForAltText();
    150 }
    151 
    152 void ImageInputType::willMoveToNewOwnerDocument()
    153 {
    154     BaseButtonInputType::willMoveToNewOwnerDocument();
    155     if (m_imageLoader)
    156         m_imageLoader->elementDidMoveToNewDocument();
    157147}
    158148
     
    193183
    194184        // If the image is available, use its height.
    195         if (m_imageLoader && m_imageLoader->image())
    196             return m_imageLoader->image()->imageSizeForRenderer(element->renderer(), 1).height();
     185        if (element->hasImageLoader()) {
     186            HTMLImageLoader* imageLoader = element->imageLoader();
     187            if (imageLoader->image())
     188                return imageLoader->image()->imageSizeForRenderer(element->renderer(), 1).height();
     189        }
    197190    }
    198191
     
    214207
    215208        // If the image is available, use its width.
    216         if (m_imageLoader && m_imageLoader->image())
    217             return m_imageLoader->image()->imageSizeForRenderer(element->renderer(), 1).width();
     209        if (element->hasImageLoader()) {
     210            HTMLImageLoader* imageLoader = element->imageLoader();
     211            if (imageLoader->image())
     212                return imageLoader->image()->imageSizeForRenderer(element->renderer(), 1).width();
     213        }
    218214    }
    219215
  • trunk/Source/WebCore/html/ImageInputType.h

    r116389 r145423  
    4040namespace WebCore {
    4141
    42 class HTMLImageLoader;
    43 
    4442class ImageInputType : public BaseButtonInputType {
    4543public:
     
    5755    virtual void srcAttributeChanged() OVERRIDE;
    5856    virtual void attach() OVERRIDE;
    59     virtual void willMoveToNewOwnerDocument() OVERRIDE;
    6057    virtual bool shouldRespectAlignAttribute() OVERRIDE;
    6158    virtual bool canBeSuccessfulSubmitButton() OVERRIDE;
     
    6663    virtual unsigned width() const OVERRIDE;
    6764
    68     OwnPtr<HTMLImageLoader> m_imageLoader;
    6965    IntPoint m_clickLocation; // Valid only during HTMLFormElement::prepareForSubmission().
    7066};
  • trunk/Source/WebCore/html/InputType.cpp

    r145362 r145423  
    597597}
    598598
    599 void InputType::willMoveToNewOwnerDocument()
    600 {
    601 }
    602 
    603599bool InputType::shouldRespectAlignAttribute()
    604600{
  • trunk/Source/WebCore/html/InputType.h

    r145055 r145423  
    246246    virtual void altAttributeChanged();
    247247    virtual void srcAttributeChanged();
    248     virtual void willMoveToNewOwnerDocument();
    249248    virtual bool shouldRespectAlignAttribute();
    250249    virtual FileList* files();
Note: See TracChangeset for help on using the changeset viewer.