Commit 861096a5 authored by unknown's avatar unknown
Browse files

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().
parent c90f464d
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -67,6 +67,14 @@ class String
      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)
  {
+4 −1
Original line number Diff line number Diff line
@@ -120,7 +120,10 @@ class Item_func :public Item_result_field
  {
    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);
+2 −2
Original line number Diff line number Diff line
@@ -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;
}


+8 −0
Original line number Diff line number Diff line
@@ -74,6 +74,14 @@ class String
      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)
  {