On Fri, Jun 17, 2011 at 04:16:33AM -0400, Jeff King wrote:
> Yeah, they even ship a commented-out implementation of strspn; the patch
> I mentioned above basically just uncomments it.
> [...]
> I'll attach the full pristine patch from valgrind 3.6.1-5 that fixes it
> for me.
I get a similar issue with the optimized strcasestr:
$ cat >foo.c <<'EOF'
#define _GNU_SOURCE
#include <string.h>
int main(void)
{
char buf[32];
strcpy(buf, "foo");
return strcasestr(buf, "bar") != buf;
}
EOF
$ gcc -o foo foo.c
$ valgrind ./foo
==27953== Conditional jump or move depends on uninitialised value(s)
==27953== at 0x4B34E2D: __strcasestr_sse42 (strstr.c:218)
==27953== by 0x400519: main (in /home/peff/foo/valgrind/foo)
The attached patch fixes it (the implementation is ripped from the
strstr that valgrind provides, with tolower() used as appropriate (this
is what their strcasecmp re-implementation does)).
-Peff
diff --git a/memcheck/mc_replace_strmem.c b/memcheck/mc_replace_strmem.c
index 0622a5e..8c7747d 100644
--- a/memcheck/mc_replace_strmem.c
+++ b/memcheck/mc_replace_strmem.c
@@ -1045,6 +1045,48 @@ STRSTR(VG_Z_LIBC_SONAME, strstr)
#endif
+#define STRCASESTR(soname, fnname) \
+ void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+ (void* haystack, void* needle); \
+ void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+ (void* haystack, void* needle) \
+ { \
+ 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)
+#endif
+
+
#define STRPBRK(soname, fnname) \
void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
(void* sV, void* acceptV); \