From 588cb9a977c0ec4f278b827a67d7b46b84573057 Mon Sep 17 00:00:00 2001 From: rcombs Date: Fri, 26 Mar 2021 02:32:49 -0500 Subject: mac: avoid unnecessary unsafe conversions; fixes crash in debug builds Previously, running a debug build of mpv would crash with this output when preinit() at vo_libmpv.c:732 calls control(vo, VOCTRL_PREINIT, NULL): Swift/Optional.swift:247: Fatal error: unsafelyUnwrapped of nil optional This comes from this line of code: var data = UnsafeMutableRawPointer.init(bitPattern: 0).unsafelyUnwrapped Unsafely unwrapping a UnsafeMutableRawPointer.init has always been UB, but the Swift runtime began asserting on it in debug builds a couple macOS versions ago. --- video/out/cocoa_cb_common.swift | 12 ++---------- video/out/mac/common.swift | 24 ++++++++++++------------ 2 files changed, 14 insertions(+), 22 deletions(-) diff --git a/video/out/cocoa_cb_common.swift b/video/out/cocoa_cb_common.swift index dd0738f7e3..5c312cbff0 100644 --- a/video/out/cocoa_cb_common.swift +++ b/video/out/cocoa_cb_common.swift @@ -167,17 +167,9 @@ class CocoaCB: Common { layer?.update(force: true) } - var controlCallback: mp_render_cb_control_fn = { ( v, ctx, e, request, d ) -> Int32 in + var controlCallback: mp_render_cb_control_fn = { ( v, ctx, e, request, data ) -> Int32 in let ccb = unsafeBitCast(ctx, to: CocoaCB.self) - // the data pointer can be a null pointer, the libmpv control callback - // provides nil instead of the 0 address like the usual control call of - // an internal vo, workaround to create a null pointer instead of nil - var data = UnsafeMutableRawPointer.init(bitPattern: 0).unsafelyUnwrapped - if let dunwrapped = d { - data = dunwrapped - } - guard let vo = v, let events = e else { ccb.log.sendWarning("Unexpected nil value in Control Callback") return VO_FALSE @@ -189,7 +181,7 @@ class CocoaCB: Common { override func control(_ vo: UnsafeMutablePointer, events: UnsafeMutablePointer, request: UInt32, - data: UnsafeMutableRawPointer) -> Int32 + data: UnsafeMutableRawPointer?) -> Int32 { switch mp_voctrl(request) { case VOCTRL_PREINIT: diff --git a/video/out/mac/common.swift b/video/out/mac/common.swift index 5a48ccef7b..66faf816d0 100644 --- a/video/out/mac/common.swift +++ b/video/out/mac/common.swift @@ -523,7 +523,7 @@ class Common: NSObject { @objc func control(_ vo: UnsafeMutablePointer, events: UnsafeMutablePointer, request: UInt32, - data: UnsafeMutableRawPointer) -> Int32 + data: UnsafeMutableRawPointer?) -> Int32 { guard let mpv = mpv else { log.sendWarning("Unexpected nil value in Control Callback") @@ -573,11 +573,11 @@ class Common: NSObject { } return VO_TRUE case VOCTRL_GET_DISPLAY_FPS: - let fps = data.assumingMemoryBound(to: CDouble.self) + let fps = data!.assumingMemoryBound(to: CDouble.self) fps.pointee = currentFps() return VO_TRUE case VOCTRL_GET_HIDPI_SCALE: - let scaleFactor = data.assumingMemoryBound(to: CDouble.self) + let scaleFactor = data!.assumingMemoryBound(to: CDouble.self) let screen = getCurrentScreen() let factor = window?.backingScaleFactor ?? screen?.backingScaleFactor ?? 1.0 @@ -590,7 +590,7 @@ class Common: NSObject { disableDisplaySleep() return VO_TRUE case VOCTRL_SET_CURSOR_VISIBILITY: - let cursorVisibility = data.assumingMemoryBound(to: CBool.self) + let cursorVisibility = data!.assumingMemoryBound(to: CBool.self) cursorVisibilityWanted = cursorVisibility.pointee DispatchQueue.main.async { self.setCursorVisibility(self.cursorVisibilityWanted) @@ -603,7 +603,7 @@ class Common: NSObject { return VO_TRUE } - let icc = data.assumingMemoryBound(to: bstr.self) + let icc = data!.assumingMemoryBound(to: bstr.self) iccData.withUnsafeMutableBytes { (ptr: UnsafeMutableRawBufferPointer) in guard let baseAddress = ptr.baseAddress, ptr.count > 0 else { return } let u8Ptr = baseAddress.assumingMemoryBound(to: UInt8.self) @@ -612,13 +612,13 @@ class Common: NSObject { return VO_TRUE case VOCTRL_GET_AMBIENT_LUX: if lightSensor != 0 { - let lux = data.assumingMemoryBound(to: Int32.self) + let lux = data!.assumingMemoryBound(to: Int32.self) lux.pointee = Int32(lmuToLux(lastLmu)) return VO_TRUE; } return VO_NOTIMPL case VOCTRL_GET_UNFS_WINDOW_SIZE: - let sizeData = data.assumingMemoryBound(to: Int32.self) + let sizeData = data!.assumingMemoryBound(to: Int32.self) let size = UnsafeMutableBufferPointer(start: sizeData, count: 2) var rect = window?.unfsContentFrame ?? NSRect(x: 0, y: 0, width: 1280, height: 720) if let screen = window?.currentScreen, !Bool(mpv.opts.hidpi_window_scale) { @@ -629,7 +629,7 @@ class Common: NSObject { size[1] = Int32(rect.size.height) return VO_TRUE case VOCTRL_SET_UNFS_WINDOW_SIZE: - let sizeData = data.assumingMemoryBound(to: Int32.self) + let sizeData = data!.assumingMemoryBound(to: Int32.self) let size = UnsafeBufferPointer(start: sizeData, count: 2) var rect = NSMakeRect(0, 0, CGFloat(size[0]), CGFloat(size[1])) DispatchQueue.main.async { @@ -640,7 +640,7 @@ class Common: NSObject { } return VO_TRUE case VOCTRL_GET_DISPLAY_NAMES: - let dnames = data.assumingMemoryBound(to: UnsafeMutablePointer?>?.self) + let dnames = data!.assumingMemoryBound(to: UnsafeMutablePointer?>?.self) var array: UnsafeMutablePointer?>? = nil var count: Int32 = 0 let displayName = getCurrentScreen()?.displayName ?? "Unknown" @@ -654,18 +654,18 @@ class Common: NSObject { log.sendWarning("No Screen available to retrieve frame") return VO_NOTAVAIL } - let sizeData = data.assumingMemoryBound(to: Int32.self) + let sizeData = data!.assumingMemoryBound(to: Int32.self) let size = UnsafeMutableBufferPointer(start: sizeData, count: 2) let frame = screen.convertRectToBacking(screen.frame) size[0] = Int32(frame.size.width) size[1] = Int32(frame.size.height) return VO_TRUE case VOCTRL_GET_FOCUSED: - let focus = data.assumingMemoryBound(to: CBool.self) + let focus = data!.assumingMemoryBound(to: CBool.self) focus.pointee = NSApp.isActive return VO_TRUE case VOCTRL_UPDATE_WINDOW_TITLE: - let titleData = data.assumingMemoryBound(to: Int8.self) + let titleData = data!.assumingMemoryBound(to: Int8.self) DispatchQueue.main.async { let title = NSString(utf8String: titleData) as String? self.title = title ?? "Unknown Title" -- cgit v1.2.3