mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-03 18:13:01 +00:00
Add a replacement for strcasestr, along with test case. Fixes #282979.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@12187
This commit is contained in:
parent
141e66b02a
commit
1fd197db11
@ -93,6 +93,7 @@
|
||||
20320 STRPBRK
|
||||
20330 STRCSPN
|
||||
20340 STRSPN
|
||||
20350 STRCASESTR
|
||||
*/
|
||||
|
||||
|
||||
@ -1451,6 +1452,54 @@ static inline void my_exit ( int x )
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------- strcasestr ----------------------*/
|
||||
|
||||
#define STRCASESTR(soname, fnname) \
|
||||
void* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
|
||||
(void* haystack, void* needle); \
|
||||
void* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
|
||||
(void* haystack, void* needle) \
|
||||
{ \
|
||||
extern int tolower(int); \
|
||||
UChar* h = (UChar*)haystack; \
|
||||
UChar* n = (UChar*)needle; \
|
||||
\
|
||||
/* find the length of n, not including terminating zero */ \
|
||||
UWord nlen = 0; \
|
||||
while (n[nlen]) nlen++; \
|
||||
\
|
||||
/* if n is the empty string, match immediately. */ \
|
||||
if (nlen == 0) return h; \
|
||||
\
|
||||
/* assert(nlen >= 1); */ \
|
||||
UChar n0 = tolower(n[0]); \
|
||||
\
|
||||
while (1) { \
|
||||
UChar hh = tolower(*h); \
|
||||
if (hh == 0) return NULL; \
|
||||
if (hh != n0) { h++; continue; } \
|
||||
\
|
||||
UWord i; \
|
||||
for (i = 0; i < nlen; i++) { \
|
||||
if (tolower(n[i]) != tolower(h[i])) \
|
||||
break; \
|
||||
} \
|
||||
/* assert(i >= 0 && i <= nlen); */ \
|
||||
if (i == nlen) \
|
||||
return h; \
|
||||
\
|
||||
h++; \
|
||||
} \
|
||||
}
|
||||
|
||||
#if defined(VGO_linux)
|
||||
STRCASESTR(VG_Z_LIBC_SONAME, strcasestr)
|
||||
|
||||
#elif defined(VGO_darwin)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*------------------------------------------------------------*/
|
||||
/*--- Improve definedness checking of process environment ---*/
|
||||
/*------------------------------------------------------------*/
|
||||
|
||||
@ -1373,6 +1373,33 @@ test_strncasecmp (void)
|
||||
check(strncasecmp("ADC", "abcd", 2) > 0, 20);
|
||||
}
|
||||
|
||||
static void
|
||||
test_strcasestr (void)
|
||||
{
|
||||
it = "strcasestr";
|
||||
check(strcasestr("abCd", "z") == NULL, 1); /* Not found. */
|
||||
check(strcasestr("AbcD", "abX") == NULL, 2); /* Dead end. */
|
||||
(void) strcpy(one, "abCd");
|
||||
check(strcasestr(one, "c") == one+2, 3); /* Basic test. */
|
||||
check(strcasestr(one, "Bc") == one+1, 4); /* Multichar. */
|
||||
check(strcasestr(one, "d") == one+3, 5); /* End of string. */
|
||||
check(strcasestr(one, "Cd") == one+2, 6); /* Tail of string. */
|
||||
check(strcasestr(one, "aBc") == one, 7); /* Beginning. */
|
||||
check(strcasestr(one, "aBcd") == one, 8); /* Exact match. */
|
||||
check(strcasestr(one, "AbcDe") == NULL, 9); /* Too long. */
|
||||
check(strcasestr(one, "dE") == NULL, 10); /* Past end. */
|
||||
check(strcasestr(one, "") == one, 11); /* Finding empty. */
|
||||
(void) strcpy(one, "abAba");
|
||||
check(strcasestr(one, "Ba") == one+1, 12); /* Finding first. */
|
||||
(void) strcpy(one, "");
|
||||
check(strcasestr(one, "b") == NULL, 13); /* Empty string. */
|
||||
check(strcasestr(one, "") == one, 14); /* Empty in empty string. */
|
||||
(void) strcpy(one, "BcbCa");
|
||||
check(strcasestr(one, "bCa") == one+2, 15); /* False start. */
|
||||
(void) strcpy(one, "bbBcaBbcA");
|
||||
check(strcasestr(one, "bbCa") == one+1, 16); /* With overlap. */
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
@ -1501,6 +1528,8 @@ main (void)
|
||||
/* strncasecmp. Without locale dependencies. */
|
||||
test_strncasecmp ();
|
||||
|
||||
test_strcasestr ();
|
||||
|
||||
if (errors == 0)
|
||||
{
|
||||
status = EXIT_SUCCESS;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user