Commit a29b1d71 authored by unknown's avatar unknown
Browse files

BUG#11338 (logging of prepared statement w/ blob type)

In cp932, '\' character can be the second byte in a 
multi-byte character stream. This makes it difficult to use
mysql_escape_string. Added flag to indicate which languages allow
'\' as second byte of multibyte sequence so that when putting a prepared
statement into the binlog we can decide at runtime whether hex encoding
is really needed.


include/m_ctype.h:
  Added bool to indicate character sets which allow '\' as the second
  byte of a multibyte character set (currently only cp932). For these
  character sets, escaping with '\' is dangerous and leads to corruption
  in replication.
include/my_sys.h:
  Add function to enocde a string as hex with no prefix (bare)
mysys/charset.c:
  Add function to encode string as hex with no prefix (bare).
sql/item.cc:
  Check the connection character set to see if escape_string_for_mysql
  is safe, or if character set requires unambiguous (hex) encoding
sql/item.h:
  Pass thd to query_val_str for access to charset()
sql/sql_prepare.cc:
  Pass thd to query_val_str.
strings/ctype-big5.c:
  Add escape_with_backslash_is_dangerous flag.
strings/ctype-bin.c:
  Add escape_with_backslash_is_dangerous flag
strings/ctype-cp932.c:
  Add escape_with_backslash_is_dangerous flag.
strings/ctype-czech.c:
  Add escape_with_backslash_is_dangerous flag.
strings/ctype-euc_kr.c:
  Add escape_with_backslash_is_dangerous flag.
strings/ctype-extra.c:
  Add escape_with_backslash_is_dangerous flag.
strings/ctype-gb2312.c:
  Add escape_with_backslash_is_dangerous flag.
strings/ctype-gbk.c:
  Added escape_with_backslash_is_dangerous flag.
strings/ctype-latin1.c:
  Added escape_with_backslash_is_dangerous flag.
strings/ctype-sjis.c:
  Added escape_with_backslash_is_dangerous flag.
strings/ctype-tis620.c:
  Added esacpe_with_backslash_character_is_dangerous flag.
strings/ctype-uca.c:
  Added escape_with_backslash_is_dangerous flag.
strings/ctype-ucs2.c:
  Added escape_with_backslash_is_dangerous.
strings/ctype-ujis.c:
  Added escape_with_backslash_is_dangerous flag.
strings/ctype-utf8.c:
  Added escape_with_backslash_is_dangerous.
strings/ctype-win1250ch.c:
  Added escape_with_backslash_is_dangerous.
parent bf076931
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -220,6 +220,7 @@ typedef struct charset_info_st
  uint      mbmaxlen;
  uint16    min_sort_char;
  uint16    max_sort_char; /* For LIKE optimization */
  my_bool   escape_with_backslash_is_dangerous;
  
  MY_CHARSET_HANDLER *cset;
  MY_COLLATION_HANDLER *coll;
+1 −0
Original line number Diff line number Diff line
@@ -788,6 +788,7 @@ extern my_bool init_compiled_charsets(myf flags);
extern void add_compiled_collation(CHARSET_INFO *cs);
extern ulong escape_string_for_mysql(CHARSET_INFO *charset_info, char *to,
                                     const char *from, ulong length);
extern char *bare_str_to_hex(char *to, const char *from, uint len);
#ifdef __WIN__
#define BACKSLASH_MBTAIL
/* File system character set */
+18 −0
Original line number Diff line number Diff line
@@ -663,3 +663,21 @@ CHARSET_INFO *fs_character_set()
  return fs_cset_cache;
}
#endif

/*
  Transforms a string into hex form.
 */
char *bare_str_to_hex(char *to, const char *from, uint len)
{
  char *p= to;
  uint i;
  for (i= 0; i < len; i++, p+= 2)
  {
    /* val[i] is char. Casting to uchar helps greatly if val[i] < 0 */
    uint tmp= (uint) (uchar) from[i];
    p[0]= _dig_vec_upper[tmp >> 4];
    p[1]= _dig_vec_upper[tmp & 15];
  }
  *p= 0;
  return p; // pointer to end 0 of 'to'
}
+13 −5
Original line number Diff line number Diff line
@@ -1443,7 +1443,7 @@ String *Item_param::val_str(String* str)
  and avoid one more memcpy/alloc between str and log string.
*/

const String *Item_param::query_val_str(String* str) const
const String *Item_param::query_val_str(String* str, THD *thd) const
{
  switch (state) {
  case INT_VALUE:
@@ -1482,9 +1482,17 @@ const String *Item_param::query_val_str(String* str) const

      buf= str->c_ptr_quick();
      ptr= buf;
      if (thd->charset()->escape_with_backslash_is_dangerous)
      {
        ptr= strmov(ptr, "x\'");
        ptr= bare_str_to_hex(ptr, str_value.ptr(), str_value.length());
      }
      else
      {
        *ptr++= '\'';
        ptr+= escape_string_for_mysql(str_value.charset(), ptr,
                                      str_value.ptr(), str_value.length());
      }
      *ptr++='\'';
      str->length(ptr - buf);
      break;
+1 −1
Original line number Diff line number Diff line
@@ -591,7 +591,7 @@ class Item_param :public Item
  */
  void (*set_param_func)(Item_param *param, uchar **pos, ulong len);

  const String *query_val_str(String *str) const;
  const String *query_val_str(String *str, THD *thd) const;

  bool convert_str_value(THD *thd);

Loading