mirror of
https://github.com/reactos/reactos.git
synced 2025-05-28 13:38:19 +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,
|
||||
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();
|
||||
|
||||
ASSERT(Name->Length);
|
||||
|
@ -169,74 +171,44 @@ FsRtlIsDbcsInExpression(IN PANSI_STRING Expression,
|
|||
|
||||
while (NamePosition < Name->Length && ExpressionPosition < Expression->Length)
|
||||
{
|
||||
/* Basic check to test if chars are equal */
|
||||
if ((Expression->Buffer[ExpressionPosition] == Name->Buffer[NamePosition]))
|
||||
{
|
||||
NamePosition++;
|
||||
ExpressionPosition++;
|
||||
}
|
||||
else if (StarFound != MAXUSHORT && (Expression->Buffer[StarFound + 1] == '*' ||
|
||||
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);
|
||||
}
|
||||
}
|
||||
/* Check cases that eat one char */
|
||||
else if ((Expression->Buffer[ExpressionPosition] == '?') || (Expression->Buffer[ExpressionPosition] == ANSI_DOS_QM) ||
|
||||
(Expression->Buffer[ExpressionPosition] == ANSI_DOS_DOT && Name->Buffer[NamePosition] == '.'))
|
||||
{
|
||||
NamePosition++;
|
||||
ExpressionPosition++;
|
||||
StarFound = MAXUSHORT;
|
||||
}
|
||||
/* Test star */
|
||||
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)
|
||||
{
|
||||
NamePosition = Name->Length;
|
||||
break;
|
||||
}
|
||||
else if (Expression->Buffer[ExpressionPosition] != '?')
|
||||
{
|
||||
NamePosition++;
|
||||
}
|
||||
}
|
||||
/* Check DOS_STAR */
|
||||
else if (Expression->Buffer[ExpressionPosition] == ANSI_DOS_STAR)
|
||||
{
|
||||
StarFound = MAXUSHORT;
|
||||
MatchingChars = NamePosition;
|
||||
while (MatchingChars < Name->Length)
|
||||
{
|
||||
|
@ -248,19 +220,24 @@ FsRtlIsDbcsInExpression(IN PANSI_STRING Expression,
|
|||
}
|
||||
ExpressionPosition++;
|
||||
}
|
||||
else if (StarFound != MAXUSHORT)
|
||||
/* If nothing match, try to backtrack */
|
||||
else if (StarFound >= 0)
|
||||
{
|
||||
ExpressionPosition = StarFound + 1;
|
||||
while (NamePosition < Name->Length &&
|
||||
Name->Buffer[NamePosition] != Expression->Buffer[ExpressionPosition])
|
||||
{
|
||||
NamePosition++;
|
||||
}
|
||||
ExpressionPosition = BackTracking[StarFound--];
|
||||
}
|
||||
/* Otherwise, fail */
|
||||
else
|
||||
{
|
||||
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 &&
|
||||
Expression->Buffer[ExpressionPosition] == ANSI_DOS_DOT)
|
||||
|
|
|
@ -23,8 +23,10 @@ FsRtlIsNameInExpressionPrivate(IN PUNICODE_STRING Expression,
|
|||
IN BOOLEAN IgnoreCase,
|
||||
IN PWCHAR UpcaseTable OPTIONAL)
|
||||
{
|
||||
USHORT ExpressionPosition = 0, NamePosition = 0, MatchingChars, StarFound = MAXUSHORT;
|
||||
SHORT StarFound = -1;
|
||||
PUSHORT BackTracking = NULL;
|
||||
UNICODE_STRING IntExpression;
|
||||
USHORT ExpressionPosition = 0, NamePosition = 0, MatchingChars;
|
||||
PAGED_CODE();
|
||||
|
||||
/* 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))
|
||||
{
|
||||
/* Basic check to test if chars are equal */
|
||||
if ((Expression->Buffer[ExpressionPosition] == (IgnoreCase ? UpcaseTable[Name->Buffer[NamePosition]] : Name->Buffer[NamePosition])))
|
||||
{
|
||||
NamePosition++;
|
||||
ExpressionPosition++;
|
||||
}
|
||||
else if (StarFound != MAXUSHORT && (Expression->Buffer[StarFound + 1] == L'*' ||
|
||||
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);
|
||||
}
|
||||
}
|
||||
/* Check cases that eat one char */
|
||||
else if (Expression->Buffer[ExpressionPosition] == L'?' || (Expression->Buffer[ExpressionPosition] == DOS_QM) ||
|
||||
(Expression->Buffer[ExpressionPosition] == DOS_DOT && Name->Buffer[NamePosition] == L'.'))
|
||||
{
|
||||
NamePosition++;
|
||||
ExpressionPosition++;
|
||||
StarFound = MAXUSHORT;
|
||||
}
|
||||
/* Test star */
|
||||
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))
|
||||
{
|
||||
NamePosition = Name->Length / sizeof(WCHAR);
|
||||
break;
|
||||
}
|
||||
else if (Expression->Buffer[ExpressionPosition] != L'?')
|
||||
{
|
||||
NamePosition++;
|
||||
}
|
||||
}
|
||||
/* Check DOS_STAR */
|
||||
else if (Expression->Buffer[ExpressionPosition] == DOS_STAR)
|
||||
{
|
||||
StarFound = MAXUSHORT;
|
||||
MatchingChars = NamePosition;
|
||||
while (MatchingChars < Name->Length / sizeof(WCHAR))
|
||||
{
|
||||
|
@ -180,20 +151,25 @@ FsRtlIsNameInExpressionPrivate(IN PUNICODE_STRING Expression,
|
|||
}
|
||||
ExpressionPosition++;
|
||||
}
|
||||
else if (StarFound != MAXUSHORT)
|
||||
/* If nothing match, try to backtrack */
|
||||
else if (StarFound >= 0)
|
||||
{
|
||||
ExpressionPosition = StarFound + 1;
|
||||
while (NamePosition < Name->Length / sizeof(WCHAR) &&
|
||||
(IgnoreCase ? UpcaseTable[Name->Buffer[NamePosition]] :
|
||||
Name->Buffer[NamePosition]) != Expression->Buffer[ExpressionPosition])
|
||||
{
|
||||
NamePosition++;
|
||||
}
|
||||
ExpressionPosition = BackTracking[StarFound--];
|
||||
}
|
||||
/* Otherwise, fail */
|
||||
else
|
||||
{
|
||||
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) &&
|
||||
Expression->Buffer[ExpressionPosition] == DOS_DOT)
|
||||
|
@ -201,6 +177,11 @@ FsRtlIsNameInExpressionPrivate(IN PUNICODE_STRING Expression,
|
|||
ExpressionPosition++;
|
||||
}
|
||||
|
||||
if (BackTracking)
|
||||
{
|
||||
ExFreePoolWithTag(BackTracking, 'nrSF');
|
||||
}
|
||||
|
||||
return (ExpressionPosition == Expression->Length / sizeof(WCHAR) && NamePosition == Name->Length / sizeof(WCHAR));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue