Improve OSC 9;9 parsing logic & add tests (#8934)

This PR fixes the parsing of OSC 9;9 sequences with path surrounded by
quotation marks.

Original OSC 9;9 PR: #8330 

Unit test added. Manually tested with oh-my-posh.

Closes #8930
This commit is contained in:
Chester Liu 2021-02-04 09:10:21 +08:00 committed by GitHub
parent 619710852c
commit 0811c572ae
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 70 additions and 1 deletions

View file

@ -474,7 +474,19 @@ bool TerminalDispatch::DoConEmuAction(const std::wstring_view string) noexcept
{
if (parts.size() >= 2)
{
return _terminalApi.SetWorkingDirectory(til::at(parts, 1));
const auto path = til::at(parts, 1);
// The path should be surrounded with '"' according to the documentation of ConEmu.
// An example: 9;"D:/"
if (path.at(0) == L'"' && path.at(path.size() - 1) == L'"' && path.size() >= 3)
{
return _terminalApi.SetWorkingDirectory(path.substr(1, path.size() - 2));
}
else
{
// If we fail to find the surrounding quotation marks, we'll give the path a try anyway.
// ConEmu also does this.
return _terminalApi.SetWorkingDirectory(path);
}
}
}

View file

@ -40,6 +40,7 @@ namespace TerminalCoreUnitTests
TEST_METHOD(AddHyperlinkCustomIdDifferentUri);
TEST_METHOD(SetTaskbarProgress);
TEST_METHOD(SetWorkingDirectory);
};
};
@ -388,3 +389,59 @@ void TerminalCoreUnitTests::TerminalApiTest::SetTaskbarProgress()
VERIFY_ARE_EQUAL(term.GetTaskbarState(), gsl::narrow<size_t>(1));
VERIFY_ARE_EQUAL(term.GetTaskbarProgress(), gsl::narrow<size_t>(80));
}
void TerminalCoreUnitTests::TerminalApiTest::SetWorkingDirectory()
{
Terminal term;
DummyRenderTarget emptyRT;
term.Create({ 100, 100 }, 0, emptyRT);
auto& stateMachine = *(term._stateMachine);
// Test setting working directory using OSC 9;9
// Initial CWD should be empty
VERIFY_IS_TRUE(term.GetWorkingDirectory().empty());
// Invalid sequences should not change CWD
stateMachine.ProcessString(L"\x1b]9;9\x9c");
VERIFY_IS_TRUE(term.GetWorkingDirectory().empty());
stateMachine.ProcessString(L"\x1b]9;9\"\x9c");
VERIFY_IS_TRUE(term.GetWorkingDirectory().empty());
stateMachine.ProcessString(L"\x1b]9;9\"C:\\\"\x9c");
VERIFY_IS_TRUE(term.GetWorkingDirectory().empty());
// Valid sequences should change CWD
stateMachine.ProcessString(L"\x1b]9;9;\"C:\\\"\x9c");
VERIFY_ARE_EQUAL(term.GetWorkingDirectory(), L"C:\\");
stateMachine.ProcessString(L"\x1b]9;9;\"C:\\Program Files\"\x9c");
VERIFY_ARE_EQUAL(term.GetWorkingDirectory(), L"C:\\Program Files");
stateMachine.ProcessString(L"\x1b]9;9;\"D:\\中文\"\x9c");
VERIFY_ARE_EQUAL(term.GetWorkingDirectory(), L"D:\\中文");
// Test OSC 9;9 sequences without quotation marks
stateMachine.ProcessString(L"\x1b]9;9;C:\\\x9c");
VERIFY_ARE_EQUAL(term.GetWorkingDirectory(), L"C:\\");
stateMachine.ProcessString(L"\x1b]9;9;C:\\Program Files\x9c");
VERIFY_ARE_EQUAL(term.GetWorkingDirectory(), L"C:\\Program Files");
stateMachine.ProcessString(L"\x1b]9;9;D:\\中文\x9c");
VERIFY_ARE_EQUAL(term.GetWorkingDirectory(), L"D:\\中文");
// These OSC 9;9 sequences will result in invalid CWD. We shouldn't crash on these.
stateMachine.ProcessString(L"\x1b]9;9;\"\x9c");
VERIFY_ARE_EQUAL(term.GetWorkingDirectory(), L"\"");
stateMachine.ProcessString(L"\x1b]9;9;\"\"\x9c");
VERIFY_ARE_EQUAL(term.GetWorkingDirectory(), L"\"\"");
stateMachine.ProcessString(L"\x1b]9;9;\"\"\"\x9c");
VERIFY_ARE_EQUAL(term.GetWorkingDirectory(), L"\"");
stateMachine.ProcessString(L"\x1b]9;9;\"\"\"\"\x9c");
VERIFY_ARE_EQUAL(term.GetWorkingDirectory(), L"\"\"");
}