From: Pierre Schweitzer Date: Fri, 25 Mar 2016 22:12:08 +0000 (+0000) Subject: [NTOSKRNL_VISTA] X-Git-Tag: ReactOS-0.4.1~177 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=de0bb0d2288f832ba826e2f9fbd5ebb43f0bb498 [NTOSKRNL_VISTA] Bug fixes to FsRtlRemoveDotsFromPath() (buffer overrun, buffer underrun, etc.). This fixes the failing test svn path=/trunk/; revision=71047 --- diff --git a/reactos/lib/drivers/ntoskrnl_vista/fsrtl.c b/reactos/lib/drivers/ntoskrnl_vista/fsrtl.c index 607d11d1dc2..36cc1e01aa0 100644 --- a/reactos/lib/drivers/ntoskrnl_vista/fsrtl.c +++ b/reactos/lib/drivers/ntoskrnl_vista/fsrtl.c @@ -16,7 +16,7 @@ FsRtlRemoveDotsFromPath(IN PWSTR OriginalString, IN USHORT PathLength, OUT USHORT *NewLength) { - USHORT Length, ReadPos, WritePos = 0; + USHORT Length, ReadPos, WritePos; Length = PathLength / sizeof(WCHAR); @@ -35,79 +35,79 @@ FsRtlRemoveDotsFromPath(IN PWSTR OriginalString, return STATUS_IO_REPARSE_DATA_INVALID; } - if (Length > 0) + for (ReadPos = 0, WritePos = 0; ReadPos < Length; ++WritePos) { - ReadPos = 0; - - for (; ReadPos < Length; ++WritePos) + for (; ReadPos > 0 && ReadPos < Length; ++ReadPos) { - for (; ReadPos < Length; ++ReadPos) + if (ReadPos < Length - 1 && OriginalString[ReadPos] == '\\' && OriginalString[ReadPos + 1] == '\\') { - if (ReadPos < Length - 1 && OriginalString[ReadPos] == '\\' && OriginalString[ReadPos + 1] == '\\') - { - continue; - } + continue; + } - if (OriginalString[ReadPos] != '.') - { - break; - } + if (OriginalString[ReadPos] != '.') + { + break; + } - if (ReadPos == Length - 1) + if (ReadPos == Length - 1) + { + if (OriginalString[ReadPos - 1] == '\\') { - if (OriginalString[ReadPos - 1] == '\\') + if (WritePos > 1) { - if (WritePos > 1) - { - --WritePos; - } - - continue; + --WritePos; } - OriginalString[WritePos] = '.'; - ++WritePos; continue; } - if (OriginalString[ReadPos + 1] == '\\') + OriginalString[WritePos] = '.'; + ++WritePos; + continue; + } + + if (OriginalString[ReadPos + 1] == '\\') + { + if (OriginalString[ReadPos - 1] != '\\') { - if (OriginalString[ReadPos - 1] != '\\') - { - OriginalString[WritePos] = '.'; - ++WritePos; - continue; - } + OriginalString[WritePos] = '.'; + ++WritePos; + continue; } - else + } + else + { + if (OriginalString[ReadPos + 1] != '.' || OriginalString[ReadPos - 1] != '\\' || + ((ReadPos != Length - 2) && OriginalString[ReadPos + 2] != '\\')) { - if (OriginalString[ReadPos + 1] != '.' || OriginalString[ReadPos - 1] != '\\' || - ((ReadPos != Length - 2) && OriginalString[ReadPos + 2] != '\\')) - { - OriginalString[WritePos] = '.'; - ++WritePos; - continue; - } - - for (WritePos -= 2; (SHORT)WritePos > 0 && OriginalString[WritePos] != '\\'; --WritePos); + OriginalString[WritePos] = '.'; + ++WritePos; + continue; + } - if ((SHORT)WritePos < 0 || OriginalString[WritePos] != '\\') - { - return STATUS_IO_REPARSE_DATA_INVALID; - } + for (WritePos -= 2; (SHORT)WritePos > 0 && OriginalString[WritePos] != '\\'; --WritePos); - if (WritePos == 0 && ReadPos == Length - 2) - { - WritePos = 1; - } + if ((SHORT)WritePos < 0 || OriginalString[WritePos] != '\\') + { + return STATUS_IO_REPARSE_DATA_INVALID; } - ++ReadPos; + if (WritePos == 0 && ReadPos == Length - 2) + { + WritePos = 1; + } } - OriginalString[WritePos] = OriginalString[ReadPos]; ++ReadPos; } + + if (ReadPos >= Length) + { + break; + } + + OriginalString[WritePos] = OriginalString[ReadPos]; + ++ReadPos; } *NewLength = WritePos * sizeof(WCHAR);