1
0
mirror of https://github.com/MariaDB/server.git synced 2026-10-23 18:49:29 +03:00

reject out of range rec_per_key in replay context

Index_statistics::set_avg_frequency() casts rec_per_key * 100000 to
ulonglong, which is undefined for negative or too large values.

Reject them when parsing the context.

Assisted-by: Claude:claude-5.5-opus
This commit is contained in:
Sergei Golubchik
2026-10-14 22:58:11 +02:00
parent 9c5864f70b
commit 0e2780afc6
3 changed files with 55 additions and 0 deletions

View File

@@ -507,4 +507,34 @@ Warning 4270 Failed to match the stats from replay context with the optimizer st
Warning 4270 Failed to match the stats from replay context with the optimizer stats: test.t1 with key_number:0, records:10, eq_ref:0 doesn't exist in cost_for_index_read_calls
set optimizer_replay_context='';
drop table t1;
#
# rec_per_key out of range
#
create table t1 (a int, b int, key(a));
insert into t1 select seq%10, seq from seq_1_to_100;
select count(*) from t1 where a=3;
count(*)
10
set @opt_context=
(select REGEXP_SUBSTR(
context,
'(?<=set @opt_context=\')([\n\r].*)*(?=\'\;#opt_context_ends)')
from information_schema.optimizer_context);
set @opt_context_rpk= json_replace(@opt_context,
'$.tables[0].indexes[0].rec_per_key[0]', -1);
set optimizer_replay_context='opt_context_rpk';
select count(*) from t1 where a=3;
count(*)
10
Warnings:
Warning 4269 Failed to parse saved optimizer context: rec_per_key value is out of range at offset 229.
set @opt_context_rpk= json_replace(@opt_context,
'$.tables[0].indexes[0].rec_per_key[0]', 1e300);
select count(*) from t1 where a=3;
count(*)
10
Warnings:
Warning 4269 Failed to parse saved optimizer context: rec_per_key value is out of range at offset 232.
set optimizer_replay_context='';
drop table t1;
# End of 13.1 tests

View File

@@ -325,4 +325,21 @@ explain select t1.b from t1, t1 t2 where t1.a = t2.a;
set optimizer_replay_context='';
drop table t1;
--echo #
--echo # rec_per_key out of range
--echo #
create table t1 (a int, b int, key(a));
insert into t1 select seq%10, seq from seq_1_to_100;
select count(*) from t1 where a=3;
--source include/opt_context_save_in_var.inc
set @opt_context_rpk= json_replace(@opt_context,
'$.tables[0].indexes[0].rec_per_key[0]', -1);
set optimizer_replay_context='opt_context_rpk';
select count(*) from t1 where a=3;
set @opt_context_rpk= json_replace(@opt_context,
'$.tables[0].indexes[0].rec_per_key[0]', 1e300);
select count(*) from t1 where a=3;
set optimizer_replay_context='';
drop table t1;
--echo # End of 13.1 tests

View File

@@ -1352,6 +1352,14 @@ public:
if (read_double(je , name, err_buf, val))
return 1;
/* Index_statistics stores it multiplied by 100000 in a ulonglong */
if (val < 0 || val > 1e14)
{
err_buf->append(name, strlen(name));
err_buf->append(STRING_WITH_LEN(" value is out of range"));
return 1;
}
if (list_values->append(val) || json_scan_next(je))
return 1;
}