diff --git a/src/cascadia/TerminalApp/AppLogic.cpp b/src/cascadia/TerminalApp/AppLogic.cpp index bb43bca3e54..173ff5ab2cf 100644 --- a/src/cascadia/TerminalApp/AppLogic.cpp +++ b/src/cascadia/TerminalApp/AppLogic.cpp @@ -27,10 +27,12 @@ namespace winrt // !!! IMPORTANT !!! // Make sure that these keys are in the same order as the // SettingsLoadWarnings/Errors enum is! -static const std::array settingsLoadWarningsLabels { +static const std::array settingsLoadWarningsLabels { USES_RESOURCE(L"MissingDefaultProfileText"), USES_RESOURCE(L"DuplicateProfileText"), - USES_RESOURCE(L"UnknownColorSchemeText") + USES_RESOURCE(L"UnknownColorSchemeText"), + USES_RESOURCE(L"InvalidBackgroundImage"), + USES_RESOURCE(L"InvalidIcon") }; static const std::array settingsLoadErrorsLabels { USES_RESOURCE(L"NoProfilesText"), diff --git a/src/cascadia/TerminalApp/CascadiaSettings.cpp b/src/cascadia/TerminalApp/CascadiaSettings.cpp index f520ec517bf..d51cff25532 100644 --- a/src/cascadia/TerminalApp/CascadiaSettings.cpp +++ b/src/cascadia/TerminalApp/CascadiaSettings.cpp @@ -198,6 +198,10 @@ void CascadiaSettings::_ValidateSettings() // just use the hardcoded defaults _ValidateAllSchemesExist(); + // Ensure all profile's with specified images resources have valid file path. + // This validates icons and background images. + _ValidateMediaResources(); + // TODO:GH#2548 ensure there's at least one key bound. Display a warning if // there's _NO_ keys bound to any actions. That's highly irregular, and // likely an indication of an error somehow. @@ -424,6 +428,64 @@ void CascadiaSettings::_ValidateAllSchemesExist() } } +// Method Description: +// - Ensures that all specified images resources (icons and background images) are valid URIs. +// This does not verify that the icon or background image files are encoded as an image. +// Arguments: +// - +// Return Value: +// - +// - Appends a SettingsLoadWarnings::InvalidBackgroundImage to our list of warnings if +// we find any invalid background images. +// - Appends a SettingsLoadWarnings::InvalidIconImage to our list of warnings if +// we find any invalid icon images. +void CascadiaSettings::_ValidateMediaResources() +{ + bool invalidBackground{ false }; + bool invalidIcon{ false }; + + for (auto& profile : _profiles) + { + if (profile.HasBackgroundImage()) + { + // Attempt to convert the path to a URI, the ctor will throw if it's invalid/unparseable. + // This covers file paths on the machine, app data, URLs, and other resource paths. + try + { + winrt::Windows::Foundation::Uri imagePath{ profile.GetExpandedBackgroundImagePath() }; + } + catch (...) + { + profile.ResetBackgroundImagePath(); + invalidBackground = true; + } + } + + if (profile.HasIcon()) + { + try + { + winrt::Windows::Foundation::Uri imagePath{ profile.GetExpandedIconPath() }; + } + catch (...) + { + profile.ResetIconPath(); + invalidIcon = true; + } + } + } + + if (invalidBackground) + { + _warnings.push_back(::TerminalApp::SettingsLoadWarnings::InvalidBackgroundImage); + } + + if (invalidIcon) + { + _warnings.push_back(::TerminalApp::SettingsLoadWarnings::InvalidIcon); + } +} + // Method Description: // - Create a TerminalSettings object for the provided newTerminalArgs. We'll // use the newTerminalArgs to look up the profile that should be used to diff --git a/src/cascadia/TerminalApp/CascadiaSettings.h b/src/cascadia/TerminalApp/CascadiaSettings.h index 9c5daecb980..50fa261a187 100644 --- a/src/cascadia/TerminalApp/CascadiaSettings.h +++ b/src/cascadia/TerminalApp/CascadiaSettings.h @@ -115,6 +115,7 @@ class TerminalApp::CascadiaSettings final void _ReorderProfilesToMatchUserSettingsOrder(); void _RemoveHiddenProfiles(); void _ValidateAllSchemesExist(); + void _ValidateMediaResources(); friend class TerminalAppLocalTests::SettingsTests; friend class TerminalAppLocalTests::ProfileTests; diff --git a/src/cascadia/TerminalApp/Profile.cpp b/src/cascadia/TerminalApp/Profile.cpp index d4b2170f4cd..9fba138aa70 100644 --- a/src/cascadia/TerminalApp/Profile.cpp +++ b/src/cascadia/TerminalApp/Profile.cpp @@ -847,6 +847,14 @@ void Profile::SetIconPath(std::wstring_view path) _icon.emplace(path); } +// Method Description: +// - Resets the std::optional holding the icon file path string. +// HasIcon() will return false after the execution of this function. +void Profile::ResetIconPath() +{ + _icon.reset(); +} + // Method Description: // - Returns this profile's icon path, if one is set. Otherwise returns the // empty string. This method will expand any environment variables in the @@ -880,6 +888,14 @@ winrt::hstring Profile::GetExpandedBackgroundImagePath() const return result; } +// Method Description: +// - Resets the std::optional holding the background image file path string. +// HasBackgroundImage() will return false after the execution of this function. +void Profile::ResetBackgroundImagePath() +{ + _backgroundImage.reset(); +} + // Method Description: // - Returns the name of this profile. // Arguments: diff --git a/src/cascadia/TerminalApp/Profile.h b/src/cascadia/TerminalApp/Profile.h index 6f0e0a1f50a..19979eee307 100644 --- a/src/cascadia/TerminalApp/Profile.h +++ b/src/cascadia/TerminalApp/Profile.h @@ -89,9 +89,11 @@ class TerminalApp::Profile final bool HasIcon() const noexcept; winrt::hstring GetExpandedIconPath() const; void SetIconPath(std::wstring_view path); + void ResetIconPath(); bool HasBackgroundImage() const noexcept; winrt::hstring GetExpandedBackgroundImagePath() const; + void ResetBackgroundImagePath(); CloseOnExitMode GetCloseOnExitMode() const noexcept; bool GetSuppressApplicationTitle() const noexcept; diff --git a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw index 3296a65b221..d8e5fa3a09e 100644 --- a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw @@ -210,4 +210,10 @@ Temporarily using the Windows Terminal default settings. Do you want to close all tabs? + + Found a profile with an invalid "backgroundImage". Defaulting that profile to have no background image. Make sure that when setting a "backgroundImage", the value is a valid file path to an image. + + + Found a profile with an invalid "icon". Defaulting that profile to have no icon. Make sure that when setting an "icon", the value is a valid file path to an image. + diff --git a/src/cascadia/TerminalApp/TerminalWarnings.h b/src/cascadia/TerminalApp/TerminalWarnings.h index 19d6fdcd665..35db814d999 100644 --- a/src/cascadia/TerminalApp/TerminalWarnings.h +++ b/src/cascadia/TerminalApp/TerminalWarnings.h @@ -23,7 +23,9 @@ namespace TerminalApp { MissingDefaultProfile = 0, DuplicateProfile = 1, - UnknownColorScheme = 2 + UnknownColorScheme = 2, + InvalidBackgroundImage = 3, + InvalidIcon = 4 }; // SettingsLoadWarnings are scenarios where the settings had invalid state