From cd2166aedfbb4cf31f72673511bbc97f48ea476c Mon Sep 17 00:00:00 2001 From: James Holderness Date: Mon, 11 Jul 2022 13:36:08 +0100 Subject: [PATCH] Allow leading spaces to bypass console aliases (#13476) ## Summary of the Pull Request When you create a console alias that overrides an existing command, it should still be possible to execute the original command by prefixing it with a space. However, at some point in the past, there was an attempt to improve the usability by trimming leading spaces, and that ended up breaking this functionality. This PR reverts that change, so leading spaces can once again be used to bypass an alias. ## PR Checklist * [x] Closes #4189 * [x] CLA signed. * [x] Tests added/passed * [ ] Documentation updated. * [ ] Schema updated. * [x] I've discussed this with core contributors already. Issue number where discussion took place: #4189 ## Validation Steps Performed I've updated the existing alias unit test for leading spaces to match the new behavior, i.e. it now confirms that a command with leading spaces will not match the alias. I've also manually confirmed that the `doskey` test case reported in issue #4189 is now working as expected. --- src/host/alias.cpp | 15 --------------- src/host/alias.h | 1 - src/host/ut_host/AliasTests.cpp | 14 ++++++-------- 3 files changed, 6 insertions(+), 24 deletions(-) diff --git a/src/host/alias.cpp b/src/host/alias.cpp index 9032630755b..b7c885bc9f4 100644 --- a/src/host/alias.cpp +++ b/src/host/alias.cpp @@ -817,18 +817,6 @@ void Alias::s_ClearCmdExeAliases() CATCH_RETURN(); } -// Routine Description: -// - Trims leading spaces off of a string -// Arguments: -// - str - String to trim -void Alias::s_TrimLeadingSpaces(std::wstring& str) -{ - // Erase from the beginning of the string up until the first - // character found that is not a space. - str.erase(str.begin(), - std::find_if(str.begin(), str.end(), [](wchar_t ch) { return !std::iswspace(ch); })); -} - // Routine Description: // - Trims trailing \r\n off of a string // Arguments: @@ -1148,9 +1136,6 @@ std::wstring Alias::s_MatchAndCopyAlias(const std::wstring& sourceText, // Trim trailing \r\n off of sourceCopy if it has one. s_TrimTrailingCrLf(sourceCopy); - // Trim leading spaces off of sourceCopy if it has any. - s_TrimLeadingSpaces(sourceCopy); - // Check if we have an EXE in the list that matches the request first. auto exeIter = g_aliasData.find(exeName); if (exeIter == g_aliasData.end()) diff --git a/src/host/alias.h b/src/host/alias.h index ba0d0b27f50..1a745c601f7 100644 --- a/src/host/alias.h +++ b/src/host/alias.h @@ -29,7 +29,6 @@ class Alias size_t& lineCount); private: - static void s_TrimLeadingSpaces(std::wstring& str); static void s_TrimTrailingCrLf(std::wstring& str); static std::deque s_Tokenize(const std::wstring& str); static std::wstring s_GetArgString(const std::wstring& str); diff --git a/src/host/ut_host/AliasTests.cpp b/src/host/ut_host/AliasTests.cpp index b6326ebb2a4..6443dd22f63 100644 --- a/src/host/ut_host/AliasTests.cpp +++ b/src/host/ut_host/AliasTests.cpp @@ -340,10 +340,10 @@ class AliasTests auto rgwchTargetBefore = std::make_unique(cchTarget); wcscpy_s(rgwchTargetBefore.get(), cchTarget, rgwchTarget.get()); size_t cbTargetUsed = 0; - const auto cbTargetUsedExpected = cbTarget; + const auto cbTargetUsedBefore = cbTargetUsed; DWORD dwLines = 0; - const auto dwLinesExpected = dwLines + 1; + const auto dwLinesBefore = dwLines; // Register the correct alias name before we try. std::wstring exe(L"exe.exe"); @@ -351,9 +351,7 @@ class AliasTests std::wstring target(L"someTarget"); Alias::s_TestAddAlias(exe, source, target); - auto targetExpected = target + L"\r\n"; - - // We should be able to match through the leading spaces. They should be stripped. + // Leading spaces should bypass the alias. This should not match anything. Alias::s_MatchAndCopyAliasLegacy(pwszSource, cbSource, rgwchTarget.get(), @@ -362,9 +360,9 @@ class AliasTests exe, dwLines); - VERIFY_ARE_EQUAL(cbTargetUsedExpected, cbTargetUsed, L"No target bytes should be used."); - VERIFY_ARE_EQUAL(String(targetExpected.data(), gsl::narrow(targetExpected.size())), String(rgwchTarget.get(), cchTarget), L"Target string should match expected."); - VERIFY_ARE_EQUAL(dwLinesExpected, dwLines, L"Line count be updated to 1."); + VERIFY_ARE_EQUAL(cbTargetUsedBefore, cbTargetUsed, L"No bytes should be used if nothing was found."); + VERIFY_ARE_EQUAL(String(rgwchTargetBefore.get(), cchTarget), String(rgwchTarget.get(), cchTarget), L"Target string should be unmodified."); + VERIFY_ARE_EQUAL(dwLinesBefore, dwLines, L"Line count should pass through."); } TEST_METHOD(TrimTrailing)