diff --git a/NearbyShare/Connection/NearbyConnectionManager.swift b/NearbyShare/Connection/NearbyConnectionManager.swift index 2f8ea26..492328a 100644 --- a/NearbyShare/Connection/NearbyConnectionManager.swift +++ b/NearbyShare/Connection/NearbyConnectionManager.swift @@ -44,7 +44,6 @@ public class NearbyConnectionManager: NSObject, NetServiceDelegate, InboundNearb private static let customDeviceNameKey = "com.leonboettger.quickdrop.deviceName" public let endpointID: [UInt8] = generateEndpointID() - public static let maxNameChars = 31 public static let shared = NearbyConnectionManager() @@ -151,13 +150,13 @@ public class NearbyConnectionManager: NSObject, NetServiceDelegate, InboundNearb let deviceType = isMac() ? RemoteDeviceInfo.DeviceType.computer : (isiPadOrMac() ? .tablet : .phone) if let customName = getCustomDeviceName() { - return EndpointInfo(name: String(customName.prefix(Self.maxNameChars)), deviceType: deviceType) + return EndpointInfo(name: String(customName), deviceType: deviceType) } #if os(macOS) - return EndpointInfo(name: String((Host.current().localizedName ?? "Mac").prefix(Self.maxNameChars)), deviceType: deviceType) + return EndpointInfo(name: String((Host.current().localizedName ?? "Mac")), deviceType: deviceType) #else - return EndpointInfo(name: String(Device.current.description.withoutBracketedContent.prefix(Self.maxNameChars)), deviceType: deviceType) + return EndpointInfo(name: String(Device.current.description.withoutBracketedContent), deviceType: deviceType) #endif } diff --git a/NearbyShare/Model/DataModel.swift b/NearbyShare/Model/DataModel.swift index 0454a50..ea719cc 100644 --- a/NearbyShare/Model/DataModel.swift +++ b/NearbyShare/Model/DataModel.swift @@ -182,14 +182,15 @@ public struct EndpointInfo { var name: String? let deviceType: RemoteDeviceInfo.DeviceType let qrCodeData: Data? - + static let maxNameChars = 32 + init(name: String, deviceType: RemoteDeviceInfo.DeviceType) { - self.name = name + self.name = String(decoding: Self.sanitizedString(name), as: UTF8.self) self.deviceType = deviceType self.qrCodeData = nil } - + init?(data: Data) { guard data.count > 17 else { @@ -254,19 +255,30 @@ public struct EndpointInfo { var endpointInfo: [UInt8] = [UInt8(deviceType.rawValue << 1)] // 16 bytes: unknown random bytes for _ in 0 ... 15 { - endpointInfo.append(UInt8.random(in: 0 ... 255)) + endpointInfo.append(UInt8.random(in: 0...255)) } // Device name in UTF-8 prefixed with 1-byte length - var nameChars = [UInt8]((name ?? "").utf8) - if nameChars.count > 255 { - nameChars = [UInt8](nameChars[0 ..< 255]) - } + let nameChars = Self.sanitizedString(self.name ?? "") endpointInfo.append(UInt8(nameChars.count)) for ch in nameChars { endpointInfo.append(UInt8(ch)) } return Data(endpointInfo) } + + + private static func sanitizedString(_ string: String) -> [UInt8] { + var out: [UInt8] = [] + out.reserveCapacity(min(Self.maxNameChars, string.utf8.count)) + + for scalar in string.unicodeScalars { + let bytes = Array(scalar.utf8) + if out.count + bytes.count > Self.maxNameChars { break } + out.append(contentsOf: bytes) + } + + return out + } } diff --git a/QuickDrop/View/ChangeDeviceNameModifier.swift b/QuickDrop/View/ChangeDeviceNameModifier.swift index f33aa06..c9180b2 100644 --- a/QuickDrop/View/ChangeDeviceNameModifier.swift +++ b/QuickDrop/View/ChangeDeviceNameModifier.swift @@ -12,18 +12,11 @@ struct ChangeDeviceNameAlertModifier: ViewModifier { @Binding var isPresented: Bool @State var customName = "" - let maxLength = NearbyConnectionManager.maxNameChars - func body(content: Content) -> some View { content .alert("ChangeDeviceName", isPresented: $isPresented) { TextField("DeviceName", text: $customName) - .onChange(of: customName) { newValue in - if newValue.count > maxLength { - customName = String(newValue.prefix(maxLength)) - } - } Button("Save") { let trimmed = customName.trimmingCharacters(in: .whitespacesAndNewlines)