mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Bug#25126: Wrongly resolved field leads to a crash.
When the ORDER BY clause gets fixed it's allowed to search in the current item_list in order to find aliased fields and expressions. This is ok for a SELECT but wrong for an UPDATE statement. If the ORDER BY clause will contain a non-existing field which is mentioned in the UPDATE set list then the server will crash due to using of non-existing (0x0) field. When an Item_field is getting fixed it's allowed to search item list for aliased expressions and fields only for selects.
This commit is contained in:
@ -377,3 +377,7 @@ create table t1(f1 int, `*f2` int);
|
||||
insert into t1 values (1,1);
|
||||
update t1 set `*f2`=1;
|
||||
drop table t1;
|
||||
create table t1(f1 int);
|
||||
update t1 set f2=1 order by f2;
|
||||
ERROR 42S22: Unknown column 'f2' in 'order clause'
|
||||
drop table t1;
|
||||
|
@ -306,4 +306,12 @@ create table t1(f1 int, `*f2` int);
|
||||
insert into t1 values (1,1);
|
||||
update t1 set `*f2`=1;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug#25126: Wrongly resolved field leads to a crash
|
||||
#
|
||||
create table t1(f1 int);
|
||||
--error 1054
|
||||
update t1 set f2=1 order by f2;
|
||||
drop table t1;
|
||||
# End of 4.1 tests
|
||||
|
@ -2518,11 +2518,14 @@ int setup_fields(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
|
||||
{
|
||||
reg2 Item *item;
|
||||
List_iterator<Item> it(fields);
|
||||
bool save_is_item_list_lookup;
|
||||
DBUG_ENTER("setup_fields");
|
||||
|
||||
thd->set_query_id=set_query_id;
|
||||
thd->allow_sum_func= allow_sum_func;
|
||||
thd->where="field list";
|
||||
save_is_item_list_lookup= thd->lex->current_select->is_item_list_lookup;
|
||||
thd->lex->current_select->is_item_list_lookup= 0;
|
||||
|
||||
/*
|
||||
To prevent fail on forward lookup we fill it with zerows,
|
||||
@ -2543,7 +2546,10 @@ int setup_fields(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
|
||||
{
|
||||
if (!item->fixed && item->fix_fields(thd, tables, it.ref()) ||
|
||||
(item= *(it.ref()))->check_cols(1))
|
||||
{
|
||||
thd->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
|
||||
DBUG_RETURN(-1); /* purecov: inspected */
|
||||
}
|
||||
if (ref)
|
||||
*(ref++)= item;
|
||||
if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM &&
|
||||
@ -2551,6 +2557,7 @@ int setup_fields(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
|
||||
item->split_sum_func(thd, ref_pointer_array, *sum_func_list);
|
||||
thd->used_tables|=item->used_tables();
|
||||
}
|
||||
thd->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
|
||||
DBUG_RETURN(test(thd->net.report_error));
|
||||
}
|
||||
|
||||
@ -2747,6 +2754,8 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
|
||||
{
|
||||
table_map not_null_tables= 0;
|
||||
Item_arena *arena= 0, backup;
|
||||
bool save_is_item_list_lookup= thd->lex->current_select->is_item_list_lookup;
|
||||
thd->lex->current_select->is_item_list_lookup= 0;
|
||||
DBUG_ENTER("setup_conds");
|
||||
|
||||
thd->set_query_id=1;
|
||||
@ -2756,7 +2765,10 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
|
||||
thd->where="where clause";
|
||||
if (!(*conds)->fixed && (*conds)->fix_fields(thd, tables, conds) ||
|
||||
(*conds)->check_cols(1))
|
||||
{
|
||||
thd->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
not_null_tables= (*conds)->not_null_tables();
|
||||
}
|
||||
|
||||
@ -2772,7 +2784,10 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
|
||||
if (!table->on_expr->fixed &&
|
||||
table->on_expr->fix_fields(thd, tables, &table->on_expr) ||
|
||||
table->on_expr->check_cols(1))
|
||||
{
|
||||
thd->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
thd->lex->current_select->cond_count++;
|
||||
|
||||
/*
|
||||
@ -2794,9 +2809,13 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
|
||||
}
|
||||
if ((*conds) && !(*conds)->fixed &&
|
||||
(*conds)->fix_fields(thd, tables, conds))
|
||||
{
|
||||
thd->lex->current_select->is_item_list_lookup=
|
||||
save_is_item_list_lookup;
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (table->natural_join)
|
||||
{
|
||||
arena= thd->change_arena_if_needed(&backup);
|
||||
@ -2846,9 +2865,13 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
|
||||
{
|
||||
if (!(*conds)->fixed &&
|
||||
(*conds)->fix_fields(thd, tables, conds))
|
||||
{
|
||||
thd->lex->current_select->is_item_list_lookup=
|
||||
save_is_item_list_lookup;
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
table->on_expr= and_conds(table->on_expr, cond_and);
|
||||
@ -2859,10 +2882,14 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
|
||||
{
|
||||
if (!table->on_expr->fixed &&
|
||||
table->on_expr->fix_fields(thd, tables, &table->on_expr))
|
||||
{
|
||||
thd->lex->current_select->is_item_list_lookup=
|
||||
save_is_item_list_lookup;
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (arena)
|
||||
{
|
||||
thd->restore_backup_item_arena(arena, &backup);
|
||||
@ -2881,9 +2908,11 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
|
||||
*/
|
||||
thd->lex->current_select->where= *conds;
|
||||
}
|
||||
thd->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
|
||||
DBUG_RETURN(test(thd->net.report_error));
|
||||
|
||||
err:
|
||||
thd->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
|
||||
if (arena)
|
||||
thd->restore_backup_item_arena(arena, &backup);
|
||||
DBUG_RETURN(1);
|
||||
|
@ -265,6 +265,7 @@ JOIN::prepare(Item ***rref_pointer_array,
|
||||
select_lex->join= this;
|
||||
union_part= (unit_arg->first_select()->next_select() != 0);
|
||||
|
||||
thd->lex->current_select->is_item_list_lookup= 1;
|
||||
/* Check that all tables, fields, conds and order are ok */
|
||||
|
||||
if (setup_tables(tables_list) ||
|
||||
@ -8702,16 +8703,12 @@ find_order_in_list(THD *thd, Item **ref_pointer_array,
|
||||
|
||||
'it' reassigned in if condition because fix_field can change it.
|
||||
*/
|
||||
thd->lex->current_select->is_item_list_lookup= 1;
|
||||
if (!it->fixed &&
|
||||
(it->fix_fields(thd, tables, order->item) ||
|
||||
(it= *order->item)->check_cols(1) ||
|
||||
thd->is_fatal_error))
|
||||
{
|
||||
thd->lex->current_select->is_item_list_lookup= 0;
|
||||
return 1; // Wrong field
|
||||
}
|
||||
thd->lex->current_select->is_item_list_lookup= 0;
|
||||
|
||||
uint el= all_fields.elements;
|
||||
all_fields.push_front(it); // Add new field to field list
|
||||
ref_pointer_array[el]= it;
|
||||
|
Reference in New Issue
Block a user