Skip to content

fix(osx): prevent bluetooth connect crashes from missing device metadata.#709

Open
giovanninibarbosa wants to merge 5 commits into
timschneeb:masterfrom
giovanninibarbosa:fix/macos-bluetooth-null-strings
Open

fix(osx): prevent bluetooth connect crashes from missing device metadata.#709
giovanninibarbosa wants to merge 5 commits into
timschneeb:masterfrom
giovanninibarbosa:fix/macos-bluetooth-null-strings

Conversation

@giovanninibarbosa

Copy link
Copy Markdown

Summary

This fixes a macOS Bluetooth crash where connect or disconnect notifications can arrive without complete device metadata. The native watcher previously copied NSString.UTF8String values directly into C strings, which could dereference a null pointer before the managed callback was reached.

Tasks

  • Harden Bluetooth connect and disconnect watcher callbacks by validating the device address before invoking managed code.
  • Add safe native UTF-8 string copying and name fallback handling for optional Bluetooth device names.
  • Make paired-device enumeration resilient to missing native name or address strings and clean up partial allocations on failure.
  • Add managed-side null pointer handling before converting native UTF-8 strings.

Verification

  • git diff --check.
  • xcodebuild -project GalaxyBudsClient.Platform.OSX/Native/NativeInterop.xcodeproj -scheme NativeInterop -destination platform=macOS build.

Not Run

  • dotnet restore --configfile GalaxyBudsClient/nuget.config GalaxyBudsClient/GalaxyBudsClient.csproj: dotnet is not available in this shell.
  • dotnet build GalaxyBudsClient.sln -c Debug: dotnet is not available in this shell.
  • dotnet test GalaxyBudsClient.Tests/GalaxyBudsClient.Tests.csproj -c Debug: dotnet is not available in this shell.
  • Manual Bluetooth connect/disconnect regression checks.

Notes

There is no dedicated pull request template in docs/ or .github; this draft follows the docs contribution guidance to explain the changes.

Copilot AI review requested due to automatic review settings May 14, 2026 22:06

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens the macOS Bluetooth native interop path against missing device metadata, especially null native strings in connect/disconnect notifications and paired-device enumeration.

Changes:

  • Adds safe Objective-C NSString to UTF-8 C string copying helpers in native Bluetooth code.
  • Guards watcher connect/disconnect callbacks against missing addresses and optional names.
  • Adds managed-side null pointer handling before converting native UTF-8 strings.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
GalaxyBudsClient.Platform.OSX/Native/src/BluetoothDeviceWatcher.mm Adds safe string copying and address validation for native connect/disconnect notifications.
GalaxyBudsClient.Platform.OSX/Native/src/Bluetooth.mm Adds safe enumeration string allocation and cleanup for paired Bluetooth devices.
GalaxyBudsClient.Platform.OSX/BluetoothService.cs Centralizes native UTF-8 pointer conversion and applies it to enumeration and watcher callbacks.
Comments suppressed due to low confidence (1)

GalaxyBudsClient.Platform.OSX/Native/src/Bluetooth.mm:246

  • When addressString is missing, FirstNonEmptyString turns it into an empty string and the enumeration still returns success for that device. That exposes a BluetoothDevice with an empty Address; for example the manual pairing dialog registers the selected device address without revalidating it, and native bt_connect cannot resolve an empty address. Missing addresses should be filtered out or treated as an enumeration failure rather than returned as valid devices.
        NSString *addressString = FirstNonEmptyString([device addressString], nil, nil);
        NSString *nameString = FirstNonEmptyString([device name], [device nameOrAddress], addressString);

        resultDevice->device_name = CopyNSStringToUtf8CString(nameString);
        resultDevice->mac_address = CopyNSStringToUtf8CString(addressString);

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread GalaxyBudsClient.Platform.OSX/Native/src/BluetoothDeviceWatcher.mm Outdated
Comment thread GalaxyBudsClient.Platform.OSX/Native/src/Bluetooth.mm Outdated
Extract IsNullOrEmpty, FirstNonEmptyString and CopyNSStringToUtf8CString
into Native/src/NativeStringUtils.h so the paired-device enumeration and
watcher callback paths share a single definition instead of keeping two
verbatim copies in lockstep.
Skip IOBluetoothDevice entries whose addressString is null or empty
instead of returning them with an empty mac_address. Empty addresses
flowed through to the manual pairing dialog and bt_connect, which
cannot resolve them. result->length now reflects the count of usable
devices populated in the loop.
@giovanninibarbosa giovanninibarbosa force-pushed the fix/macos-bluetooth-null-strings branch from d2028ea to 34cf2ee Compare May 19, 2026 19:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants