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`)
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
# 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
--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/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) 2016, 2020, MariaDB Corporation.
Copyright (c) 2016, 2022, 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
......@@ -3651,11 +3651,14 @@ dict_load_foreigns(
/* Copy the string because the page may be modified or evicted
after mtr_commit() below. */
char fk_id[MAX_TABLE_NAME_LEN + 1];
ut_a(len <= MAX_TABLE_NAME_LEN);
memcpy(fk_id, field, len);
fk_id[len] = '\0';
char fk_id[MAX_TABLE_NAME_LEN + NAME_LEN + 1];
err = DB_SUCCESS;
if (UNIV_LIKELY(len < sizeof fk_id)) {
memcpy(fk_id, field, len);
fk_id[len] = '\0';
} else {
err = DB_CORRUPTION;
}
btr_pcur_store_position(&pcur, &mtr);
......@@ -3663,9 +3666,11 @@ dict_load_foreigns(
/* Load the foreign constraint definition to the dictionary cache */
err = dict_load_foreign(fk_id, col_names,
check_recursive, check_charsets, ignore_err,
fk_tables);
if (err == DB_SUCCESS) {
err = dict_load_foreign(fk_id, col_names,
check_recursive, check_charsets,
ignore_err, fk_tables);
}
if (err != DB_SUCCESS) {
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