Commit 3771d623 authored by Kristofer Pettersson's avatar Kristofer Pettersson

Bug#45613 handle failures from my_hash_insert

Not all my_hash_insert() calls are checked for return value.

This patch adds appropriate checks and failure responses
where needed.
parent e131edc9
......@@ -334,6 +334,7 @@ my_bool my_hash_insert(HASH *info, const uchar *record)
size_t idx,halfbuff,hash_nr,first_index;
uchar *UNINIT_VAR(ptr_to_rec),*UNINIT_VAR(ptr_to_rec2);
HASH_LINK *data,*empty,*UNINIT_VAR(gpos),*UNINIT_VAR(gpos2),*pos;
DBUG_EXECUTE("fail_hash_insert",return(TRUE););
if (HASH_UNIQUE & info->flags)
{
......
......@@ -5649,9 +5649,8 @@ int TC_LOG_BINLOG::recover(IO_CACHE *log, Format_description_log_event *fdle)
Xid_log_event *xev=(Xid_log_event *)ev;
uchar *x= (uchar *) memdup_root(&mem_root, (uchar*) &xev->xid,
sizeof(xev->xid));
if (! x)
if (!x || my_hash_insert(&xids, x))
goto err2;
my_hash_insert(&xids, x);
}
delete ev;
}
......
......@@ -559,7 +559,12 @@ HOSTS";
goto err;
}
si->server_id = log_server_id;
my_hash_insert(&slave_list, (uchar*)si);
if (my_hash_insert(&slave_list, (uchar*)si))
{
error= "the slave is out of memory";
pthread_mutex_unlock(&LOCK_slave_list);
goto err;
}
}
strmake(si->host, row[1], sizeof(si->host)-1);
si->port = atoi(row[port_ind]);
......
......@@ -119,7 +119,13 @@ int table_mapping::set_table(ulong table_id, TABLE* table)
}
e->table_id= table_id;
e->table= table;
my_hash_insert(&m_table_ids,(uchar *)e);
if (my_hash_insert(&m_table_ids,(uchar *)e))
{
/* we add this entry to the chain of free (free for use) entries */
e->next= m_free;
m_free= e;
DBUG_RETURN(ERR_MEMORY_ALLOCATION);
}
DBUG_PRINT("info", ("tid %lu -> table 0x%lx (%s)",
table_id, (long) e->table,
......
......@@ -1506,7 +1506,8 @@ static bool add_used_routine(LEX *lex, Query_arena *arena,
rn->key.length= key->length;
rn->key.str= (char *)rn + sizeof(Sroutine_hash_entry);
memcpy(rn->key.str, key->str, key->length + 1);
my_hash_insert(&lex->sroutines, (uchar *)rn);
if (my_hash_insert(&lex->sroutines, (uchar *)rn))
return FALSE;
lex->sroutines_list.link_in_list((uchar *)rn, (uchar **)&rn->next);
rn->belong_to_view= belong_to_view;
return TRUE;
......@@ -1584,16 +1585,24 @@ void sp_remove_not_own_routines(LEX *lex)
dependant on time of life of elements from source hash. It also
won't touch lists linking elements in source and destination
hashes.
@returns
@return TRUE Failure
@return FALSE Success
*/
void sp_update_sp_used_routines(HASH *dst, HASH *src)
bool sp_update_sp_used_routines(HASH *dst, HASH *src)
{
for (uint i=0 ; i < src->records ; i++)
{
Sroutine_hash_entry *rt= (Sroutine_hash_entry *)hash_element(src, i);
if (!hash_search(dst, (uchar *)rt->key.str, rt->key.length))
my_hash_insert(dst, (uchar *)rt);
{
if (my_hash_insert(dst, (uchar *)rt))
return TRUE;
}
}
return FALSE;
}
......
......@@ -69,7 +69,7 @@ void sp_get_prelocking_info(THD *thd, bool *need_prelocking,
void sp_add_used_routine(LEX *lex, Query_arena *arena,
sp_name *rt, char rt_type);
void sp_remove_not_own_routines(LEX *lex);
void sp_update_sp_used_routines(HASH *dst, HASH *src);
bool sp_update_sp_used_routines(HASH *dst, HASH *src);
int sp_cache_routines_and_add_tables(THD *thd, LEX *lex,
bool first_no_prelock);
int sp_cache_routines_and_add_tables_for_view(THD *thd, LEX *lex,
......
......@@ -36,10 +36,16 @@ public:
sp_cache();
~sp_cache();
inline void insert(sp_head *sp)
/**
Inserts a sp_head object into a hash table.
@returns Success status
@return TRUE Failure
@return FALSE Success
*/
inline bool insert(sp_head *sp)
{
/* TODO: why don't we check return value? */
my_hash_insert(&m_hashtable, (const uchar *)sp);
return my_hash_insert(&m_hashtable, (const uchar *)sp);
}
inline sp_head *lookup(char *name, uint namelen)
......
......@@ -2087,8 +2087,18 @@ sp_head::reset_lex(THD *thd)
DBUG_RETURN(FALSE);
}
/// Restore lex during parsing, after we have parsed a sub statement.
void
/**
Restore lex during parsing, after we have parsed a sub statement.
@param thd Thread handle
@return
@retval TRUE failure
@retval FALSE success
*/
bool
sp_head::restore_lex(THD *thd)
{
DBUG_ENTER("sp_head::restore_lex");
......@@ -2099,7 +2109,7 @@ sp_head::restore_lex(THD *thd)
oldlex= (LEX *)m_lex.pop();
if (! oldlex)
return; // Nothing to restore
DBUG_RETURN(FALSE); // Nothing to restore
oldlex->trg_table_fields.push_back(&sublex->trg_table_fields);
......@@ -2115,7 +2125,8 @@ sp_head::restore_lex(THD *thd)
Add routines which are used by statement to respective set for
this routine.
*/
sp_update_sp_used_routines(&m_sroutines, &sublex->sroutines);
if (sp_update_sp_used_routines(&m_sroutines, &sublex->sroutines))
DBUG_RETURN(TRUE);
/*
Merge tables used by this statement (but not by its functions or
procedures) to multiset of tables used by this routine.
......@@ -2127,7 +2138,7 @@ sp_head::restore_lex(THD *thd)
delete sublex;
}
thd->lex= oldlex;
DBUG_VOID_RETURN;
DBUG_RETURN(FALSE);
}
/**
......@@ -3865,7 +3876,8 @@ sp_head::merge_table_list(THD *thd, TABLE_LIST *table, LEX *lex_for_tmp_check)
tab->lock_type= table->lock_type;
tab->lock_count= tab->query_lock_count= 1;
tab->trg_event_map= table->trg_event_map;
my_hash_insert(&m_sptabs, (uchar *)tab);
if (my_hash_insert(&m_sptabs, (uchar *)tab))
return FALSE;
}
}
return TRUE;
......
......@@ -340,7 +340,7 @@ public:
@todo Conflicting comment in sp_head.cc
*/
void
bool
restore_lex(THD *thd);
/// Put the instruction on the backpatch list, associated with the label.
......
......@@ -2400,7 +2400,12 @@ GRANT_TABLE::GRANT_TABLE(TABLE *form, TABLE *col_privs)
privs = cols = 0; /* purecov: deadcode */
return; /* purecov: deadcode */
}
my_hash_insert(&hash_columns, (uchar *) mem_check);
if (my_hash_insert(&hash_columns, (uchar *) mem_check))
{
/* Invalidate this entry */
privs= cols= 0;
return;
}
} while (!col_privs->file->index_next(col_privs->record[0]) &&
!key_cmp_if_same(col_privs,key,0,key_prefix_len));
col_privs->file->ha_index_end();
......@@ -2605,7 +2610,11 @@ static int replace_column_table(GRANT_TABLE *g_t,
goto end; /* purecov: inspected */
}
grant_column= new GRANT_COLUMN(column->column,privileges);
my_hash_insert(&g_t->hash_columns,(uchar*) grant_column);
if (my_hash_insert(&g_t->hash_columns,(uchar*) grant_column))
{
result= -1;
goto end;
}
}
}
......@@ -3130,12 +3139,12 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
Str->user.str, table_name,
rights,
column_priv);
if (!grant_table) // end of memory
if (!grant_table ||
my_hash_insert(&column_priv_hash,(uchar*) grant_table))
{
result= TRUE; /* purecov: deadcode */
continue; /* purecov: deadcode */
}
my_hash_insert(&column_priv_hash,(uchar*) grant_table);
}
/* If revoke_grant, calculate the new column privilege for tables_priv */
......@@ -3339,12 +3348,13 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
grant_name= new GRANT_NAME(Str->host.str, db_name,
Str->user.str, table_name,
rights);
if (!grant_name)
if (!grant_name ||
my_hash_insert(is_proc ?
&proc_priv_hash : &func_priv_hash,(uchar*) grant_name))
{
result= TRUE;
continue;
}
my_hash_insert(is_proc ? &proc_priv_hash : &func_priv_hash,(uchar*) grant_name);
}
if (replace_routine_table(thd, grant_name, tables[1].table, *Str,
......
......@@ -2933,7 +2933,12 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
DBUG_PRINT("info", ("inserting table '%s'.'%s' 0x%lx into the cache",
table->s->db.str, table->s->table_name.str,
(long) table));
VOID(my_hash_insert(&open_cache,(uchar*) table));
if (my_hash_insert(&open_cache,(uchar*) table))
{
my_free(table, MYF(0));
VOID(pthread_mutex_unlock(&LOCK_open));
DBUG_RETURN(NULL);
}
}
check_unused(); // Debugging call
......
......@@ -13862,7 +13862,10 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table,
goto err;
}
else
(void) my_hash_insert(&hash, org_key_pos);
{
if (my_hash_insert(&hash, org_key_pos))
goto err;
}
key_pos+=extra_length;
}
my_free((char*) key_buffer,MYF(0));
......
......@@ -2330,8 +2330,8 @@ sp_decl:
}
pctx->declare_var_boundary(0);
lex->sphead->restore_lex(YYTHD);
if (lex->sphead->restore_lex(YYTHD))
MYSQL_YYABORT;
$$.vars= $2;
$$.conds= $$.hndlrs= $$.curs= 0;
}
......@@ -2441,7 +2441,8 @@ sp_cursor_stmt:
}
lex->sp_lex_in_use= TRUE;
$$= lex;
lex->sphead->restore_lex(YYTHD);
if (lex->sphead->restore_lex(YYTHD))
MYSQL_YYABORT;
}
;
......@@ -2660,7 +2661,8 @@ sp_proc_stmt_statement:
sp->add_instr(i))
MYSQL_YYABORT;
}
sp->restore_lex(thd);
if (sp->restore_lex(thd))
MYSQL_YYABORT;
}
;
......@@ -2688,7 +2690,8 @@ sp_proc_stmt_return:
MYSQL_YYABORT;
sp->m_flags|= sp_head::HAS_RETURN;
}
sp->restore_lex(YYTHD);
if (sp->restore_lex(YYTHD))
MYSQL_YYABORT;
}
;
......@@ -2928,7 +2931,8 @@ sp_if:
sp->add_cont_backpatch(i) ||
sp->add_instr(i))
MYSQL_YYABORT;
sp->restore_lex(YYTHD);
if (sp->restore_lex(YYTHD))
MYSQL_YYABORT;
}
sp_proc_stmts1
{
......@@ -2974,7 +2978,9 @@ simple_case_stmt:
if (case_stmt_action_expr(lex, $3))
MYSQL_YYABORT;
lex->sphead->restore_lex(YYTHD); /* For expr $3 */
/* For expr $3 */
if (lex->sphead->restore_lex(YYTHD))
MYSQL_YYABORT;
}
simple_when_clause_list
else_clause_opt
......@@ -3024,7 +3030,9 @@ simple_when_clause:
LEX *lex= Lex;
if (case_stmt_action_when(lex, $3, true))
MYSQL_YYABORT;
lex->sphead->restore_lex(YYTHD); /* For expr $3 */
/* For expr $3 */
if (lex->sphead->restore_lex(YYTHD))
MYSQL_YYABORT;
}
THEN_SYM
sp_proc_stmts1
......@@ -3045,7 +3053,9 @@ searched_when_clause:
LEX *lex= Lex;
if (case_stmt_action_when(lex, $3, false))
MYSQL_YYABORT;
lex->sphead->restore_lex(YYTHD); /* For expr $3 */
/* For expr $3 */
if (lex->sphead->restore_lex(YYTHD))
MYSQL_YYABORT;
}
THEN_SYM
sp_proc_stmts1
......@@ -3222,7 +3232,8 @@ sp_unlabeled_control:
sp->new_cont_backpatch(i) ||
sp->add_instr(i))
MYSQL_YYABORT;
sp->restore_lex(YYTHD);
if (sp->restore_lex(YYTHD))
MYSQL_YYABORT;
}
sp_proc_stmts1 END WHILE_SYM
{
......@@ -3248,7 +3259,8 @@ sp_unlabeled_control:
if (i == NULL ||
lex->sphead->add_instr(i))
MYSQL_YYABORT;
lex->sphead->restore_lex(YYTHD);
if (lex->sphead->restore_lex(YYTHD))
MYSQL_YYABORT;
/* We can shortcut the cont_backpatch here */
i->m_cont_dest= ip+1;
}
......@@ -11770,7 +11782,8 @@ option_type_value:
if (sp->add_instr(i))
MYSQL_YYABORT;
}
lex->sphead->restore_lex(thd);
if (lex->sphead->restore_lex(thd))
MYSQL_YYABORT;
}
}
;
......
......@@ -1315,8 +1315,16 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
share->timestamp_field_offset= i;
if (use_hash)
(void) my_hash_insert(&share->name_hash,
(uchar*) field_ptr); // never fail
if (my_hash_insert(&share->name_hash, (uchar*) field_ptr) )
{
/*
Set return code 8 here to indicate that an error has
occurred but that the error message already has been
sent (OOM).
*/
error= 8;
goto err;
}
}
*field_ptr=0; // End marker
......
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