Description
Bluetooth accessory names containing a typographic apostrophe can be corrupted in the TUI.
For example:
- Expected:
yuchen’s Magic Keyboard
- Actual:
yuchen�s Magic Keyboard
The raw output from pmset -g accps can contain byte 0xD5, which represents U+2019 RIGHT SINGLE QUOTATION MARK in MacRoman. Decoding the output with String::from_utf8_lossy treats that byte as invalid UTF-8 and inserts U+FFFD.
Current code
Some(o) if o.status.success() => {
String::from_utf8_lossy(&o.stdout).to_string()
}
Fix
Keep the command output as bytes, preserve valid UTF-8, and fall back to MacRoman decoding only when needed:
Some(o) if o.status.success() => o.stdout,
fn parse_bluetooth_devices(output: &[u8]) -> Vec<BluetoothDevice> {
let output = match std::str::from_utf8(output) {
Ok(text) => std::borrow::Cow::Borrowed(text),
Err(_) => {
let (text, _, _) = encoding_rs::MACINTOSH.decode(output);
text
}
};
// Existing Bluetooth device parsing continues here.
}
Regression tests should cover both MacRoman and already-valid UTF-8 device names.
Pull request
A fix has already been submitted in #18.
Description
Bluetooth accessory names containing a typographic apostrophe can be corrupted in the TUI.
For example:
yuchen’s Magic Keyboardyuchen�s Magic KeyboardThe raw output from
pmset -g accpscan contain byte0xD5, which representsU+2019 RIGHT SINGLE QUOTATION MARKin MacRoman. Decoding the output withString::from_utf8_lossytreats that byte as invalid UTF-8 and insertsU+FFFD.Current code
Fix
Keep the command output as bytes, preserve valid UTF-8, and fall back to MacRoman decoding only when needed:
Regression tests should cover both MacRoman and already-valid UTF-8 device names.
Pull request
A fix has already been submitted in #18.