Title: [288897] trunk/Source/WebCore
Revision
288897
Author
[email protected]
Date
2022-02-01 11:03:45 -0800 (Tue, 01 Feb 2022)

Log Message

[Cocoa] "index 0 out of bounds" exception in AVTrackPrivateAVFObjCImpl::videoTrackConfiguration()
https://bugs.webkit.org/show_bug.cgi?id=235918
<rdar://87651247>

Reviewed by Eric Carlson.

Crash data shows a rare exception thrown from inside a static method formatDescriptionFor()
in AVTrackPrivateAVFObjCImpl. The method first queries whether the .formatDescriptions
NSArray property is queryable, then for its count, then retrieves the first object in the
array. It's possible that the array is mutated on a background thread between the count
check and when the first object is retrieved.

To eliminate the possibility that the property is mutated between queries, pull the value
into a RetainPtr and run the query on that retained object. Use -[NSArray firstObject]
rather than -objectAtIndex:0, as the former will return nil if the -count is 0, while the
latter will throw an exception. To guard against the possibility that the
CMFormatDescriptionRef will go out of scope after the return, return the format description
itself wrapped in a RetainPtr as well.

* platform/graphics/avfoundation/AVTrackPrivateAVFObjCImpl.mm:
(WebCore::formatDescriptionFor):
(WebCore::AVTrackPrivateAVFObjCImpl::codec const):
(WebCore::AVTrackPrivateAVFObjCImpl::colorSpace const):
(WebCore::AVTrackPrivateAVFObjCImpl::sampleRate const):
(WebCore::AVTrackPrivateAVFObjCImpl::numberOfChannels const):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (288896 => 288897)


--- trunk/Source/WebCore/ChangeLog	2022-02-01 18:37:19 UTC (rev 288896)
+++ trunk/Source/WebCore/ChangeLog	2022-02-01 19:03:45 UTC (rev 288897)
@@ -1,3 +1,31 @@
+2022-02-01  Jer Noble  <[email protected]>
+
+        [Cocoa] "index 0 out of bounds" exception in AVTrackPrivateAVFObjCImpl::videoTrackConfiguration()
+        https://bugs.webkit.org/show_bug.cgi?id=235918
+        <rdar://87651247>
+
+        Reviewed by Eric Carlson.
+
+        Crash data shows a rare exception thrown from inside a static method formatDescriptionFor()
+        in AVTrackPrivateAVFObjCImpl. The method first queries whether the .formatDescriptions
+        NSArray property is queryable, then for its count, then retrieves the first object in the
+        array. It's possible that the array is mutated on a background thread between the count
+        check and when the first object is retrieved.
+
+        To eliminate the possibility that the property is mutated between queries, pull the value
+        into a RetainPtr and run the query on that retained object. Use -[NSArray firstObject]
+        rather than -objectAtIndex:0, as the former will return nil if the -count is 0, while the
+        latter will throw an exception. To guard against the possibility that the
+        CMFormatDescriptionRef will go out of scope after the return, return the format description
+        itself wrapped in a RetainPtr as well.
+
+        * platform/graphics/avfoundation/AVTrackPrivateAVFObjCImpl.mm:
+        (WebCore::formatDescriptionFor):
+        (WebCore::AVTrackPrivateAVFObjCImpl::codec const):
+        (WebCore::AVTrackPrivateAVFObjCImpl::colorSpace const):
+        (WebCore::AVTrackPrivateAVFObjCImpl::sampleRate const):
+        (WebCore::AVTrackPrivateAVFObjCImpl::numberOfChannels const):
+
 2022-02-01  Ada Chan  <[email protected]>
 
         [WebXR] Handle changes in XRSession's visibility state

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/AVTrackPrivateAVFObjCImpl.mm (288896 => 288897)


--- trunk/Source/WebCore/platform/graphics/avfoundation/AVTrackPrivateAVFObjCImpl.mm	2022-02-01 18:37:19 UTC (rev 288896)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/AVTrackPrivateAVFObjCImpl.mm	2022-02-01 19:03:45 UTC (rev 288897)
@@ -303,17 +303,18 @@
     return nil;
 }
 
-static CMFormatDescriptionRef formatDescriptionFor(const AVTrackPrivateAVFObjCImpl& impl)
+static RetainPtr<CMFormatDescriptionRef> formatDescriptionFor(const AVTrackPrivateAVFObjCImpl& impl)
 {
     auto assetTrack = assetTrackFor(impl);
-    if (!assetTrack || [assetTrack statusOfValueForKey:@"formatDescriptions" error:nil] != AVKeyValueStatusLoaded || !assetTrack.formatDescriptions.count)
+    if (!assetTrack || [assetTrack statusOfValueForKey:@"formatDescriptions" error:nil] != AVKeyValueStatusLoaded)
         return nullptr;
-    return static_cast<CMFormatDescriptionRef>(assetTrack.formatDescriptions[0]);
+
+    return static_cast<CMFormatDescriptionRef>(assetTrack.formatDescriptions.firstObject);
 }
 
 String AVTrackPrivateAVFObjCImpl::codec() const
 {
-    return codecFromFormatDescription(formatDescriptionFor(*this));
+    return codecFromFormatDescription(formatDescriptionFor(*this).get());
 }
 
 uint32_t AVTrackPrivateAVFObjCImpl::width() const
@@ -334,7 +335,7 @@
 
 PlatformVideoColorSpace AVTrackPrivateAVFObjCImpl::colorSpace() const
 {
-    if (auto colorSpace = colorSpaceFromFormatDescription(formatDescriptionFor(*this)))
+    if (auto colorSpace = colorSpaceFromFormatDescription(formatDescriptionFor(*this).get()))
         return *colorSpace;
     return { };
 }
@@ -355,7 +356,7 @@
     if (!formatDescription)
         return 0;
 
-    const AudioStreamBasicDescription* const asbd = PAL::CMAudioFormatDescriptionGetStreamBasicDescription(formatDescription);
+    const AudioStreamBasicDescription* const asbd = PAL::CMAudioFormatDescriptionGetStreamBasicDescription(formatDescription.get());
     if (!asbd)
         return 0;
 
@@ -368,7 +369,7 @@
     if (!formatDescription)
         return 0;
 
-    const AudioStreamBasicDescription* const asbd = PAL::CMAudioFormatDescriptionGetStreamBasicDescription(formatDescription);
+    const AudioStreamBasicDescription* const asbd = PAL::CMAudioFormatDescriptionGetStreamBasicDescription(formatDescription.get());
     if (!asbd)
         return 0;
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to