1 diff -ruN dpkg-1.15.5.6ubuntu4/scripts/Dpkg/Source/Archive.pm dpkg-1.15.5.6ubuntu4.5//scripts/Dpkg/Source/Archive.pm
2 --- dpkg-1.15.5.6ubuntu4/scripts/Dpkg/Source/Archive.pm 2010-04-15 13:38:58.000000000 +0200
3 +++ dpkg-1.15.5.6ubuntu4.5//scripts/Dpkg/Source/Archive.pm 2011-01-06 21:08:30.000000000 +0200
5 # Call tar extraction process
6 $fork_opts{"delete_env"} = [ "TAR_OPTIONS" ];
7 $fork_opts{'exec'} = [ 'tar', '--no-same-owner', '--no-same-permissions',
8 - @{$opts{"options"}}, '-xkf', '-' ];
9 + @{$opts{"options"}}, '-xf', '-' ];
10 fork_and_exec(%fork_opts);
11 $self->cleanup_after_open();
17 - if (scalar(@entries) == 1 && -d "$tmp/$entries[0]") {
18 + if (scalar(@entries) == 1 && ! -l "$tmp/$entries[0]" && -d _) {
19 rename("$tmp/$entries[0]", $dest) ||
20 syserr(_g("Unable to rename %s to %s"),
21 "$tmp/$entries[0]", $dest);
22 diff -ruN dpkg-1.15.5.6ubuntu4/scripts/Dpkg/Source/Package/V2.pm dpkg-1.15.5.6ubuntu4.5//scripts/Dpkg/Source/Package/V2.pm
23 --- dpkg-1.15.5.6ubuntu4/scripts/Dpkg/Source/Package/V2.pm 2010-04-15 13:38:58.000000000 +0200
24 +++ dpkg-1.15.5.6ubuntu4.5//scripts/Dpkg/Source/Package/V2.pm 2011-01-06 21:08:30.000000000 +0200
26 # Extract main tarball
27 info(_g("unpacking %s"), $tarfile);
28 my $tar = Dpkg::Source::Archive->new(filename => "$dscdir$tarfile");
29 - $tar->extract($newdirectory, no_fixperms => 1);
30 + $tar->extract($newdirectory, no_fixperms => 1,
31 + options => [ "--anchored", "--no-wildcards-match-slash",
32 + "--exclude", "*/.pc", "--exclude", ".pc" ]);
33 + # The .pc exclusion is only needed for 3.0 (quilt) and to avoid
34 + # having an upstream tarball provide a directory with symlinks
35 + # that would be blindly followed when applying the patches
37 # Extract additional orig tarballs
38 foreach my $subdir (keys %origtar) {
39 diff -ruN dpkg-1.15.5.6ubuntu4/scripts/Dpkg/Source/Patch.pm dpkg-1.15.5.6ubuntu4.5//scripts/Dpkg/Source/Patch.pm
40 --- dpkg-1.15.5.6ubuntu4/scripts/Dpkg/Source/Patch.pm 2010-04-15 13:38:58.000000000 +0200
41 +++ dpkg-1.15.5.6ubuntu4.5//scripts/Dpkg/Source/Patch.pm 2011-01-06 21:08:30.000000000 +0200
43 $header =~ s/\s.*// unless ($header =~ s/\t.*//);
47 + sub intuit_file_patched {
48 + my ($old, $new) = @_;
49 + return $new unless defined $old;
50 + return $old unless defined $new;
51 + return $new if -e $new and not -e $old;
52 + return $old if -e $old and not -e $new;
53 + # We don't consider the case where both files are non-existent and
54 + # where patch picks the one with the fewest directories to create
55 + # since dpkg-source will pre-create the required directories
57 + # Precalculate metrics used by patch
58 + my ($tmp_o, $tmp_n) = ($old, $new);
59 + my ($len_o, $len_n) = (length($old), length($new));
60 + $tmp_o =~ s{[/\\]+}{/}g;
61 + $tmp_n =~ s{[/\\]+}{/}g;
62 + my $nb_comp_o = ($tmp_o =~ tr{/}{/});
63 + my $nb_comp_n = ($tmp_n =~ tr{/}{/});
64 + $tmp_o =~ s{^.*/}{};
65 + $tmp_n =~ s{^.*/}{};
66 + my ($blen_o, $blen_n) = (length($tmp_o), length($tmp_n));
67 + # Decide like patch would
68 + if ($nb_comp_o != $nb_comp_n) {
69 + return ($nb_comp_o < $nb_comp_n) ? $old : $new;
70 + } elsif ($blen_o != $blen_n) {
71 + return ($blen_o < $blen_n) ? $old : $new;
72 + } elsif ($len_o != $len_n) {
73 + return ($len_o < $len_n) ? $old : $new;
77 $_ = getline($diff_handle);
80 while (defined($_) || not eof($diff_handle)) {
83 # skip comments leading up to patch (if any)
85 last HUNK if not defined($_ = getline($diff_handle));
88 error(_g("expected ^--- in line %d of diff `%s'"), $., $diff);
91 - if ($_ eq '/dev/null' or s{^[^/]+/}{$destdir/}) {
93 - error(_g("%s contains an insecure path: %s"), $diff, $_) if m{/\.\./};
95 + $path{'old'} = $_ = strip_ts($_);
96 + $fn{'old'} = $_ if $_ ne '/dev/null' and s{^[^/]*/+}{$destdir/};
98 error(_g("diff `%s' patches file with name ending .dpkg-orig"), $diff);
100 @@ -342,46 +370,47 @@
101 unless (s/^\+\+\+ //) {
102 error(_g("line after --- isn't as expected in diff `%s' (line %d)"), $diff, $.);
105 - if ($_ eq '/dev/null' or s{^[^/]+/}{$destdir/}) {
107 - error(_g("%s contains an insecure path: %s"), $diff, $_) if m{/\.\./};
109 - unless (defined $fn) {
110 - error(_g("none of the filenames in ---/+++ are relative in diff `%s' (line %d)"),
114 + $path{'new'} = $_ = strip_ts($_);
115 + $fn{'new'} = $_ if $_ ne '/dev/null' and s{^[^/]*/+}{$destdir/};
117 + unless (defined $fn{'old'} or defined $fn{'new'}) {
118 + error(_g("none of the filenames in ---/+++ are valid in diff '%s' (line %d)"),
122 - if (defined($fn) and $fn eq '/dev/null') {
123 + # Safety checks on both filenames that patch could use
124 + foreach my $key ("old", "new") {
125 + next unless defined $fn{$key};
126 + if ($path{$key} =~ m{/\.\./}) {
127 + error(_g("%s contains an insecure path: %s"), $diff, $path{$key});
129 + my $path = $fn{$key};
132 + error(_g("diff %s modifies file %s through a symlink: %s"),
133 + $diff, $fn{$key}, $path);
135 + last unless $path =~ s{/+[^/]*$}{};
136 + last if length($path) <= length($destdir); # $destdir is assumed safe
140 + if ($path{'old'} eq '/dev/null' and $path{'new'} eq '/dev/null') {
141 error(_g("original and modified files are /dev/null in diff `%s' (line %d)"),
142 - $diff, $.) if (defined($fn2) and $fn2 eq '/dev/null');
144 - } elsif (defined($fn2) and $fn2 ne '/dev/null') {
145 - $fn = $fn2 unless defined $fn;
146 - $fn = $fn2 if ((not -e $fn) and -e $fn2);
147 - } elsif (defined($fn2) and $fn2 eq '/dev/null') {
149 + } elsif ($path{'new'} eq '/dev/null') {
150 error(_g("file removal without proper filename in diff `%s' (line %d)"),
151 - $diff, $. - 1) unless defined $fn;
152 + $diff, $. - 1) unless defined $fn{'old'};
153 warning(_g("diff %s removes a non-existing file %s (line %d)"),
154 - $diff, $fn, $.) unless -e $fn;
155 + $diff, $fn{'old'}, $.) unless -e $fn{'old'};
157 + my $fn = intuit_file_patched($fn{'old'}, $fn{'new'});
160 if ($dirname =~ s{/[^/]+$}{} && not -d $dirname) {
161 $dirtocreate{$dirname} = 1;
164 - # Sanity check, refuse to patch through a symlink
168 - error(_g("diff %s modifies file %s through a symlink: %s"),
169 - $diff, $fn, $dirname);
171 - last unless $dirname =~ s{/[^/]+$}{};
174 if (-e $fn and not -f _) {
175 error(_g("diff `%s' patches something which is not a plain file"), $diff);