From 82f7b439c889500ad2e8bececb8cebe595886381 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sun, 5 Apr 2015 10:59:07 +0300 Subject: [PATCH 1/2] Improved text pasting on OS X Support for UTF-8 and UTF-16 encodings should cover all cases of text pasting from clipboard --- src/posix/i_system.cpp | 44 ++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/src/posix/i_system.cpp b/src/posix/i_system.cpp index b3de61419..f87cf76ae 100644 --- a/src/posix/i_system.cpp +++ b/src/posix/i_system.cpp @@ -603,6 +603,15 @@ int I_FindAttr (findstate_t *fileinfo) #ifdef __APPLE__ static PasteboardRef s_clipboard; + +static CFDataRef GetPasteboardData(const PasteboardItemID itemID, const CFStringRef flavorType) +{ + CFDataRef data = NULL; + + const OSStatus result = PasteboardCopyItemFlavorData(s_clipboard, itemID, flavorType, &data); + + return noErr == result ? data : NULL; +} #endif // __APPLE__ // Clipboard support requires GTK+ @@ -688,35 +697,36 @@ FString I_GetFromClipboard (bool use_primary_selection) return FString(); } - CFArrayRef flavorTypeArray; - - if (0 != PasteboardCopyItemFlavors(s_clipboard, itemID, &flavorTypeArray)) + if (CFDataRef data = GetPasteboardData(itemID, kUTTypeUTF8PlainText)) { - return FString(); + result = reinterpret_cast(CFDataGetBytePtr(data)); } - - const CFIndex flavorCount = CFArrayGetCount(flavorTypeArray); - - for (CFIndex flavorIndex = 0; flavorIndex < flavorCount; ++flavorIndex) + else if (CFDataRef data = GetPasteboardData(itemID, kUTTypeUTF16PlainText)) { - const CFStringRef flavorType = static_cast( - CFArrayGetValueAtIndex(flavorTypeArray, flavorIndex)); +#ifdef __LITTLE_ENDIAN__ + static const CFStringEncoding ENCODING = kCFStringEncodingUTF16LE; +#else // __BIG_ENDIAN__ + static const CFStringEncoding ENCODING = kCFStringEncodingUTF16BE; +#endif // __LITTLE_ENDIAN__ - if (UTTypeConformsTo(flavorType, CFSTR("public.utf8-plain-text"))) + if (const CFStringRef utf16 = CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, data, ENCODING)) { - CFDataRef flavorData; + const CFRange range = { 0, CFStringGetLength(utf16) }; + CFIndex bufferLength = 0; - if (0 == PasteboardCopyItemFlavorData(s_clipboard, itemID, flavorType, &flavorData)) + if (CFStringGetBytes(utf16, range, kCFStringEncodingUTF8, '?', false, NULL, 0, &bufferLength) > 0) { - result += reinterpret_cast(CFDataGetBytePtr(flavorData)); + UInt8* const buffer = reinterpret_cast(result.LockNewBuffer(bufferLength)); + + CFStringGetBytes(utf16, range, kCFStringEncodingUTF8, '?', false, buffer, bufferLength, NULL); + + result.UnlockBuffer(); } - CFRelease(flavorData); + CFRelease(utf16); } } - CFRelease(flavorTypeArray); - return result; #endif return ""; From 7b8931292318c145ce34ec53d4ee8f6a3291274e Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sun, 5 Apr 2015 11:52:57 +0300 Subject: [PATCH 2/2] Fixed potential issue with read beyond buffer boundaries --- src/posix/i_system.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/posix/i_system.cpp b/src/posix/i_system.cpp index f87cf76ae..0a1b2f69a 100644 --- a/src/posix/i_system.cpp +++ b/src/posix/i_system.cpp @@ -699,7 +699,12 @@ FString I_GetFromClipboard (bool use_primary_selection) if (CFDataRef data = GetPasteboardData(itemID, kUTTypeUTF8PlainText)) { - result = reinterpret_cast(CFDataGetBytePtr(data)); + const CFIndex bufferLength = CFDataGetLength(data); + char* const buffer = result.LockNewBuffer(bufferLength); + + memcpy(buffer, CFDataGetBytePtr(data), bufferLength); + + result.UnlockBuffer(); } else if (CFDataRef data = GetPasteboardData(itemID, kUTTypeUTF16PlainText)) {