Commit 99318017 authored by Ramil Kalimullin's avatar Ramil Kalimullin

Fix for bug #42803: Field_bit does not have unsigned_flag field,

can lead to bad memory access

Problem: Field_bit is the only field which returns INT_RESULT
and doesn't have unsigned flag. As it's not a descendant of the 
Field_num, so using ((Field_num *) field_bit)->unsigned_flag may lead
to unpredictable results.

Fix: check the field type before casting.
parent 14f76673
......@@ -749,4 +749,14 @@ bin(a1)
110000111111111
110001011111111
drop table t1bit7, t2bit7;
#
# Bug42803: Field_bit does not have unsigned_flag field,
# can lead to bad memory access
#
CREATE TABLE t1 (a BIT(7), b BIT(9), KEY(a, b));
INSERT INTO t1 VALUES(0, 0), (5, 3), (5, 6), (6, 4), (7, 0);
EXPLAIN SELECT a+0, b+0 FROM t1 WHERE a > 4 and b < 7 ORDER BY 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 2 NULL 4 Using where; Using index; Using filesort
DROP TABLE t1;
End of 5.0 tests
......@@ -397,4 +397,15 @@ insert into t2bit7 values (b'110011011111111');
select bin(a1) from t1bit7, t2bit7 where t1bit7.a1=t2bit7.b1;
drop table t1bit7, t2bit7;
--echo #
--echo # Bug42803: Field_bit does not have unsigned_flag field,
--echo # can lead to bad memory access
--echo #
CREATE TABLE t1 (a BIT(7), b BIT(9), KEY(a, b));
INSERT INTO t1 VALUES(0, 0), (5, 3), (5, 6), (6, 4), (7, 0);
EXPLAIN SELECT a+0, b+0 FROM t1 WHERE a > 4 and b < 7 ORDER BY 2;
DROP TABLE t1;
--echo End of 5.0 tests
......@@ -4536,6 +4536,7 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part,
if (type == Item_func::LT_FUNC && (value->val_int() > 0))
type = Item_func::LE_FUNC;
else if (type == Item_func::GT_FUNC &&
(field->type() != FIELD_TYPE_BIT) &&
!((Field_num*)field)->unsigned_flag &&
!((Item_int*)value)->unsigned_flag &&
(value->val_int() < 0))
......@@ -4572,7 +4573,9 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part,
*/
if (field->result_type() == INT_RESULT &&
value->result_type() == INT_RESULT &&
((Field_num*)field)->unsigned_flag && !((Item_int*)value)->unsigned_flag)
((field->type() == FIELD_TYPE_BIT ||
((Field_num *) field)->unsigned_flag) &&
!((Item_int*) value)->unsigned_flag))
{
longlong item_val= value->val_int();
if (item_val < 0)
......
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