From 91717fe91dc50180e130b77734d6d63012d316d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C5=93ur?= Date: Wed, 12 Apr 2023 06:36:22 +0800 Subject: [PATCH] fix: potential NSString leak in tr_strv_convert_utf8() --- Transmission.xcodeproj/project.pbxproj | 3 -- libtransmission/CMakeLists.txt | 4 ++ libtransmission/utils.mm | 55 ++++++++++++++------------ macosx/CMakeLists.txt | 34 ++++++++++------ macosx/QuickLookPlugin/CMakeLists.txt | 10 ++--- 5 files changed, 62 insertions(+), 44 deletions(-) diff --git a/Transmission.xcodeproj/project.pbxproj b/Transmission.xcodeproj/project.pbxproj index 6f8b67e72..f20694f91 100644 --- a/Transmission.xcodeproj/project.pbxproj +++ b/Transmission.xcodeproj/project.pbxproj @@ -3717,7 +3717,6 @@ buildSettings = { CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_OBJC_ARC = NO; HEADER_SEARCH_PATHS = ( "$(inherited)", "third-party/dht", @@ -3961,7 +3960,6 @@ buildSettings = { CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_OBJC_ARC = NO; HEADER_SEARCH_PATHS = ( "$(inherited)", "third-party/dht", @@ -4277,7 +4275,6 @@ buildSettings = { CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_OBJC_ARC = NO; HEADER_SEARCH_PATHS = ( "$(inherited)", "third-party/dht", diff --git a/libtransmission/CMakeLists.txt b/libtransmission/CMakeLists.txt index 6fc5d26da..4476b1628 100644 --- a/libtransmission/CMakeLists.txt +++ b/libtransmission/CMakeLists.txt @@ -10,6 +10,10 @@ endif() check_symbol_exists(SO_REUSEPORT "sys/types.h;sys/socket.h" HAVE_SO_REUSEPORT) +add_compile_options( + # equivalent of XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC YES for this directory + $<$,$>:-fobjc-arc>) + add_library(${TR_NAME} STATIC) target_sources(${TR_NAME} diff --git a/libtransmission/utils.mm b/libtransmission/utils.mm index 125a5b0c0..1045779f3 100644 --- a/libtransmission/utils.mm +++ b/libtransmission/utils.mm @@ -15,35 +15,40 @@ std::string tr_strv_convert_utf8(std::string_view sv) { - // UTF-8 encoding - char const* validUTF8 = [[NSString alloc] initWithBytes:std::data(sv) length:std::size(sv) encoding:NSUTF8StringEncoding].UTF8String; - if (validUTF8) + // local pool for non-app tools like transmission-daemon, transmission-remote, transmission-create, ... + @autoreleasepool { - return std::string(validUTF8); - } - - // autodetection of the encoding (#3434) - NSString* convertedString; - NSStringEncoding stringEncoding = [NSString - stringEncodingForData:[NSData dataWithBytes:std::data(sv) length:std::size(sv)] - encodingOptions:@{ - // We disallow lossy conversion, and will leave it to `utf8::unchecked::replace_invalid`. - NSStringEncodingDetectionAllowLossyKey : @NO, - // We only set the likely language. - // If we were to set suggested encodings, then whatever is listed first would take precedence on all others, making for instance kCFStringEncodingDOSJapanese (cp932) and kCFStringEncodingDOSRussian (cp866) taking priority on each other. - NSStringEncodingDetectionLikelyLanguageKey : NSLocale.currentLocale.languageCode - } - convertedString:&convertedString - usedLossyConversion:nil]; - if (stringEncoding) - { - validUTF8 = convertedString.UTF8String; + // UTF-8 encoding + char const* validUTF8 = [[NSString alloc] initWithBytes:std::data(sv) length:std::size(sv) encoding:NSUTF8StringEncoding] + .UTF8String; if (validUTF8) { return std::string(validUTF8); } - } - // invalid encoding - return tr_strv_replace_invalid(sv); + // autodetection of the encoding (#3434) + NSString* convertedString; + NSStringEncoding stringEncoding = [NSString + stringEncodingForData:[NSData dataWithBytes:std::data(sv) length:std::size(sv)] + encodingOptions:@{ + // We disallow lossy conversion, and will leave it to `utf8::unchecked::replace_invalid`. + NSStringEncodingDetectionAllowLossyKey : @NO, + // We only set the likely language. + // If we were to set suggested encodings, then whatever is listed first would take precedence on all others, making for instance kCFStringEncodingDOSJapanese (cp932) and kCFStringEncodingDOSRussian (cp866) taking priority on each other. + NSStringEncodingDetectionLikelyLanguageKey : NSLocale.currentLocale.languageCode + } + convertedString:&convertedString + usedLossyConversion:nil]; + if (stringEncoding) + { + validUTF8 = convertedString.UTF8String; + if (validUTF8) + { + return std::string(validUTF8); + } + } + + // invalid encoding + return tr_strv_replace_invalid(sv); + } } diff --git a/macosx/CMakeLists.txt b/macosx/CMakeLists.txt index b15caaec8..5cef802d1 100644 --- a/macosx/CMakeLists.txt +++ b/macosx/CMakeLists.txt @@ -1,20 +1,32 @@ +# minimum macOS target support if(CMAKE_OSX_DEPLOYMENT_TARGET VERSION_LESS MACOS_SUPPORT_MINIMUM) message(FATAL_ERROR "Targeting macOS versions before ${MACOS_SUPPORT_MINIMUM} is not supported for the macOS project, please adjust CMAKE_OSX_DEPLOYMENT_TARGET (${CMAKE_OSX_DEPLOYMENT_TARGET})") endif() +find_program(ACTOOL_EXECUTABLE actool REQUIRED) +find_program(CODESIGN_EXECUTABLE codesign REQUIRED) + set(MAC_BUNDLE_NAME Transmission) add_compile_options( - -fcxx-modules - -fmodules - -fobjc-arc - # #warnings are good practice in development - "-Wno-#warnings" - # GNU extensions are good practice in Objective-C - -Wno-gnu) + $<$:-fmodules> + $<$:-fcxx-modules> -find_program(ACTOOL_EXECUTABLE actool REQUIRED) -find_program(CODESIGN_EXECUTABLE codesign REQUIRED) + # equivalent of XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC YES for this directory + $<$:-fobjc-arc> + + # equivalent of XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_WEAK YES for this directory + $<$:-fobjc-weak> + + # GNU extensions are good practice in Objective-C + $<$:-Wno-gnu> + + # Our #warnings are good practice in IDE development, not in command-line compilation + $<$>,$>:-Wno-\#warnings>) + +add_link_options( + # equivalent of XCODE_ATTRIBUTE_DEAD_CODE_STRIPPING YES for this directory + $<$:-dead_strip>) add_subdirectory(QuickLookPlugin) add_subdirectory(VDKQueue) @@ -411,10 +423,10 @@ endif() set_target_properties( ${TR_NAME}-mac PROPERTIES - OUTPUT_NAME ${MAC_BUNDLE_NAME} + INSTALL_RPATH "@executable_path;@executable_path/../Frameworks" MACOSX_BUNDLE_GUI_IDENTIFIER "org.m0k.transmission" MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist.in - INSTALL_RPATH "@executable_path;@executable_path/../Frameworks") + OUTPUT_NAME ${MAC_BUNDLE_NAME}) install( TARGETS ${TR_NAME}-mac diff --git a/macosx/QuickLookPlugin/CMakeLists.txt b/macosx/QuickLookPlugin/CMakeLists.txt index 541d9e8f4..3441cf91b 100644 --- a/macosx/QuickLookPlugin/CMakeLists.txt +++ b/macosx/QuickLookPlugin/CMakeLists.txt @@ -1,3 +1,5 @@ +set(MAC_QL_BUNDLE_NAME QuickLookPlugin) + add_library(${TR_NAME}-mac-ql MODULE) target_sources(${TR_NAME}-mac-ql @@ -61,17 +63,15 @@ target_sources(${TR_NAME}-mac-ql PRIVATE ${RESOURCES}) -set(MAC_QL_BUNDLE_NAME QuickLookPlugin) - set_target_properties( ${TR_NAME}-mac-ql PROPERTIES - OUTPUT_NAME ${MAC_QL_BUNDLE_NAME} - MACOSX_BUNDLE ON BUNDLE ON BUNDLE_EXTENSION qlgenerator + INSTALL_RPATH "@loader_path/../../../../../MacOS;@loader_path/../../../../../Frameworks" + MACOSX_BUNDLE ON MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Info.plist.in" - INSTALL_RPATH "@loader_path/../../../../../MacOS;@loader_path/../../../../../Frameworks") + OUTPUT_NAME ${MAC_QL_BUNDLE_NAME}) target_include_directories(${TR_NAME}-mac-ql PRIVATE