diff options
author | unknown <serg@serg.mylan> | 2005-03-17 12:27:45 +0100 |
---|---|---|
committer | unknown <serg@serg.mylan> | 2005-03-17 12:27:45 +0100 |
commit | b6e29d09b0c22037f7c1d54c55c76045a01b03ac (patch) | |
tree | 6647c711e18c396c34022d37fca3cc74234620f2 | |
parent | 278e691ba885480cb1ab0879d1464ecbd8d3803f (diff) | |
download | mariadb-git-b6e29d09b0c22037f7c1d54c55c76045a01b03ac.tar.gz |
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
-rw-r--r-- | include/my_sys.h | 3 | ||||
-rw-r--r-- | libmysql/libmysql.c | 4 | ||||
-rw-r--r-- | mysys/charset.c | 75 | ||||
-rw-r--r-- | sql/field.cc | 23 | ||||
-rw-r--r-- | sql/item.cc | 2 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 2 |
6 files changed, 64 insertions, 45 deletions
diff --git a/include/my_sys.h b/include/my_sys.h index afd2803b75d..c4385cd5fd2 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -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 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, +extern ulong escape_string_for_mysql(CHARSET_INFO *charset_info, + char *to, ulong to_length, const char *from, ulong length); extern void thd_increment_bytes_sent(ulong length); diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 20a000f1e4d..7e5d9667be2 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -1575,14 +1575,14 @@ mysql_hex_string(char *to, const char *from, ulong length) ulong STDCALL 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 mysql_real_escape_string(MYSQL *mysql, char *to,const char *from, ulong length) { - return escape_string_for_mysql(mysql->charset, to, from, length); + return escape_string_for_mysql(mysql->charset, to, 0, from, length); } diff --git a/mysys/charset.c b/mysys/charset.c index 4b7ad3e59f4..a4a8205a3f9 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -547,10 +547,10 @@ CHARSET_INFO *get_charset_by_csname(const char *cs_name, DBUG_PRINT("enter",("name: '%s'", cs_name)); (void) init_available_charsets(MYF(0)); /* If it isn't initialized */ - + cs_number= get_charset_number(cs_name, cs_flags); cs= cs_number ? get_internal_charset(cs_number, flags) : NULL; - + if (!cs && (flags & MY_WME)) { char index_file[FN_REFLEN]; @@ -561,21 +561,34 @@ CHARSET_INFO *get_charset_by_csname(const char *cs_name, 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 *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 my_bool use_mb_flag= use_mb(charset_info); #endif - for (end= from + length; from != end; from++) + for (end= from + length; from < end; from++) { + char escape=0; #ifdef USE_MB int l; if (use_mb_flag && (l= my_ismbchar(charset_info, from, end))) { + if (to + l >= to_end) + { + overflow=1; + break; + } while (l--) *to++= *from++; from--; @@ -593,45 +606,53 @@ ulong escape_string_for_mysql(CHARSET_INFO *charset_info, char *to, a valid GBK character, but 0xbf5c is. (0x27 = ', 0x5c = \) */ if (use_mb_flag && (l= my_mbcharlen(charset_info, *from)) > 1) - { - *to++= '\\'; - *to++= *from; - continue; - } + escape= *from; + else #endif switch (*from) { case 0: /* Must be escaped for 'mysql' */ - *to++= '\\'; - *to++= '0'; + escape= '0'; break; case '\n': /* Must be escaped for logs */ - *to++= '\\'; - *to++= 'n'; + escape= 'n'; break; case '\r': - *to++= '\\'; - *to++= 'r'; + escape= 'r'; break; case '\\': - *to++= '\\'; - *to++= '\\'; + escape= '\\'; break; case '\'': - *to++= '\\'; - *to++= '\''; + escape= '\''; break; case '"': /* Better safe than sorry */ - *to++= '\\'; - *to++= '"'; + escape= '"'; break; case '\032': /* This gives problems on Win32 */ - *to++= '\\'; - *to++= 'Z'; + escape= 'Z'; break; - default: + } + if (escape) + { + if (to + 2 >= to_end) + { + overflow=1; + break; + } + *to++= '\\'; + *to++= escape; + } + else + { + if (to + 1 >= to_end) + { + overflow=1; + break; + } *to++= *from; } } *to= 0; - return (ulong) (to - to_start); + return overflow ? (ulong)~0 : (ulong) (to - to_start); } + diff --git a/sql/field.cc b/sql/field.cc index b6dd00d62a7..ae9b76e2dc4 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -752,25 +752,22 @@ bool Field::quote_data(String *unquoted_string) { char escaped_string[IO_SIZE]; char *unquoted_string_buffer= (char *)(unquoted_string->ptr()); - uint need_quotes; DBUG_ENTER("Field::quote_data"); - // this is the same call that mysql_real_escape_string() calls - escape_string_for_mysql(&my_charset_bin, (char *)escaped_string, - unquoted_string->ptr(), unquoted_string->length()); - - need_quotes= needs_quotes(); - - if (need_quotes == 0) + if (!needs_quotes()) 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 unquoted_string->length(0); - if (unquoted_string->append('\'')) - DBUG_RETURN(1); - if (unquoted_string->append((char *)escaped_string)) - DBUG_RETURN(1); - if (unquoted_string->append('\'')) + if (unquoted_string->append('\'') || + unquoted_string->append((char *)escaped_string) || + unquoted_string->append('\'')) DBUG_RETURN(1); DBUG_RETURN(0); } diff --git a/sql/item.cc b/sql/item.cc index e6be934e334..3489c54286c 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -2038,7 +2038,7 @@ const String *Item_param::query_val_str(String* str) const buf= str->c_ptr_quick(); ptr= buf; *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()); *ptr++= '\''; str->length(ptr - buf); diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 7862717bb18..1cbc52a2a5a 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -865,7 +865,7 @@ static bool insert_params_from_vars_with_log(Prepared_statement *stmt, *ptr++= '\''; ptr+= 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++= '\''; str.length(ptr - buf); |