Commit f2cfcd91 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-5226 mysql_tzinfo_to_sql errors with tzdata 2013f and above

Allow only one level of symlink recursion in mysql_tzdata_to_sql,
to avoid infinite loops.
parent a4dc526f
......@@ -78,7 +78,7 @@ EXTRA_DIST = README README.suites \
TEST_DIRS = t r include std_data std_data/parts collections \
std_data/ndb_backup50 std_data/ndb_backup51 \
std_data/ndb_backup51_data_be std_data/ndb_backup51_data_le \
std_data/funcs_1 \
std_data/funcs_1 std_data/zoneinfo \
extra/binlog_tests/ extra/rpl_tests \
suite/binlog suite/binlog/t suite/binlog/r suite/binlog/std_data \
suite/federated \
......
......@@ -2298,6 +2298,13 @@ sub environment_setup {
"$path_client_bindir/perror");
$ENV{'MY_PERROR'}= native_path($exe_perror);
# ----------------------------------------------------
# mysql_tzinfo_to_sql
# ----------------------------------------------------
my $exe_mysql_tzinfo_to_sql= mtr_exe_exists("$basedir/sql$opt_vs_config/mysql_tzinfo_to_sql",
"$path_client_bindir/mysql_tzinfo_to_sql");
$ENV{'MYSQL_TZINFO_TO_SQL'}= native_path($exe_mysql_tzinfo_to_sql);
# Create an environment variable to make it possible
# to detect that valgrind is being used from test cases
$ENV{'VALGRIND_TEST'}= $opt_valgrind;
......
#
# MDEV-5226 mysql_tzinfo_to_sql errors with tzdata 2013f and above
#
TRUNCATE TABLE time_zone;
TRUNCATE TABLE time_zone_name;
TRUNCATE TABLE time_zone_transition;
TRUNCATE TABLE time_zone_transition_type;
INSERT INTO time_zone (Use_leap_seconds) VALUES ('N');
SET @time_zone_id= LAST_INSERT_ID();
INSERT INTO time_zone_name (Name, Time_zone_id) VALUES ('GMT', @time_zone_id);
INSERT INTO time_zone_transition_type (Time_zone_id, Transition_type_id, Offset, Is_DST, Abbreviation) VALUES
(@time_zone_id, 0, 0, 0, 'GMT')
;
INSERT INTO time_zone (Use_leap_seconds) VALUES ('N');
SET @time_zone_id= LAST_INSERT_ID();
INSERT INTO time_zone_name (Name, Time_zone_id) VALUES ('posix/GMT', @time_zone_id);
INSERT INTO time_zone_transition_type (Time_zone_id, Transition_type_id, Offset, Is_DST, Abbreviation) VALUES
(@time_zone_id, 0, 0, 0, 'GMT')
;
Warning: Skipping directory 'MYSQLTEST_VARDIR/zoneinfo/posix/posix': to avoid infinite symlink recursion.
ALTER TABLE time_zone_transition ORDER BY Time_zone_id, Transition_time;
ALTER TABLE time_zone_transition_type ORDER BY Time_zone_id, Transition_type_id;
--source include/have_symlink.inc
--source include/not_windows.inc
--echo #
--echo # MDEV-5226 mysql_tzinfo_to_sql errors with tzdata 2013f and above
--echo #
--exec mkdir $MYSQLTEST_VARDIR/zoneinfo
--exec ln -s $MYSQLTEST_VARDIR/zoneinfo $MYSQLTEST_VARDIR/zoneinfo/posix
--copy_file std_data/zoneinfo/GMT $MYSQLTEST_VARDIR/zoneinfo/GMT
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
--exec $MYSQL_TZINFO_TO_SQL $MYSQLTEST_VARDIR/zoneinfo 2>&1
--exec rm -rf $MYSQLTEST_VARDIR/zoneinfo
......@@ -2433,7 +2433,7 @@ char *root_name_end;
*/
my_bool
scan_tz_dir(char * name_end)
scan_tz_dir(char * name_end, uint symlink_recursion_level)
{
MY_DIR *cur_dir;
char *name_end_tmp;
......@@ -2453,7 +2453,32 @@ scan_tz_dir(char * name_end)
if (MY_S_ISDIR(cur_dir->dir_entry[i].mystat->st_mode))
{
if (scan_tz_dir(name_end_tmp))
my_bool is_symlink;
if ((is_symlink= my_is_symlink(fullname)) &&
symlink_recursion_level > 0)
{
/*
The timezone definition data in some Linux distributions
(e.g. the "timezone-data-2013f" package in Gentoo)
may have synlimks like:
/usr/share/zoneinfo/posix/ -> /usr/share/zoneinfo/,
so the same timezone files are available under two names
(e.g. "CET" and "posix/CET").
We allow one level of symlink recursion for backward
compatibility with earlier timezone data packages that have
duplicate copies of the same timezone files inside the root
directory and the "posix" subdirectory (instead of symlinking).
This makes "posix/CET" still available, but helps to avoid
following such symlinks infinitely:
/usr/share/zoneinfo/posix/posix/posix/.../posix/
*/
fflush(stdout);
fprintf(stderr, "Warning: Skipping directory '%s': "
"to avoid infinite symlink recursion.\n", fullname);
continue;
}
if (scan_tz_dir(name_end_tmp, symlink_recursion_level + is_symlink))
{
my_dirend(cur_dir);
return 1;
......@@ -2465,14 +2490,20 @@ scan_tz_dir(char * name_end)
if (!tz_load(fullname, &tz_info, &tz_storage))
print_tz_as_sql(root_name_end + 1, &tz_info);
else
{
fflush(stdout);
fprintf(stderr,
"Warning: Unable to load '%s' as time zone. Skipping it.\n",
fullname);
}
free_root(&tz_storage, MYF(0));
}
else
{
fflush(stdout);
fprintf(stderr, "Warning: '%s' is not regular file or directory\n",
fullname);
}
}
}
......@@ -2506,8 +2537,9 @@ main(int argc, char **argv)
printf("TRUNCATE TABLE time_zone_transition;\n");
printf("TRUNCATE TABLE time_zone_transition_type;\n");
if (scan_tz_dir(root_name_end))
if (scan_tz_dir(root_name_end, 0))
{
fflush(stdout);
fprintf(stderr, "There were fatal errors during processing "
"of zoneinfo directory\n");
return 1;
......@@ -2526,6 +2558,7 @@ main(int argc, char **argv)
{
if (tz_load(argv[2], &tz_info, &tz_storage))
{
fflush(stdout);
fprintf(stderr, "Problems with zoneinfo file '%s'\n", argv[2]);
return 1;
}
......@@ -2535,6 +2568,7 @@ main(int argc, char **argv)
{
if (tz_load(argv[1], &tz_info, &tz_storage))
{
fflush(stdout);
fprintf(stderr, "Problems with zoneinfo file '%s'\n", argv[2]);
return 1;
}
......
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