Piotr Caban : msvcrt: Don't use strstr from C-library.

Alexandre Julliard julliard at winehq.org
Mon Oct 28 16:43:36 CDT 2019


Module: wine
Branch: master
Commit: df6057365335757b027efc69e192d54a2eb274d1
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=df6057365335757b027efc69e192d54a2eb274d1

Author: Piotr Caban <piotr at 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 at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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();
 }




More information about the wine-cvs mailing list