Skip to content

Commit d6cc483

Browse files
author
Tor Didriksen
committed
Bug#36563773 MYSQL SERVER 8.3.0 GLOBAL-BUFFER-OVERFLOW AT 'DECIMAL_BIN_SIZE_INLINE'
Limit the scale used when computing averages of decimal numbers. Also verify that we do not set precision > DECIMAL_MAX_PRECISION Change-Id: If32143ad7ed55f841e3973e78fa8e98cc245e775
1 parent 9b7e3b1 commit d6cc483

File tree

4 files changed

+15
-6
lines changed

4 files changed

+15
-6
lines changed

sql/item.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1569,6 +1569,7 @@ class Item : public Parse_tree_node {
15691569
inline void set_data_type_decimal(uint8 precision, uint8 scale) {
15701570
set_data_type(MYSQL_TYPE_NEWDECIMAL);
15711571
collation.set_numeric();
1572+
assert(precision <= DECIMAL_MAX_PRECISION);
15721573
decimals = scale;
15731574
fix_char_length(my_decimal_precision_to_length_no_truncation(
15741575
precision, scale, unsigned_flag));

sql/item_func.cc

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2784,7 +2784,8 @@ bool Item_func_neg::resolve_type(THD *thd) {
27842784
the negated number
27852785
*/
27862786
unsigned_flag = false;
2787-
set_data_type_decimal(args[0]->decimal_precision(), 0);
2787+
set_data_type_decimal(
2788+
min<uint>(args[0]->decimal_precision(), DECIMAL_MAX_PRECISION), 0);
27882789
hybrid_type = DECIMAL_RESULT;
27892790
DBUG_PRINT("info", ("Type changed: DECIMAL_RESULT"));
27902791
}
@@ -3351,6 +3352,7 @@ bool Item_func_int_val::resolve_type_inner(THD *) {
33513352
// order of magnitude.
33523353
int precision = args[0]->decimal_precision() - args[0]->decimals;
33533354
if (args[0]->decimals != 0) ++precision;
3355+
precision = std::min(precision, DECIMAL_MAX_PRECISION);
33543356
set_data_type_decimal(precision, 0);
33553357
hybrid_type = DECIMAL_RESULT;
33563358

@@ -3508,6 +3510,7 @@ bool Item_func_round::resolve_type(THD *thd) {
35083510
new_scale = val1;
35093511
}
35103512
if (precision == 0) precision = 1;
3513+
precision = min<uint>(precision, DECIMAL_MAX_PRECISION);
35113514
set_data_type_decimal(precision, new_scale);
35123515
hybrid_type = DECIMAL_RESULT;
35133516
break;
@@ -6100,7 +6103,9 @@ bool Item_func_set_user_var::resolve_type(THD *thd) {
61006103
args[0]->max_length; // Preserves "length" of integer constants
61016104
break;
61026105
case MYSQL_TYPE_NEWDECIMAL:
6103-
set_data_type_decimal(args[0]->decimal_precision(), args[0]->decimals);
6106+
set_data_type_decimal(
6107+
min<uint>(args[0]->decimal_precision(), DECIMAL_MAX_PRECISION),
6108+
args[0]->decimals);
61046109
break;
61056110
case MYSQL_TYPE_DOUBLE:
61066111
set_data_type_double();

sql/item_json_func.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3373,7 +3373,8 @@ static void set_data_type_from_cast_type(Item *item, Cast_target cast_type,
33733373
item->set_data_type_datetime(decimals);
33743374
return;
33753375
case ITEM_CAST_DECIMAL:
3376-
item->set_data_type_decimal(length, decimals);
3376+
item->set_data_type_decimal(
3377+
std::min<unsigned>(length, DECIMAL_MAX_PRECISION), decimals);
33773378
return;
33783379
case ITEM_CAST_CHAR:
33793380
// If no character set is specified, the JSON default character set is

sql/item_sum.cc

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1929,7 +1929,8 @@ bool Item_sum_sum::resolve_type(THD *thd) {
19291929
case DECIMAL_RESULT: {
19301930
// SUM result cannot be longer than length(arg) + length(MAX_ROWS)
19311931
const int precision =
1932-
args[0]->decimal_precision() + DECIMAL_LONGLONG_DIGITS;
1932+
min<uint>(args[0]->decimal_precision() + DECIMAL_LONGLONG_DIGITS,
1933+
DECIMAL_MAX_PRECISION);
19331934
set_data_type_decimal(precision, args[0]->decimals);
19341935
curr_dec_buff = 0;
19351936
my_decimal_set_zero(dec_buffs);
@@ -2264,13 +2265,14 @@ bool Item_sum_avg::resolve_type(THD *thd) {
22642265
null_value = true;
22652266
prec_increment = thd->variables.div_precincrement;
22662267
if (hybrid_type == DECIMAL_RESULT) {
2267-
const int precision = args[0]->decimal_precision() + prec_increment;
2268+
const int precision = min<uint>(
2269+
args[0]->decimal_precision() + prec_increment, DECIMAL_MAX_PRECISION);
22682270
int scale =
22692271
min<uint>(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
22702272
set_data_type_decimal(precision, scale);
22712273
f_precision =
22722274
min(precision + DECIMAL_LONGLONG_DIGITS, DECIMAL_MAX_PRECISION);
2273-
f_scale = args[0]->decimals;
2275+
f_scale = min<uint>(args[0]->decimals, f_precision);
22742276
dec_bin_size = my_decimal_get_binary_size(f_precision, f_scale);
22752277
} else {
22762278
assert(hybrid_type == REAL_RESULT);

0 commit comments

Comments
 (0)