#!/usr/bin/perl
BEGIN {
use_ok(
'Dpkg::Source::Archive'
);
}
my
$tmpdir
= test_get_temp_path();
sub
test_path_escape
{
my
$name
=
shift
;
my
$treedir
= File::Spec->rel2abs(
"$tmpdir/$name-tree"
);
my
$overdir
= File::Spec->rel2abs(
"$tmpdir/$name-overlay"
);
my
$outdir
=
"$tmpdir/$name-out"
;
my
$expdir
=
"$tmpdir/$name-exp"
;
make_path(
"$treedir/subdir-a"
);
file_touch(
"$treedir/subdir-a/file-a"
);
file_touch(
"$treedir/subdir-a/file-pre-a"
);
make_path(
"$treedir/subdir-b"
);
file_touch(
"$treedir/subdir-b/file-b"
);
file_touch(
"$treedir/subdir-b/file-pre-b"
);
symlink
File::Spec->abs2rel(
$outdir
,
$treedir
),
"$treedir/symlink-escape"
;
symlink
File::Spec->abs2rel(
"$outdir/nonexistent"
,
$treedir
),
"$treedir/symlink-nonexistent"
;
symlink
"$treedir/file"
,
"$treedir/symlink-within"
;
file_touch(
"$treedir/supposed-dir"
);
make_path(
$overdir
);
make_path(
"$overdir/subdir-a/aa"
);
file_dump(
"$overdir/subdir-a/aa/file-aa"
,
'aa'
);
file_dump(
"$overdir/subdir-a/file-a"
,
'a'
);
make_path(
"$overdir/subdir-b/bb"
);
file_dump(
"$overdir/subdir-b/bb/file-bb"
,
'bb'
);
file_dump(
"$overdir/subdir-b/file-b"
,
'b'
);
make_path(
"$overdir/symlink-escape"
);
file_dump(
"$overdir/symlink-escape/escaped-file"
,
'escaped'
);
file_dump(
"$overdir/symlink-nonexistent"
,
'nonexistent'
);
make_path(
"$overdir/symlink-within"
);
make_path(
"$overdir/supposed-dir"
);
file_dump(
"$overdir/supposed-dir/supposed-file"
,
'something'
);
system
(
$Dpkg::PROGTAR
,
'-cf'
,
"$overdir.tar"
,
'-C'
,
$overdir
,
qw(
subdir-a subdir-b
symlink-escape/escaped-file symlink-nonexistent symlink-within
supposed-dir
)
) == 0
or
die
"cannot create overlay tar archive\n"
;
make_path(
$expdir
);
system
(
'cp'
,
'-a'
,
$overdir
,
$expdir
) == 0
or
die
"cannot copy overlay hierarchy into expected directory\n"
;
system
(
$Dpkg::PROGTAR
,
'-cf'
,
"$expdir.tar"
,
'-C'
,
$overdir
,
qw(
subdir-a subdir-b
symlink-escape/escaped-file symlink-nonexistent symlink-within
supposed-dir
)
,
'-C'
,
$treedir
,
qw(
subdir-a/file-pre-a
subdir-b/file-pre-b
)
) == 0
or
die
"cannot create expected tar archive\n"
;
make_path(
$outdir
);
my
$warnseen
;
local
$SIG
{__WARN__} =
sub
{
$warnseen
=
$_
[0] };
my
$tar
= Dpkg::Source::Archive->new(
filename
=>
"$overdir.tar"
);
$tar
->extract(
$treedir
,
in_place
=> 1);
system
(
$Dpkg::PROGTAR
,
'-cf'
,
"$treedir.tar"
,
'-C'
,
$treedir
,
'.'
);
ok(
length
$warnseen
&&
$warnseen
=~ m/points outside source root/,
'expected warning seen'
);
ok(
system
(
$Dpkg::PROGTAR
,
'--compare'
,
'-f'
,
"$expdir.tar"
,
'-C'
,
$treedir
) == 0,
'expected directory matches'
);
ok(! -e
"$outdir/escaped-file"
,
'expected output directory is empty, directory traversal'
);
}
test_path_escape(
'in-place'
);