From: Sebastian Lackner Subject: [1/5] shlwapi: Fix incorrect usage of CompareString in StrRStrIA. Message-Id: <546C5358.1080402@fds-team.de> Date: Wed, 19 Nov 2014 09:22:48 +0100 The implementation of CharPrevA is so slow (always searches the whole string from the beginning), that it is more useful to use the comctl32 implementation here than fixing the existing one - with a slight modification: the existing tests show that when lpszEnd is passed, the function reads past the end of the string, even on Windows. --- dlls/shlwapi/string.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) From 30101df0b3402170e1d07292401ab0a798390094 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Wed, 19 Nov 2014 08:17:58 +0100 Subject: shlwapi: Fix incorrect usage of CompareString in StrRStrIA. --- dlls/shlwapi/string.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/dlls/shlwapi/string.c b/dlls/shlwapi/string.c index eaaaf3b..316dd3f 100644 --- a/dlls/shlwapi/string.c +++ b/dlls/shlwapi/string.c @@ -585,6 +585,7 @@ LPWSTR WINAPI StrStrW(LPCWSTR lpszStr, LPCWSTR lpszSearch) */ LPSTR WINAPI StrRStrIA(LPCSTR lpszStr, LPCSTR lpszEnd, LPCSTR lpszSearch) { + LPSTR lpszRet = NULL; WORD ch1, ch2; INT iLen; @@ -593,28 +594,28 @@ LPSTR WINAPI StrRStrIA(LPCSTR lpszStr, LPCSTR lpszEnd, LPCSTR lpszSearch) if (!lpszStr || !lpszSearch || !*lpszSearch) return NULL; - if (!lpszEnd) - lpszEnd = lpszStr + lstrlenA(lpszStr); - if (lpszEnd == lpszStr) - return NULL; - if (IsDBCSLeadByte(*lpszSearch)) ch1 = *lpszSearch << 8 | (UCHAR)lpszSearch[1]; else ch1 = *lpszSearch; iLen = lstrlenA(lpszSearch); - do + if (!lpszEnd) + lpszEnd = lpszStr + lstrlenA(lpszStr); + else /* reproduce the broken behaviour on Windows */ + lpszEnd += min(iLen - 1, lstrlenA(lpszEnd)); + + while (lpszStr + iLen <= lpszEnd && *lpszStr) { - lpszEnd = CharPrevA(lpszStr, lpszEnd); - ch2 = IsDBCSLeadByte(*lpszEnd)? *lpszEnd << 8 | (UCHAR)lpszEnd[1] : *lpszEnd; + ch2 = IsDBCSLeadByte(*lpszStr)? *lpszStr << 8 | (UCHAR)lpszStr[1] : *lpszStr; if (!ChrCmpIA(ch1, ch2)) { - if (!StrCmpNIA(lpszEnd, lpszSearch, iLen)) - return (LPSTR)lpszEnd; + if (!StrCmpNIA(lpszStr, lpszSearch, iLen)) + lpszRet = (LPSTR)lpszStr; } - } while (lpszEnd > lpszStr); - return NULL; + lpszStr = CharNextA(lpszStr); + } + return lpszRet; } /************************************************************************* -- 2.1.3