Module: wine Branch: master Commit: df6057365335757b027efc69e192d54a2eb274d1 URL: https://source.winehq.org/git/wine.git/?a=commit;h=df6057365335757b027efc69e...
Author: Piotr Caban piotr@codeweavers.com Date: Mon Oct 28 13:29:15 2019 +0100
msvcrt: Don't use strstr from C-library.
Signed-off-by: Piotr Caban piotr@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/msvcrt/mbcs.c | 2 +- dlls/msvcrt/msvcrt.h | 1 + dlls/msvcrt/string.c | 37 ++++++++++++++++++++++++++++++++++++- dlls/msvcrt/tests/string.c | 34 ++++++++++++++++++++++++++++++++++ 4 files changed, 72 insertions(+), 2 deletions(-)
diff --git a/dlls/msvcrt/mbcs.c b/dlls/msvcrt/mbcs.c index 6a62909128..526ae9b9b5 100644 --- a/dlls/msvcrt/mbcs.c +++ b/dlls/msvcrt/mbcs.c @@ -1211,7 +1211,7 @@ unsigned char* CDECL _mbscpy( unsigned char *dst, const unsigned char *src ) */ unsigned char * CDECL _mbsstr(const unsigned char *haystack, const unsigned char *needle) { - return (unsigned char *)strstr( (const char *)haystack, (const char *)needle ); + return (unsigned char *)MSVCRT_strstr( (const char *)haystack, (const char *)needle ); }
/********************************************************************* diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h index 4bf26fbe9a..bfc084425f 100644 --- a/dlls/msvcrt/msvcrt.h +++ b/dlls/msvcrt/msvcrt.h @@ -1176,6 +1176,7 @@ int __cdecl MSVCRT__stricmp(const char*, const char*); int __cdecl MSVCRT__strnicmp(const char*, const char*, MSVCRT_size_t); int __cdecl MSVCRT__strnicoll_l(const char*, const char*, MSVCRT_size_t, MSVCRT__locale_t); int __cdecl MSVCRT__strncoll_l(const char*, const char*, MSVCRT_size_t, MSVCRT__locale_t); +char* __cdecl MSVCRT_strstr(const char*, const char*); unsigned int __cdecl MSVCRT__get_output_format(void); char* __cdecl MSVCRT_strtok_s(char*, const char*, char**);
diff --git a/dlls/msvcrt/string.c b/dlls/msvcrt/string.c index 038463c319..4ae523cece 100644 --- a/dlls/msvcrt/string.c +++ b/dlls/msvcrt/string.c @@ -2005,7 +2005,42 @@ int __cdecl MSVCRT__stricmp(const char *s1, const char *s2) */ char* __cdecl MSVCRT_strstr(const char *haystack, const char *needle) { - return strstr(haystack, needle); + MSVCRT_size_t i, j, len, needle_len, lps_len; + BYTE lps[256]; + + needle_len = MSVCRT_strlen(needle); + if (!needle_len) return (char*)haystack; + lps_len = needle_len > ARRAY_SIZE(lps) ? ARRAY_SIZE(lps) : needle_len; + + lps[0] = 0; + len = 0; + i = 1; + while (i < lps_len) + { + if (needle[i] == needle[len]) lps[i++] = ++len; + else if (len) len = lps[len-1]; + else lps[i++] = 0; + } + + i = j = 0; + while (haystack[i]) + { + while (j < lps_len && haystack[i] && haystack[i] == needle[j]) + { + i++; + j++; + } + + if (j == needle_len) return (char*)haystack + i - j; + else if (j) + { + if (j == ARRAY_SIZE(lps) && !MSVCRT_strncmp(haystack + i, needle + j, needle_len - j)) + return (char*)haystack + i - j; + j = lps[j-1]; + } + else if (haystack[i]) i++; + } + return NULL; }
/********************************************************************* diff --git a/dlls/msvcrt/tests/string.c b/dlls/msvcrt/tests/string.c index f83130fc26..05d7a4f28b 100644 --- a/dlls/msvcrt/tests/string.c +++ b/dlls/msvcrt/tests/string.c @@ -3897,6 +3897,39 @@ static void test_C_locale(void) } }
+static void test_strstr(void) +{ + static char long_str[1024]; + const struct { + const char *haystack; + const char *needle; + int off; + } tests[] = { + { "", "", 0 }, + { "", "a", -1 }, + { "a", "", 0 }, + { "aabc", "abc", 1 }, + { "aaaa", "aaaa", 0 }, + { "simple", "simple", 0 }, + { "aaaaxaaaaxaaaa", "aaaaa", -1 }, + { "aaaaxaaaaxaaaaa", "aaaaa", 10 }, + { "abcabcdababcdabcdabde", "abcdabd", 13 }, + { "abababababcabababcababbba", "abababcaba", 4 }, + { long_str, long_str+1, 0 } + }; + const char *r, *exp; + int i; + + memset(long_str, 'a', sizeof(long_str)-1); + + for (i=0; i<ARRAY_SIZE(tests); i++) + { + r = strstr(tests[i].haystack, tests[i].needle); + exp = tests[i].off == -1 ? NULL : tests[i].haystack + tests[i].off; + ok(r == exp, "%d) strstr returned %p, expected %p\n", i, r, exp); + } +} + START_TEST(string) { char mem[100]; @@ -4036,4 +4069,5 @@ START_TEST(string) test__tcsnicoll(); test___strncnt(); test_C_locale(); + test_strstr(); }