mirror of
https://github.com/reactos/reactos.git
synced 2025-05-29 22:18:13 +00:00
[NTOSKRNL]
Fix FsRtlIs*InExpression() by (finally) implementing backtracking. No regressions noticed regarding kmtest. Also commented code. svn path=/trunk/; revision=53859
This commit is contained in:
parent
d858435e44
commit
f5465755dc
2 changed files with 71 additions and 113 deletions
|
@ -160,7 +160,9 @@ NTAPI
|
||||||
FsRtlIsDbcsInExpression(IN PANSI_STRING Expression,
|
FsRtlIsDbcsInExpression(IN PANSI_STRING Expression,
|
||||||
IN PANSI_STRING Name)
|
IN PANSI_STRING Name)
|
||||||
{
|
{
|
||||||
USHORT ExpressionPosition = 0, NamePosition = 0, MatchingChars, StarFound = MAXUSHORT;
|
SHORT StarFound = -1;
|
||||||
|
PUSHORT BackTracking = NULL;
|
||||||
|
USHORT ExpressionPosition = 0, NamePosition = 0, MatchingChars;
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
ASSERT(Name->Length);
|
ASSERT(Name->Length);
|
||||||
|
@ -169,74 +171,44 @@ FsRtlIsDbcsInExpression(IN PANSI_STRING Expression,
|
||||||
|
|
||||||
while (NamePosition < Name->Length && ExpressionPosition < Expression->Length)
|
while (NamePosition < Name->Length && ExpressionPosition < Expression->Length)
|
||||||
{
|
{
|
||||||
|
/* Basic check to test if chars are equal */
|
||||||
if ((Expression->Buffer[ExpressionPosition] == Name->Buffer[NamePosition]))
|
if ((Expression->Buffer[ExpressionPosition] == Name->Buffer[NamePosition]))
|
||||||
{
|
{
|
||||||
NamePosition++;
|
NamePosition++;
|
||||||
ExpressionPosition++;
|
ExpressionPosition++;
|
||||||
}
|
}
|
||||||
else if (StarFound != MAXUSHORT && (Expression->Buffer[StarFound + 1] == '*' ||
|
/* Check cases that eat one char */
|
||||||
Expression->Buffer[StarFound + 1] == '?' || Expression->Buffer[StarFound + 1] == ANSI_DOS_DOT))
|
|
||||||
{
|
|
||||||
ExpressionPosition = StarFound + 1;
|
|
||||||
switch (Expression->Buffer[ExpressionPosition])
|
|
||||||
{
|
|
||||||
case '*':
|
|
||||||
StarFound = MAXUSHORT;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '?':
|
|
||||||
if (++ExpressionPosition == Expression->Length)
|
|
||||||
{
|
|
||||||
NamePosition = Name->Length;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
MatchingChars = NamePosition;
|
|
||||||
while (NamePosition < Name->Length &&
|
|
||||||
Name->Buffer[NamePosition] != Expression->Buffer[ExpressionPosition])
|
|
||||||
{
|
|
||||||
NamePosition++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NamePosition - MatchingChars > 0)
|
|
||||||
{
|
|
||||||
StarFound = MAXUSHORT;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ANSI_DOS_DOT:
|
|
||||||
while (NamePosition < Name->Length && Name->Buffer[NamePosition] != '.')
|
|
||||||
{
|
|
||||||
NamePosition++;
|
|
||||||
}
|
|
||||||
ExpressionPosition++;
|
|
||||||
StarFound = MAXUSHORT;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
/* Should never happen */
|
|
||||||
ASSERT(FALSE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ((Expression->Buffer[ExpressionPosition] == '?') || (Expression->Buffer[ExpressionPosition] == ANSI_DOS_QM) ||
|
else if ((Expression->Buffer[ExpressionPosition] == '?') || (Expression->Buffer[ExpressionPosition] == ANSI_DOS_QM) ||
|
||||||
(Expression->Buffer[ExpressionPosition] == ANSI_DOS_DOT && Name->Buffer[NamePosition] == '.'))
|
(Expression->Buffer[ExpressionPosition] == ANSI_DOS_DOT && Name->Buffer[NamePosition] == '.'))
|
||||||
{
|
{
|
||||||
NamePosition++;
|
NamePosition++;
|
||||||
ExpressionPosition++;
|
ExpressionPosition++;
|
||||||
StarFound = MAXUSHORT;
|
|
||||||
}
|
}
|
||||||
|
/* Test star */
|
||||||
else if (Expression->Buffer[ExpressionPosition] == '*')
|
else if (Expression->Buffer[ExpressionPosition] == '*')
|
||||||
{
|
{
|
||||||
StarFound = ExpressionPosition++;
|
/* Save star position */
|
||||||
|
if (!BackTracking)
|
||||||
|
{
|
||||||
|
BackTracking = ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,
|
||||||
|
Expression->Length * sizeof(USHORT), 'nrSF');
|
||||||
|
}
|
||||||
|
BackTracking[++StarFound] = ExpressionPosition++;
|
||||||
|
|
||||||
|
/* If star is at the end, then eat all rest and leave */
|
||||||
if (ExpressionPosition == Expression->Length)
|
if (ExpressionPosition == Expression->Length)
|
||||||
{
|
{
|
||||||
NamePosition = Name->Length;
|
NamePosition = Name->Length;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
else if (Expression->Buffer[ExpressionPosition] != '?')
|
||||||
|
{
|
||||||
|
NamePosition++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
/* Check DOS_STAR */
|
||||||
else if (Expression->Buffer[ExpressionPosition] == ANSI_DOS_STAR)
|
else if (Expression->Buffer[ExpressionPosition] == ANSI_DOS_STAR)
|
||||||
{
|
{
|
||||||
StarFound = MAXUSHORT;
|
|
||||||
MatchingChars = NamePosition;
|
MatchingChars = NamePosition;
|
||||||
while (MatchingChars < Name->Length)
|
while (MatchingChars < Name->Length)
|
||||||
{
|
{
|
||||||
|
@ -248,19 +220,24 @@ FsRtlIsDbcsInExpression(IN PANSI_STRING Expression,
|
||||||
}
|
}
|
||||||
ExpressionPosition++;
|
ExpressionPosition++;
|
||||||
}
|
}
|
||||||
else if (StarFound != MAXUSHORT)
|
/* If nothing match, try to backtrack */
|
||||||
|
else if (StarFound >= 0)
|
||||||
{
|
{
|
||||||
ExpressionPosition = StarFound + 1;
|
ExpressionPosition = BackTracking[StarFound--];
|
||||||
while (NamePosition < Name->Length &&
|
|
||||||
Name->Buffer[NamePosition] != Expression->Buffer[ExpressionPosition])
|
|
||||||
{
|
|
||||||
NamePosition++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
/* Otherwise, fail */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Under certain circumstances, expression is over, but name isn't
|
||||||
|
* and we can backtrack, then, backtrack */
|
||||||
|
if (ExpressionPosition == Expression->Length &&
|
||||||
|
NamePosition != Name->Length && StarFound >= 0)
|
||||||
|
{
|
||||||
|
ExpressionPosition = BackTracking[StarFound--];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (ExpressionPosition + 1 == Expression->Length && NamePosition == Name->Length &&
|
if (ExpressionPosition + 1 == Expression->Length && NamePosition == Name->Length &&
|
||||||
Expression->Buffer[ExpressionPosition] == ANSI_DOS_DOT)
|
Expression->Buffer[ExpressionPosition] == ANSI_DOS_DOT)
|
||||||
|
|
|
@ -23,8 +23,10 @@ FsRtlIsNameInExpressionPrivate(IN PUNICODE_STRING Expression,
|
||||||
IN BOOLEAN IgnoreCase,
|
IN BOOLEAN IgnoreCase,
|
||||||
IN PWCHAR UpcaseTable OPTIONAL)
|
IN PWCHAR UpcaseTable OPTIONAL)
|
||||||
{
|
{
|
||||||
USHORT ExpressionPosition = 0, NamePosition = 0, MatchingChars, StarFound = MAXUSHORT;
|
SHORT StarFound = -1;
|
||||||
|
PUSHORT BackTracking = NULL;
|
||||||
UNICODE_STRING IntExpression;
|
UNICODE_STRING IntExpression;
|
||||||
|
USHORT ExpressionPosition = 0, NamePosition = 0, MatchingChars;
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
/* Check if we were given strings at all */
|
/* Check if we were given strings at all */
|
||||||
|
@ -99,76 +101,45 @@ FsRtlIsNameInExpressionPrivate(IN PUNICODE_STRING Expression,
|
||||||
|
|
||||||
while (NamePosition < Name->Length / sizeof(WCHAR) && ExpressionPosition < Expression->Length / sizeof(WCHAR))
|
while (NamePosition < Name->Length / sizeof(WCHAR) && ExpressionPosition < Expression->Length / sizeof(WCHAR))
|
||||||
{
|
{
|
||||||
|
/* Basic check to test if chars are equal */
|
||||||
if ((Expression->Buffer[ExpressionPosition] == (IgnoreCase ? UpcaseTable[Name->Buffer[NamePosition]] : Name->Buffer[NamePosition])))
|
if ((Expression->Buffer[ExpressionPosition] == (IgnoreCase ? UpcaseTable[Name->Buffer[NamePosition]] : Name->Buffer[NamePosition])))
|
||||||
{
|
{
|
||||||
NamePosition++;
|
NamePosition++;
|
||||||
ExpressionPosition++;
|
ExpressionPosition++;
|
||||||
}
|
}
|
||||||
else if (StarFound != MAXUSHORT && (Expression->Buffer[StarFound + 1] == L'*' ||
|
/* Check cases that eat one char */
|
||||||
Expression->Buffer[StarFound + 1] == L'?' || Expression->Buffer[StarFound + 1] == DOS_DOT))
|
|
||||||
{
|
|
||||||
ExpressionPosition = StarFound + 1;
|
|
||||||
switch (Expression->Buffer[ExpressionPosition])
|
|
||||||
{
|
|
||||||
case L'*':
|
|
||||||
StarFound = MAXUSHORT;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case L'?':
|
|
||||||
if (++ExpressionPosition == Expression->Length / sizeof(WCHAR))
|
|
||||||
{
|
|
||||||
NamePosition = Name->Length / sizeof(WCHAR);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
MatchingChars = NamePosition;
|
|
||||||
while (NamePosition < Name->Length / sizeof(WCHAR) &&
|
|
||||||
(IgnoreCase ? UpcaseTable[Name->Buffer[NamePosition]] :
|
|
||||||
Name->Buffer[NamePosition]) != Expression->Buffer[ExpressionPosition])
|
|
||||||
{
|
|
||||||
NamePosition++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NamePosition - MatchingChars > 0)
|
|
||||||
{
|
|
||||||
StarFound = MAXUSHORT;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DOS_DOT:
|
|
||||||
while (NamePosition < Name->Length / sizeof(WCHAR) &&
|
|
||||||
Name->Buffer[NamePosition] != L'.')
|
|
||||||
{
|
|
||||||
NamePosition++;
|
|
||||||
}
|
|
||||||
ExpressionPosition++;
|
|
||||||
StarFound = MAXUSHORT;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
/* Should never happen */
|
|
||||||
ASSERT(FALSE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (Expression->Buffer[ExpressionPosition] == L'?' || (Expression->Buffer[ExpressionPosition] == DOS_QM) ||
|
else if (Expression->Buffer[ExpressionPosition] == L'?' || (Expression->Buffer[ExpressionPosition] == DOS_QM) ||
|
||||||
(Expression->Buffer[ExpressionPosition] == DOS_DOT && Name->Buffer[NamePosition] == L'.'))
|
(Expression->Buffer[ExpressionPosition] == DOS_DOT && Name->Buffer[NamePosition] == L'.'))
|
||||||
{
|
{
|
||||||
NamePosition++;
|
NamePosition++;
|
||||||
ExpressionPosition++;
|
ExpressionPosition++;
|
||||||
StarFound = MAXUSHORT;
|
|
||||||
}
|
}
|
||||||
|
/* Test star */
|
||||||
else if (Expression->Buffer[ExpressionPosition] == L'*')
|
else if (Expression->Buffer[ExpressionPosition] == L'*')
|
||||||
{
|
{
|
||||||
StarFound = ExpressionPosition++;
|
/* Save star position */
|
||||||
|
if (!BackTracking)
|
||||||
|
{
|
||||||
|
BackTracking = ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,
|
||||||
|
(Expression->Length / sizeof(WCHAR)) * sizeof(USHORT),
|
||||||
|
'nrSF');
|
||||||
|
}
|
||||||
|
BackTracking[++StarFound] = ExpressionPosition++;
|
||||||
|
|
||||||
|
/* If star is at the end, then eat all rest and leave */
|
||||||
if (ExpressionPosition == Expression->Length / sizeof(WCHAR))
|
if (ExpressionPosition == Expression->Length / sizeof(WCHAR))
|
||||||
{
|
{
|
||||||
NamePosition = Name->Length / sizeof(WCHAR);
|
NamePosition = Name->Length / sizeof(WCHAR);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
else if (Expression->Buffer[ExpressionPosition] != L'?')
|
||||||
|
{
|
||||||
|
NamePosition++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
/* Check DOS_STAR */
|
||||||
else if (Expression->Buffer[ExpressionPosition] == DOS_STAR)
|
else if (Expression->Buffer[ExpressionPosition] == DOS_STAR)
|
||||||
{
|
{
|
||||||
StarFound = MAXUSHORT;
|
|
||||||
MatchingChars = NamePosition;
|
MatchingChars = NamePosition;
|
||||||
while (MatchingChars < Name->Length / sizeof(WCHAR))
|
while (MatchingChars < Name->Length / sizeof(WCHAR))
|
||||||
{
|
{
|
||||||
|
@ -180,20 +151,25 @@ FsRtlIsNameInExpressionPrivate(IN PUNICODE_STRING Expression,
|
||||||
}
|
}
|
||||||
ExpressionPosition++;
|
ExpressionPosition++;
|
||||||
}
|
}
|
||||||
else if (StarFound != MAXUSHORT)
|
/* If nothing match, try to backtrack */
|
||||||
|
else if (StarFound >= 0)
|
||||||
{
|
{
|
||||||
ExpressionPosition = StarFound + 1;
|
ExpressionPosition = BackTracking[StarFound--];
|
||||||
while (NamePosition < Name->Length / sizeof(WCHAR) &&
|
|
||||||
(IgnoreCase ? UpcaseTable[Name->Buffer[NamePosition]] :
|
|
||||||
Name->Buffer[NamePosition]) != Expression->Buffer[ExpressionPosition])
|
|
||||||
{
|
|
||||||
NamePosition++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
/* Otherwise, fail */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Under certain circumstances, expression is over, but name isn't
|
||||||
|
* and we can backtrack, then, backtrack */
|
||||||
|
if (ExpressionPosition == Expression->Length / sizeof(WCHAR) &&
|
||||||
|
NamePosition != Name->Length / sizeof(WCHAR) &&
|
||||||
|
StarFound >= 0)
|
||||||
|
{
|
||||||
|
ExpressionPosition = BackTracking[StarFound--];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (ExpressionPosition + 1 == Expression->Length / sizeof(WCHAR) && NamePosition == Name->Length / sizeof(WCHAR) &&
|
if (ExpressionPosition + 1 == Expression->Length / sizeof(WCHAR) && NamePosition == Name->Length / sizeof(WCHAR) &&
|
||||||
Expression->Buffer[ExpressionPosition] == DOS_DOT)
|
Expression->Buffer[ExpressionPosition] == DOS_DOT)
|
||||||
|
@ -201,6 +177,11 @@ FsRtlIsNameInExpressionPrivate(IN PUNICODE_STRING Expression,
|
||||||
ExpressionPosition++;
|
ExpressionPosition++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (BackTracking)
|
||||||
|
{
|
||||||
|
ExFreePoolWithTag(BackTracking, 'nrSF');
|
||||||
|
}
|
||||||
|
|
||||||
return (ExpressionPosition == Expression->Length / sizeof(WCHAR) && NamePosition == Name->Length / sizeof(WCHAR));
|
return (ExpressionPosition == Expression->Length / sizeof(WCHAR) && NamePosition == Name->Length / sizeof(WCHAR));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue