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.

Attachment: smime.p7s
Description: Signature cryptographique S/MIME

_______________________________________________
Ros-dev mailing list
Ros-dev@reactos.org
http://www.reactos.org/mailman/listinfo/ros-dev

Reply via email to