Title: [264610] trunk/Source/WebCore
Revision
264610
Author
[email protected]
Date
2020-07-20 12:52:09 -0700 (Mon, 20 Jul 2020)

Log Message

[Cocoa] MediaSampleAVFObjC::createImageSample depends on function argument evaluation order
https://bugs.webkit.org/show_bug.cgi?id=214560

Reviewed by Anders Carlsson.

* platform/graphics/avfoundation/objc/MediaSampleAVFObjC.mm:
(WebCore::deallocateVectorBuffer): Renamed from releaseUint8Vector.
(WebCore::MediaSampleAVFObjC::createImageSample): Rearranged code so that we don't call both
data() and releaseBuffer() on the same vector in the same function call; that isn't safe because
the order of argument evaluation is not guaranteed, and so data() could be called after the
buffer is released. Also added code to deallocate the buffer if CVPixelBufferCreateWithBytes
fails. The old code would have leaked it in that case. Also made some style tweaks to use
adoptCF more consistently to handle reference counting, and slightly optimized a loop to
only get the array count once.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (264609 => 264610)


--- trunk/Source/WebCore/ChangeLog	2020-07-20 19:47:49 UTC (rev 264609)
+++ trunk/Source/WebCore/ChangeLog	2020-07-20 19:52:09 UTC (rev 264610)
@@ -1,3 +1,20 @@
+2020-07-20  Darin Adler  <[email protected]>
+
+        [Cocoa] MediaSampleAVFObjC::createImageSample depends on function argument evaluation order
+        https://bugs.webkit.org/show_bug.cgi?id=214560
+
+        Reviewed by Anders Carlsson.
+
+        * platform/graphics/avfoundation/objc/MediaSampleAVFObjC.mm:
+        (WebCore::deallocateVectorBuffer): Renamed from releaseUint8Vector.
+        (WebCore::MediaSampleAVFObjC::createImageSample): Rearranged code so that we don't call both
+        data() and releaseBuffer() on the same vector in the same function call; that isn't safe because
+        the order of argument evaluation is not guaranteed, and so data() could be called after the
+        buffer is released. Also added code to deallocate the buffer if CVPixelBufferCreateWithBytes
+        fails. The old code would have leaked it in that case. Also made some style tweaks to use
+        adoptCF more consistently to handle reference counting, and slightly optimized a loop to
+        only get the array count once.
+
 2020-07-20  Philippe Normand  <[email protected]>
 
         [GStreamer] Add support for canvas captureStream, tests failing since they were added in r213598

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaSampleAVFObjC.mm (264609 => 264610)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaSampleAVFObjC.mm	2020-07-20 19:47:49 UTC (rev 264609)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaSampleAVFObjC.mm	2020-07-20 19:52:09 UTC (rev 264610)
@@ -41,7 +41,7 @@
 
 namespace WebCore {
 
-static inline void releaseUint8Vector(void *array, const void*)
+static void deallocateVectorBuffer(void* array, const void*)
 {
     WTF::VectorMalloc::free(array);
 }
@@ -48,33 +48,33 @@
 
 RefPtr<MediaSampleAVFObjC> MediaSampleAVFObjC::createImageSample(Vector<uint8_t>&& array, unsigned width, unsigned height)
 {
-    CVPixelBufferRef pixelBuffer = nullptr;
-    auto status = CVPixelBufferCreateWithBytes(kCFAllocatorDefault, width, height, kCVPixelFormatType_32BGRA, array.data(), width * 4, releaseUint8Vector, array.releaseBuffer().leakPtr(), NULL, &pixelBuffer);
-    auto imageBuffer = adoptCF(pixelBuffer);
-
+    CVPixelBufferRef pixelBufferRaw = nullptr;
+    auto data = ""
+    auto status = CVPixelBufferCreateWithBytes(kCFAllocatorDefault, width, height, kCVPixelFormatType_32BGRA, data, width * 4, deallocateVectorBuffer, data, nullptr, &pixelBufferRaw);
+    auto pixelBuffer = adoptCF(pixelBufferRaw);
+    if (!pixelBuffer) {
+        deallocateVectorBuffer(data, nullptr);
+        return nullptr;
+    }
     ASSERT_UNUSED(status, !status);
-    if (!imageBuffer)
-        return nullptr;
 
-    CMVideoFormatDescriptionRef formatDescription = nullptr;
-    status = CMVideoFormatDescriptionCreateForImageBuffer(kCFAllocatorDefault, imageBuffer.get(), &formatDescription);
+    CMVideoFormatDescriptionRef formatDescriptionRaw = nullptr;
+    status = CMVideoFormatDescriptionCreateForImageBuffer(kCFAllocatorDefault, pixelBuffer.get(), &formatDescriptionRaw);
     ASSERT(!status);
+    auto formatDescription = adoptCF(formatDescriptionRaw);
 
     CMSampleTimingInfo sampleTimingInformation = { kCMTimeInvalid, kCMTimeInvalid, kCMTimeInvalid };
-
-    CMSampleBufferRef sampleBuffer;
-    status = CMSampleBufferCreateReadyWithImageBuffer(kCFAllocatorDefault, imageBuffer.get(), formatDescription, &sampleTimingInformation, &sampleBuffer);
-    CFRelease(formatDescription);
+    CMSampleBufferRef sampleBufferRaw = nullptr;
+    status = CMSampleBufferCreateReadyWithImageBuffer(kCFAllocatorDefault, pixelBuffer.get(), formatDescription.get(), &sampleTimingInformation, &sampleBufferRaw);
     ASSERT(!status);
+    auto sampleBuffer = adoptCF(sampleBufferRaw);
 
-    auto sample = adoptCF(sampleBuffer);
-
-    CFArrayRef attachmentsArray = CMSampleBufferGetSampleAttachmentsArray(sample.get(), true);
-    for (CFIndex i = 0; i < CFArrayGetCount(attachmentsArray); ++i) {
+    CFArrayRef attachmentsArray = CMSampleBufferGetSampleAttachmentsArray(sampleBuffer.get(), true);
+    for (CFIndex i = 0, count = CFArrayGetCount(attachmentsArray); i < count; ++i) {
         CFMutableDictionaryRef attachments = checked_cf_cast<CFMutableDictionaryRef>(CFArrayGetValueAtIndex(attachmentsArray, i));
         CFDictionarySetValue(attachments, kCMSampleAttachmentKey_DisplayImmediately, kCFBooleanTrue);
     }
-    return create(sample.get());
+    return create(sampleBuffer.get());
 }
 
 MediaTime MediaSampleAVFObjC::presentationTime() const
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to