On 2013-08-06 03:03, Guillem Jover wrote: > Hi! > > [...] > > Actually, “_” members can be inserted before data.tar and after > debian-binary (which is the only member with a hardcoded index), so > control.tar.gz might not be the second (absolute) member. I guess this > was not really clear from the deb(5) man page, so I'll try to clarify it. > > (I also just noticed dpkg-deb does not enforce control.tar > data.tar > index order :/, I'll be fixing this for 1.17.2 too…) > > Thanks, > Guillem > >
Okay, I got a revised patch that should be able to cope with "_" members before control.tar.gz as well. ~Niels
>From 65369b07cd8e0d602c70a122a96016dbcfcb4d6f Mon Sep 17 00:00:00 2001 From: Niels Thykier <ni...@thykier.net> Date: Mon, 5 Aug 2013 23:39:01 +0200 Subject: [PATCH] c/deb-format: Add new tag for "extra" deb members Add a separate tag for "extra" members in deb files that are permitted by the format (as described by deb(5)). Signed-off-by: Niels Thykier <ni...@thykier.net> --- checks/deb-format.desc | 7 +++ checks/deb-format.pm | 103 +++++++++++++++++++++++++++++++----- data/deb-format/extra-members | 16 ++++++ debian/changelog | 10 +++- t/debs/deb-format-extra-member/desc | 2 +- t/debs/deb-format-extra-member/tags | 2 +- t/debs/deb-format-wrong-order/tags | 2 +- 7 files changed, 125 insertions(+), 17 deletions(-) create mode 100644 data/deb-format/extra-members diff --git a/checks/deb-format.desc b/checks/deb-format.desc index d28f615..8a4f214 100644 --- a/checks/deb-format.desc +++ b/checks/deb-format.desc @@ -17,6 +17,13 @@ Info: The binary package is not a correctly constructed archive. A binary of 2. Ref: deb(5) +Tag: misplaced-extra-member-in-deb +Severity: important +Certainty: certain +Info: The binary package contains an extra member that Lintian did not + expect or expected at a different position. +Ref: deb(5) + Tag: lzma-deb-archive Severity: serious Certainty: certain diff --git a/checks/deb-format.pm b/checks/deb-format.pm index 5ea1995..6485f77 100644 --- a/checks/deb-format.pm +++ b/checks/deb-format.pm @@ -20,7 +20,10 @@ use strict; use warnings; use autodie; +use List::MoreUtils qw(first_index none); + use Lintian::Command qw(spawn); +use Lintian::Data; use Lintian::Tags qw(tag); # The files that contain error messages from tar, which we'll check and issue @@ -33,6 +36,8 @@ our %ERRORS = ( 'unpacked-errors' => 'tar-errors-from-data' ); +my $EXTRA_MEMBERS = Lintian::Data->new('deb-format/extra-members'); + sub run { my (undef, $type, $info) = @_; my $deb = $info->lab_data_path('deb'); @@ -43,25 +48,97 @@ sub run { my $success = spawn($opts, ['ar', 't', $deb]); if ($success) { my @members = split("\n", ${ $opts->{out} }); - if (@members != 3) { - my $count = scalar(@members); - tag 'malformed-deb-archive',"found $count members instead of 3"; + my $count = scalar(@members); + my ($ctrl_member, $data_member); + if ($count < 3) { + tag 'malformed-deb-archive', + "found only $count members instead of 3"; } elsif ($members[0] ne 'debian-binary') { tag 'malformed-deb-archive', "first member $members[0] not debian-binary"; - } elsif ($members[1] ne 'control.tar.gz') { - tag 'malformed-deb-archive', - "second member $members[1] not control.tar.gz"; - } elsif ($type eq 'udeb' && $members[2] !~ m/^data\.tar\.[gx]z$/) { - tag 'udeb-uses-unsupported-compression-for-data-tarball'; - } elsif ($members[2] eq 'data.tar.lzma') { - # Ubuntu's archive allows lzma packages. - tag 'lzma-deb-archive'; - } elsif ($members[2] !~ /^data\.tar\.(?:gz|bz2|xz)\z/) { + } elsif ($count == 3 and none { + substr($_, 0, 1) eq '_'; + } + @members + ) { + # Fairly common case - if there are only 3 members without + # "_", we can trivially determine their (expected) + # positions. We only use this case when there are no + # "extra" members, because they can trigger more tags + # (see below) + (undef, $ctrl_member, $data_member) = @members; + } else { + my $ctrl_index + = first_index { substr($_, 0, 1) ne '_' } @members[1..$#members]; + my $data_index; + + if ($ctrl_index != -1) { + # Since we searched only a sublist of @members, we have to + # add 1 to $ctrl_index + $ctrl_index++; + $ctrl_member = $members[$ctrl_index]; + $data_index = first_index { substr($_, 0, 1) ne '_' } + @members[$ctrl_index..$#members]; + if ($data_index != -1) { + # Since we searched only a sublist of @members, we + # have to adjust $data_index + $data_index += $ctrl_index + 1; + $data_member = $members[$data_index]; + } + } + + # Extra members + for my $i (1..$#members) { + my $member = $members[$i]; + my $actual_index = $i; + my ($expected, $text); + next if $i == $ctrl_index or $i == $data_index; + $expected = $EXTRA_MEMBERS->value($member); + if (defined($expected)) { + next if $expected eq 'ANYWHERE'; + next if $expected == $actual_index; + $text = "expected at position $expected, but appeared"; + } else { + $text = 'unexpected member'; + } + tag 'misplaced-extra-member-in-deb', + "$member ($text at position $actual_index)"; + } + } + if (not defined($ctrl_member)) { + # Somehow I doubt we will ever get this far without a control + # file... :) + tag 'malformed-deb-archive', 'Missing control.tar.gz member'; + } elsif ($ctrl_member ne 'control.tar.gz') { tag 'malformed-deb-archive', - "third member $members[2] not data.tar.(gz|bz2|xz)"; + "second (official) member $ctrl_member not control.tar.gz"; + } elsif (not defined($data_member)) { + # Somehow I doubt we will ever get this far without a data + # member (i.e. I suspect unpacked and index will fail), but + # mah + tag 'malformed-deb-archive', 'Missing data.tar member'; } else { + # Probably okay $okay = 1; + if ( + $data_member !~ m/\A + data\.tar(?:\.(?:gz|bz2|xz|lzma))? \Z/xsm + ) { + # wasn't okay after all + $okay = 0; + } elsif ($type eq 'udeb' + && $data_member !~ m/^data\.tar\.[gx]z$/) { + tag 'udeb-uses-unsupported-compression-for-data-tarball'; + } elsif ($data_member eq 'data.tar.lzma') { + # Ubuntu's archive allows lzma packages. + tag 'lzma-deb-archive'; + } + if (not $okay) { + tag 'malformed-deb-archive', + join(' ', + "third (official) member $data_member", + 'not data.tar.(gz|bz2|xz)'); + } } } else { # unpack will probably fail so we'll never get here, but may as well be diff --git a/data/deb-format/extra-members b/data/deb-format/extra-members new file mode 100644 index 0000000..23d298f --- /dev/null +++ b/data/deb-format/extra-members @@ -0,0 +1,16 @@ +# List of extra members permitted in the .deb files +# +# Format is: +# <name> => <position> +# +# +# <position> is a 0-indexed position of where the extra member is +# expected. It can be "ANYWHERE" if the order is not relevant. Note +# despite of the value of <position>, any member appearing before the +# data.tar member MUST have a name starting with "_". If not Lintian +# will presume it is the control.tar or the data.tar member (depending +# on how early it occurs). It is impossible for any valid "2.0" deb +# file to have an extra member at position 0 (which is exclusively +# reserved for the "debian-binary" member) +# +# For Debian, no extra members are defined, so the file is empty atm. diff --git a/debian/changelog b/debian/changelog index bbd923e..239c795 100644 --- a/debian/changelog +++ b/debian/changelog @@ -7,7 +7,15 @@ lintian (2.5.18) UNRELEASED; urgency=low (Closes: #721252) + [BR] Extend tag description of the gfdl-invariants tag. (Closes: #722102) - * checks/files.{pm,desc}: + * checks/deb-format.{desc,pm}: + + [NT] Allow data.tar members in deb files. Thanks to + Guillem Jover for the report. + + [NT] Support (but tag) unofficial members after the + "debian-binary" member where allowed by dpkg. These + members will trigger misplaced-extra-member-in-deb tag. + Thanks to Guillem Jover for the report and the feedback. + (Closes: #718349) + * checks/files.{desc,pm}: + [BR] Fix false-positive dir-or-file-in-build-tree for the sbuild source package. (Closes: #720910) + [NT] Add check for empty udeb packages. Thanks to Cyril diff --git a/t/debs/deb-format-extra-member/desc b/t/debs/deb-format-extra-member/desc index c5f24b7..3d55144 100644 --- a/t/debs/deb-format-extra-member/desc +++ b/t/debs/deb-format-extra-member/desc @@ -2,4 +2,4 @@ Testname: deb-format-extra-member Sequence: 6000 Version: 1.0 Description: Test package for an ar archive in the wrong order -Test-For: malformed-deb-archive +Test-For: misplaced-extra-member-in-deb diff --git a/t/debs/deb-format-extra-member/tags b/t/debs/deb-format-extra-member/tags index 6e19acf..30c21d6 100644 --- a/t/debs/deb-format-extra-member/tags +++ b/t/debs/deb-format-extra-member/tags @@ -1 +1 @@ -E: deb-format-extra-member: malformed-deb-archive found 4 members instead of 3 +E: deb-format-extra-member: misplaced-extra-member-in-deb extra-stuff (unexpected member at position 3) diff --git a/t/debs/deb-format-wrong-order/tags b/t/debs/deb-format-wrong-order/tags index aafecf5..10abed7 100644 --- a/t/debs/deb-format-wrong-order/tags +++ b/t/debs/deb-format-wrong-order/tags @@ -1 +1 @@ -E: deb-format-wrong-order: malformed-deb-archive second member data.tar.gz not control.tar.gz +E: deb-format-wrong-order: malformed-deb-archive second (official) member data.tar.gz not control.tar.gz -- 1.8.4.rc3