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