Commit 14521992 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-27336 Crash on DROP DATABASE due to out-of-bounds result from InnoDB SUBSTR()

eval_substr(): Do not allow the string buffer of the first argument
to be extended. Trim the length of the returned result if it would
exceed the end of the buffer.
parent 8e5f09a6
......@@ -10,3 +10,13 @@ create table `#mysql50#q.q` select 1;
ERROR 42000: Incorrect table name '#mysql50#q.q'
create table `#mysql50#q·q` select 1;
drop database `b`;
#
# MDEV-27336 Crash on DROP DATABASE due to out-of-bounds result
# from InnoDB SUBSTR() function
#
USE test;
CREATE TABLE t1(a INT PRIMARY KEY) ENGINE=InnoDB;
CREATE TABLE t2(a INT PRIMARY KEY REFERENCES t1(a)) ENGINE=InnoDB;
CREATE DATABASE somewhat_longer_name_to_cause_trouble;
DROP DATABASE somewhat_longer_name_to_cause_trouble;
DROP TABLE t2,t1;
......@@ -14,3 +14,14 @@ use `b`;
create table `#mysql50#q.q` select 1;
create table `#mysql50#q·q` select 1;
drop database `b`;
--echo #
--echo # MDEV-27336 Crash on DROP DATABASE due to out-of-bounds result
--echo # from InnoDB SUBSTR() function
--echo #
USE test;
CREATE TABLE t1(a INT PRIMARY KEY) ENGINE=InnoDB;
CREATE TABLE t2(a INT PRIMARY KEY REFERENCES t1(a)) ENGINE=InnoDB;
CREATE DATABASE somewhat_longer_name_to_cause_trouble;
DROP DATABASE somewhat_longer_name_to_cause_trouble;
DROP TABLE t2,t1;
/*****************************************************************************
Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2019, MariaDB Corporation.
Copyright (c) 2019, 2021, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
......@@ -378,12 +378,23 @@ eval_substr(
str1 = static_cast<byte*>(dfield_get_data(que_node_get_val(arg1)));
const ulint str1_len = dfield_get_len(que_node_get_val(arg1));
len1 = (ulint) eval_node_get_int_val(arg2);
len2 = (ulint) eval_node_get_int_val(arg3);
dfield = que_node_get_val(func_node);
dfield_set_data(dfield, str1 + len1, len2);
if (len1 > str1_len) {
len2 = 0;
} else {
str1 += len1;
if (len2 > str1_len - len1) {
len2 = str1_len - len1;
}
}
dfield_set_data(dfield, str1, len2);
}
/*****************************************************************//**
......
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