Skip to content

Commit 7a7cdec

Browse files
authored
Disallow fragments from containing UNC media paths (#19615)
Fragments are not allowed to declare web-source icons; this is equally true for UNC paths in the local network (or WebDAV paths!)
1 parent c7c742c commit 7a7cdec

File tree

3 files changed

+102
-0
lines changed

3 files changed

+102
-0
lines changed

.github/actions/spelling/allow/apis.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ ubrk
178178
UChar
179179
UFIELD
180180
ULARGE
181+
UNCEx
181182
UOI
182183
UPDATEINIFILE
183184
urlmon

src/cascadia/TerminalSettingsModel/CascadiaSettings.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,16 @@ static void _resolveSingleMediaResourceInner(Model::OriginTag origin, std::wstri
587587
}
588588
}
589589

590+
if (origin == winrt::Microsoft::Terminal::Settings::Model::OriginTag::Fragment)
591+
{
592+
if (PathIsUNCEx(resourcePath.c_str(), nullptr))
593+
{
594+
// A UNC path is just another type of network path, which fragments are not allowed to specify.
595+
resource.Reject();
596+
return;
597+
}
598+
}
599+
590600
// Not a URI? Try a path.
591601
try
592602
{

src/cascadia/UnitTests_SettingsModel/MediaResourceTests.cpp

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ namespace SettingsModelUnitTests
103103
TEST_METHOD(RealResolverFilePaths);
104104
TEST_METHOD(RealResolverSpecialKeywords);
105105
TEST_METHOD(RealResolverUrlCases);
106+
TEST_METHOD(RealResolverUNCCases);
106107

107108
static constexpr std::wstring_view pingCommandline{ LR"(C:\Windows\System32\PING.EXE)" }; // Normalized by Profile (this is the casing that Windows stores on disk)
108109
static constexpr std::wstring_view overrideCommandline{ LR"(C:\Windows\System32\cscript.exe)" };
@@ -1342,5 +1343,95 @@ namespace SettingsModelUnitTests
13421343
VERIFY_ARE_NOT_EQUAL(image.Resolved(), image.Path());
13431344
}
13441345
}
1346+
1347+
void MediaResourceTests::RealResolverUNCCases()
1348+
{
1349+
WEX::TestExecution::DisableVerifyExceptions disableVerifyExceptions{};
1350+
1351+
g_mediaResolverHook = nullptr; // Use the real resolver
1352+
1353+
// For profile, we test images instead of icon because Icon has a fallback behavior.
1354+
auto settings = createSettingsWithFragments(R"({})", { Fragment{ L"fragment", fragmentBasePath1, R"(
1355+
{
1356+
"profiles": {
1357+
"list": [
1358+
{
1359+
"backgroundImage": "\\\\server",
1360+
"name": "ProfileUNCServerOnly"
1361+
},
1362+
{
1363+
"backgroundImage": "\\\\server\\share",
1364+
"name": "ProfileUNCServerShare"
1365+
},
1366+
{
1367+
"backgroundImage": "\\\\server\\share\\file",
1368+
"name": "ProfileUNCFullPath"
1369+
},
1370+
{
1371+
"backgroundImage": "\\\\?\\UNC\\server",
1372+
"name": "ProfileWin32NamespaceUNCServerOnly"
1373+
},
1374+
{
1375+
"backgroundImage": "\\\\?\\UNC\\server\\share",
1376+
"name": "ProfileWin32NamespaceUNCServerShare"
1377+
},
1378+
{
1379+
"backgroundImage": "\\\\?\\UNC\\server\\share\\file",
1380+
"name": "ProfileWin32NamespaceUNCFullPath"
1381+
},
1382+
{
1383+
"backgroundImage": "\\\\?\\C:\\Windows\\System32\\cmd.exe",
1384+
"name": "ProfileWin32NamespaceDrivePath"
1385+
},
1386+
]
1387+
}
1388+
})" } });
1389+
1390+
{
1391+
auto profile{ settings->GetProfileByName(L"ProfileUNCServerOnly") };
1392+
auto image{ profile.DefaultAppearance().BackgroundImagePath() };
1393+
VERIFY_IS_FALSE(image.Ok());
1394+
}
1395+
1396+
{
1397+
auto profile{ settings->GetProfileByName(L"ProfileUNCServerShare") };
1398+
auto image{ profile.DefaultAppearance().BackgroundImagePath() };
1399+
VERIFY_IS_FALSE(image.Ok());
1400+
}
1401+
1402+
{
1403+
auto profile{ settings->GetProfileByName(L"ProfileUNCFullPath") };
1404+
auto image{ profile.DefaultAppearance().BackgroundImagePath() };
1405+
VERIFY_IS_FALSE(image.Ok());
1406+
}
1407+
1408+
{
1409+
auto profile{ settings->GetProfileByName(L"ProfileWin32NamespaceUNCServerOnly") };
1410+
auto image{ profile.DefaultAppearance().BackgroundImagePath() };
1411+
VERIFY_IS_FALSE(image.Ok());
1412+
}
1413+
1414+
{
1415+
auto profile{ settings->GetProfileByName(L"ProfileWin32NamespaceUNCServerShare") };
1416+
auto image{ profile.DefaultAppearance().BackgroundImagePath() };
1417+
VERIFY_IS_FALSE(image.Ok());
1418+
}
1419+
1420+
{
1421+
auto profile{ settings->GetProfileByName(L"ProfileWin32NamespaceUNCFullPath") };
1422+
auto image{ profile.DefaultAppearance().BackgroundImagePath() };
1423+
VERIFY_IS_FALSE(image.Ok());
1424+
}
1425+
1426+
// The only one of these paths which is OK is the one to \\?\C:\Windows
1427+
{
1428+
auto profile{ settings->GetProfileByName(L"ProfileWin32NamespaceDrivePath") };
1429+
auto image{ profile.DefaultAppearance().BackgroundImagePath() };
1430+
VERIFY_IS_TRUE(image.Ok());
1431+
}
1432+
1433+
// We cannot test that user-originated UNC paths resolve properly because we cannot guarantee
1434+
// the existence of a network share on any test machine, be it in a lab or owned by a user.
1435+
}
13451436
#pragma endregion
13461437
}

0 commit comments

Comments
 (0)