From ba974f83712e458275ac2a3d2a803c36871cf4f0 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 27 Nov 2007 09:36:43 +0400 Subject: [PATCH] Fix for bug #32559: connection hangs on query with name_const Problem: passing a non-constant name to the NAME_CONST function results in a crash. Fix: check the NAME_CONST name argument; return fake item type if we got non-constant argument(s). mysql-test/r/func_misc.result: Fix for bug #32559: connection hangs on query with name_const - test result. mysql-test/t/func_misc.test: Fix for bug #32559: connection hangs on query with name_const - test case. sql/item.cc: Fix for bug #32559: connection hangs on query with name_const - Item_name_const::type() now returns NULL_ITEM if non-constant arguments were used to create the item to avoid wrong type casting. sql/item.h: Fix for bug #32559: connection hangs on query with name_const - NAME_CONST name argument checked for invariability. --- mysql-test/r/func_misc.result | 7 +++++++ mysql-test/t/func_misc.test | 12 +++++++++++- sql/item.cc | 12 +++++++++++- sql/item.h | 4 +++- 4 files changed, 32 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result index c941790c35b..889dfb7e078 100644 --- a/mysql-test/r/func_misc.result +++ b/mysql-test/r/func_misc.result @@ -207,4 +207,11 @@ test SELECT NAME_CONST('test', 'test'); test test +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES (), (), (); +SELECT NAME_CONST(a, '1') FROM t1; +ERROR HY000: Incorrect arguments to NAME_CONST +SET INSERT_ID= NAME_CONST(a, a); +ERROR HY000: Incorrect arguments to NAME_CONST +DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/t/func_misc.test b/mysql-test/t/func_misc.test index 2c34f77b1ff..4870379d69e 100644 --- a/mysql-test/t/func_misc.test +++ b/mysql-test/t/func_misc.test @@ -204,5 +204,15 @@ SELECT NAME_CONST('test', 1.0); SELECT NAME_CONST('test', -1.0); SELECT NAME_CONST('test', 'test'); ---echo End of 5.0 tests +# +# Bug #32559: connection hangs on query with name_const +# +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES (), (), (); +--error ER_WRONG_ARGUMENTS +SELECT NAME_CONST(a, '1') FROM t1; +--error ER_WRONG_ARGUMENTS +SET INSERT_ID= NAME_CONST(a, a); +DROP TABLE t1; +--echo End of 5.0 tests diff --git a/sql/item.cc b/sql/item.cc index 431d82af331..a75d0159848 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1209,7 +1209,17 @@ bool Item_name_const::is_null() Item::Type Item_name_const::type() const { - return value_item->type(); + /* + As + 1. one can try to create the Item_name_const passing non-constant + arguments, although it's incorrect and + 2. the type() method can be called before the fix_fields() to get + type information for a further type cast, e.g. + if (item->type() == FIELD_ITEM) + ((Item_field *) item)->... + we return NULL_ITEM in the case to avoid wrong casting. + */ + return valid_args ? value_item->type() : NULL_ITEM; } diff --git a/sql/item.h b/sql/item.h index a1135c2c725..fbf4b94b276 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1111,11 +1111,13 @@ class Item_name_const : public Item { Item *value_item; Item *name_item; + bool valid_args; public: Item_name_const(Item *name_arg, Item *val): value_item(val), name_item(name_arg) { - if(!value_item->basic_const_item()) + if (!(valid_args= name_item->basic_const_item() & + value_item->basic_const_item())) my_error(ER_WRONG_ARGUMENTS, MYF(0), "NAME_CONST"); Item::maybe_null= TRUE; }