From cd9c0892d93af280065fae302b098ece1908d02e Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Fri, 21 May 2010 15:23:48 +0400 Subject: Bug #42064: low memory crash when importing hex strings, in Item_hex_string::Item_hex_string The status of memory allocation in the Lex_input_stream (called from the Parser_state constructor) was not checked which led to a parser crash in case of the out-of-memory error. The solution is to introduce new init() member function in Parser_state and Lex_input_stream so that status of memory allocation can be returned to the caller. mysql-test/r/error_simulation.result: Added a test case for bug #42064. mysql-test/t/error_simulation.test: Added a test case for bug #42064. mysys/my_alloc.c: Added error injection code for the regression test. mysys/my_malloc.c: Added error injection code for the regression test. mysys/safemalloc.c: Added error injection code for the regression test. sql/event_data_objects.cc: Use the new init() member function of Parser_state and check its return value to handle memory allocation failures. sql/mysqld.cc: Added error injection code for the regression test. sql/sp.cc: Use the new init() member function of Parser_state and check its return value to handle memory allocation failures. sql/sql_lex.cc: Moved memory allocation from constructor to the separate init() member function. Added error injection code for the regression test. sql/sql_lex.h: Moved memory allocation from constructor to the separate init() member function. sql/sql_parse.cc: Use the new init() member function of Parser_state and check its return value to handle memory allocation failures. sql/sql_partition.cc: Use the new init() member function of Parser_state and check its return value to handle memory allocation failures. sql/sql_prepare.cc: Use the new init() member function of Parser_state and check its return value to handle memory allocation failures. sql/sql_trigger.cc: Use the new init() member function of Parser_state and check its return value to handle memory allocation failures. sql/sql_view.cc: Use the new init() member function of Parser_state and check its return value to handle memory allocation failures.. sql/thr_malloc.cc: Added error injection code for the regression test. --- sql/sql_lex.cc | 50 +++++++++++++++++++++----------------------------- 1 file changed, 21 insertions(+), 29 deletions(-) (limited to 'sql/sql_lex.cc') diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index a3776f59241..35a5e2aeefc 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -110,39 +110,31 @@ st_parsing_options::reset() allows_derived= TRUE; } -Lex_input_stream::Lex_input_stream(THD *thd, - const char* buffer, - unsigned int length) -: m_thd(thd), - yylineno(1), - yytoklen(0), - yylval(NULL), - m_ptr(buffer), - m_tok_start(NULL), - m_tok_end(NULL), - m_end_of_query(buffer + length), - m_tok_start_prev(NULL), - m_buf(buffer), - m_buf_length(length), - m_echo(TRUE), - m_cpp_tok_start(NULL), - m_cpp_tok_start_prev(NULL), - m_cpp_tok_end(NULL), - m_body_utf8(NULL), - m_cpp_utf8_processed_ptr(NULL), - next_state(MY_LEX_START), - found_semicolon(NULL), - ignore_space(test(thd->variables.sql_mode & MODE_IGNORE_SPACE)), - stmt_prepare_mode(FALSE), - in_comment(NO_COMMENT), - m_underscore_cs(NULL) + +bool Lex_input_stream::init(THD *thd, const char *buff, unsigned int length) { + DBUG_EXECUTE_IF("bug42064_simulate_oom", + DBUG_SET("+d,simulate_out_of_memory");); + m_cpp_buf= (char*) thd->alloc(length + 1); + + DBUG_EXECUTE_IF("bug42064_simulate_oom", + DBUG_SET("-d,bug42064_simulate_oom");); + + if (m_cpp_buf == NULL) + return FALSE; + m_cpp_ptr= m_cpp_buf; -} + m_thd= thd; + m_ptr= buff; + m_end_of_query= buff + length; + m_buf= buff; + m_buf_length= length; + ignore_space= test(thd->variables.sql_mode & MODE_IGNORE_SPACE); + + return FALSE; + } -Lex_input_stream::~Lex_input_stream() -{} /** The operation is called from the parser in order to -- cgit v1.2.1 From fd4b3c6c1c7ee47af58e9abd84818809053b7c86 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Thu, 10 Jun 2010 17:45:22 -0300 Subject: Bug#42733: Type-punning warnings when compiling MySQL -- strict aliasing violations. One somewhat major source of strict-aliasing violations and related warnings is the SQL_LIST structure. For example, consider its member function `link_in_list` which takes a pointer to pointer of type T (any type) as a pointer to pointer to unsigned char. Dereferencing this pointer, which is done to reset the next field, violates strict-aliasing rules and might cause problems for surrounding code that uses the next field of the object being added to the list. The solution is to use templates to parametrize the SQL_LIST structure in order to deference the pointers with compatible types. As a side bonus, it becomes possible to remove quite a few casts related to acessing data members of SQL_LIST. sql/handler.h: Use the appropriate template type argument. sql/item.cc: Remove now-unnecessary cast. sql/item_subselect.cc: Remove now-unnecessary casts. sql/item_sum.cc: Use the appropriate template type argument. Remove now-unnecessary cast. sql/mysql_priv.h: Move SQL_LIST structure to sql_list.h Use the appropriate template type argument. sql/sp.cc: Remove now-unnecessary casts. sql/sql_delete.cc: Use the appropriate template type argument. Remove now-unnecessary casts. sql/sql_derived.cc: Remove now-unnecessary casts. sql/sql_lex.cc: Remove now-unnecessary casts. sql/sql_lex.h: SQL_LIST now takes a template type argument which must match the type of the elements of the list. Use forward declaration when the type is not available, it is used in pointers anyway. sql/sql_list.h: Rename SQL_LIST to SQL_I_List. The template parameter is the type of object that is stored in the list. sql/sql_olap.cc: Remove now-unnecessary casts. sql/sql_parse.cc: Remove now-unnecessary casts. sql/sql_prepare.cc: Remove now-unnecessary casts. sql/sql_select.cc: Remove now-unnecessary casts. sql/sql_show.cc: Remove now-unnecessary casts. sql/sql_table.cc: Remove now-unnecessary casts. sql/sql_trigger.cc: Remove now-unnecessary casts. sql/sql_union.cc: Remove now-unnecessary casts. sql/sql_update.cc: Remove now-unnecessary casts. sql/sql_view.cc: Remove now-unnecessary casts. sql/sql_yacc.yy: Remove now-unnecessary casts. storage/myisammrg/ha_myisammrg.cc: Remove now-unnecessary casts. --- sql/sql_lex.cc | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'sql/sql_lex.cc') diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index a3776f59241..7eb2607147c 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1641,7 +1641,7 @@ void st_select_lex::init_select() linkage= UNSPECIFIED_TYPE; order_list.elements= 0; order_list.first= 0; - order_list.next= (uchar**) &order_list.first; + order_list.next= &order_list.first; /* Set limit and offset to default values */ select_limit= 0; /* denotes the default limit = HA_POS_ERROR */ offset_limit= 0; /* denotes the default offset = 0 */ @@ -1963,7 +1963,7 @@ uint st_select_lex::get_in_sum_expr() TABLE_LIST* st_select_lex::get_table_list() { - return (TABLE_LIST*) table_list.first; + return table_list.first; } List* st_select_lex::get_item_list() @@ -2020,9 +2020,8 @@ void st_select_lex_unit::print(String *str, enum_query_type query_type) if (fake_select_lex->order_list.elements) { str->append(STRING_WITH_LEN(" order by ")); - fake_select_lex->print_order( - str, - (ORDER *) fake_select_lex->order_list.first, + fake_select_lex->print_order(str, + fake_select_lex->order_list.first, query_type); } fake_select_lex->print_limit(thd, str, query_type); @@ -2667,7 +2666,7 @@ TABLE_LIST *st_lex::unlink_first_table(bool *link_to_local) { select_lex.context.table_list= select_lex.context.first_name_resolution_table= first->next_local; - select_lex.table_list.first= (uchar*) (first->next_local); + select_lex.table_list.first= first->next_local; select_lex.table_list.elements--; //safety first->next_local= 0; /* @@ -2699,7 +2698,7 @@ TABLE_LIST *st_lex::unlink_first_table(bool *link_to_local) void st_lex::first_lists_tables_same() { - TABLE_LIST *first_table= (TABLE_LIST*) select_lex.table_list.first; + TABLE_LIST *first_table= select_lex.table_list.first; if (query_tables != first_table && first_table != 0) { TABLE_LIST *next; @@ -2746,9 +2745,9 @@ void st_lex::link_first_table_back(TABLE_LIST *first, if (link_to_local) { - first->next_local= (TABLE_LIST*) select_lex.table_list.first; + first->next_local= select_lex.table_list.first; select_lex.context.table_list= first; - select_lex.table_list.first= (uchar*) first; + select_lex.table_list.first= first; select_lex.table_list.elements++; //safety } } @@ -2914,7 +2913,7 @@ void st_select_lex::fix_prepare_information(THD *thd, Item **conds, prep_having= *having_conds; *having_conds= having= prep_having->copy_andor_structure(thd); } - fix_prepare_info_in_table_list(thd, (TABLE_LIST *)table_list.first); + fix_prepare_info_in_table_list(thd, table_list.first); } } -- cgit v1.2.1