diff --git a/.github/actions/spelling/dictionary/dictionary.txt b/.github/actions/spelling/dictionary/dictionary.txt index de26c13938a..2b3236d31dc 100644 --- a/.github/actions/spelling/dictionary/dictionary.txt +++ b/.github/actions/spelling/dictionary/dictionary.txt @@ -183443,6 +183443,8 @@ hostlership hostlerwife hostless hostly +hostname +hostnames hostry hosts hostship diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index b96a0e7cc09..8431ea32f49 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -2148,7 +2148,7 @@ namespace winrt::TerminalApp::implementation try { auto parsed = winrt::Windows::Foundation::Uri(eventArgs.Uri().c_str()); - if (parsed.SchemeName() == L"http" || parsed.SchemeName() == L"https") + if (_IsUriSupported(parsed)) { ShellExecute(nullptr, L"open", eventArgs.Uri().c_str(), nullptr, nullptr, SW_SHOWNORMAL); } @@ -2185,6 +2185,37 @@ namespace winrt::TerminalApp::implementation } } + // Method Description: + // - Determines if the given URI is currently supported + // Arguments: + // - The parsed URI + // Return value: + // - True if we support it, false otherwise + bool TerminalPage::_IsUriSupported(const winrt::Windows::Foundation::Uri& parsedUri) + { + if (parsedUri.SchemeName() == L"http" || parsedUri.SchemeName() == L"https") + { + return true; + } + if (parsedUri.SchemeName() == L"file") + { + const auto host = parsedUri.Host(); + // If no hostname was provided or if the hostname was "localhost", Host() will return an empty string + // and we allow it + if (host == L"") + { + return true; + } + // TODO: by the OSC 8 spec, if a hostname (other than localhost) is provided, we _should_ be + // comparing that value against what is returned by GetComputerNameExW and making sure they match. + // However, ShellExecute does not seem to be happy with file URIs of the form + // file://{hostname}/path/to/file.ext + // and so while we could do the hostname matching, we do not know how to actually open the URI + // if its given in that form. So for now we ignore all hostnames other than localhost + } + return false; + } + void TerminalPage::_ControlNoticeRaisedHandler(const IInspectable /*sender*/, const Microsoft::Terminal::TerminalControl::NoticeEventArgs eventArgs) { winrt::hstring message = eventArgs.Message(); diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index 67ca1841d60..603ddb1c551 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -217,6 +217,8 @@ namespace winrt::TerminalApp::implementation const Microsoft::Terminal::TerminalControl::PasteFromClipboardEventArgs eventArgs); void _OpenHyperlinkHandler(const IInspectable sender, const Microsoft::Terminal::TerminalControl::OpenHyperlinkEventArgs eventArgs); + bool _IsUriSupported(const winrt::Windows::Foundation::Uri& parsedUri); + void _ShowCouldNotOpenDialog(winrt::hstring reason, winrt::hstring uri); bool _CopyText(const bool singleLine, const Windows::Foundation::IReference& formats);