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 0ab969688863ea5baa66c64ec6045da10c2309b9..0b6805a9f38bae061e0a4fd5394236f922d0f931 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 0da24c13b43c9f4ac8a5e9d06a41e0415d8c49d4..5967d5ad9601df53cbf897cf52cd6f96b56cc95f 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 a8eaee48b82734ca6b21e47a2574d69ac5eba986..6f9765191f7e8bc99faaefe026f90d3988544337 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 ec98703cc8dd57d75a472b53e9715940d8f8458c..5a0215d0010c5f2b239d2a382d5c64af8e10d58e 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 f4ab4ba2b22a634ced3b319f0547aa9aa9fbcaf4..325eac39ffd4f1fb80e810985abe087f3fb1e782 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;