>From fbdadfe9226b3de9712cafcbb0734131e0a73f4f 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 7f4103a..49e1973 100644 --- a/src/common.h +++ b/src/common.h @@ -566,6 +566,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 19d0b9b..932882c 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 219aa77..02f757c 100644 --- a/src/names.c +++ b/src/names.c @@ -1543,6 +1543,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 aa7d49b..439ca6c 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -71,6 +71,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 17d37fa..88d74bc 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -242,6 +242,7 @@ m4_include([recurs02.at]) m4_include([shortrec.at]) m4_include([numeric.at]) m4_include([deref01.at]) +m4_include([deref02.at]) AT_BANNER([The --same-order option]) m4_include([same-order01.at]) -- 2.7.4