Reviewed by Mitz.
authordarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 1 Dec 2007 19:04:15 +0000 (19:04 +0000)
committerdarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 1 Dec 2007 19:04:15 +0000 (19:04 +0000)
        - fix problem tracked by these bugs:
          http://bugs.webkit.org/show_bug.cgi?id=16097
          <rdar://problem/5619305> Safari crashes during load of LexisNexis search results
          <rdar://problem/5510779> CrashTracer: [USER] 25 crashes in Safari at
          WebCore::DocumentLoader::isLoadingMultipartContent const

        * loader/ImageDocument.cpp:
        (WebCore::ImageDocument::createDocumentStructure): Create an ImageDocumentElement
        instead of an HTMLImageElement.
        (WebCore::ImageDocument::scale): Added a null check for m_imageElement.
        (WebCore::ImageDocument::resizeImageToFit): Ditto.
        (WebCore::ImageDocument::restoreImageSize): Ditto.
        (WebCore::ImageDocument::imageFitsInWindow): Ditto.
        (WebCore::ImageDocument::windowSizeChanged): Ditto.
        (WebCore::ImageDocumentElement::~ImageDocumentElement): Call
        disconnectImageElement so m_imageElement will be set to 0
         if we're still connected to the document.
        (WebCore::ImageDocumentElement::willMoveToNewOwnerDocument): Ditto.

        * loader/ImageDocument.h: Changed image element type to be
        ImageDocumentElement instead of HTMLImageElement. Also added
        a disconnectImageElement function that sets m_imageElement to 0.

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

WebCore/ChangeLog
WebCore/loader/ImageDocument.cpp
WebCore/loader/ImageDocument.h

index 458ba6c..7521529 100644 (file)
@@ -1,5 +1,32 @@
 2007-12-01  Darin Adler  <darin@apple.com>
 
+        Reviewed by Mitz.
+
+        - fix problem tracked by these bugs:
+          http://bugs.webkit.org/show_bug.cgi?id=16097
+          <rdar://problem/5619305> Safari crashes during load of LexisNexis search results
+          <rdar://problem/5510779> CrashTracer: [USER] 25 crashes in Safari at
+          WebCore::DocumentLoader::isLoadingMultipartContent const
+
+        * loader/ImageDocument.cpp:
+        (WebCore::ImageDocument::createDocumentStructure): Create an ImageDocumentElement
+        instead of an HTMLImageElement.
+        (WebCore::ImageDocument::scale): Added a null check for m_imageElement.
+        (WebCore::ImageDocument::resizeImageToFit): Ditto.
+        (WebCore::ImageDocument::restoreImageSize): Ditto.
+        (WebCore::ImageDocument::imageFitsInWindow): Ditto.
+        (WebCore::ImageDocument::windowSizeChanged): Ditto.
+        (WebCore::ImageDocumentElement::~ImageDocumentElement): Call
+        disconnectImageElement so m_imageElement will be set to 0
+         if we're still connected to the document.
+        (WebCore::ImageDocumentElement::willMoveToNewOwnerDocument): Ditto.
+
+        * loader/ImageDocument.h: Changed image element type to be
+        ImageDocumentElement instead of HTMLImageElement. Also added
+        a disconnectImageElement function that sets m_imageElement to 0.
+
+2007-12-01  Darin Adler  <darin@apple.com>
+
         - remove the empty directories
 
         * ksvg2: Removed.
         * Don't hide symbols when in Debug mode
         * On Linux (glibc) provide a backtrace in the test output for debugging purposes
 
-
         * WebCore.pro:
 
 2007-11-30  Alp Toker  <alp@atoker.com>
index e4fffb0..a1b566d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -56,8 +56,8 @@ using namespace HTMLNames;
 class ImageEventListener : public EventListener {
 public:
     ImageEventListener(ImageDocument* doc) : m_doc(doc) { }
-    
     virtual void handleEvent(Event*, bool isWindowEvent);
+
 private:
     ImageDocument* m_doc;
 };
@@ -65,17 +65,30 @@ private:
 class ImageTokenizer : public Tokenizer {
 public:
     ImageTokenizer(ImageDocument* doc) : m_doc(doc) {}
-        
+
     virtual bool write(const SegmentedString&, bool appendData);
     virtual void finish();
     virtual bool isWaitingForScripts() const;
     
     virtual bool wantsRawData() const { return true; }
     virtual bool writeRawData(const char* data, int len);
+
 private:
     ImageDocument* m_doc;
 };
 
+class ImageDocumentElement : public HTMLImageElement {
+public:
+    ImageDocumentElement(ImageDocument* doc) : HTMLImageElement(doc), m_imageDocument(doc) { }
+    virtual ~ImageDocumentElement();
+    virtual void willMoveToNewOwnerDocument();
+
+private:
+    ImageDocument* m_imageDocument;
+};
+
+// --------
+
 bool ImageTokenizer::write(const SegmentedString& s, bool appendData)
 {
     ASSERT_NOT_REACHED();
@@ -123,6 +136,8 @@ bool ImageTokenizer::isWaitingForScripts() const
     return false;
 }
     
+// --------
+
 ImageDocument::ImageDocument(DOMImplementation* implementation, Frame* frame)
     : HTMLDocument(implementation, frame)
     , m_imageElement(0)
@@ -150,12 +165,11 @@ void ImageDocument::createDocumentStructure()
     
     rootElement->appendChild(body, ec);
     
-    RefPtr<Element> imageElement = createElementNS(xhtmlNamespaceURI, "img", ec);
+    RefPtr<ImageDocumentElement> imageElement = new ImageDocumentElement(this);
     
-    m_imageElement = static_cast<HTMLImageElement *>(imageElement.get());
-    m_imageElement->setAttribute(styleAttr, "-webkit-user-select: none");        
-    m_imageElement->setLoadManually(true);
-    m_imageElement->setSrc(URL());
+    imageElement->setAttribute(styleAttr, "-webkit-user-select: none");        
+    imageElement->setLoadManually(true);
+    imageElement->setSrc(URL());
     
     body->appendChild(imageElement, ec);
     
@@ -163,12 +177,17 @@ void ImageDocument::createDocumentStructure()
         // Add event listeners
         RefPtr<EventListener> listener = new ImageEventListener(this);
         addWindowEventListener("resize", listener, false);
-        m_imageElement->addEventListener("click", listener.release(), false);
+        imageElement->addEventListener("click", listener.release(), false);
     }
+
+    m_imageElement = imageElement.get();
 }
 
 float ImageDocument::scale() const
 {
+    if (!m_imageElement)
+        return 1.0f;
+
     IntSize imageSize = m_imageElement->cachedImage()->imageSize();
     IntSize windowSize = IntSize(frame()->view()->width(), frame()->view()->height());
     
@@ -180,6 +199,9 @@ float ImageDocument::scale() const
 
 void ImageDocument::resizeImageToFit()
 {
+    if (!m_imageElement)
+        return;
+
     IntSize imageSize = m_imageElement->cachedImage()->imageSize();
 
     float scale = this->scale();
@@ -233,7 +255,7 @@ void ImageDocument::imageChanged()
 
 void ImageDocument::restoreImageSize()
 {
-    if (!m_imageSizeIsKnown)
+    if (!m_imageElement || !m_imageSizeIsKnown)
         return;
     
     m_imageElement->setWidth(m_imageElement->cachedImage()->imageSize().width());
@@ -250,6 +272,9 @@ void ImageDocument::restoreImageSize()
 
 bool ImageDocument::imageFitsInWindow() const
 {
+    if (!m_imageElement)
+        return true;
+
     IntSize imageSize = m_imageElement->cachedImage()->imageSize();
     IntSize windowSize = IntSize(frame()->view()->width(), frame()->view()->height());
     
@@ -258,7 +283,7 @@ bool ImageDocument::imageFitsInWindow() const
 
 void ImageDocument::windowSizeChanged()
 {
-    if (!m_imageSizeIsKnown)
+    if (!m_imageElement || !m_imageSizeIsKnown)
         return;
 
     bool fitsInWindow = imageFitsInWindow();
@@ -305,6 +330,8 @@ bool ImageDocument::shouldShrinkToFit() const
         frame()->page()->mainFrame() == frame();
 }
 
+// --------
+
 void ImageEventListener::handleEvent(Event* event, bool isWindowEvent)
 {
     if (event->type() == resizeEvent)
@@ -315,4 +342,21 @@ void ImageEventListener::handleEvent(Event* event, bool isWindowEvent)
     }
 }
 
+// --------
+
+ImageDocumentElement::~ImageDocumentElement()
+{
+    if (m_imageDocument)
+        m_imageDocument->disconnectImageElement();
+}
+
+void ImageDocumentElement::willMoveToNewOwnerDocument()
+{
+    if (m_imageDocument) {
+        m_imageDocument->disconnectImageElement();
+        m_imageDocument = 0;
+    }
+    HTMLImageElement::willMoveToNewOwnerDocument();
+}
+
 }
index 0621cc9..0cca1a7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -21,6 +21,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  */
+
 #ifndef ImageDocument_h
 #define ImageDocument_h
 
 
 namespace WebCore {
     
-class DOMImplementation;
-class FrameView;
-class HTMLImageElement;
+class ImageDocumentElement;
 
-class ImageDocument : public HTMLDocument
-{
+class ImageDocument : public HTMLDocument {
 public:
     ImageDocument(DOMImplementation*, Frame*);
 
@@ -42,11 +40,13 @@ public:
     virtual Tokenizer* createTokenizer();
     
     CachedImage* cachedImage();
-    HTMLImageElement* imageElement() const { return m_imageElement; }
+    ImageDocumentElement* imageElement() const { return m_imageElement; }
+    void disconnectImageElement() { m_imageElement = 0; }
     
     void windowSizeChanged();
     void imageChanged();
     void imageClicked(int x, int y);
+
 private:
     void createDocumentStructure();
     void resizeImageToFit();
@@ -55,7 +55,7 @@ private:
     bool shouldShrinkToFit() const;
     float scale() const;
     
-    HTMLImageElement* m_imageElement;
+    ImageDocumentElement* m_imageElement;
     
     // Whether enough of the image has been loaded to determine its size
     bool m_imageSizeIsKnown;