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

Signed-off-by: Piotr Caban <piotr@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Piotr Caban 2019-10-28 13:29:15 +01:00 committed by Alexandre Julliard
parent 225dad5d0d
commit df60573653
4 changed files with 72 additions and 2 deletions

View File

@ -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) 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 );
} }
/********************************************************************* /*********************************************************************

View File

@ -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__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__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); 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); unsigned int __cdecl MSVCRT__get_output_format(void);
char* __cdecl MSVCRT_strtok_s(char*, const char*, char**); char* __cdecl MSVCRT_strtok_s(char*, const char*, char**);

View File

@ -2005,7 +2005,42 @@ int __cdecl MSVCRT__stricmp(const char *s1, const char *s2)
*/ */
char* __cdecl MSVCRT_strstr(const char *haystack, const char *needle) 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;
} }
/********************************************************************* /*********************************************************************

View File

@ -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) START_TEST(string)
{ {
char mem[100]; char mem[100];
@ -4036,4 +4069,5 @@ START_TEST(string)
test__tcsnicoll(); test__tcsnicoll();
test___strncnt(); test___strncnt();
test_C_locale(); test_C_locale();
test_strstr();
} }