[ros-dev] [ros-diffs] [dchapyshev] 72835: [NTOS:FSRTL] Rework FsRtlIsNameInExpressionPrivate for correct parsing some expressions * Fixes 1 test for kmtest:FsRtlExpression and 15 tests for kernel32:file
Pierre Schweitzer
pierre at reactos.org
Wed Sep 28 09:21:36 UTC 2016
Don't forget to apply the changes (not reviewed, sorry, no time) to
FsRtlIsDbcsInExpression.
Le 28/09/2016 à 01:00, dchapyshev at svn.reactos.org a écrit :
> Author: dchapyshev
> Date: Tue Sep 27 23:00:20 2016
> New Revision: 72835
>
> URL: http://svn.reactos.org/svn/reactos?rev=72835&view=rev
> Log:
> [NTOS:FSRTL] Rework FsRtlIsNameInExpressionPrivate for correct parsing some expressions
>
> * Fixes 1 test for kmtest:FsRtlExpression and 15 tests for kernel32:file
>
> Modified:
> trunk/reactos/ntoskrnl/fsrtl/name.c
>
> Modified: trunk/reactos/ntoskrnl/fsrtl/name.c
> URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/fsrtl/name.c?rev=72835&r1=72834&r2=72835&view=diff
> ==============================================================================
> --- trunk/reactos/ntoskrnl/fsrtl/name.c [iso-8859-1] (original)
> +++ trunk/reactos/ntoskrnl/fsrtl/name.c [iso-8859-1] Tue Sep 27 23:00:20 2016
> @@ -23,13 +23,14 @@
> IN BOOLEAN IgnoreCase,
> IN PWCHAR UpcaseTable OPTIONAL)
> {
> - SHORT StarFound = -1, DosStarFound = -1;
> - USHORT BackTrackingBuffer[5], DosBackTrackingBuffer[5];
> - PUSHORT BackTracking = BackTrackingBuffer, DosBackTracking = DosBackTrackingBuffer;
> - SHORT BackTrackingSize = RTL_NUMBER_OF(BackTrackingBuffer);
> - SHORT DosBackTrackingSize = RTL_NUMBER_OF(DosBackTrackingBuffer);
> + USHORT Offset, Position, BackTrackingPosition, OldBackTrackingPosition;
> + USHORT BackTrackingBuffer[16], OldBackTrackingBuffer[16] = {0};
> + PUSHORT BackTrackingSwap, BackTracking = BackTrackingBuffer, OldBackTracking = OldBackTrackingBuffer;
> UNICODE_STRING IntExpression;
> - USHORT ExpressionPosition = 0, NamePosition = 0, MatchingChars, LastDot;
> + USHORT ExpressionPosition = 0, NamePosition = 0, MatchingChars = 1;
> + BOOLEAN EndOfName = FALSE;
> + BOOLEAN Result = FALSE;
> + BOOLEAN DontSkipDot;
> WCHAR CompareChar;
> PAGED_CODE();
>
> @@ -37,7 +38,7 @@
> if (!Name->Length || !Expression->Length)
> {
> /* Return TRUE if both strings are empty, otherwise FALSE */
> - if (Name->Length == 0 && Expression->Length == 0)
> + if (!Name->Length && !Expression->Length)
> return TRUE;
> else
> return FALSE;
> @@ -103,193 +104,144 @@
> }
> }
>
> - while ((NamePosition < Name->Length / sizeof(WCHAR)) &&
> - (ExpressionPosition < Expression->Length / sizeof(WCHAR)))
> - {
> - /* Basic check to test if chars are equal */
> - CompareChar = IgnoreCase ? UpcaseTable[Name->Buffer[NamePosition]] :
> - Name->Buffer[NamePosition];
> - if (Expression->Buffer[ExpressionPosition] == CompareChar)
> - {
> - NamePosition++;
> - ExpressionPosition++;
> - }
> - /* Check cases that eat one char */
> - else if (Expression->Buffer[ExpressionPosition] == L'?')
> - {
> - NamePosition++;
> - ExpressionPosition++;
> - }
> - /* Test star */
> - else if (Expression->Buffer[ExpressionPosition] == L'*')
> - {
> - /* Skip contigous stars */
> - while ((ExpressionPosition + 1 < (USHORT)(Expression->Length / sizeof(WCHAR))) &&
> - (Expression->Buffer[ExpressionPosition + 1] == L'*'))
> - {
> - ExpressionPosition++;
> - }
> -
> - /* Save star position */
> - StarFound++;
> - if (StarFound >= BackTrackingSize)
> - {
> - ASSERT(BackTracking == BackTrackingBuffer);
> -
> - BackTrackingSize = Expression->Length / sizeof(WCHAR);
> - BackTracking = ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,
> - BackTrackingSize * sizeof(USHORT),
> - 'nrSF');
> - RtlCopyMemory(BackTracking, BackTrackingBuffer, sizeof(BackTrackingBuffer));
> -
> - }
> - 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);
> + /* Name parsing loop */
> + for (; !EndOfName; MatchingChars = BackTrackingPosition, NamePosition++)
> + {
> + /* Reset positions */
> + OldBackTrackingPosition = BackTrackingPosition = 0;
> +
> + if (NamePosition >= Name->Length / sizeof(WCHAR))
> + {
> + EndOfName = TRUE;
> + if (OldBackTracking[MatchingChars - 1] == Expression->Length * 2)
> break;
> - }
> -
> - /* Allow null matching */
> - if (Expression->Buffer[ExpressionPosition] != L'?' &&
> - Expression->Buffer[ExpressionPosition] != Name->Buffer[NamePosition])
> - {
> - NamePosition++;
> - }
> - }
> - /* Check DOS_STAR */
> - else if (Expression->Buffer[ExpressionPosition] == DOS_STAR)
> - {
> - /* Skip contigous stars */
> - while ((ExpressionPosition + 1 < (USHORT)(Expression->Length / sizeof(WCHAR))) &&
> - (Expression->Buffer[ExpressionPosition + 1] == DOS_STAR))
> - {
> - ExpressionPosition++;
> - }
> -
> - /* Look for last dot */
> - MatchingChars = 0;
> - LastDot = (USHORT)-1;
> - while (MatchingChars < Name->Length / sizeof(WCHAR))
> - {
> - if (Name->Buffer[MatchingChars] == L'.')
> - {
> - LastDot = MatchingChars;
> - if (LastDot > NamePosition)
> - break;
> - }
> -
> - MatchingChars++;
> - }
> -
> - /* If we don't have dots or we didn't find last yet
> - * start eating everything
> - */
> - if (MatchingChars != Name->Length || LastDot == (USHORT)-1)
> - {
> - DosStarFound++;
> - if (DosStarFound >= DosBackTrackingSize)
> - {
> - ASSERT(DosBackTracking == DosBackTrackingBuffer);
> -
> - DosBackTrackingSize = Expression->Length / sizeof(WCHAR);
> - DosBackTracking = ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,
> - DosBackTrackingSize * sizeof(USHORT),
> + }
> +
> + while (MatchingChars > OldBackTrackingPosition)
> + {
> + ExpressionPosition = (OldBackTracking[OldBackTrackingPosition++] + 1) / 2;
> +
> + /* Expression parsing loop */
> + for (Offset = 0; ExpressionPosition < Expression->Length; Offset = sizeof(WCHAR))
> + {
> + ExpressionPosition += Offset;
> +
> + if (ExpressionPosition == Expression->Length)
> + {
> + BackTracking[BackTrackingPosition++] = Expression->Length * 2;
> + break;
> + }
> +
> + /* If buffer too small */
> + if (BackTrackingPosition > RTL_NUMBER_OF(BackTrackingBuffer) - 1)
> + {
> + /* Allocate memory for BackTracking */
> + BackTracking = ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,
> + (Expression->Length + sizeof(WCHAR)) * sizeof(USHORT),
> + 'nrSF');
> + /* Copy old buffer content */
> + RtlCopyMemory(BackTracking,
> + BackTrackingBuffer,
> + RTL_NUMBER_OF(BackTrackingBuffer) * sizeof(USHORT));
> +
> + /* Allocate memory for OldBackTracking */
> + OldBackTracking = ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,
> + (Expression->Length + sizeof(WCHAR)) * sizeof(USHORT),
> 'nrSF');
> - RtlCopyMemory(DosBackTracking, DosBackTrackingBuffer, sizeof(DosBackTrackingBuffer));
> - }
> - DosBackTracking[DosStarFound] = ExpressionPosition++;
> -
> - /* Not the same char, start exploring */
> - if (Expression->Buffer[ExpressionPosition] != Name->Buffer[NamePosition])
> - NamePosition++;
> - }
> - else
> - {
> - /* Else, if we are at last dot, eat it - otherwise, null match */
> - if (Name->Buffer[NamePosition] == '.')
> - NamePosition++;
> -
> - ExpressionPosition++;
> - }
> - }
> - /* Check DOS_DOT */
> - else if (Expression->Buffer[ExpressionPosition] == DOS_DOT)
> - {
> - /* We only match dots */
> - if (Name->Buffer[NamePosition] == L'.')
> - {
> - NamePosition++;
> - }
> - /* Try to explore later on for null matching */
> - else if ((ExpressionPosition + 1 < (USHORT)(Expression->Length / sizeof(WCHAR))) &&
> - (Name->Buffer[NamePosition] == Expression->Buffer[ExpressionPosition + 1]))
> - {
> - NamePosition++;
> - }
> - ExpressionPosition++;
> - }
> - /* Check DOS_QM */
> - else if (Expression->Buffer[ExpressionPosition] == DOS_QM)
> - {
> - /* We match everything except dots */
> - if (Name->Buffer[NamePosition] != L'.')
> - {
> - NamePosition++;
> - }
> - ExpressionPosition++;
> - }
> - /* If nothing match, try to backtrack */
> - else if (StarFound >= 0)
> - {
> - ExpressionPosition = BackTracking[StarFound--];
> - }
> - else if (DosStarFound >= 0)
> - {
> - ExpressionPosition = DosBackTracking[DosStarFound--];
> - }
> - /* 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 we have nullable matching wc at the end of the string, eat them */
> - if (ExpressionPosition != Expression->Length / sizeof(WCHAR) && NamePosition == Name->Length / sizeof(WCHAR))
> - {
> - while (ExpressionPosition < Expression->Length / sizeof(WCHAR))
> - {
> - if (Expression->Buffer[ExpressionPosition] != DOS_DOT &&
> - Expression->Buffer[ExpressionPosition] != L'*' &&
> - Expression->Buffer[ExpressionPosition] != DOS_STAR)
> - {
> + /* Copy old buffer content */
> + RtlCopyMemory(OldBackTracking,
> + OldBackTrackingBuffer,
> + RTL_NUMBER_OF(OldBackTrackingBuffer) * sizeof(USHORT));
> + }
> +
> + /* Basic check to test if chars are equal */
> + CompareChar = IgnoreCase ? UpcaseTable[Name->Buffer[NamePosition]] :
> + Name->Buffer[NamePosition];
> + if (Expression->Buffer[ExpressionPosition / sizeof(WCHAR)] == CompareChar && !EndOfName)
> + {
> + BackTracking[BackTrackingPosition++] = (ExpressionPosition + sizeof(WCHAR)) * 2;
> + }
> + /* Check cases that eat one char */
> + else if (Expression->Buffer[ExpressionPosition / sizeof(WCHAR)] == L'?' && !EndOfName)
> + {
> + BackTracking[BackTrackingPosition++] = (ExpressionPosition + sizeof(WCHAR)) * 2;
> + }
> + /* Test star */
> + else if (Expression->Buffer[ExpressionPosition / sizeof(WCHAR)] == L'*')
> + {
> + BackTracking[BackTrackingPosition++] = ExpressionPosition * 2;
> + BackTracking[BackTrackingPosition++] = (ExpressionPosition * 2) + 3;
> + continue;
> + }
> + /* Check DOS_STAR */
> + else if (Expression->Buffer[ExpressionPosition / sizeof(WCHAR)] == DOS_STAR)
> + {
> + /* Look for last dot */
> + DontSkipDot = TRUE;
> + if (!EndOfName && Name->Buffer[NamePosition] == '.')
> + {
> + for (Position = NamePosition - 1; Position < Name->Length; Position++)
> + {
> + if (Name->Buffer[Position] == L'.')
> + {
> + DontSkipDot = FALSE;
> + break;
> + }
> + }
> + }
> +
> + if (EndOfName || Name->Buffer[NamePosition] != L'.' || !DontSkipDot)
> + BackTracking[BackTrackingPosition++] = ExpressionPosition * 2;
> +
> + BackTracking[BackTrackingPosition++] = (ExpressionPosition * 2) + 3;
> + continue;
> + }
> + /* Check DOS_DOT */
> + else if (Expression->Buffer[ExpressionPosition / sizeof(WCHAR)] == DOS_DOT)
> + {
> + if (EndOfName) continue;
> +
> + if (Name->Buffer[NamePosition] == L'.')
> + BackTracking[BackTrackingPosition++] = (ExpressionPosition + sizeof(WCHAR)) * 2;
> + }
> + /* Check DOS_QM */
> + else if (Expression->Buffer[ExpressionPosition / sizeof(WCHAR)] == DOS_QM)
> + {
> + if (EndOfName || Name->Buffer[NamePosition] == L'.') continue;
> +
> + BackTracking[BackTrackingPosition++] = (ExpressionPosition + sizeof(WCHAR)) * 2;
> + }
> +
> + /* Leave from loop */
> break;
> }
> - ExpressionPosition++;
> - }
> - }
> -
> - if (BackTracking != BackTrackingBuffer)
> - {
> +
> + for (Position = 0; MatchingChars > OldBackTrackingPosition && Position < BackTrackingPosition; Position++)
> + {
> + while (MatchingChars > OldBackTrackingPosition &&
> + BackTracking[Position] > OldBackTracking[OldBackTrackingPosition])
> + {
> + ++OldBackTrackingPosition;
> + }
> + }
> + }
> +
> + /* Swap pointers */
> + BackTrackingSwap = BackTracking;
> + BackTracking = OldBackTracking;
> + OldBackTracking = BackTrackingSwap;
> + }
> +
> + /* Store result value */
> + Result = (OldBackTracking[MatchingChars - 1] == (Expression->Length * 2));
> +
> + /* Frees the memory if necessary */
> + if (BackTracking != BackTrackingBuffer && BackTracking != OldBackTrackingBuffer)
> ExFreePoolWithTag(BackTracking, 'nrSF');
> - }
> - if (DosBackTracking != DosBackTrackingBuffer)
> - {
> - ExFreePoolWithTag(DosBackTracking, 'nrSF');
> - }
> -
> - return (ExpressionPosition == Expression->Length / sizeof(WCHAR) && NamePosition == Name->Length / sizeof(WCHAR));
> + if (OldBackTracking != BackTrackingBuffer && OldBackTracking != OldBackTrackingBuffer)
> + ExFreePoolWithTag(OldBackTracking, 'nrSF');
> +
> + return Result;
> }
>
> /* PUBLIC FUNCTIONS **********************************************************/
>
>
--
Pierre Schweitzer <pierre at reactos.org>
System & Network Administrator
Senior Kernel Developer
ReactOS Deutschland e.V.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 3960 bytes
Desc: Signature cryptographique S/MIME
URL: <http://www.reactos.org/pipermail/ros-dev/attachments/20160928/7a850334/attachment-0001.bin>
More information about the Ros-dev
mailing list