3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program. If not, see <https://www.gnu.org/licenses/>.
19 use Test
::More tests
=> 34;
20 use Test
::Dpkg
qw(:paths);
23 use File
::Path
qw(make_path rmtree);
24 use File
::Spec
::Functions
qw(abs2rel);
28 use_ok
('Dpkg::Path', 'canonpath', 'resolve_symlink',
29 'check_files_are_the_same',
30 'check_directory_traversal',
32 'guess_pkg_root_dir', 'relative_to_pkg_root');
34 my $tmpdir = test_get_temp_path
();
36 make_path
("$tmpdir/a/b/c");
37 make_path
("$tmpdir/a/DEBIAN");
38 make_path
("$tmpdir/debian/a/b/c");
39 symlink 'a/b/c', "$tmpdir/cbis";
40 symlink '/this/does/not/exist', "$tmpdir/tmp";
41 symlink '.', "$tmpdir/here";
43 is
(canonpath
("$tmpdir/./a///b/c"), "$tmpdir/a/b/c", 'canonpath basic test');
44 is
(canonpath
("$tmpdir/a/b/../../a/b/c"), "$tmpdir/a/b/c", 'canonpath and ..');
45 is
(canonpath
("$tmpdir/a/b/c/../../"), "$tmpdir/a", 'canonpath .. at end');
46 is
(canonpath
("$tmpdir/cbis/../"), "$tmpdir/cbis/..", 'canonpath .. after symlink');
48 is
(resolve_symlink
("$tmpdir/here/cbis"), "$tmpdir/here/a/b/c", 'resolve_symlink');
49 is
(resolve_symlink
("$tmpdir/tmp"), '/this/does/not/exist', 'resolve_symlink absolute');
50 is
(resolve_symlink
("$tmpdir/here"), $tmpdir, 'resolve_symlink .');
52 ok
(!check_files_are_the_same
("$tmpdir/here", $tmpdir), 'Symlink is not the same!');
53 ok
(check_files_are_the_same
("$tmpdir/here/a", "$tmpdir/a"), 'Same directory');
55 sub gen_hier_travbase
{
58 make_path
("$basedir/subdir");
59 file_touch
("$basedir/file");
60 file_touch
("$basedir/subdir/subfile");
61 symlink 'file', "$basedir/symlink-file";
62 symlink 'subdir/subfile', "$basedir/symlink-subfile";
65 my $travbase = "$tmpdir/travbase";
66 my $travbase_out = "$tmpdir/travbase-out";
74 chroot => "$tmpdir/travbase-same",
77 symlink '../..', "$basedir/subdir/root";
84 symlink '/dev/null', "$basedir/dev-null";
91 symlink 'aa..bb..cc', "$basedir/dots";
98 symlink '../../..', "$basedir/rel";
105 symlink '/etc', "$basedir/abs";
112 symlink 'self', "$basedir/self";
119 symlink 'not-existent', "$basedir/enoent-rel";
126 symlink '/not-existent', "$basedir/enoent-abs";
129 enoent_indirect_rel
=> {
133 symlink 'not-existent', "$basedir/enoent-rel";
134 symlink 'enoent-rel', "$basedir/enoent-indirect-rel";
137 enoent_indirect_abs
=> {
141 symlink '/not-existent', "$basedir/enoent-abs";
142 symlink realpath
("$basedir/enoent-abs"), "$basedir/enoent-indirect-abs";
149 rename $basedir, "$basedir-real";
150 symlink 'base_in_none-real', $basedir;
157 rename $basedir, "$basedir-real";
158 symlink 'base_in_rel-real', $basedir;
159 symlink '../../..', "$basedir/rel";
166 rename $basedir, "$basedir-real";
167 symlink 'base_in_abs-real', $basedir;
168 symlink '/etc', "$basedir/abs";
173 root
=> $travbase_out,
182 root
=> $travbase_out,
187 root
=> $travbase_out,
190 symlink '../../..', "$basedir/rel";
195 root
=> $travbase_out,
198 symlink '/etc', "$basedir/abs";
203 foreach my $travtype (sort keys %travtype) {
204 my $trav = $travtype{$travtype};
205 my $rootdir = $trav->{chroot} // $trav->{root
} // $travbase;
206 my $hierdir = "$rootdir/$travtype";
207 my $travdir = "$travbase/$travtype";
209 gen_hier_travbase
($hierdir);
210 symlink abs2rel
($hierdir, $travbase), $travdir if exists $trav->{root
};
211 $trav->{gen
}->($hierdir);
215 check_directory_traversal
($travbase, $travdir);
221 ok
($catch, "directory traversal type $travtype detected");
222 note
("traversal reason: $catch") if $catch;
224 ok
(! $catch, "no directory traversal type $travtype");
225 diag
("error from check_directory_traversal => $catch") if $catch;
229 is
(get_pkg_root_dir
("$tmpdir/a/b/c"), "$tmpdir/a", 'get_pkg_root_dir');
230 is
(guess_pkg_root_dir
("$tmpdir/a/b/c"), "$tmpdir/a", 'guess_pkg_root_dir');
231 is
(relative_to_pkg_root
("$tmpdir/a/b/c"), 'b/c', 'relative_to_pkg_root');
235 is
(get_pkg_root_dir
('debian/a/b/c'), undef, 'get_pkg_root_dir undef');
236 is
(relative_to_pkg_root
('debian/a/b/c'), undef, 'relative_to_pkg_root undef');
237 is
(guess_pkg_root_dir
('debian/a/b/c'), 'debian/a', 'guess_pkg_root_dir fallback');