>From c8ff44a85c9ef537a757bf6c4faf8fc11df044bf Mon Sep 17 00:00:00 2001 From: Pavel Raiskup Date: Sun, 15 Nov 2015 12:54:19 +0100 Subject: [PATCH 3/3] incremen: don't indefinitely recurse into symlink loop This complements previous commit. * src/common.h (nl_dir_loop_point): New prototype. * src/incremen.c (nl_dir_loop_point): New function. * src/names.c (add_hierarchy_to_namelist): Don't recurse down to the directory if the directory is already in namelist. Use nl_dir_loop_point for detection. * tests/deref02.at: New testcase. * tests/testsuite.at: Mention new testcase. * tests/Makefile.am (TESTSUITE_AT): Likewise. --- src/common.h | 1 + src/incremen.c | 19 +++++++++++++++++++ src/names.c | 8 ++++++++ tests/Makefile.am | 1 + tests/deref02.at | 40 ++++++++++++++++++++++++++++++++++++++++ tests/testsuite.at | 1 + 6 files changed, 70 insertions(+) create mode 100644 tests/deref02.at diff --git a/src/common.h b/src/common.h index 8c69f29..d320d57 100644 --- a/src/common.h +++ b/src/common.h @@ -551,6 +551,7 @@ void update_parent_directory (struct tar_stat_info *st); size_t dumpdir_size (const char *p); bool is_dumpdir (struct tar_stat_info *stat_info); void clear_directory_table (void); +bool nl_dir_loop_point (struct name *name); /* Module list.c. */ diff --git a/src/incremen.c b/src/incremen.c index d73a7bb..d514841 100644 --- a/src/incremen.c +++ b/src/incremen.c @@ -1758,6 +1758,25 @@ try_purge_directory (char const *directory_name) return true; } +bool +nl_dir_loop_point (struct name *name) +{ + const struct name *ptr = name; + + if (!dereference_option) + return false; + + while (ptr->parent) + { + ptr = ptr->parent; + if (ptr->directory->device_number == name->directory->device_number + && ptr->directory->inode_number == name->directory->inode_number) + return true; + } + + return false; +} + void purge_directory (char const *directory_name) { diff --git a/src/names.c b/src/names.c index 6e4616d..b31c747 100644 --- a/src/names.c +++ b/src/names.c @@ -1044,6 +1044,14 @@ add_hierarchy_to_namelist (struct tar_stat_info *st, struct name *name) const char *buffer; name->directory = scan_directory (st); + + if (nl_dir_loop_point (name)) + { + WARN ((0, 0, _("%s: stopping recursion due to directory loop"), + name->name)); + return; + } + buffer = directory_contents (name->directory); if (buffer) { diff --git a/tests/Makefile.am b/tests/Makefile.am index 9a783e5..4fa08f2 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -68,6 +68,7 @@ TESTSUITE_AT = \ delete04.at\ delete05.at\ deref01.at\ + deref02.at\ exclude.at\ exclude01.at\ exclude02.at\ diff --git a/tests/deref02.at b/tests/deref02.at new file mode 100644 index 0000000..0c20c08 --- /dev/null +++ b/tests/deref02.at @@ -0,0 +1,40 @@ +# Process this file with autom4te to create testsuite. -*- Autotest -*- +# +# Test suite for GNU tar. +# Copyright 2015 Free Software Foundation, Inc. + +# This file is part of GNU tar. + +# GNU tar 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 Foundation; either version 3 of the License, or +# (at your option) any later version. + +# GNU tar is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Test description: +# Symlink loop on directory with --dereference and --incremental. + +AT_SETUP([dereference: symlink loop and --incremental]) +AT_KEYWORDS([create dereference deref02 incremental]) + +AT_TAR_CHECK([ +mkdir dir +ln -s ../dir dir/dir || AT_SKIP_TEST +tar --incremental -chf test.tar dir && tar -tf test.tar +], +[0], +[dir/ +dir/dir/ +], +[tar: dir/dir: stopping recursion due to directory loop +], +[],[],[gnu, oldgnu, posix]) + +AT_CLEANUP diff --git a/tests/testsuite.at b/tests/testsuite.at index 0b0a778..a9e0cf2 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -218,6 +218,7 @@ m4_include([recurs02.at]) m4_include([shortrec.at]) m4_include([iotty.at]) m4_include([deref01.at]) +m4_include([deref02.at]) AT_BANNER([The --same-order option]) m4_include([same-order01.at]) -- 2.5.0