Skip to content

Commit

Permalink
Don't ever allow ~ as a startingDirectory
Browse files Browse the repository at this point in the history
Basically, some WSL distros ship fragments that replace the commandline with the executable for their distro (`ubuntu.exe`, etc.). We didn't exxpect that.

Unfortunately, `~` is really never a valid path for a process on windows, so those distros would now fail with

```
[error 2147942667 (0x8007010b) when launching `ubuntu1804.exe']
Could not access starting directory "~"
```

* [x] Closes #12353
* [x] Tested with a (`ubuntu1804.exe`, `~`) profile - launched successfully, where 1.13 in market fails.
  • Loading branch information
zadjii-msft committed Feb 8, 2022
1 parent a935bb7 commit 015084f
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 1 deletion.
24 changes: 24 additions & 0 deletions src/types/ut_types/UtilsTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -479,5 +479,29 @@ void UtilsTests::TestMangleWSLPaths()
VERIFY_ARE_EQUAL(LR"("wsl" --cd "\\wsl.localhost\Ubuntu\home\user" -d Ubuntu)", commandline);
VERIFY_ARE_EQUAL(L"", path);
}

/// Tests for GH #12353

const auto expectedUserProfilePath = wil::ExpandEnvironmentStringsW<std::wstring>(L"%USERPROFILE%");
{
auto [commandline, path] = MangleStartingDirectoryForWSL(LR"(wsl -d Ubuntu)", L"~");
VERIFY_ARE_EQUAL(LR"("wsl" --cd "~" -d Ubuntu)", commandline);
VERIFY_ARE_EQUAL(L"", path);
}
{
auto [commandline, path] = MangleStartingDirectoryForWSL(LR"(wsl ~ -d Ubuntu)", L"~");
VERIFY_ARE_EQUAL(LR"(wsl ~ -d Ubuntu)", commandline);
VERIFY_ARE_EQUAL(expectedUserProfilePath, path);
}
{
auto [commandline, path] = MangleStartingDirectoryForWSL(LR"(ubuntu ~ -d Ubuntu)", L"~");
VERIFY_ARE_EQUAL(LR"(ubuntu ~ -d Ubuntu)", commandline);
VERIFY_ARE_EQUAL(expectedUserProfilePath, path);
}
{
auto [commandline, path] = MangleStartingDirectoryForWSL(LR"(powershell.exe)", L"~");
VERIFY_ARE_EQUAL(LR"(powershell.exe)", commandline);
VERIFY_ARE_EQUAL(expectedUserProfilePath, path);
}
}
#endif
11 changes: 10 additions & 1 deletion src/types/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,7 @@ bool Utils::IsElevated()
std::tuple<std::wstring, std::wstring> Utils::MangleStartingDirectoryForWSL(std::wstring_view commandLine,
std::wstring_view startingDirectory)
{
bool executableWasWSL{ false };
do
{
if (startingDirectory.size() > 0 && commandLine.size() >= 3)
Expand All @@ -611,6 +612,7 @@ std::tuple<std::wstring, std::wstring> Utils::MangleStartingDirectoryForWSL(std:
const auto executableFilename{ executablePath.filename().wstring() };
if (executableFilename == L"wsl" || executableFilename == L"wsl.exe")
{
executableWasWSL = true;
// We've got a WSL -- let's just make sure it's the right one.
if (executablePath.has_parent_path())
{
Expand Down Expand Up @@ -670,8 +672,15 @@ std::tuple<std::wstring, std::wstring> Utils::MangleStartingDirectoryForWSL(std:
}
} while (false);

// GH #12353: `~` is never a valid windows path. We can only accept that as
// a startingDirectory when the exe is specifically wsl.exe, because that
// can override the real startingDirectory. If the user set the
// startingDirectory to ~, but the commandline to something like pwsh.exe,
// that won't actually work. In that case, mangle the startingDirectory to
// %userprofile%, so it's at least something reasonable.
return {
std::wstring{ commandLine },
std::wstring{ startingDirectory }
std::wstring{ startingDirectory == L"~" ? wil::ExpandEnvironmentStringsW<std::wstring>(L"%USERPROFILE%") :
startingDirectory }
};
}

0 comments on commit 015084f

Please sign in to comment.