From 861096a58f9c3f246d8a7b448601a422c8e04f26 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 1 Jul 2006 14:31:52 -0400 Subject: [PATCH 1/2] Bug#19006: 4.0 valgrind problems (in test func_str) On exactly-sized Strings, the String::c_ptr() function peeked beyond the end of the buffer, possibly into unititialized space to see whether the buffer was NUL-terminated. In a place that did peek improperly, we now use a c_ptr_safe() function, which doesn't peek where it shouldn't. client/sql_string.h: Back-port String::c_ptr_safe(). sql/item_func.h: Describe side-effect behavior. sql/item_strfunc.cc: Use the "_safe" version of c_ptr to avoid looking for a terminating NUL character outside the initialized memory area. Valgrind hates it when one does that, and it theoretically could lead to a SEGV. sql/sql_string.h: Back-port String::c_ptr_safe(). --- client/sql_string.h | 8 ++++++++ sql/item_func.h | 5 ++++- sql/item_strfunc.cc | 4 ++-- sql/sql_string.h | 8 ++++++++ 4 files changed, 22 insertions(+), 3 deletions(-) diff --git a/client/sql_string.h b/client/sql_string.h index cffe78936a0..13687eef4dc 100644 --- a/client/sql_string.h +++ b/client/sql_string.h @@ -67,6 +67,14 @@ public: Ptr[str_length]=0; return Ptr; } + inline char *c_ptr_safe() + { + if (Ptr && str_length < Alloced_length) + Ptr[str_length]=0; + else + (void) realloc(str_length); + return Ptr; + } void set(String &str,uint32 offset,uint32 arg_length) { diff --git a/sql/item_func.h b/sql/item_func.h index 3627af4ebb1..3336f2afd1b 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -120,7 +120,10 @@ public: { return (null_value=args[0]->get_time(ltime)); } - bool is_null() { (void) val_int(); return null_value; } + bool is_null() { + (void) val_int(); /* Discard result. It sets null_value as side-effect. */ + return null_value; + } friend class udf_handler; unsigned int size_of() { return sizeof(*this);} Field *tmp_table_field(TABLE *t_arg); diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 2ea693e94a3..81e3129471c 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -51,14 +51,14 @@ double Item_str_func::val() { String *res; res=val_str(&str_value); - return res ? atof(res->c_ptr()) : 0.0; + return res ? atof(res->c_ptr_safe()) : 0.0; } longlong Item_str_func::val_int() { String *res; res=val_str(&str_value); - return res ? strtoll(res->c_ptr(),NULL,10) : (longlong) 0; + return res ? strtoll(res->c_ptr_safe(),NULL,10) : (longlong) 0; } diff --git a/sql/sql_string.h b/sql/sql_string.h index ad7455ecbf1..25abfd27eef 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -74,6 +74,14 @@ public: Ptr[str_length]=0; return Ptr; } + inline char *c_ptr_safe() + { + if (Ptr && str_length < Alloced_length) + Ptr[str_length]=0; + else + (void) realloc(str_length); + return Ptr; + } void set(String &str,uint32 offset,uint32 arg_length) { From 89c7db0cb0a67a8c7bd30eb4043ec948554244e9 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 7 Jul 2006 16:47:57 -0400 Subject: [PATCH 2/2] Add a more reliable "getconf" test for Linuxthreads. The later trees should already have a better test (and so this should be null-merged there). ALSO! Make it so that it accepts NPTL as a valid _equivalent_ implementation. --- configure.in | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/configure.in b/configure.in index 8dd224d0a87..376cf48c476 100644 --- a/configure.in +++ b/configure.in @@ -1241,8 +1241,9 @@ if test "$with_named_thread" = "no" -a "$with_mit_threads" = "no" then # Look for LinuxThreads. AC_MSG_CHECKING("LinuxThreads") - res=`grep Linuxthreads /usr/include/pthread.h 2>/dev/null | wc -l` - if test "$res" -gt 0 + grepres=`grep Linuxthreads /usr/include/pthread.h 2>/dev/null | wc -l` + getconfres=`which getconf >/dev/null && getconf GNU_LIBPTHREAD_VERSION | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ |grep LINUXTHREADS | wc -l || echo 0` + if test "$grepres" -gt 0 -o "$getconfres" -gt 0 then AC_MSG_RESULT("Found") AC_DEFINE(HAVE_LINUXTHREADS) @@ -1255,12 +1256,20 @@ then else AC_MSG_RESULT("Not found") # If this is a linux machine we should barf + AC_MSG_CHECKING("NPTL") if test "$IS_LINUX" = "true" then - AC_MSG_ERROR([This is a linux system and Linuxthreads was not -found. On linux Linuxthreads should be used. Please install Linuxthreads -(or a new glibc) and try again. See the Installation chapter in the -Reference Manual for more information.]) + getconfres=`which getconf >/dev/null && getconf GNU_LIBPTHREAD_VERSION | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ |grep NPTL | wc -l || echo 0` + if test "$getconfres" -gt 0 + then + AC_DEFINE(HAVE_LINUXTHREADS) dnl All this code predates NPTL, so "have linuxthreads" is a poor name. + with_named_thread="-lpthread" + else + AC_MSG_ERROR([This is a Linux system and neither Linuxthreads nor NPTL were +found. Please install Linuxthreads or a new glibc and try +again. See the Installation chapter in the Reference Manual for +more information.]) + fi else AC_MSG_CHECKING("DEC threads") if test -f /usr/shlib/libpthread.so -a -f /usr/lib/libmach.a -a -f /usr/ccs/lib/cmplrs/cc/libexc.a