Reviewed by hyatt.
authorharrison <harrison@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 22 Mar 2007 04:31:50 +0000 (04:31 +0000)
committerharrison <harrison@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 22 Mar 2007 04:31:50 +0000 (04:31 +0000)
        <rdar://problem/5072460> CrashTracer: [USER] 1 crashes in Xcode at com.apple.ImageIO.framework: getBandProcPNG + 168

        An NSData object was being alloc/init'd, then returned callers who cast the pointer as a
        CFDataRef, including calling CFRelease on it. The problem is that under garbage collection, the NS
        retain count is ignored (it's always 0), but the CFRetain and CFRelease are not ignored. This
        caused the object to be over-released. The solution that works in both GC and non-GC is to "transfer"
        the initial NS retain count to the CF retain count, using HardRetainWithNSRelease.

        The creator of the NSData was SharedBuffer::createNSData. The callers were PDFDocumentImage::dataChanged()
        and ImageSource::setData(). This particular crash involved the ImageSource::setData() case.

        * platform/SharedBuffer.h:
        Declare createCFData().

        * platform/graphics/cg/ImageSourceCG.cpp:
        (WebCore::ImageSource::setData):
        Call createCFData instead of createNSData.

        * platform/graphics/cg/PDFDocumentImage.cpp:
        (WebCore::PDFDocumentImage::dataChanged):
        Call createCFData instead of createNSData.

       * platform/mac/SharedBufferMac.mm:
        (WebCore::SharedBuffer::createCFData):
        Implement createCFData(). Use HardRetainWithNSRelease for gc safety.

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

WebCore/ChangeLog
WebCore/platform/SharedBuffer.h
WebCore/platform/graphics/cg/ImageSourceCG.cpp
WebCore/platform/graphics/cg/PDFDocumentImage.cpp
WebCore/platform/mac/SharedBufferMac.mm

index 0ab9696..0b6805a 100644 (file)
@@ -1,3 +1,33 @@
+2007-03-21  David Harrison  <harrison@apple.com>
+
+        Reviewed by hyatt.
+
+        <rdar://problem/5072460> CrashTracer: [USER] 1 crashes in Xcode at com.apple.ImageIO.framework: getBandProcPNG + 168
+
+        An NSData object was being alloc/init'd, then returned callers who cast the pointer as a
+        CFDataRef, including calling CFRelease on it. The problem is that under garbage collection, the NS
+        retain count is ignored (it's always 0), but the CFRetain and CFRelease are not ignored. This
+        caused the object to be over-released. The solution that works in both GC and non-GC is to "transfer"
+        the initial NS retain count to the CF retain count, using HardRetainWithNSRelease.
+        
+        The creator of the NSData was SharedBuffer::createNSData. The callers were PDFDocumentImage::dataChanged()
+        and ImageSource::setData(). This particular crash involved the ImageSource::setData() case.
+
+        * platform/SharedBuffer.h:
+        Declare createCFData().
+        
+        * platform/graphics/cg/ImageSourceCG.cpp:
+        (WebCore::ImageSource::setData):
+        Call createCFData instead of createNSData.
+        
+        * platform/graphics/cg/PDFDocumentImage.cpp:
+        (WebCore::PDFDocumentImage::dataChanged):
+        Call createCFData instead of createNSData.
+        
+       * platform/mac/SharedBufferMac.mm:
+        (WebCore::SharedBuffer::createCFData):
+        Implement createCFData(). Use HardRetainWithNSRelease for gc safety.
+        
 2007-03-21  Mitz Pettel  <mitz@webkit.org>
 
         Reviewed by Darin.
index 0da24c1..5967d5a 100644 (file)
@@ -48,6 +48,7 @@ public:
     SharedBuffer(const char*, int);
 #if PLATFORM(MAC)
     NSData *createNSData();
+    CFDataRef createCFData();
     static PassRefPtr<SharedBuffer> wrapNSData(NSData *data);
 #endif
         
index a8eaee4..6f97651 100644 (file)
@@ -78,8 +78,8 @@ void ImageSource::setData(SharedBuffer* data, bool allDataReceived)
         m_decoder = CGImageSourceCreateIncremental(NULL);
 #if PLATFORM(MAC)
     // On Mac the NSData inside the SharedBuffer can be secretly appended to without the SharedBuffer's knowledge.  We use SharedBuffer's ability
-    // to wrap itself in an NSData to get around this, ensuring that ImageIO is really looking at the SharedBuffer.
-    CFDataRef cfData = (CFDataRef)data->createNSData();
+    // to wrap itself inside CFData to get around this, ensuring that ImageIO is really looking at the SharedBuffer.
+    CFDataRef cfData = data->createCFData();
 #else
     // If no NSData is available, then we know SharedBuffer will always just be a vector.  That means no secret changes can occur to it behind the
     // scenes.  We use CFDataCreateWithBytesNoCopy in that case.
index ec98703..5a0215d 100644 (file)
@@ -58,8 +58,8 @@ bool PDFDocumentImage::dataChanged(bool allDataReceived)
     if (allDataReceived && !m_document) {
 #if PLATFORM(MAC)
         // On Mac the NSData inside the SharedBuffer can be secretly appended to without the SharedBuffer's knowledge.  We use SharedBuffer's ability
-        // to wrap itself in an NSData to get around this, ensuring that ImageIO is really looking at the SharedBuffer.
-        CFDataRef data = (CFDataRef)m_data->createNSData();
+        // to wrap itself inside CFData to get around this, ensuring that ImageIO is really looking at the SharedBuffer.
+        CFDataRef data = m_data->createCFData();
 #else
         // If no NSData is available, then we know SharedBuffer will always just be a vector.  That means no secret changes can occur to it behind the
         // scenes.  We use CFDataCreateWithBytesNoCopy in that case.
index f4ab4ba..325eac3 100644 (file)
@@ -24,6 +24,7 @@
  */
 
 #include "config.h"
+#include "FoundationExtras.h"
 #include "SharedBuffer.h"
 #include "WebCoreObjCExtras.h"
 #include <string.h>
@@ -103,6 +104,11 @@ NSData *SharedBuffer::createNSData()
     return [[SharedBufferData alloc] initWithSharedBuffer:this];
 }
 
+CFDataRef SharedBuffer::createCFData()
+{    
+    return (CFDataRef)HardRetainWithNSRelease([[SharedBufferData alloc] initWithSharedBuffer:this]);
+}
+
 bool SharedBuffer::hasPlatformData() const
 {
     return m_nsData;