[Kernel] Enforce *. in wildcard matching. Supersedes #1675.

This commit is contained in:
gibbed 2020-11-15 13:22:04 -06:00 committed by Rick Gibbed
parent d1f7ee3593
commit 32e8b47a33
1 changed files with 28 additions and 3 deletions

View File

@ -1,4 +1,4 @@
/** /**
****************************************************************************** ******************************************************************************
* Xenia : Xbox 360 Emulator Research Project * * Xenia : Xbox 360 Emulator Research Project *
****************************************************************************** ******************************************************************************
@ -41,10 +41,23 @@ struct CreateOptions {
static bool IsValidPath(const std::string_view s, bool is_pattern) { static bool IsValidPath(const std::string_view s, bool is_pattern) {
// TODO(gibbed): validate path components individually // TODO(gibbed): validate path components individually
bool got_asterisk = false;
for (const auto& c : s) { for (const auto& c : s) {
if (c <= 31 || c >= 127) { if (c <= 31 || c >= 127) {
return false; return false;
} }
if (got_asterisk) {
// * must be followed by a . (*.)
//
// Viva Piñata: Party Animals (4D530819) has a bug in its game code where
// it attempts to FindFirstFile() with filters of "Game:\\*_X3.rkv",
// "Game:\\m*_X3.rkv", and "Game:\\w*_X3.rkv" and will infinite loop if
// the path filter is allowed.
if (c != '.') {
return false;
}
got_asterisk = false;
}
switch (c) { switch (c) {
case '"': case '"':
// case '*': // case '*':
@ -59,18 +72,30 @@ static bool IsValidPath(const std::string_view s, bool is_pattern) {
case '|': { case '|': {
return false; return false;
} }
case '*': case '*': {
// Pattern-specific (for NtQueryDirectoryFile)
if (!is_pattern) {
return false;
}
got_asterisk = true;
break;
}
case '?': { case '?': {
// Pattern-specific (for NtQueryDirectoryFile) // Pattern-specific (for NtQueryDirectoryFile)
if (!is_pattern) { if (!is_pattern) {
return false; return false;
} }
break;
} }
default: { default: {
break; break;
} }
} }
} }
if (got_asterisk) {
// * must be followed by a . (*.)
return false;
}
return true; return true;
} }
@ -425,7 +450,7 @@ dword_result_t NtQueryDirectoryFile(
// Enforce that the path is ASCII. // Enforce that the path is ASCII.
if (!IsValidPath(name, true)) { if (!IsValidPath(name, true)) {
return X_STATUS_OBJECT_NAME_INVALID; return X_STATUS_INVALID_PARAMETER;
} }
if (file) { if (file) {