From 7cfb364406efee67e8c666ba66438fba5ef575b5 Mon Sep 17 00:00:00 2001 From: ftsui Date: Wed, 2 Oct 2024 16:59:53 -0700 Subject: [PATCH 1/2] [url_launcher] Decode file URLs before passing it to ShellExecuteW. - ShellExecuteW does not handle file: urls that contain %-encoded UTF-8 strings correctly. %-encoded ASCII strings are handled correctly, as are file "urls" that contain Unicode strings in its path component. - This change perform URL decode on file: urls before passing to ShellExecuteW. --- .../url_launcher_windows/CHANGELOG.md | 3 ++- .../url_launcher_windows/pubspec.yaml | 2 +- .../windows/CMakeLists.txt | 4 +-- .../test/url_launcher_windows_test.cpp | 25 +++++++++++++++++++ .../windows/url_launcher_plugin.cpp | 15 ++++++++++- 5 files changed, 44 insertions(+), 5 deletions(-) diff --git a/packages/url_launcher/url_launcher_windows/CHANGELOG.md b/packages/url_launcher/url_launcher_windows/CHANGELOG.md index 13405529be9..6d37416d091 100644 --- a/packages/url_launcher/url_launcher_windows/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_windows/CHANGELOG.md @@ -1,6 +1,7 @@ -## NEXT +## 3.1.3 * Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. +* Fix handling of file: URLs that contain UTF-8 encoded paths. ## 3.1.2 diff --git a/packages/url_launcher/url_launcher_windows/pubspec.yaml b/packages/url_launcher/url_launcher_windows/pubspec.yaml index addd5363905..629e9dc7196 100644 --- a/packages/url_launcher/url_launcher_windows/pubspec.yaml +++ b/packages/url_launcher/url_launcher_windows/pubspec.yaml @@ -2,7 +2,7 @@ name: url_launcher_windows description: Windows implementation of the url_launcher plugin. repository: https://github.com/flutter/packages/tree/main/packages/url_launcher/url_launcher_windows issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+url_launcher%22 -version: 3.1.2 +version: 3.1.3 environment: sdk: ^3.3.0 diff --git a/packages/url_launcher/url_launcher_windows/windows/CMakeLists.txt b/packages/url_launcher/url_launcher_windows/windows/CMakeLists.txt index da39522c562..2b07f3a75a0 100644 --- a/packages/url_launcher/url_launcher_windows/windows/CMakeLists.txt +++ b/packages/url_launcher/url_launcher_windows/windows/CMakeLists.txt @@ -25,7 +25,7 @@ set_target_properties(${PLUGIN_NAME} PROPERTIES CXX_VISIBILITY_PRESET hidden) target_compile_definitions(${PLUGIN_NAME} PRIVATE FLUTTER_PLUGIN_IMPL) target_include_directories(${PLUGIN_NAME} INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/include") -target_link_libraries(${PLUGIN_NAME} PRIVATE flutter flutter_wrapper_plugin) +target_link_libraries(${PLUGIN_NAME} PRIVATE flutter flutter_wrapper_plugin shlwapi.lib) # List of absolute paths to libraries that should be bundled with the plugin set(file_chooser_bundled_libraries @@ -62,7 +62,7 @@ add_executable(${TEST_RUNNER} ) apply_standard_settings(${TEST_RUNNER}) target_include_directories(${TEST_RUNNER} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}") -target_link_libraries(${TEST_RUNNER} PRIVATE flutter_wrapper_plugin) +target_link_libraries(${TEST_RUNNER} PRIVATE flutter_wrapper_plugin shlwapi.lib) target_link_libraries(${TEST_RUNNER} PRIVATE gtest_main gmock) # flutter_wrapper_plugin has link dependencies on the Flutter DLL. add_custom_command(TARGET ${TEST_RUNNER} POST_BUILD diff --git a/packages/url_launcher/url_launcher_windows/windows/test/url_launcher_windows_test.cpp b/packages/url_launcher/url_launcher_windows/windows/test/url_launcher_windows_test.cpp index 26729574000..db46e1a4a98 100644 --- a/packages/url_launcher/url_launcher_windows/windows/test/url_launcher_windows_test.cpp +++ b/packages/url_launcher/url_launcher_windows/windows/test/url_launcher_windows_test.cpp @@ -22,10 +22,12 @@ namespace { using flutter::EncodableMap; using flutter::EncodableValue; +using ::testing::_; using ::testing::DoAll; using ::testing::Pointee; using ::testing::Return; using ::testing::SetArgPointee; +using ::testing::StrEq; class MockSystemApis : public SystemApis { public: @@ -135,5 +137,28 @@ TEST(UrlLauncherPlugin, LaunchReportsError) { EXPECT_TRUE(result.has_error()); } +TEST(UrlLauncherPlugin, LaunchUTF8EncodedFileURLSuccess) { + std::unique_ptr system = std::make_unique(); + + // Return a success value (>32) from launching. + EXPECT_CALL( + *system, + ShellExecuteW( + _, StrEq(L"open"), + // 家の管理/スキャナ"), + StrEq( + L"file:///G:/\x5bb6\x306e\x7ba1\x7406/\x30b9\x30ad\x30e3\x30ca"), + _, _, _)) + .WillOnce(Return(reinterpret_cast(33))); + + UrlLauncherPlugin plugin(std::move(system)); + ErrorOr result = plugin.LaunchUrl( + "file:///G:/%E5%AE%B6%E3%81%AE%E7%AE%A1%E7%90%86/" + "%E3%82%B9%E3%82%AD%E3%83%A3%E3%83%8A"); + + ASSERT_FALSE(result.has_error()); + EXPECT_TRUE(result.value()); +} + } // namespace test } // namespace url_launcher_windows diff --git a/packages/url_launcher/url_launcher_windows/windows/url_launcher_plugin.cpp b/packages/url_launcher/url_launcher_windows/windows/url_launcher_plugin.cpp index c8e7b2f516c..b737b4579b8 100644 --- a/packages/url_launcher/url_launcher_windows/windows/url_launcher_plugin.cpp +++ b/packages/url_launcher/url_launcher_windows/windows/url_launcher_plugin.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -98,7 +99,19 @@ ErrorOr UrlLauncherPlugin::CanLaunchUrl(const std::string& url) { } ErrorOr UrlLauncherPlugin::LaunchUrl(const std::string& url) { - std::wstring url_wide = Utf16FromUtf8(url); + std::wstring url_wide; + if (url.find("file:") == 0) { + // ShellExecuteW does not process %-encoded UTF8 strings in file URLs. + DWORD unescaped_len = 0; + std::string unescaped_url = url; + if (FAILED(::UrlUnescapeA(unescaped_url.data(), /*pszUnescaped=*/nullptr, + &unescaped_len, URL_UNESCAPE_INPLACE))) { + return FlutterError("open_error", "Failed to unescape file URL"); + } + url_wide = Utf16FromUtf8(unescaped_url); + } else { + url_wide = Utf16FromUtf8(url); + } int status = static_cast(reinterpret_cast( system_apis_->ShellExecuteW(nullptr, TEXT("open"), url_wide.c_str(), From b3a34f197d6f6062bbc66430fa484b3c3af76754 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Thu, 17 Oct 2024 11:19:02 -0400 Subject: [PATCH 2/2] CHANGELOG style fixes --- packages/url_launcher/url_launcher_windows/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/url_launcher/url_launcher_windows/CHANGELOG.md b/packages/url_launcher/url_launcher_windows/CHANGELOG.md index 6d37416d091..668ee6eff6a 100644 --- a/packages/url_launcher/url_launcher_windows/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_windows/CHANGELOG.md @@ -1,7 +1,7 @@ ## 3.1.3 * Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. -* Fix handling of file: URLs that contain UTF-8 encoded paths. +* Fixes handling of `file:` URLs that contain UTF-8 encoded paths. ## 3.1.2