diff --git a/src/cascadia/LocalTests_SettingsModel/TerminalSettingsTests.cpp b/src/cascadia/LocalTests_SettingsModel/TerminalSettingsTests.cpp index 841c43a8827..4f1ce422c14 100644 --- a/src/cascadia/LocalTests_SettingsModel/TerminalSettingsTests.cpp +++ b/src/cascadia/LocalTests_SettingsModel/TerminalSettingsTests.cpp @@ -199,6 +199,10 @@ namespace SettingsModelLocalTests "guid": "{6239a42c-3333-49a3-80bd-e8fdd045185c}", "commandline": "cmd.exe /A /C", "connectionType": "{9a9977a7-1fe0-49c0-b6c0-13a0cd1c98a1}" + }, + { + "guid": "{6239a42c-4444-49a3-80bd-e8fdd045185c}", + "commandline": "C:\\invalid.exe", } ] } @@ -217,7 +221,7 @@ namespace SettingsModelLocalTests TestCase{ L"cmd.exe", 0 }, // SearchPathW() normalization + case insensitive matching. TestCase{ L"cmd.exe /a", 1 }, - TestCase{ L"C:\\Windows\\System32\\cmd.exe /A", 1 }, + TestCase{ L"%SystemRoot%\\System32\\cmd.exe /A", 1 }, // Test that we don't pick the equally long but different "/A /B" variant. TestCase{ L"C:\\Windows\\System32\\cmd.exe /A /C", 1 }, // Test that we don't pick the shorter "/A" variant, @@ -227,6 +231,9 @@ namespace SettingsModelLocalTests // Ignore profiles with a connection type, like the Azure cloud shell. // Instead it should pick any other prefix. TestCase{ L"C:\\Windows\\System32\\cmd.exe /A /C", 1 }, + // Failure to normalize a path (e.g. because the path doesn't exist) + // should yield the unmodified input string (see NormalizeCommandLine). + TestCase{ L"C:\\invalid.exe /A /B", 4 }, // Return base layer profile for missing profiles. TestCase{ L"C:\\Windows\\regedit.exe", -1 }, }; diff --git a/src/cascadia/TerminalSettingsModel/CascadiaSettings.cpp b/src/cascadia/TerminalSettingsModel/CascadiaSettings.cpp index fba878395e9..4935cee4b9c 100644 --- a/src/cascadia/TerminalSettingsModel/CascadiaSettings.cpp +++ b/src/cascadia/TerminalSettingsModel/CascadiaSettings.cpp @@ -695,11 +695,6 @@ std::wstring CascadiaSettings::NormalizeCommandLine(LPCWSTR commandLine) // The index of the first argument in argv for our executable in argv[0]. // Given {"C:\Program Files\PowerShell\7\pwsh.exe", "-WorkingDirectory", "~"} this will be 1. int startOfArguments = 1; - // Returns true if the executable in argv[0] to argv[startOfArguments - 1] - // has any further arguments in argv[startOfArguments] to argv[argc - 1]. - const auto hasTrailingArguments = [&]() noexcept { - return (argc - startOfArguments) > 1; - }; // The given commandLine should start with an executable name or path. // For instance given the following argv arrays: @@ -754,7 +749,7 @@ std::wstring CascadiaSettings::NormalizeCommandLine(LPCWSTR commandLine) // Just like CreateProcessW() we thus try to concatenate arguments until we successfully resolve a valid path. // Of course we can only do that if we have at least 2 remaining arguments in argv. // All other error types aren't handled at the moment. - else if (!hasTrailingArguments() || status != HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) + else if ((argc - startOfArguments) < 2 || status != HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) { break; } @@ -770,7 +765,7 @@ std::wstring CascadiaSettings::NormalizeCommandLine(LPCWSTR commandLine) // We're now going to append all remaining arguments to the resulting string. // If argv is {"C:\Program Files\PowerShell\7\pwsh.exe", "-WorkingDirectory", "~"}, // then we'll get "C:\Program Files\PowerShell\7\pwsh.exe\0-WorkingDirectory\0~" - if (hasTrailingArguments()) + if (startOfArguments < argc) { // normalized contains a canonical form of argv[0] at this point. // -1 allows us to include the \0 between argv[0] and argv[1] in the call to append().