[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: