Commit 8aa37c26 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-28980 InnoDB: Failing assertion: len <= MAX_TABLE_NAME_LEN

dict_load_foreigns(): Use a correctly sized buffer for the maximum-length
SYS_FOREIGN.ID. In case of overflow, do not crash the server but instead
return DB_CORRUPTION.
parent e55c3dc3
...@@ -858,3 +858,17 @@ Error 1296 Got error 193 '`test`.`t1`, CONSTRAINT `t1_ibfk_1` FOREIGN KEY (`a`) ...@@ -858,3 +858,17 @@ Error 1296 Got error 193 '`test`.`t1`, CONSTRAINT `t1_ibfk_1` FOREIGN KEY (`a`)
DROP TABLE t1; DROP TABLE t1;
FOUND 1 /InnoDB: Cannot delete/update rows with cascading foreign key constraints that exceed max depth of 15.*/ in mysqld.1.err FOUND 1 /InnoDB: Cannot delete/update rows with cascading foreign key constraints that exceed max depth of 15.*/ in mysqld.1.err
# End of 10.2 tests # End of 10.2 tests
#
# MDEV-28980 InnoDB: Failing assertion: len <= MAX_TABLE_NAME_LEN
#
SET NAMES utf8;
CREATE TABLE t (a INT PRIMARY KEY) ENGINE=InnoDB;
CREATE DATABASE `db`;
CREATE TABLE `db`.u (
a INT PRIMARY KEY,
CONSTRAINT `††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††`
FOREIGN KEY (a) REFERENCES test.t (a)) ENGINE=InnoDB;
DROP TABLE `db`.u;
DROP DATABASE `db`;
DROP TABLE t;
# End of 10.3 tests
#
# MDEV-28980 InnoDB: Failing assertion: len <= MAX_TABLE_NAME_LEN
#
CREATE TABLE t (a INT PRIMARY KEY) ENGINE=InnoDB;
CREATE DATABASE `d255`;
CREATE TABLE `d255`.`d255`
(a INT PRIMARY KEY, FOREIGN KEY(a) REFERENCES test.t(a)) ENGINE=InnoDB;
ERROR HY000: Long database name and identifier for object resulted in path length exceeding 512 characters. Path: './@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023/@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@
CREATE TABLE `d255`.`_##################################################`
(a INT PRIMARY KEY, FOREIGN KEY(a) REFERENCES test.t(a)) ENGINE=InnoDB;
ERROR HY000: Long database name and identifier for object resulted in path length exceeding 512 characters. Path: './@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023/_@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023
CREATE TABLE `d255`.`##################################################`
(a INT PRIMARY KEY, FOREIGN KEY(a) REFERENCES test.t(a)) ENGINE=InnoDB;
DROP DATABASE `d255`;
DROP TABLE t;
# End of 10.3 tests
...@@ -881,4 +881,33 @@ let SEARCH_PATTERN= InnoDB: Cannot delete/update rows with cascading foreign key ...@@ -881,4 +881,33 @@ let SEARCH_PATTERN= InnoDB: Cannot delete/update rows with cascading foreign key
--echo # End of 10.2 tests --echo # End of 10.2 tests
--echo #
--echo # MDEV-28980 InnoDB: Failing assertion: len <= MAX_TABLE_NAME_LEN
--echo #
SET NAMES utf8;
CREATE TABLE t (a INT PRIMARY KEY) ENGINE=InnoDB;
# The maximum identifier length is 64 characters.
# my_charset_filename will expand some characters to 5 characters,
# e.g., # to @0023.
# Many operating systems (such as Linux) or file systems
# limit the path component length to 255 bytes, such as 51*5 characters.
# The bug was repeated with a shorter length, which we will use here,
# to avoid exceeding MAX_PATH on Microsoft Windows.
let $db=##########################;
--replace_result $db db
eval CREATE DATABASE `$db`;
--replace_result $db db
eval CREATE TABLE `$db`.u (
a INT PRIMARY KEY,
CONSTRAINT `††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††`
FOREIGN KEY (a) REFERENCES test.t (a)) ENGINE=InnoDB;
--replace_result $db db
eval DROP TABLE `$db`.u;
--replace_result $db db
eval DROP DATABASE `$db`;
DROP TABLE t;
--echo # End of 10.3 tests
--source include/wait_until_count_sessions.inc --source include/wait_until_count_sessions.inc
--source include/have_innodb.inc
--source include/not_windows.inc
--echo #
--echo # MDEV-28980 InnoDB: Failing assertion: len <= MAX_TABLE_NAME_LEN
--echo #
# The main test is innodb.foreign_key. This is an additional test that
# the maximum length cannot be exceeded for implicitly created
# constraint names. On Microsoft Windows, MAX_PATH is a much stricter
# limit than the 255-byte maximum path component length on many other systems,
# including Linux and IBM AIX.
CREATE TABLE t (a INT PRIMARY KEY) ENGINE=InnoDB;
# The maximum identifier length is 64 characters.
# my_charset_filename will expand some characters to 5 characters,
# e.g., # to @0023.
# Many operating systems (such as Linux) or file systems
# limit the path component length to 255 bytes,
# corresponding to the 51 characters below: 5*51=255.
let $d255=###################################################;
let $d250=##################################################;
--replace_result $d255 d255
eval CREATE DATABASE `$d255`;
--replace_result $d255 d255
--error ER_IDENT_CAUSES_TOO_LONG_PATH
eval CREATE TABLE `$d255`.`$d255`
(a INT PRIMARY KEY, FOREIGN KEY(a) REFERENCES test.t(a)) ENGINE=InnoDB;
--replace_result $d255 d255
--error ER_IDENT_CAUSES_TOO_LONG_PATH
eval CREATE TABLE `$d255`.`_$d250`
(a INT PRIMARY KEY, FOREIGN KEY(a) REFERENCES test.t(a)) ENGINE=InnoDB;
--replace_result $d255 d255
eval CREATE TABLE `$d255`.`$d250`
(a INT PRIMARY KEY, FOREIGN KEY(a) REFERENCES test.t(a)) ENGINE=InnoDB;
--replace_result $d255 d255
eval DROP DATABASE `$d255`;
DROP TABLE t;
--echo # End of 10.3 tests
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2016, 2020, MariaDB Corporation. Copyright (c) 2016, 2022, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software
...@@ -3651,11 +3651,14 @@ dict_load_foreigns( ...@@ -3651,11 +3651,14 @@ dict_load_foreigns(
/* Copy the string because the page may be modified or evicted /* Copy the string because the page may be modified or evicted
after mtr_commit() below. */ after mtr_commit() below. */
char fk_id[MAX_TABLE_NAME_LEN + 1]; char fk_id[MAX_TABLE_NAME_LEN + NAME_LEN + 1];
err = DB_SUCCESS;
ut_a(len <= MAX_TABLE_NAME_LEN); if (UNIV_LIKELY(len < sizeof fk_id)) {
memcpy(fk_id, field, len); memcpy(fk_id, field, len);
fk_id[len] = '\0'; fk_id[len] = '\0';
} else {
err = DB_CORRUPTION;
}
btr_pcur_store_position(&pcur, &mtr); btr_pcur_store_position(&pcur, &mtr);
...@@ -3663,9 +3666,11 @@ dict_load_foreigns( ...@@ -3663,9 +3666,11 @@ dict_load_foreigns(
/* Load the foreign constraint definition to the dictionary cache */ /* Load the foreign constraint definition to the dictionary cache */
err = dict_load_foreign(fk_id, col_names, if (err == DB_SUCCESS) {
check_recursive, check_charsets, ignore_err, err = dict_load_foreign(fk_id, col_names,
fk_tables); check_recursive, check_charsets,
ignore_err, fk_tables);
}
if (err != DB_SUCCESS) { if (err != DB_SUCCESS) {
btr_pcur_close(&pcur); btr_pcur_close(&pcur);
......
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