Commit b6e29d09 authored by unknown's avatar unknown

Field::quote_data():

  don't call escape_string_for_mysql() unnecesary
  don't overwrite local buffer
escape_string_for_mysql():
  take a length of the destination buffer as an argument


include/my_sys.h:
  prototype changed
libmysql/libmysql.c:
  prototype changed
mysys/charset.c:
  escape_string_for_mysql():
    take a length of the destination buffer as an argument
sql/field.cc:
  Field::quote_data():
    don't call escape_string_for_mysql() unnecesary
    don't overwrite local buffer
sql/item.cc:
  prototype changed
sql/sql_prepare.cc:
  prototype changed
parent 278e691b
...@@ -845,7 +845,8 @@ extern char *get_charsets_dir(char *buf); ...@@ -845,7 +845,8 @@ extern char *get_charsets_dir(char *buf);
extern my_bool my_charset_same(CHARSET_INFO *cs1, CHARSET_INFO *cs2); extern my_bool my_charset_same(CHARSET_INFO *cs1, CHARSET_INFO *cs2);
extern my_bool init_compiled_charsets(myf flags); extern my_bool init_compiled_charsets(myf flags);
extern void add_compiled_collation(CHARSET_INFO *cs); extern void add_compiled_collation(CHARSET_INFO *cs);
extern ulong escape_string_for_mysql(CHARSET_INFO *charset_info, char *to, extern ulong escape_string_for_mysql(CHARSET_INFO *charset_info,
char *to, ulong to_length,
const char *from, ulong length); const char *from, ulong length);
extern void thd_increment_bytes_sent(ulong length); extern void thd_increment_bytes_sent(ulong length);
......
...@@ -1575,14 +1575,14 @@ mysql_hex_string(char *to, const char *from, ulong length) ...@@ -1575,14 +1575,14 @@ mysql_hex_string(char *to, const char *from, ulong length)
ulong STDCALL ulong STDCALL
mysql_escape_string(char *to,const char *from,ulong length) mysql_escape_string(char *to,const char *from,ulong length)
{ {
return escape_string_for_mysql(default_charset_info, to, from, length); return escape_string_for_mysql(default_charset_info, to, 0, from, length);
} }
ulong STDCALL ulong STDCALL
mysql_real_escape_string(MYSQL *mysql, char *to,const char *from, mysql_real_escape_string(MYSQL *mysql, char *to,const char *from,
ulong length) ulong length)
{ {
return escape_string_for_mysql(mysql->charset, to, from, length); return escape_string_for_mysql(mysql->charset, to, 0, from, length);
} }
......
...@@ -561,21 +561,34 @@ CHARSET_INFO *get_charset_by_csname(const char *cs_name, ...@@ -561,21 +561,34 @@ CHARSET_INFO *get_charset_by_csname(const char *cs_name,
DBUG_RETURN(cs); DBUG_RETURN(cs);
} }
/*
ulong escape_string_for_mysql(CHARSET_INFO *charset_info, char *to, NOTE
to keep old C API, to_length may be 0 to mean "big enough"
RETURN
the length of the escaped string or ~0 if it did not fit.
*/
ulong escape_string_for_mysql(CHARSET_INFO *charset_info,
char *to, ulong to_length,
const char *from, ulong length) const char *from, ulong length)
{ {
const char *to_start= to; const char *to_start= to;
const char *end; const char *end, *to_end=to_start + (to_length ? to_length-1 : 2*length);
my_bool overflow=0;
#ifdef USE_MB #ifdef USE_MB
my_bool use_mb_flag= use_mb(charset_info); my_bool use_mb_flag= use_mb(charset_info);
#endif #endif
for (end= from + length; from != end; from++) for (end= from + length; from < end; from++)
{ {
char escape=0;
#ifdef USE_MB #ifdef USE_MB
int l; int l;
if (use_mb_flag && (l= my_ismbchar(charset_info, from, end))) if (use_mb_flag && (l= my_ismbchar(charset_info, from, end)))
{ {
if (to + l >= to_end)
{
overflow=1;
break;
}
while (l--) while (l--)
*to++= *from++; *to++= *from++;
from--; from--;
...@@ -593,45 +606,53 @@ ulong escape_string_for_mysql(CHARSET_INFO *charset_info, char *to, ...@@ -593,45 +606,53 @@ ulong escape_string_for_mysql(CHARSET_INFO *charset_info, char *to,
a valid GBK character, but 0xbf5c is. (0x27 = ', 0x5c = \) a valid GBK character, but 0xbf5c is. (0x27 = ', 0x5c = \)
*/ */
if (use_mb_flag && (l= my_mbcharlen(charset_info, *from)) > 1) if (use_mb_flag && (l= my_mbcharlen(charset_info, *from)) > 1)
{ escape= *from;
*to++= '\\'; else
*to++= *from;
continue;
}
#endif #endif
switch (*from) { switch (*from) {
case 0: /* Must be escaped for 'mysql' */ case 0: /* Must be escaped for 'mysql' */
*to++= '\\'; escape= '0';
*to++= '0';
break; break;
case '\n': /* Must be escaped for logs */ case '\n': /* Must be escaped for logs */
*to++= '\\'; escape= 'n';
*to++= 'n';
break; break;
case '\r': case '\r':
*to++= '\\'; escape= 'r';
*to++= 'r';
break; break;
case '\\': case '\\':
*to++= '\\'; escape= '\\';
*to++= '\\';
break; break;
case '\'': case '\'':
*to++= '\\'; escape= '\'';
*to++= '\'';
break; break;
case '"': /* Better safe than sorry */ case '"': /* Better safe than sorry */
*to++= '\\'; escape= '"';
*to++= '"';
break; break;
case '\032': /* This gives problems on Win32 */ case '\032': /* This gives problems on Win32 */
escape= 'Z';
break;
}
if (escape)
{
if (to + 2 >= to_end)
{
overflow=1;
break;
}
*to++= '\\'; *to++= '\\';
*to++= 'Z'; *to++= escape;
}
else
{
if (to + 1 >= to_end)
{
overflow=1;
break; break;
default: }
*to++= *from; *to++= *from;
} }
} }
*to= 0; *to= 0;
return (ulong) (to - to_start); return overflow ? (ulong)~0 : (ulong) (to - to_start);
} }
...@@ -752,25 +752,22 @@ bool Field::quote_data(String *unquoted_string) ...@@ -752,25 +752,22 @@ bool Field::quote_data(String *unquoted_string)
{ {
char escaped_string[IO_SIZE]; char escaped_string[IO_SIZE];
char *unquoted_string_buffer= (char *)(unquoted_string->ptr()); char *unquoted_string_buffer= (char *)(unquoted_string->ptr());
uint need_quotes;
DBUG_ENTER("Field::quote_data"); DBUG_ENTER("Field::quote_data");
// this is the same call that mysql_real_escape_string() calls if (!needs_quotes())
escape_string_for_mysql(&my_charset_bin, (char *)escaped_string,
unquoted_string->ptr(), unquoted_string->length());
need_quotes= needs_quotes();
if (need_quotes == 0)
DBUG_RETURN(0); DBUG_RETURN(0);
// this is the same call that mysql_real_escape_string() calls
if (escape_string_for_mysql(&my_charset_bin, (char *)escaped_string,
sizeof(escaped_string), unquoted_string->ptr(),
unquoted_string->length()) == (ulong)~0)
DBUG_RETURN(1);
// reset string, then re-append with quotes and escaped values // reset string, then re-append with quotes and escaped values
unquoted_string->length(0); unquoted_string->length(0);
if (unquoted_string->append('\'')) if (unquoted_string->append('\'') ||
DBUG_RETURN(1); unquoted_string->append((char *)escaped_string) ||
if (unquoted_string->append((char *)escaped_string)) unquoted_string->append('\''))
DBUG_RETURN(1);
if (unquoted_string->append('\''))
DBUG_RETURN(1); DBUG_RETURN(1);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
......
...@@ -2038,7 +2038,7 @@ const String *Item_param::query_val_str(String* str) const ...@@ -2038,7 +2038,7 @@ const String *Item_param::query_val_str(String* str) const
buf= str->c_ptr_quick(); buf= str->c_ptr_quick();
ptr= buf; ptr= buf;
*ptr++= '\''; *ptr++= '\'';
ptr+= escape_string_for_mysql(str_value.charset(), ptr, ptr+= escape_string_for_mysql(str_value.charset(), ptr, 0,
str_value.ptr(), str_value.length()); str_value.ptr(), str_value.length());
*ptr++= '\''; *ptr++= '\'';
str->length(ptr - buf); str->length(ptr - buf);
......
...@@ -865,7 +865,7 @@ static bool insert_params_from_vars_with_log(Prepared_statement *stmt, ...@@ -865,7 +865,7 @@ static bool insert_params_from_vars_with_log(Prepared_statement *stmt,
*ptr++= '\''; *ptr++= '\'';
ptr+= ptr+=
escape_string_for_mysql(&my_charset_utf8_general_ci, escape_string_for_mysql(&my_charset_utf8_general_ci,
ptr, entry->name.str, entry->name.length); ptr, 0, entry->name.str, entry->name.length);
*ptr++= '\''; *ptr++= '\'';
str.length(ptr - buf); str.length(ptr - buf);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment