Skip to content

Commit

Permalink
Fix theoretical new-tab file drop crash (#15336)
Browse files Browse the repository at this point in the history
After retrieving the items via `GetStorageItemsAsync()` inside a try
clause it fails to check if the pointer is actually non-null.
Apart from this this commit fixes the unsafe use of `this` by properly
using `get_weak()`. Finally it allows >1 paths to be dropped.

## Validation Steps Performed
* Dropping >1 file works ✅
* Dropping >1 directory works ✅

(cherry picked from commit 99abb2a)
Service-Card-Id: 89193984
Service-Version: 1.18
  • Loading branch information
lhecker authored and DHowett committed May 12, 2023
1 parent 6364450 commit e80661f
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 25 deletions.
52 changes: 29 additions & 23 deletions src/cascadia/TerminalApp/TerminalPage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,12 +238,7 @@ namespace winrt::TerminalApp::implementation
page->_OpenNewTerminalViaDropdown(NewTerminalArgs());
}
});
_newTabButton.Drop([weakThis{ get_weak() }](const Windows::Foundation::IInspectable&, winrt::Windows::UI::Xaml::DragEventArgs e) {
if (auto page{ weakThis.get() })
{
page->NewTerminalByDrop(e);
}
});
_newTabButton.Drop({ get_weak(), &TerminalPage::_NewTerminalByDrop });
_tabView.SelectionChanged({ this, &TerminalPage::_OnTabSelectionChanged });
_tabView.TabCloseRequested({ this, &TerminalPage::_OnTabCloseRequested });
_tabView.TabItemsChanged({ this, &TerminalPage::_OnTabItemsChanged });
Expand Down Expand Up @@ -402,35 +397,46 @@ namespace winrt::TerminalApp::implementation
}
}

winrt::fire_and_forget TerminalPage::NewTerminalByDrop(winrt::Windows::UI::Xaml::DragEventArgs& e)
winrt::fire_and_forget TerminalPage::_NewTerminalByDrop(const Windows::Foundation::IInspectable&, winrt::Windows::UI::Xaml::DragEventArgs e)
try
{
Windows::Foundation::Collections::IVectorView<Windows::Storage::IStorageItem> items;
try
const auto data = e.DataView();
if (!data.Contains(StandardDataFormats::StorageItems()))
{
items = co_await e.DataView().GetStorageItemsAsync();
co_return;
}
CATCH_LOG();

if (items.Size() == 1)
const auto weakThis = get_weak();
const auto items = co_await data.GetStorageItemsAsync();
const auto strongThis = weakThis.get();
if (!strongThis)
{
std::filesystem::path path(items.GetAt(0).Path().c_str());
co_return;
}

TraceLoggingWrite(
g_hTerminalAppProvider,
"NewTabByDragDrop",
TraceLoggingDescription("Event emitted when the user drag&drops onto the new tab button"),
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));

for (const auto& item : items)
{
auto directory = item.Path();

std::filesystem::path path(std::wstring_view{ directory });
if (!std::filesystem::is_directory(path))
{
path = path.parent_path();
directory = winrt::hstring{ path.parent_path().native() };
}

NewTerminalArgs args;
args.StartingDirectory(winrt::hstring{ path.wstring() });
this->_OpenNewTerminalViaDropdown(args);

TraceLoggingWrite(
g_hTerminalAppProvider,
"NewTabByDragDrop",
TraceLoggingDescription("Event emitted when the user drag&drops onto the new tab button"),
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
args.StartingDirectory(directory);
_OpenNewTerminalViaDropdown(args);
}
}
CATCH_LOG()

// Method Description:
// - This method is called once command palette action was chosen for dispatching
Expand Down
4 changes: 2 additions & 2 deletions src/cascadia/TerminalApp/TerminalPage.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,6 @@ namespace winrt::TerminalApp::implementation
void HandoffToElevated(const Microsoft::Terminal::Settings::Model::CascadiaSettings& settings);
Microsoft::Terminal::Settings::Model::WindowLayout GetWindowLayout();

winrt::fire_and_forget NewTerminalByDrop(winrt::Windows::UI::Xaml::DragEventArgs& e);

hstring Title();

void TitlebarClicked();
Expand Down Expand Up @@ -275,6 +273,8 @@ namespace winrt::TerminalApp::implementation

winrt::Microsoft::Terminal::TerminalConnection::ConptyConnection::NewConnection_revoker _newConnectionRevoker;

winrt::fire_and_forget _NewTerminalByDrop(const Windows::Foundation::IInspectable&, winrt::Windows::UI::Xaml::DragEventArgs e);

__declspec(noinline) CommandPalette _loadCommandPaletteSlowPath();
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::UI::Xaml::Controls::ContentDialogResult> _ShowDialogHelper(const std::wstring_view& name);

Expand Down

0 comments on commit e80661f

Please sign in to comment.