diff options
author | unknown <pem@mysql.com> | 2005-11-25 17:09:26 +0100 |
---|---|---|
committer | unknown <pem@mysql.com> | 2005-11-25 17:09:26 +0100 |
commit | d4088df5e9a02e714d85f79bec3ea97cdd8128c6 (patch) | |
tree | 025445f5fd80e1c80878febcdebb45817594e311 | |
parent | df22630555ccf3b4cb6fc6254e846b87697b53c7 (diff) | |
download | mariadb-git-d4088df5e9a02e714d85f79bec3ea97cdd8128c6.tar.gz |
Fixed BUG#14233: Crash after tampering with the mysql.proc table
Post-review version. Some minor review fixes, but also changed the way
some errors are handled: Don't return specific parse errors; instead
always use the more general "table corrupt" error (amended accordingly).
mysql-test/r/sp-destruct.result:
Updated results.
mysql-test/r/sp-error.result:
Updated for fully qualified name in "no return" error message.
mysql-test/t/sp-destruct.test:
Adopted the more consistent error handling for a corrupted mysql.proc table.
(No more "parse error" et al).
sql/share/errmsg.txt:
Changed ER_SP_PROC_TABLE_CORRUPT to be more explicit.
sql/sp.cc:
Review fixes.
Changed the handling of parse errors, and added the routine name to the "table corrupt" error message.
sql/sql_base.cc:
Review changes: Change error tests and added comments.
sql/sql_parse.cc:
Mored ER_SP_NORETURN test of functions to sql_yacc.yy for more general error handling.
sql/sql_yacc.yy:
Mored ER_SP_NORETURN test of functions from sql_parse.cc for more general error handling.
-rw-r--r-- | mysql-test/r/sp-destruct.result | 20 | ||||
-rw-r--r-- | mysql-test/r/sp-error.result | 2 | ||||
-rw-r--r-- | mysql-test/t/sp-destruct.test | 14 | ||||
-rw-r--r-- | sql/share/errmsg.txt | 2 | ||||
-rw-r--r-- | sql/sp.cc | 45 | ||||
-rw-r--r-- | sql/sql_base.cc | 27 | ||||
-rw-r--r-- | sql/sql_parse.cc | 8 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 5 |
8 files changed, 71 insertions, 52 deletions
diff --git a/mysql-test/r/sp-destruct.result b/mysql-test/r/sp-destruct.result index 65d72d2098b..1b720be9403 100644 --- a/mysql-test/r/sp-destruct.result +++ b/mysql-test/r/sp-destruct.result @@ -11,11 +11,11 @@ create table t1 (id int); create trigger t1_ai after insert on t1 for each row call bug14233(); alter table mysql.proc drop type; call bug14233(); -ERROR HY000: The table mysql.proc is missing, corrupt, or contains bad data (internal code -5) +ERROR HY000: Failed to load routine test.bug14233. The table mysql.proc is missing, corrupt, or contains bad data (internal code -5) create view v1 as select bug14233_f(); -ERROR HY000: The table mysql.proc is missing, corrupt, or contains bad data (internal code -5) +ERROR HY000: Failed to load routine test.bug14233_f. The table mysql.proc is missing, corrupt, or contains bad data (internal code -5) insert into t1 values (0); -ERROR HY000: The table mysql.proc is missing, corrupt, or contains bad data (internal code -5) +ERROR HY000: Failed to load routine test.bug14233. The table mysql.proc is missing, corrupt, or contains bad data (internal code -5) flush table mysql.proc; call bug14233(); ERROR HY000: Incorrect information in file: './mysql/proc.frm' @@ -59,21 +59,19 @@ values 'root@localhost', NOW() , '0000-00-00 00:00:00', '', '' ); select bug14233_1(); -ERROR 0A000: Not allowed to return a result set from a function +ERROR HY000: Failed to load routine test.bug14233_1. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6) create view v1 as select bug14233_1(); -ERROR 0A000: Not allowed to return a result set from a function +ERROR HY000: Failed to load routine test.bug14233_1. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6) select bug14233_2(); -ERROR 2F005: FUNCTION bug14233_2 ended without RETURN +ERROR HY000: Failed to load routine test.bug14233_2. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6) create view v1 as select bug14233_2(); -select * from v1; -ERROR 2F005: FUNCTION bug14233_2 ended without RETURN +ERROR HY000: Failed to load routine test.bug14233_2. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6) call bug14233_3(); -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'wpsj sa ^#!@ ' at line 3 +ERROR HY000: Failed to load routine test.bug14233_3. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6) drop trigger t1_ai; create trigger t1_ai after insert on t1 for each row call bug14233_3(); insert into t1 values (0); -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'wpsj sa ^#!@ ' at line 3 +ERROR HY000: Failed to load routine test.bug14233_3. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6) delete from mysql.proc where name like 'bug14233%'; drop trigger t1_ai; drop table t1; -drop view v1; diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index 50ff7ea264a..cea0b66418e 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -124,7 +124,7 @@ begin declare x int; set x = val+3; end| -ERROR 42000: No RETURN found in FUNCTION f +ERROR 42000: No RETURN found in FUNCTION test.f create function f(val int) returns int begin declare x int; diff --git a/mysql-test/t/sp-destruct.test b/mysql-test/t/sp-destruct.test index 7b13d273bd1..a2a66090866 100644 --- a/mysql-test/t/sp-destruct.test +++ b/mysql-test/t/sp-destruct.test @@ -101,26 +101,24 @@ values 'root@localhost', NOW() , '0000-00-00 00:00:00', '', '' ); ---error ER_SP_NO_RETSET +--error ER_SP_PROC_TABLE_CORRUPT select bug14233_1(); ---error ER_SP_NO_RETSET +--error ER_SP_PROC_TABLE_CORRUPT create view v1 as select bug14233_1(); ---error ER_SP_NORETURNEND +--error ER_SP_PROC_TABLE_CORRUPT select bug14233_2(); +--error ER_SP_PROC_TABLE_CORRUPT create view v1 as select bug14233_2(); ---error ER_SP_NORETURNEND -select * from v1; ---error ER_PARSE_ERROR +--error ER_SP_PROC_TABLE_CORRUPT call bug14233_3(); drop trigger t1_ai; create trigger t1_ai after insert on t1 for each row call bug14233_3(); ---error ER_PARSE_ERROR +--error ER_SP_PROC_TABLE_CORRUPT insert into t1 values (0); # Clean-up delete from mysql.proc where name like 'bug14233%'; drop trigger t1_ai; drop table t1; -drop view v1; diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index 2e2403a21a1..eab46e308b8 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -5422,4 +5422,4 @@ ER_NO_REFERENCED_ROW_2 23000 ER_SP_BAD_VAR_SHADOW 42000 eng "Variable '%-.64s' must be quoted with `...`, or renamed" ER_SP_PROC_TABLE_CORRUPT - eng "The table mysql.proc is missing, corrupt, or contains bad data (internal code %d)" + eng "Failed to load routine %s. The table mysql.proc is missing, corrupt, or contains bad data (internal code %d)" diff --git a/sql/sp.cc b/sql/sp.cc index 6f08897b1af..49671a47bad 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -1420,8 +1420,8 @@ static void sp_update_stmt_used_routines(THD *thd, LEX *lex, SQL_LIST *src) Instead this fact will be discovered during query execution. RETURN VALUE - 0 - success - -x - failure (error code, like SP_PARSE_ERROR et al) + 0 - success + non-0 - failure */ static int @@ -1430,7 +1430,7 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex, bool first_no_prelock, bool *tabs_changed) { int ret= 0; - bool result= FALSE; + int tabschnd= 0; /* Set if tables changed */ bool first= TRUE; DBUG_ENTER("sp_cache_routines_and_add_tables_aux"); @@ -1478,11 +1478,21 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex, /* Fall through */ default: /* - In some cases no error has been set (e.g. get field failed, - when the proc table has been tampered with). - */ - if (! thd->net.report_error) - my_error(ER_SP_PROC_TABLE_CORRUPT, MYF(0), ret); + Any error when loading an existing routine is either some problem + with the mysql.proc table, or a parse error because the contents + has been tampered with (in which case we clear that error). + */ + if (ret == SP_PARSE_ERROR) + thd->clear_error(); + if (!thd->net.report_error) + { + char n[NAME_LEN*2+2]; + + /* m_qname.str is not always \0 terminated */ + memcpy(n, name.m_qname.str, name.m_qname.length); + n[name.m_qname.length]= '\0'; + my_error(ER_SP_PROC_TABLE_CORRUPT, MYF(0), n, ret); + } break; } delete newlex; @@ -1493,13 +1503,14 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex, if (!(first && first_no_prelock)) { sp_update_stmt_used_routines(thd, lex, &sp->m_sroutines); - result|= sp->add_used_tables_to_table_list(thd, &lex->query_tables_last); + tabschnd|= + sp->add_used_tables_to_table_list(thd, &lex->query_tables_last); } } first= FALSE; } - if (tabs_changed) - *tabs_changed= result; + if (tabs_changed) /* it can be NULL */ + *tabs_changed= tabschnd; DBUG_RETURN(ret); } @@ -1518,8 +1529,8 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex, tabs_changed - Set to TRUE some tables were added, FALSE otherwise RETURN VALUE - 0 - success - -x - failure (error code, like SP_PARSE_ERROR et al) + 0 - success + non-0 - failure */ int @@ -1544,8 +1555,8 @@ sp_cache_routines_and_add_tables(THD *thd, LEX *lex, bool first_no_prelock, aux_lex - LEX representing view RETURN VALUE - 0 - success - -x - failure (error code, like SP_PARSE_ERROR et al) + 0 - success + non-0 - failure */ int @@ -1572,8 +1583,8 @@ sp_cache_routines_and_add_tables_for_view(THD *thd, LEX *lex, LEX *aux_lex) triggers - triggers of the table RETURN VALUE - 0 - success - -x - failure (error code, like SP_PARSE_ERROR et al) + 0 - success + non-0 - failure */ int diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 273d9f7e3b4..fa3321bcb0e 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1986,9 +1986,14 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags) if (sp_cache_routines_and_add_tables(thd, thd->lex, first_no_prelocking, - &tabs_changed) < 0) + &tabs_changed)) { - result= -1; // Fatal error + /* + Serious error during reading stored routines from mysql.proc table. + Something's wrong with the table or its contents, and an error has + been emitted; we must abort. + */ + result= -1; goto err; } else if ((tabs_changed || *start) && need_prelocking) @@ -2117,9 +2122,14 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags) if (!query_tables_last_own) query_tables_last_own= thd->lex->query_tables_last; if (sp_cache_routines_and_add_tables_for_triggers(thd, thd->lex, - tables->table->triggers) < 0) + tables->table->triggers)) { - result= -1; // Fatal error + /* + Serious error during reading stored routines from mysql.proc table. + Something's wrong with the table or its contents, and an error has + been emitted; we must abort. + */ + result= -1; goto err; } } @@ -2143,9 +2153,14 @@ process_view_routines: if (!query_tables_last_own) query_tables_last_own= thd->lex->query_tables_last; if (sp_cache_routines_and_add_tables_for_view(thd, thd->lex, - tables->view) < 0) + tables->view)) { - result= -1; // Fatal error + /* + Serious error during reading stored routines from mysql.proc table. + Something's wrong with the table or its contents, and an error has + been emitted; we must abort. + */ + result= -1; goto err; } } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 1882965fd1e..ce157eeb46f 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4111,14 +4111,6 @@ end_with_restore_list: } } #endif - if (lex->sphead->m_type == TYPE_ENUM_FUNCTION && - !(lex->sphead->m_flags & sp_head::HAS_RETURN)) - { - my_error(ER_SP_NORETURN, MYF(0), name); - delete lex->sphead; - lex->sphead= 0; - goto error; - } /* We need to copy name and db in order to use them for diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 109dcd7e86a..841d4c90a70 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1475,6 +1475,11 @@ create_function_tail: YYABORT; lex->sql_command= SQLCOM_CREATE_SPFUNCTION; sp->init_strings(YYTHD, lex, lex->spname); + if (!(sp->m_flags & sp_head::HAS_RETURN)) + { + my_error(ER_SP_NORETURN, MYF(0), sp->m_qname.str); + YYABORT; + } /* Restore flag if it was cleared above */ if (sp->m_old_cmq) YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES; |