From: Michał Janiszewski janisozaur@gmail.com
The tests in particular should trigger an edge case in implementation
Signed-off-by: Michał Janiszewski janisozaur@gmail.com --- dlls/ntdll/tests/rtlbitmap.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+)
diff --git a/dlls/ntdll/tests/rtlbitmap.c b/dlls/ntdll/tests/rtlbitmap.c index 9552318e7f..3c3992e8fc 100644 --- a/dlls/ntdll/tests/rtlbitmap.c +++ b/dlls/ntdll/tests/rtlbitmap.c @@ -40,6 +40,8 @@ static CCHAR (WINAPI *pRtlFindMostSignificantBit)(ULONGLONG); static CCHAR (WINAPI *pRtlFindLeastSignificantBit)(ULONGLONG); static ULONG (WINAPI *pRtlFindSetRuns)(PRTL_BITMAP,PRTL_BITMAP_RUN,ULONG,BOOLEAN); static ULONG (WINAPI *pRtlFindClearRuns)(PRTL_BITMAP,PRTL_BITMAP_RUN,ULONG,BOOLEAN); +static ULONG (WINAPI *pRtlFindNextForwardRunSet)(PRTL_BITMAP,ULONG,PULONG); +static ULONG (WINAPI *pRtlFindNextForwardRunClear)(PRTL_BITMAP,ULONG,PULONG); static ULONG (WINAPI *pRtlNumberOfSetBits)(PRTL_BITMAP); static ULONG (WINAPI *pRtlNumberOfClearBits)(PRTL_BITMAP); static ULONG (WINAPI *pRtlFindLongestRunSet)(PRTL_BITMAP,PULONG); @@ -69,6 +71,8 @@ static void InitFunctionPtrs(void) pRtlFindLeastSignificantBit = (void *)GetProcAddress(hntdll, "RtlFindLeastSignificantBit"); pRtlFindSetRuns = (void *)GetProcAddress(hntdll, "RtlFindSetRuns"); pRtlFindClearRuns = (void *)GetProcAddress(hntdll, "RtlFindClearRuns"); + pRtlFindNextForwardRunSet = (void *)GetProcAddress(hntdll, "RtlFindNextForwardRunSet"); + pRtlFindNextForwardRunClear = (void *)GetProcAddress(hntdll, "RtlFindNextForwardRunClear"); pRtlFindLongestRunSet = (void *)GetProcAddress(hntdll, "RtlFindLongestRunSet"); pRtlFindLongestRunClear = (void *)GetProcAddress(hntdll, "RtlFindLongestRunClear"); } @@ -620,6 +624,35 @@ static void test_RtlFindClearRuns(void) }
} + +static void test_RtlFindNextForwardRunSet(void) +{ + BYTE mask[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff }; + ULONG ulStart = 0; + ULONG ulCount, lpPos; + if (!pRtlFindNextForwardRunSet) + return; + + pRtlInitializeBitMap(&bm, mask, 62); + ulCount = pRtlFindNextForwardRunSet(&bm, ulStart, &lpPos); + ok(ulCount == 6, "Invalid length of found set run: %d, expected 6\n", ulCount); + ok(lpPos == 56, "Invalid position of found set run: %d, expected 56\n", lpPos); +} + +static void test_RtlFindNextForwardRunClear(void) +{ + BYTE mask[8] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 }; + ULONG ulStart = 0; + ULONG ulCount, lpPos; + if (!pRtlFindNextForwardRunClear) + return; + + pRtlInitializeBitMap(&bm, mask, 62); + ulCount = pRtlFindNextForwardRunClear(&bm, ulStart, &lpPos); + ok(ulCount == 6, "Invalid length of found clear run: %d, expected 6\n", ulCount); + ok(lpPos == 56, "Invalid position of found clear run: %d, expected 56\n", lpPos); +} + #endif
START_TEST(rtlbitmap) @@ -645,6 +678,8 @@ START_TEST(rtlbitmap) test_RtlFindLeastSignificantBit(); test_RtlFindSetRuns(); test_RtlFindClearRuns(); + test_RtlFindNextForwardRunSet(); + test_RtlFindNextForwardRunClear(); } #endif }
From: Michał Janiszewski janisozaur@gmail.com
This can be happen in sample arrays (hex): FindSetRun: 00 00 00 00 00 00 00 ff FindClearRun: ff ff ff ff ff ff ff 00
Such arrays were added in previous commit to tests and should now be fixed.
Signed-off-by: Michał Janiszewski janisozaur@gmail.com --- dlls/ntdll/rtlbitmap.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/dlls/ntdll/rtlbitmap.c b/dlls/ntdll/rtlbitmap.c index 20108f5035..d0a4e5cf28 100644 --- a/dlls/ntdll/rtlbitmap.c +++ b/dlls/ntdll/rtlbitmap.c @@ -731,6 +731,12 @@ static ULONG NTDLL_FindSetRun(PCRTL_BITMAP lpBits, ULONG ulStart, PULONG lpSize) return ~0U; }
+ /* Check if reached the end of bitmap */ + if (ulStart >= lpBits->SizeOfBitMap) { + *lpSize = ulCount - (ulStart - lpBits->SizeOfBitMap); + return ulFoundAt; + } + /* Count blocks of 8 set bits */ while (*lpOut == 0xff) { @@ -822,6 +828,12 @@ static ULONG NTDLL_FindClearRun(PCRTL_BITMAP lpBits, ULONG ulStart, PULONG lpSiz return ~0U; }
+ /* Check if reached the end of bitmap */ + if (ulStart >= lpBits->SizeOfBitMap) { + *lpSize = ulCount - (ulStart - lpBits->SizeOfBitMap); + return ulFoundAt; + } + /* Count blocks of 8 clear bits */ while (!*lpOut) {
2018-07-07 22:10 GMT+02:00 janisozaur@gmail.com:
From: Michał Janiszewski janisozaur@gmail.com
The tests in particular should trigger an edge case in implementation
If I understand it correctly these new tests will fail until patch 2/2 is also merged, right? That's not allowed, test should always pass. Ideally you should add some todo_wine to this patch so that the tests keep passing and remove them again in 2/2. It would also be acceptable, although slightly less nice, to simply swap the two patches in the series.
I've sent out v2 of this patch with `todo_wine`. Note only the first check in each of the tests, ulCount one, is expected to fail.
On 8 July 2018 at 21:44, Matteo Bruni matteo.mystral@gmail.com wrote:
2018-07-07 22:10 GMT+02:00 janisozaur@gmail.com:
From: Michał Janiszewski janisozaur@gmail.com
The tests in particular should trigger an edge case in implementation
If I understand it correctly these new tests will fail until patch 2/2 is also merged, right? That's not allowed, test should always pass. Ideally you should add some todo_wine to this patch so that the tests keep passing and remove them again in 2/2. It would also be acceptable, although slightly less nice, to simply swap the two patches in the series.