Don't forget to apply the changes (not reviewed, sorry, no time) to FsRtlIsDbcsInExpression.
Le 28/09/2016 à 01:00, dchapys...@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.
smime.p7s
Description: Signature cryptographique S/MIME
_______________________________________________ Ros-dev mailing list Ros-dev@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev