lintian: r661 - in trunk: checks debian testset testset/binary/debian
Author: rra
Date: 2006-05-06 23:10:50 +0200 (Sat, 06 May 2006)
New Revision: 661
Modified:
trunk/checks/common_data.pm
trunk/checks/menus
trunk/checks/menus.desc
trunk/debian/changelog
trunk/testset/binary/debian/rules
trunk/testset/tags.binary
Log:
* checks/menus{.desc,}:
+ [RA] Check that all files referenced in doc-base control files are
present in the package, based on a patch by Robert Luberda. Also
check that Index references only one file and that Format names a
known format. (Closes: #196122)
+ [RA] Fix incomplete diagnosis of missing calls to update-menus.
+ [RA] Change postrm to prerm in the check for a useless install-docs
call; calling install-docs in postrm is always a warning and useless
calls in prerm were not being diagnosed.
Modified: trunk/checks/common_data.pm
===================================================================
--- trunk/checks/common_data.pm 2006-05-06 17:05:58 UTC (rev 660)
+++ trunk/checks/common_data.pm 2006-05-06 21:10:50 UTC (rev 661)
@@ -9,6 +9,7 @@
%known_libstdcs %known_tcls %known_tclxs %known_tks %known_tkxs
%known_libpngs %known_x_metapackages
%non_standard_archs %all_cpus %all_oses
+ %known_doc_base_formats
);
# simple defines for commonly needed data
@@ -146,4 +147,8 @@
( 'x-window-system', 'x-window-system-dev', 'x-window-system-core',
'xorg', 'xorg-dev', );
+# Supported documentation formats for doc-base files.
+%known_doc_base_formats = map { $_ => 1 }
+ ( 'html', 'text', 'pdf', 'postscript', 'info', 'dvi', 'debiandoc-sgml' );
+
1;
Modified: trunk/checks/menus
===================================================================
--- trunk/checks/menus 2006-05-06 17:05:58 UTC (rev 660)
+++ trunk/checks/menus 2006-05-06 21:10:50 UTC (rev 661)
@@ -22,10 +22,13 @@
package Lintian::menus;
use strict;
+use common_data;
use Tags;
use Util;
my $pkg;
+my @all_files = ();
+my %all_links = ();
sub run {
@@ -72,7 +75,7 @@
chomp;
my ($perm,$owner,$size,$date,$time,$file) = split(' ', $_, 6);
$file =~ s,^(\./),,;
- my $temp_file = $file; # save this for the link checks to follow
+ add_file_link_info ($file);
$file =~ s/ link to .*//;
$file =~ s/ -> .*//;
@@ -115,6 +118,7 @@
}
}
}
+close IN;
# prerm scripts should not call update-menus
if ($prerm{'calls-updatemenus'}) {
@@ -153,58 +157,96 @@
tag "prerm-does-not-call-installdocs", "$docbase_file";
}
- # does postinst also call update-menus?
- if ($postinst{'calls-updatemenus'}) {
- # is there a menu file or menu-methods files?
- if ($anymenu_file) { # postrm has to call update-menus
- if (not $postrm{'calls-updatemenus'}) {
- tag "postrm-does-not-call-updatemenus", "$anymenu_file" unless $pkg eq 'menu';
- }
- } else { #no!
- tag "postinst-has-useless-call-to-update-menus", "";
- }
- }
-
# check the contents of the doc-base file(s)
opendir DOCBASEDIR, "doc-base" or fail("cannot read doc-base directory.");
while (my $dbfile = readdir DOCBASEDIR) {
- next if -x "doc-base/$dbfile"; # don't try to parse executables, plus we already warned about it
- open IN, "doc-base/$dbfile" or
- fail("cannot open doc-base file $dbfile for reading.");
- while (<IN>) {
- if (/usr\/doc/) {
- tag "doc-base-file-references-usr-doc", "$dbfile";
- }
- }
- close IN;
+ next if -x "doc-base/$dbfile"; # don't try to parse executables, plus we already warned about it
+ open IN, "doc-base/$dbfile" or
+ fail("cannot open doc-base file $dbfile for reading.");
+
+ # Check if files referenced by doc-base are included in the package.
+ # The Index field should refer to only one file without wildcards.
+ # The Files field is a whitespace-separated list of files and may
+ # contain wildcards. We skip without validating wildcard patterns
+ # containing character classes since otherwise we'd need to deal with
+ # wildcards inside character classes and aren't there yet.
+ #
+ # Defer checking files until we've read all possible continuation
+ # lines for the field. As a result, all tags will be reported on the
+ # last continuation line of the field, rather than possibly where the
+ # offending file name is.
+ my (@files, $field);
+ while (1) {
+ $_ = <IN>;
+ if ((!defined ($_) || /^\S/ || /^$/) && $field) {
+ # Figure out the right line number. It's actually the
+ # previous line, since we read ahead for continuation lines,
+ # unless we're at the end of the file.
+ my $line = $. - 1 + (defined ($_) ? 0 : 1);
+ if ($field eq 'index' && @files > 1) {
+ tag "doc-base-index-references-multiple-files", "$dbfile:$line";
+ }
+ for my $file (@files) {
+ if ($file =~ m%^/usr/doc%) {
+ tag "doc-base-file-references-usr-doc", "$dbfile:$line";
+ }
+ my $regex = quotemeta (delink ($file));
+ unless ($field eq 'index') {
+ next if $regex =~ /\[/;
+ $regex =~ s%\\\*%[^/]*%g;
+ $regex =~ s%\\\?%[^/]%g;
+ $regex .= '/?';
+ }
+ unless (grep { /^$regex\z/ } @all_files) {
+ tag "doc-base-file-references-missing-file", "$dbfile:$line", $file;
+ }
+ }
+ undef @files;
+ undef $field;
+ }
+ last unless defined $_;
+ if (/^\s/ && $field) {
+ push (@files, split ' ');
+ }
+ if (/^(Index|Files)\s*:\s*(.*)\s*$/i) {
+ $field = lc $1;
+ @files = split (' ', $2);
+ } elsif (/^Format\s*:\s*(.*)\s*$/i) {
+ my $format = lc $1;
+ tag "doc-base-file-unknown-format", "$dbfile:$.", $format
+ unless $known_doc_base_formats{$format};
+ }
+ }
+ close IN;
}
closedir DOCBASEDIR;
+} else {
+ # postinst and postrm should not need to call install-docs
+ if ($postinst{'calls-installdocs'} or $postinst{'calls-installdocs-r'}) {
+ tag "postinst-has-useless-call-to-install-docs", "";
+ }
+ if ($prerm{'calls-installdocs'} or $prerm{'calls-installdocs-r'}) {
+ tag "prerm-has-useless-call-to-install-docs", "";
+ }
}
-# no docbase file, but menu file?
-elsif ($anymenu_file) { # postinst has to call update-menus
+
+if ($anymenu_file) {
+ # postinst has to call update-menus
if (not $postinst{'calls-updatemenus'}) {
tag "postinst-does-not-call-updatemenus", "$anymenu_file";
}
# postrm has to call update-menus
if (not $postrm{'calls-updatemenus'}) {
- tag "postrm-does-not-call-updatemenus", "$anymenu_file";
+ tag "postrm-does-not-call-updatemenus", "$anymenu_file" unless $pkg eq 'menu';
}
-}
-# no menu files and no doc-base files...
-else {
+} else {
# postinst and postrm should not need to call update-menus
if ($postinst{'calls-updatemenus'}) {
tag "postinst-has-useless-call-to-update-menus", "";
}
- if ($postinst{'calls-installdocs'} or $postinst{'calls-installdocs-r'}) {
- tag "postinst-has-useless-call-to-install-docs", "";
- }
if ($postrm{'calls-updatemenus'}) {
tag "postrm-has-useless-call-to-update-menus", "";
}
- if ($postrm{'calls-installdocs'} or $postrm{'calls-installdocs-r'}) {
- tag "postrm-has-useless-call-to-install-docs", "";
- }
}
}
@@ -235,6 +277,82 @@
return $o;
}
+# Add file and link to %all_files and %all_links. Note that both files and
+# links have to include a leading /.
+sub add_file_link_info {
+ my $file = shift;
+ my $link = undef;
+
+ $file = "/" . $file if (not $file =~ m%^/%); # make file absolute
+ $file =~ s%/+%/%g; # remove duplicated `/'
+ ($file, $link) = split(/ -> /, $file);
+
+ push (@all_files, $file);
+
+ if (defined $link) {
+ if (not $link =~ m,^/,) { # not absolute link
+ $link = "/" . $link; # make sure link starts with '/'
+ $link =~ s,/+\./+,/,g; # remove all /./ parts
+ my $dcount = 1;
+ while ($link =~ s,^/+\.\./+,/,) { #\ count & remove
+ $dcount++; #/ any leading /../ parts
+ }
+ my $f = $file;
+ while ($dcount--) { #\ remove last $dcount
+ $f =~ s,/[^/]*$,,; #/ path components from $file
+ }
+ $link = $f . $link; # now we should have absolute link
+ }
+ $all_links{$file} = $link unless ($link eq $file);
+ }
+}
+
+
+# Dereference all symlinks in file. Uses %all_links.
+sub delink {
+ my $file = shift;
+
+ $file =~ s%/+%/%g; # remove duplicated '/'
+ return $file unless %all_links; # package doesn't symlinks
+
+ my $p1 = "";
+ my $p2 = $file;
+ my %used_links = ();
+
+ # In the loop below we split $file into two parts on each '/' until
+ # there's no remaining slashes. We try substituting the first part with
+ # corresponding symlink and if it succeedes, we start the procedure from
+ # beginning.
+ #
+ # Example:
+ # Let $all_links{"/a/b"} == "/d", and $file == "/a/b/c"
+ # Then 0) $p1 == "", $p2 == "/a/b/c"
+ # 1) $p1 == "/a", $p2 == "/b/c"
+ # 2) $p1 == "/a/b", $p2 == "/c" ; substitute "/d" for "/a/b"
+ # 3) $p1 == "", $p2 == "/d/c"
+ # 4) $p1 == "/d", $p2 == "/c"
+ # 5) $p1 == "/d/c", $p2 == ""
+ #
+ # Note that the algorithm supposes, that
+ # i) $all_links{$X} != $X for each $X
+ # ii) both keys and values of %all_links start with '/'
+
+ while (($p2 =~ s%^(/[^/]*)%%g) > 0) {
+ $p1 .= $1;
+ if (defined $all_links{$p1}) {
+ return '!!! SYMLINK LOOP !!!' if defined $used_links{$p1};
+ $p2 = $all_links{$p1} . $p2;
+ $p1 = "";
+ $used_links{$p1} = 1;
+ }
+ }
+
+ # After the loop $p2 should be empty and $p1 should contain the target
+ # file. In some rare cases when $file contains no slashes, $p1 will be
+ # empty and $p2 will contain the result (which will be equal to $file).
+ return $p1 ne "" ? $p1 : $p2;
+}
+
sub check_script {
my ($script,$pres) = @_;
my ($no_check_menu,$no_check_installdocs,$no_check_wmmenu,$calls_wmmenu);
Modified: trunk/checks/menus.desc
===================================================================
--- trunk/checks/menus.desc 2006-05-06 17:05:58 UTC (rev 660)
+++ trunk/checks/menus.desc 2006-05-06 21:10:50 UTC (rev 661)
@@ -140,9 +140,9 @@
Info: The <tt>postinst</tt> script calls the <tt>install-docs</tt> program
though no file is installed in <tt>/usr/share/doc-base</tt>.
-Tag: postrm-has-useless-call-to-install-docs
+Tag: prerm-has-useless-call-to-install-docs
Type: error
-Info: The <tt>postrm</tt> script calls the <tt>install-docs</tt> program
+Info: The <tt>prerm</tt> script calls the <tt>install-docs</tt> program
though no file is installed in <tt>/usr/share/doc-base</tt>.
Tag: bad-menu-file-name
@@ -156,3 +156,24 @@
Type: warning
Info: Files in <tt>/usr/share/doc-base</tt> should only contain links to
files in the <tt>/usr/share/doc</tt> directory.
+
+Tag: doc-base-index-references-multiple-files
+Type: error
+Info: The Index field in a doc-base file should reference the single index
+ file for that document. Any other files belonging to the same document
+ should be listed in the Files field.
+Ref: Debian doc-base Manual, section 2.3
+
+Tag: doc-base-file-references-missing-file
+Type: error
+Info: One of the files referenced in an Index or Files field in this
+ doc-base control file does not exist in the package. The doc-base
+ control files should be installed by the package that provides the
+ documents they are registering.
+
+Tag: doc-base-file-unknown-format
+Type: warning
+Info: The Format field in this doc-base control file declares a format
+ that is not supported. Recognized formats are "HTML", "Text", "PDF",
+ "PostScript", "Info", "DVI", and "DebianDoc-SGML" (case-insensitive).
+Ref: Debian doc-base Manual, section 2.3
Modified: trunk/debian/changelog
===================================================================
--- trunk/debian/changelog 2006-05-06 17:05:58 UTC (rev 660)
+++ trunk/debian/changelog 2006-05-06 21:10:50 UTC (rev 661)
@@ -28,6 +28,15 @@
require Pre-Depends on x11-common (>= 1:7.0.0). Remove the
duplicate check for files in /usr/bin/X11 since it no longer adds
additional information.
+ * checks/menus{.desc,}:
+ + [RA] Check that all files referenced in doc-base control files are
+ present in the package, based on a patch by Robert Luberda. Also
+ check that Index references only one file and that Format names a
+ known format. (Closes: #196122)
+ + [RA] Fix incomplete diagnosis of missing calls to update-menus.
+ + [RA] Change postrm to prerm in the check for a useless install-docs
+ call; calling install-docs in postrm is always a warning and useless
+ calls in prerm were not being diagnosed.
* checks/shared-libs.desc:
+ [RA] Document that exceptions to the -fPIC rule for shared libraries
are possible and ask that such exceptions be documented with lintian
@@ -41,7 +50,7 @@
+ [RA] Update standards version to 3.7.2 (no changes required).
+ [RA] Update description to note calibration for Policy 3.7.2.
- -- Russ Allbery <rra@debian.org> Sat, 6 May 2006 10:05:37 -0700
+ -- Russ Allbery <rra@debian.org> Sat, 6 May 2006 14:08:15 -0700
lintian (1.23.19) unstable; urgency=low
Modified: trunk/testset/binary/debian/rules
===================================================================
--- trunk/testset/binary/debian/rules 2006-05-06 17:05:58 UTC (rev 660)
+++ trunk/testset/binary/debian/rules 2006-05-06 21:10:50 UTC (rev 661)
@@ -25,11 +25,18 @@
strip --remove-section=.comment --remove-section=.note $(tmp)/boot/hello/hello-static
install -d $(tmp)/usr/share/doc/binary
install -m 644 INSTALL $(tmp)/usr/share/doc/binary
+ install -d $(tmp)/usr/share/doc/binary/html
+ echo '<html></html>' > $(tmp)/usr/share/doc/binary/html/index.html
+ echo '<html></html>' > $(tmp)/usr/share/doc/binary/html/ch1.html
+ ln -s ../html/./ch1.html $(tmp)/usr/share/doc/binary/html/ch2.html
+ ln -s /usr/share/doc/binary/htm/ch1.html $(tmp)/usr/share/doc/binary/html/ch3.html
install -d $(tmp)/usr/share/menu
install -d $(tmp)/usr/lib/menu
install -d $(tmp)/usr/share/binary
install -m 644 debian/menu $(tmp)/usr/share/menu/binary
install -m 644 debian/menu $(tmp)/usr/lib/menu/binary
+ install -d $(tmp)/usr/share/doc-base
+ install -m 644 debian/doc-base $(tmp)/usr/share/doc-base/binary
install -m 644 debian/README.Debian $(tmp)/usr/share/doc/binary
install -m 644 debian/copyright $(tmp)/usr/share/doc/binary
install -m 644 debian/changelog $(tmp)/usr/share/doc/binary
Modified: trunk/testset/tags.binary
===================================================================
--- trunk/testset/tags.binary 2006-05-06 17:05:58 UTC (rev 660)
+++ trunk/testset/tags.binary 2006-05-06 21:10:50 UTC (rev 661)
@@ -2,19 +2,29 @@
E: binary: changelog-file-not-compressed changelog
E: binary: debian-changelog-file-missing-or-wrong-name
E: binary: depends-on-x-metapackage depends: xorg
+E: binary: doc-base-file-references-missing-file binary:10 /usr/share/doc/binary/binary.sgml.gz
+E: binary: doc-base-file-references-missing-file binary:14 /usr/share/doc/binary/binary.txt
+E: binary: doc-base-file-references-missing-file binary:18 /usr/share/doc/binary/html/ch4.html
+E: binary: doc-base-file-references-missing-file binary:23 /usr/share/doc/binary/hml/*.html
+E: binary: doc-base-index-references-multiple-files binary:18
E: binary: file-directly-in-usr-share usr/share/baz
+E: binary: lengthy-symlink usr/share/doc/binary/html/ch2.html ../html/./ch1.html
E: binary: menu-item-missing-required-tag section /usr/lib/menu/binary:1
E: binary: menu-item-missing-required-tag section /usr/share/menu/binary:1
E: binary: non-wm-in-windowmanager-menu-section x11 /usr/lib/menu/binary:4
E: binary: non-wm-in-windowmanager-menu-section x11 /usr/share/menu/binary:4
+E: binary: postinst-does-not-call-installdocs usr/share/doc-base/binary
E: binary: postinst-does-not-call-updatemenus usr/lib/menu/binary
E: binary: postrm-does-not-call-updatemenus usr/lib/menu/binary
+E: binary: prerm-does-not-call-installdocs usr/share/doc-base/binary
E: binary: statically-linked-binary ./usr/bin/static-hello
E: binary: su-to-root-without--c /usr/lib/menu/binary:2
E: binary: su-to-root-without--c /usr/lib/menu/binary:3
E: binary: su-to-root-without--c /usr/share/menu/binary:2
E: binary: su-to-root-without--c /usr/share/menu/binary:3
E: binary: suidregister-used-in-maintainer-script postinst
+E: binary: symlink-contains-spurious-segments usr/share/doc/binary/html/ch2.html ../html/./ch1.html
+E: binary: symlink-should-be-relative usr/share/doc/binary/html/ch3.html /usr/share/doc/binary/htm/ch1.html
E: binary: unstripped-binary-or-object ./usr/bin/hello
I: binary source: non-standard-architecture amd64
I: binary source: non-standard-architecture kfreebsd-i386
@@ -29,6 +39,7 @@
W: binary: binary-without-manpage hello.static
W: binary: binary-without-manpage iminusrbin
W: binary: binary-without-manpage static-hello
+W: binary: doc-base-file-unknown-format binary:13 esp
W: binary: executable-not-elf-or-script ./usr/bin/iminusrbin
W: binary: file-in-unusual-dir usr/bar
W: binary: menu-command-not-in-package /usr/lib/menu/binary:6 /imnothere
Reply to: