diff --git a/dlls/shlwapi/string.c b/dlls/shlwapi/string.c index b8a046dcc28..50d81db9a72 100644 --- a/dlls/shlwapi/string.c +++ b/dlls/shlwapi/string.c @@ -639,7 +639,6 @@ LPWSTR WINAPI StrStrW(LPCWSTR lpszStr, LPCWSTR lpszSearch) */ LPSTR WINAPI StrRStrIA(LPCSTR lpszStr, LPCSTR lpszEnd, LPCSTR lpszSearch) { - LPSTR lpszRet = NULL; WORD ch1, ch2; INT iLen; @@ -650,24 +649,26 @@ LPSTR WINAPI StrRStrIA(LPCSTR lpszStr, LPCSTR lpszEnd, LPCSTR lpszSearch) if (!lpszEnd) lpszEnd = lpszStr + lstrlenA(lpszStr); + if (lpszEnd == lpszStr) + return NULL; if (IsDBCSLeadByte(*lpszSearch)) - ch1 = *lpszSearch << 8 | lpszSearch[1]; + ch1 = *lpszSearch << 8 | (UCHAR)lpszSearch[1]; else ch1 = *lpszSearch; iLen = lstrlenA(lpszSearch); - while (lpszStr <= lpszEnd && *lpszStr) + do { - ch2 = IsDBCSLeadByte(*lpszStr)? *lpszStr << 8 | lpszStr[1] : *lpszStr; + lpszEnd = CharPrevA(lpszStr, lpszEnd); + ch2 = IsDBCSLeadByte(*lpszEnd)? *lpszEnd << 8 | (UCHAR)lpszEnd[1] : *lpszEnd; if (!ChrCmpIA(ch1, ch2)) { - if (!StrCmpNIA(lpszStr, lpszSearch, iLen)) - lpszRet = (LPSTR)lpszStr; + if (!StrCmpNIA(lpszEnd, lpszSearch, iLen)) + return (LPSTR)lpszEnd; } - lpszStr = CharNextA(lpszStr); - } - return lpszRet; + } while (lpszEnd > lpszStr); + return NULL; } /************************************************************************* @@ -677,7 +678,6 @@ LPSTR WINAPI StrRStrIA(LPCSTR lpszStr, LPCSTR lpszEnd, LPCSTR lpszSearch) */ LPWSTR WINAPI StrRStrIW(LPCWSTR lpszStr, LPCWSTR lpszEnd, LPCWSTR lpszSearch) { - LPWSTR lpszRet = NULL; INT iLen; TRACE("(%s,%s)\n", debugstr_w(lpszStr), debugstr_w(lpszSearch)); @@ -687,19 +687,21 @@ LPWSTR WINAPI StrRStrIW(LPCWSTR lpszStr, LPCWSTR lpszEnd, LPCWSTR lpszSearch) if (!lpszEnd) lpszEnd = lpszStr + strlenW(lpszStr); + if (lpszEnd == lpszStr) + return NULL; iLen = strlenW(lpszSearch); - - while (lpszStr <= lpszEnd && *lpszStr) + + do { - if (!ChrCmpIW(*lpszSearch, *lpszStr)) + lpszEnd = CharPrevW(lpszStr, lpszEnd); + if (!ChrCmpIW(*lpszSearch, *lpszEnd)) { - if (!StrCmpNIW(lpszStr, lpszSearch, iLen)) - lpszRet = (LPWSTR)lpszStr; + if (!StrCmpNIW(lpszEnd, lpszSearch, iLen)) + return (LPWSTR)lpszEnd; } - lpszStr = CharNextW(lpszStr); - } - return lpszRet; + } while (lpszEnd > lpszStr); + return NULL; } /************************************************************************* diff --git a/dlls/shlwapi/tests/string.c b/dlls/shlwapi/tests/string.c index 71533af8de4..209a3c8d0c6 100644 --- a/dlls/shlwapi/tests/string.c +++ b/dlls/shlwapi/tests/string.c @@ -683,6 +683,45 @@ static void test_StrCpyNXW(void) dest + 5, lpszRes, dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]); } +#define check_strrstri(type, str, pos, needle, exp) \ + ret##type = StrRStrI##type(str, str+pos, needle); \ + ok(ret##type == (exp), "Type " #type ", expected %p but got %p (string base %p)\n", \ + (exp), ret##type, str); + +static void test_StrRStrI() +{ + static const CHAR szTest[] = "yAxxxxAy"; + static const CHAR szTest2[] = "ABABABAB"; + static const WCHAR wszTest[] = {'y','A','x','x','x','x','A','y',0}; + static const WCHAR wszTest2[] = {'A','B','A','B','A','B','A','B',0}; + + static const WCHAR wszPattern1[] = {'A',0}; + static const WCHAR wszPattern2[] = {'a','X',0}; + static const WCHAR wszPattern3[] = {'A','y',0}; + static const WCHAR wszPattern4[] = {'a','b',0}; + LPWSTR retW; + LPSTR retA; + + check_strrstri(A, szTest, 4, "A", szTest+1); + check_strrstri(A, szTest, 4, "aX", szTest+1); + check_strrstri(A, szTest, 4, "Ay", NULL); + check_strrstri(W, wszTest, 4, wszPattern1, wszTest+1); + check_strrstri(W, wszTest, 4, wszPattern2, wszTest+1); + check_strrstri(W, wszTest, 4, wszPattern3, NULL); + + check_strrstri(A, szTest2, 4, "ab", szTest2+2); + check_strrstri(A, szTest2, 3, "ab", szTest2+2); + check_strrstri(A, szTest2, 2, "ab", szTest2); + check_strrstri(A, szTest2, 1, "ab", szTest2); + check_strrstri(A, szTest2, 0, "ab", NULL); + check_strrstri(W, wszTest2, 4, wszPattern4, wszTest2+2); + check_strrstri(W, wszTest2, 3, wszPattern4, wszTest2+2); + check_strrstri(W, wszTest2, 2, wszPattern4, wszTest2); + check_strrstri(W, wszTest2, 1, wszPattern4, wszTest2); + check_strrstri(W, wszTest2, 0, wszPattern4, NULL); + +} + static void test_SHAnsiToAnsi(void) { char dest[8]; @@ -760,6 +799,7 @@ START_TEST(string) test_StrRetToBSTR(); test_StrCpyNXA(); test_StrCpyNXW(); + test_StrRStrI(); test_SHAnsiToAnsi(); test_SHUnicodeToUnicode(); }