From e260cc3ff28d4d1130efe29cab917f6fb946faf7 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Fri, 30 Jul 2010 17:33:10 -0300 Subject: [PATCH 1/2] Bug#45288: pb2 returns a lot of compilation warnings on linux Fix compiler warnings. --- mysys/stacktrace.c | 4 +++- sql/sql_lex.cc | 3 --- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/mysys/stacktrace.c b/mysys/stacktrace.c index 75fda93b56e..7bac8017324 100644 --- a/mysys/stacktrace.c +++ b/mysys/stacktrace.c @@ -86,7 +86,9 @@ void my_print_stacktrace(uchar* stack_bottom __attribute__((unused)), #if BACKTRACE_DEMANGLE -char __attribute__ ((weak)) *my_demangle(const char *mangled_name, int *status) +char __attribute__ ((weak)) * +my_demangle(const char *mangled_name __attribute__((unused)), + int *status __attribute__((unused))) { return NULL; } diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 2bff036b1f1..24c51be2512 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1303,8 +1303,6 @@ int MYSQLlex(void *arg, void *yythd) } else { - const char* version_mark= lip->get_ptr() - 1; - DBUG_ASSERT(*version_mark == '!'); /* Patch and skip the conditional comment to avoid it being propagated infinitely (eg. to a slave). @@ -1313,7 +1311,6 @@ int MYSQLlex(void *arg, void *yythd) comment_closed= ! consume_comment(lip, 1); if (! comment_closed) { - DBUG_ASSERT(pcom == version_mark); *pcom= '!'; } /* version allowed to have one level of comment inside. */ From 38165ce4a3fdd0d539fa5b0972d105af31a0d134 Mon Sep 17 00:00:00 2001 From: Gleb Shchepa Date: Sun, 1 Aug 2010 22:12:36 +0400 Subject: [PATCH 2/2] Bug #54461: crash with longblob and union or update with subquery Queries may crash, if 1) the GREATEST or the LEAST function has a mixed list of numeric and LONGBLOB arguments and 2) the result of such a function goes through an intermediate temporary table. An Item that references a LONGBLOB field has max_length of UINT_MAX32 == (2^32 - 1). The current implementation of GREATEST/LEAST returns REAL result for a mixed list of numeric and string arguments (that contradicts with the current documentation, this contradiction was discussed and it was decided to update the documentation). The max_length of such a function call was calculated as a maximum of argument max_length values (i.e. UINT_MAX32). That max_length value of UINT_MAX32 was used as a length for the intermediate temporary table Field_double to hold GREATEST/LEAST function result. The Field_double::val_str() method call on that field allocates a String value. Since an allocation of String reserves an additional byte for a zero-termination, the size of String buffer was set to (UINT_MAX32 + 1), that caused an integer overflow: actually, an empty buffer of size 0 was allocated. An initialization of the "first" byte of that zero-size buffer with '\0' caused a crash. The Item_func_min_max::fix_length_and_dec() has been modified to calculate max_length for the REAL result like we do it for arithmetical operators. ****** Bug #54461: crash with longblob and union or update with subquery Queries may crash, if 1) the GREATEST or the LEAST function has a mixed list of numeric and LONGBLOB arguments and 2) the result of such a function goes through an intermediate temporary table. An Item that references a LONGBLOB field has max_length of UINT_MAX32 == (2^32 - 1). The current implementation of GREATEST/LEAST returns REAL result for a mixed list of numeric and string arguments (that contradicts with the current documentation, this contradiction was discussed and it was decided to update the documentation). The max_length of such a function call was calculated as a maximum of argument max_length values (i.e. UINT_MAX32). That max_length value of UINT_MAX32 was used as a length for the intermediate temporary table Field_double to hold GREATEST/LEAST function result. The Field_double::val_str() method call on that field allocates a String value. Since an allocation of String reserves an additional byte for a zero-termination, the size of String buffer was set to (UINT_MAX32 + 1), that caused an integer overflow: actually, an empty buffer of size 0 was allocated. An initialization of the "first" byte of that zero-size buffer with '\0' caused a crash. The Item_func_min_max::fix_length_and_dec() has been modified to calculate max_length for the REAL result like we do it for arithmetical operators. --- mysql-test/r/func_misc.result | 15 +++++++++++++++ mysql-test/t/func_misc.test | 12 ++++++++++++ sql/item_func.cc | 2 ++ 3 files changed, 29 insertions(+) diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result index 81dddd0f648..eee56ae7461 100644 --- a/mysql-test/r/func_misc.result +++ b/mysql-test/r/func_misc.result @@ -336,4 +336,19 @@ End of 5.0 tests select connection_id() > 0; connection_id() > 0 1 +# +# Bug #54461: crash with longblob and union or update with subquery +# +CREATE TABLE t1 (a INT, b LONGBLOB); +INSERT INTO t1 VALUES (1, '2'), (2, '3'), (3, '2'); +SELECT DISTINCT LEAST(a, (SELECT b FROM t1 LIMIT 1)) FROM t1 UNION SELECT 1; +LEAST(a, (SELECT b FROM t1 LIMIT 1)) +1 +2 +SELECT DISTINCT GREATEST(a, (SELECT b FROM t1 LIMIT 1)) FROM t1 UNION SELECT 1; +GREATEST(a, (SELECT b FROM t1 LIMIT 1)) +2 +3 +1 +DROP TABLE t1; End of tests diff --git a/mysql-test/t/func_misc.test b/mysql-test/t/func_misc.test index 6590b43f2dc..c6b5ffd5a3f 100644 --- a/mysql-test/t/func_misc.test +++ b/mysql-test/t/func_misc.test @@ -467,4 +467,16 @@ select NAME_CONST('_id',1234) as id; select connection_id() > 0; +--echo # +--echo # Bug #54461: crash with longblob and union or update with subquery +--echo # + +CREATE TABLE t1 (a INT, b LONGBLOB); +INSERT INTO t1 VALUES (1, '2'), (2, '3'), (3, '2'); + +SELECT DISTINCT LEAST(a, (SELECT b FROM t1 LIMIT 1)) FROM t1 UNION SELECT 1; +SELECT DISTINCT GREATEST(a, (SELECT b FROM t1 LIMIT 1)) FROM t1 UNION SELECT 1; + +DROP TABLE t1; + --echo End of tests diff --git a/sql/item_func.cc b/sql/item_func.cc index 1bec4700bff..1b13297c951 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2243,6 +2243,8 @@ void Item_func_min_max::fix_length_and_dec() max_length= my_decimal_precision_to_length_no_truncation(max_int_part + decimals, decimals, unsigned_flag); + else if (cmp_type == REAL_RESULT) + max_length= float_length(decimals); cached_field_type= agg_field_type(args, arg_count); }