From: Tor Didriksen Date: February 22 2012 8:57am Subject: bzr push into mysql-trunk branch (tor.didriksen:3939 to 3940) Bug#12677197 List-Archive: http://lists.mysql.com/commits/143023 X-Bug: 12677197 Message-Id: <201202220857.q1M8vu0A022682@acsmt357.oracle.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 3940 Tor Didriksen 2012-02-22 Bug#12677197 MAKE_SET() AND MY_EMPTY_STRING BUGS CAUSE CRASHING The patch for: Bug#11765225 58165: "MY_EMPTY_STRING" GETS MODIFIED AND CAUSES LOAD DATA TO FAIL AND OTHER CR removed most uses of my_empty_string. This patch removes it as a global variable, and makes it (and a few others) const, so that it cannot be modified. @ client/sql_string.cc Make String::numchars() a const member function. @ client/sql_string.h Make String::numchars() a const member function. @ mysql-test/r/func_set.result New tests. @ mysql-test/t/func_set.test New tests. @ sql/item_strfunc.cc Don't use my_empty_string, use make_empty_result() instead. @ sql/item_strfunc.h Remove the global my_empty_string. @ sql/log_event.cc Do not modify a string which might be constant. @ sql/sql_class.cc Constify a few static, default values. @ sql/sql_class.h Several of the string pointers in sql_exchange may point to const strings, so declare them 'const String *' rather than 'String *'. @ sql/sql_load.cc Constify a few string pointers/references. @ sql/sql_string.cc Make String::numchars() a const member function. @ sql/sql_string.h Make String::numchars() a const member function. modified: client/sql_string.cc client/sql_string.h mysql-test/r/func_set.result mysql-test/t/func_set.test sql/item_strfunc.cc sql/item_strfunc.h sql/log_event.cc sql/sql_class.cc sql/sql_class.h sql/sql_load.cc sql/sql_string.cc sql/sql_string.h 3939 Vasil Dimov 2012-02-21 [merge] Merge mysql-5.5 -> mysql-trunk modified: mysql-test/suite/innodb/t/innodb_bug34300.test === modified file 'client/sql_string.cc' --- a/client/sql_string.cc 2012-02-16 09:51:14 +0000 +++ b/client/sql_string.cc 2012-02-22 08:57:27 +0000 @@ -479,7 +479,7 @@ bool String::append_with_prefill(const c return FALSE; } -uint32 String::numchars() +uint32 String::numchars() const { return str_charset->cset->numchars(str_charset, Ptr, Ptr+str_length); } === modified file 'client/sql_string.h' --- a/client/sql_string.h 2011-06-30 15:50:45 +0000 +++ b/client/sql_string.h 2012-02-22 08:57:27 +0000 @@ -269,7 +269,7 @@ public: friend int sortcmp(const String *a,const String *b, const CHARSET_INFO *cs); friend int stringcmp(const String *a,const String *b); friend String *copy_if_not_alloced(String *a,String *b,uint32 arg_length); - uint32 numchars(); + uint32 numchars() const; int charpos(int i,uint32 offset=0); int reserve(uint32 space_needed) === modified file 'mysql-test/r/func_set.result' --- a/mysql-test/r/func_set.result 2012-01-10 08:24:24 +0000 +++ b/mysql-test/r/func_set.result 2012-02-22 08:57:27 +0000 @@ -211,3 +211,37 @@ COUNT(*) 2 DROP TABLE t1; # End of test BUG#12211480 +# +# Bug#12677197 MAKE_SET() AND MY_EMPTY_STRING BUGS CAUSE CRASHING +# +do +nullif( ( rtrim( make_set((cast(('%S') as unsigned)), +(point((0xaf),('')))) +) +), ('')) +; +Warnings: +Warning 1292 Truncated incorrect INTEGER value: '%S' +do +dayofmonth( ( not( trim( trailing( convert((''), binary(4))) +from( make_set( ('>>'), ('`')))) +))) +; +Warnings: +Warning 1292 Truncated incorrect INTEGER value: '>>' +Warning 1292 Incorrect datetime value: '1' +do quote(make_set((''), (cast(('-2147483649.1') as binary(513))))); +Warnings: +Warning 1292 Truncated incorrect INTEGER value: '' +do +trim( both(-8388607) +from( make_set( ( extract( minute_second from +( str_to_date((rpad(1.0,4,1)), (''))) +) +), +( char((connection_id()) using macce))) +) +) +; +Warnings: +Warning 1292 Truncated incorrect date value: '1.01' === modified file 'mysql-test/t/func_set.test' --- a/mysql-test/t/func_set.test 2012-01-10 08:24:24 +0000 +++ b/mysql-test/t/func_set.test 2012-02-22 08:57:27 +0000 @@ -131,3 +131,33 @@ SELECT COUNT(*) FROM t1 GROUP BY MAKE_SE DROP TABLE t1; --echo # End of test BUG#12211480 + +--echo # +--echo # Bug#12677197 MAKE_SET() AND MY_EMPTY_STRING BUGS CAUSE CRASHING +--echo # + +do +nullif( ( rtrim( make_set((cast(('%S') as unsigned)), + (point((0xaf),('')))) + ) + ), ('')) +; + +do +dayofmonth( ( not( trim( trailing( convert((''), binary(4))) + from( make_set( ('>>'), ('`')))) + ))) +; + +do quote(make_set((''), (cast(('-2147483649.1') as binary(513))))); + +do +trim( both(-8388607) + from( make_set( ( extract( minute_second from + ( str_to_date((rpad(1.0,4,1)), (''))) + ) + ), + ( char((connection_id()) using macce))) + ) + ) +; === modified file 'sql/item_strfunc.cc' --- a/sql/item_strfunc.cc 2012-02-17 10:30:31 +0000 +++ b/sql/item_strfunc.cc 2012-02-22 08:57:27 +0000 @@ -58,11 +58,6 @@ C_MODE_END using std::min; using std::max; -/** - @todo Remove this. It is not safe to use a shared String object. - */ -String my_empty_string("",default_charset_info); - /* For the Items which have only val_str_ascii() method and don't have their own "native" val_str(), @@ -2599,7 +2594,7 @@ String *Item_func_make_set::val_str(Stri ulonglong bits; bool first_found=0; Item **ptr=args; - String *result=&my_empty_string; + String *result= NULL; bits=item->val_int(); if ((null_value=item->null_value)) @@ -2631,17 +2626,21 @@ String *Item_func_make_set::val_str(Stri { if (result != &tmp_str) { // Copy data to tmp_str - if (tmp_str.alloc(result->length()+res->length()+1) || + if (tmp_str.alloc((result != NULL ? result->length() : 0) + + res->length() + 1) || tmp_str.copy(*result)) return make_empty_result(); result= &tmp_str; } - if (tmp_str.append(STRING_WITH_LEN(","), &my_charset_bin) || tmp_str.append(*res)) + if (tmp_str.append(STRING_WITH_LEN(","), &my_charset_bin) || + tmp_str.append(*res)) return make_empty_result(); } } } } + if (result == NULL) + return make_empty_result(); return result; } === modified file 'sql/item_strfunc.h' --- a/sql/item_strfunc.h 2012-01-10 08:24:24 +0000 +++ b/sql/item_strfunc.h 2012-02-22 08:57:27 +0000 @@ -989,6 +989,4 @@ public: String *val_str(String *); }; -extern String my_empty_string; - #endif /* ITEM_STRFUNC_INCLUDED */ === modified file 'sql/log_event.cc' --- a/sql/log_event.cc 2012-02-07 23:33:54 +0000 +++ b/sql/log_event.cc 2012-02-22 08:57:27 +0000 @@ -6113,6 +6113,7 @@ int Load_log_event::do_apply_event(NET* String line_term(sql_ex.line_term,sql_ex.line_term_len,log_cs); String line_start(sql_ex.line_start,sql_ex.line_start_len,log_cs); String escaped(sql_ex.escaped,sql_ex.escaped_len, log_cs); + const String empty_str("", 0, log_cs); ex.field_term= &field_term; ex.enclosed= &enclosed; ex.line_term= &line_term; @@ -6121,7 +6122,7 @@ int Load_log_event::do_apply_event(NET* ex.opt_enclosed = (sql_ex.opt_flags & OPT_ENCLOSED_FLAG); if (sql_ex.empty_flags & FIELD_TERM_EMPTY) - ex.field_term->length(0); + ex.field_term= &empty_str; ex.skip_lines = skip_lines; List field_list; === modified file 'sql/sql_class.cc' --- a/sql/sql_class.cc 2012-02-17 18:30:34 +0000 +++ b/sql/sql_class.cc 2012-02-22 08:57:27 +0000 @@ -2167,10 +2167,12 @@ bool select_result::check_simple_select( } -static String default_line_term("\n",default_charset_info); -static String default_escaped("\\",default_charset_info); -static String default_field_term("\t",default_charset_info); -static String default_xml_row_term("", default_charset_info); +static const String default_line_term("\n",default_charset_info); +static const String default_escaped("\\",default_charset_info); +static const String default_field_term("\t",default_charset_info); +static const String default_xml_row_term("", default_charset_info); +static const String my_empty_string("",default_charset_info); + sql_exchange::sql_exchange(char *name, bool flag, enum enum_filetype filetype_arg) === modified file 'sql/sql_class.h' --- a/sql/sql_class.h 2012-02-15 13:57:17 +0000 +++ b/sql/sql_class.h 2012-02-22 08:57:27 +0000 @@ -3878,7 +3878,7 @@ class sql_exchange :public Sql_alloc public: enum enum_filetype filetype; /* load XML, Added by Arnold & Erik */ char *file_name; - String *field_term,*enclosed,*line_term,*line_start,*escaped; + const String *field_term, *enclosed, *line_term, *line_start, *escaped; bool opt_enclosed; bool dumpfile; ulong skip_lines; === modified file 'sql/sql_load.cc' --- a/sql/sql_load.cc 2012-02-16 09:51:14 +0000 +++ b/sql/sql_load.cc 2012-02-22 08:57:27 +0000 @@ -67,7 +67,7 @@ class READ_INFO { *end_of_buff; /* Data in bufferts ends here */ uint buff_length, /* Length of buffert */ max_length; /* Max length of row */ - char *field_term_ptr,*line_term_ptr,*line_start_ptr,*line_start_end; + const char *field_term_ptr, *line_term_ptr, *line_start_ptr, *line_start_end; uint field_term_length,line_term_length,enclosed_length; int field_term_char,line_term_char,enclosed_char,escape_char; int *stack,*stack_pos; @@ -84,14 +84,17 @@ public: const CHARSET_INFO *read_charset; READ_INFO(File file,uint tot_length,const CHARSET_INFO *cs, - String &field_term,String &line_start,String &line_term, - String &enclosed,int escape,bool get_it_from_net, bool is_fifo); + const String &field_term, + const String &line_start, + const String &line_term, + const String &enclosed, + int escape,bool get_it_from_net, bool is_fifo); ~READ_INFO(); int read_field(); int read_fixed_length(void); int next_line(void); char unescape(char chr); - int terminator(char *ptr,uint length); + int terminator(const char *ptr,uint length); bool find_start_of_fields(); /* load xml */ List taglist; @@ -125,13 +128,13 @@ static int read_fixed_length(THD *thd, C static int read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, List &fields_vars, List &set_fields, List &set_values, READ_INFO &read_info, - String &enclosed, ulong skip_lines, + const String &enclosed, ulong skip_lines, bool ignore_check_option_errors); static int read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, List &fields_vars, List &set_fields, List &set_values, READ_INFO &read_info, - String &enclosed, ulong skip_lines, + ulong skip_lines, bool ignore_check_option_errors); #ifndef EMBEDDED_LIBRARY @@ -176,8 +179,9 @@ int mysql_load(THD *thd,sql_exchange *ex File file; TABLE *table= NULL; int error= 0; - String *field_term=ex->field_term,*escaped=ex->escaped; - String *enclosed=ex->enclosed; + const String *field_term= ex->field_term; + const String *escaped= ex->escaped; + const String *enclosed= ex->enclosed; bool is_fifo=0; #ifndef EMBEDDED_LIBRARY LOAD_FILE_INFO lf_info; @@ -493,7 +497,7 @@ int mysql_load(THD *thd,sql_exchange *ex if (ex->filetype == FILETYPE_XML) /* load xml */ error= read_xml_field(thd, info, table_list, fields_vars, set_fields, set_values, read_info, - *(ex->line_term), skip_lines, ignore); + skip_lines, ignore); else if (!field_term->length() && !enclosed->length()) error= read_fixed_length(thd, info, table_list, fields_vars, set_fields, set_values, read_info, @@ -922,7 +926,7 @@ static int read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, List &fields_vars, List &set_fields, List &set_values, READ_INFO &read_info, - String &enclosed, ulong skip_lines, + const String &enclosed, ulong skip_lines, bool ignore_check_option_errors) { List_iterator_fast it(fields_vars); @@ -1134,7 +1138,7 @@ static int read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, List &fields_vars, List &set_fields, List &set_values, READ_INFO &read_info, - String &row_tag, ulong skip_lines, + ulong skip_lines, bool ignore_check_option_errors) { List_iterator_fast it(fields_vars); @@ -1317,16 +1321,18 @@ READ_INFO::unescape(char chr) READ_INFO::READ_INFO(File file_par, uint tot_length, const CHARSET_INFO *cs, - String &field_term, String &line_start, String &line_term, - String &enclosed_par, int escape, bool get_it_from_net, - bool is_fifo) + const String &field_term, + const String &line_start, + const String &line_term, + const String &enclosed_par, + int escape, bool get_it_from_net, bool is_fifo) :file(file_par), buff_length(tot_length), escape_char(escape), found_end_of_line(false), eof(false), need_end_io_cache(false), error(false), line_cuted(false), found_null(false), read_charset(cs) { - field_term_ptr=(char*) field_term.ptr(); + field_term_ptr= field_term.ptr(); field_term_length= field_term.length(); - line_term_ptr=(char*) line_term.ptr(); + line_term_ptr= line_term.ptr(); line_term_length= line_term.length(); level= 0; /* for load xml */ if (line_start.length() == 0) @@ -1412,7 +1418,7 @@ READ_INFO::~READ_INFO() #define PUSH(A) *(stack_pos++)=(A) -inline int READ_INFO::terminator(char *ptr,uint length) +inline int READ_INFO::terminator(const char *ptr,uint length) { int chr=0; // Keep gcc happy uint i; @@ -1732,7 +1738,7 @@ bool READ_INFO::find_start_of_fields() return 1; } } while ((char) chr != line_start_ptr[0]); - for (char *ptr=line_start_ptr+1 ; ptr != line_start_end ; ptr++) + for (const char *ptr=line_start_ptr+1 ; ptr != line_start_end ; ptr++) { chr=GET; // Eof will be checked later if ((char) chr != *ptr) === modified file 'sql/sql_string.cc' --- a/sql/sql_string.cc 2012-02-16 09:51:14 +0000 +++ b/sql/sql_string.cc 2012-02-22 08:57:27 +0000 @@ -539,7 +539,7 @@ bool String::append_with_prefill(const c return FALSE; } -uint32 String::numchars() +uint32 String::numchars() const { return str_charset->cset->numchars(str_charset, Ptr, Ptr+str_length); } === modified file 'sql/sql_string.h' --- a/sql/sql_string.h 2011-11-01 11:52:24 +0000 +++ b/sql/sql_string.h 2012-02-22 08:57:27 +0000 @@ -320,7 +320,7 @@ public: friend int sortcmp(const String *a,const String *b, const CHARSET_INFO *cs); friend int stringcmp(const String *a,const String *b); friend String *copy_if_not_alloced(String *a,String *b,uint32 arg_length); - uint32 numchars(); + uint32 numchars() const; int charpos(int i,uint32 offset=0); int reserve(uint32 space_needed) No bundle (reason: useless for push emails).