diff options
author | Gleb Shchepa <gshchepa@mysql.com> | 2010-08-01 22:12:36 +0400 |
---|---|---|
committer | Gleb Shchepa <gshchepa@mysql.com> | 2010-08-01 22:12:36 +0400 |
commit | 38165ce4a3fdd0d539fa5b0972d105af31a0d134 (patch) | |
tree | cc51b601f1e44402353a460d535aafeae348477b /mysql-test/r/func_misc.result | |
parent | bb3fbba1af97d95ec60f604e10796b9cff9b432d (diff) | |
download | mariadb-git-38165ce4a3fdd0d539fa5b0972d105af31a0d134.tar.gz |
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.
Diffstat (limited to 'mysql-test/r/func_misc.result')
-rw-r--r-- | mysql-test/r/func_misc.result | 15 |
1 files changed, 15 insertions, 0 deletions
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 |