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

Bug#620829: [new checks] implements parts of the java policy



Package: lintian
Version: 2.5.0~rc1
Severity: wishlist
Tags: patch

  Hello,

  Currently lintian does not cover at all the java packaging policy,
and that's probably one of the reasons why it is not very well
respected (especially since there are some quite devious tricks
there).

  I have started an implementation of that in a clone of the git
repository. I have attached a patch containing some of my work. Please
note that this patch addresses #575447 but also a lot more.

  I plan to go on working on that, if that's fine by you. Anyway,
there are a lot of things that still need to be implemented. What is
the workflow of the lintian team ?  Shall I send you regularly batches
of git format-patch ? (which I haven't done this time). How can I
actually join the lintian team ?

  Cheers,

	Vincent

-- System Information:
Debian Release: wheezy/sid
  APT prefers unstable
  APT policy: (500, 'unstable'), (500, 'testing'), (500, 'stable'), (1, 'experimental')
Architecture: amd64 (x86_64)

Kernel: Linux 2.6.38-2-amd64 (SMP w/2 CPU cores)
Locale: LANG=en_GB.utf8, LC_CTYPE=en_GB.utf8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages lintian depends on:
ii  binutils               2.21.0.20110327-2 The GNU assembler, linker and bina
ii  diffstat               1.54-1            produces graph of changes introduc
ii  dpkg-dev               1.16.0            Debian package development tools
ii  file                   5.04-5            Determines file type using "magic"
ii  gettext                0.18.1.1-3        GNU Internationalization utilities
ii  intltool-debian        0.35.0+20060710.1 Help i18n of RFC822 compliant conf
ii  libapt-pkg-perl        0.1.24+b1         Perl interface to libapt-pkg
ii  libclass-accessor-perl 0.34-1            Perl module that automatically gen
ii  libemail-valid-perl    0.184-1           Perl module for checking the valid
ii  libipc-run-perl        0.89-1            Perl module for running processes
ii  libparse-debianchangel 1.1.1-2.1         parse Debian changelogs and output
ii  libtimedate-perl       1.2000-1          collection of modules to manipulat
ii  liburi-perl            1.58-1            module to manipulate and access UR
ii  locales                2.11.2-13         Embedded GNU C Library: National L
ii  man-db                 2.5.9-4           on-line manual pager
ii  perl [libdigest-sha-pe 5.10.1-19         Larry Wall's Practical Extraction 

lintian recommends no packages.

Versions of packages lintian suggests:
pn  binutils-multiarch            <none>     (no description available)
pn  libtext-template-perl         <none>     (no description available)
ii  man-db                        2.5.9-4    on-line manual pager

-- no debconf information
diff --git a/checks/java b/checks/java
new file mode 100644
index 0000000..9aabf2a
--- /dev/null
+++ b/checks/java
@@ -0,0 +1,115 @@
+# java -- lintian check script -*- perl -*-
+
+# Copyright (C) 2011 Vincent Fourmond
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, you can find it on the World Wide
+# Web at http://www.gnu.org/copyleft/gpl.html, or write to the Free
+# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+# MA 02110-1301, USA.
+
+package Lintian::java;
+use strict;
+use warnings;
+
+use lib "$ENV{'LINTIAN_ROOT'}/checks/";
+use common_data;
+
+use Lintian::Tags qw(tag);
+use Util;
+
+use File::Basename qw(fileparse);
+
+
+# The packages that are necessary to directly run an executable JAR
+# file.
+our @jarwrapper_or_equivalent = (
+    'jarwrapper'
+    );
+
+sub run {
+
+my $pkg = shift;
+my $type = shift;
+my $info = shift;
+
+my $java_info = $info->java_info;
+my $missing_jarwrapper = 0;
+
+# We first loop over jar files to find problems
+
+for my $jar_file (keys %{$java_info}) {
+    my $manifest = $java_info->{$jar_file};
+
+    if($manifest->{'Manifest-Version'}) {
+	# We do have a real JAR with a real manifest.
+
+	my $operm = $info->{index}->{$jar_file}->{operm};
+	if(($operm & 01 or
+	    $operm & 010 or $operm & 0100)) {
+	    # Executable ?
+	    tag "executable-jar-without-main-class", "$jar_file" unless
+		$manifest->{'Main-Class'};
+
+	    # Here, we need to check that the package depends on
+	    # jarwrapper.
+	    my $ok = 0;
+
+	    for my $p (@jarwrapper_or_equivalent) {
+		my $depends = Lintian::Relation->new($p);
+		if($info->relation('strong')->
+		   implies($depends)) {
+		    $ok = 1;
+		    last;
+		}
+	    }
+	    $missing_jarwrapper = 1 unless ($ok);
+	}
+	elsif ($jar_file !~ m#^usr/share/(java|$pkg)/#) {
+	    tag "jar-not-in-usr-share", "$jar_file";
+	}
+    }
+
+    my $cp = $manifest->{'Class-Path'};
+
+    my $relative = 0;
+    my $outside_usr_share = 0;
+    my @paths = split(/\s+/, $cp);
+    for my $p (@paths) {
+	if($p) {
+	    if($p !~ m#^/#) {
+		$relative++;
+	    }
+	    elsif($p !~ m#/usr/share/#) {
+		$outside_usr_share++;
+	    }
+	}
+    }
+
+    if($relative) {
+	tag "classpath-contains-relative-path", "$jar_file: $cp";
+    }
+
+    if($outside_usr_share) {
+	tag "classpath-contains-files-not-in-usr-share", "$jar_file: $cp";
+    }
+    
+    
+   }
+
+if($missing_jarwrapper) {
+    tag 'missing-dep-on-jarwrapper';
+}
+
+}
+1;
diff --git a/checks/java.desc b/checks/java.desc
new file mode 100644
index 0000000..e1781b9
--- /dev/null
+++ b/checks/java.desc
@@ -0,0 +1,44 @@
+Check-Script: java
+Author: Vincent Fourmond <fourmond@debian.org>
+Abbrev: java
+Type: binary
+Needs-Info: java-info
+Info: This script checks if the packages comply with various aspects of the
+ debian Java policy.
+
+Tag: classpath-contains-relative-path
+Severity: normal
+Certainty: certain
+Info: The classpath listed in some of the files references relative paths,
+ which should never be needed in a system JAR, especially as far as
+ security is concerned.
+
+Tag: classpath-contains-files-not-in-usr-share
+Severity: normal
+Certainty: certain
+Info: The classpath listed in some of the files references files outside
+ of /usr/share, while all installed JAR files must be within
+ /usr/share/java for libraries or /usr/share/<i>package</i> for JARs for
+ private use.
+
+Tag: jar-not-in-usr-share
+Severity: serious
+Certainty: certain
+Ref: java sub-policy 2.2 and 2.3
+Info: The classpath listed in some of the files references files outside
+ of /usr/share, while all installed JAR files must be within
+ /usr/share/java for libraries or /usr/share/<i>package</i> for JARs for
+ private use.
+
+Tag: executable-jar-without-main-class
+Severity: serious
+Certainty: certain
+Ref: java sub-policy 2.2
+Info: An executable JAR must have a Main-Class set in its manifest.
+
+Tag: missing-dep-on-jarwrapper
+Severity: serious
+Certainty: certain
+Ref: java sub-policy 2.2
+Info: Packages containing an executable JAR must depend on jarwrapper or
+ other packages providing similar functionalities.
\ No newline at end of file
diff --git a/collection/java-info b/collection/java-info
new file mode 100755
index 0000000..fb90739
--- /dev/null
+++ b/collection/java-info
@@ -0,0 +1,75 @@
+#!/usr/bin/perl -w
+# java-info -- lintian collection script
+
+# Copyright (C) 2011 Vincent Fourmond
+# 
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, you can find it on the World Wide
+# Web at http://www.gnu.org/copyleft/gpl.html, or write to the Free
+# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+# MA 02110-1301, USA.
+
+use strict;
+use warnings;
+
+# Sanity check
+unless (-f 'fields/package') {
+    print STDERR 'error: collection script called in wrong directory!\n';
+    exit 2;
+}
+
+my $failed = 0;
+
+
+open (INDEX, '<', 'index')
+    or fail("cannot open index: $!");
+
+open (OUT, '>', 'java-info')
+    or fail("cannot open java-info: $!");
+
+chdir ('unpacked')
+    or fail ("unable to chdir to unpacked: $!\n");
+
+while (<INDEX>) {
+    chomp;
+    $_ = (split(' ', $_, 6))[5];
+    next if / -> .*/;		# We skip symlinks.
+    if (m#(\S+).jar$#i) {
+	my $file = $_;
+
+	# This script needs unzip, there's no way around.
+	print OUT "-- $file\n";
+	
+	open MANIFEST, "unzip -p \"$file\" META-INF/MANIFEST.MF | ";
+	my $first = 1;
+	while(my $line = <MANIFEST>) {
+	    chomp $line;
+	    $line =~ s/\r//g;
+	    if($line =~ /^(\S+:)\s*(.*)/) {
+		print OUT "\n" unless $first;
+		$first = 0;
+		print OUT "  $1 $2";
+	    }
+	    if($line =~ /^ (.*)/) {
+		print OUT "$1";
+	    }
+	}
+	close MANIFEST;
+	print OUT "\n" unless $first;
+    }
+}
+
+close INDEX;
+close OUT or fail("cannot write java-info: $!");
+
+exit $failed;
diff --git a/collection/java-info.desc b/collection/java-info.desc
new file mode 100644
index 0000000..6f93b69
--- /dev/null
+++ b/collection/java-info.desc
@@ -0,0 +1,6 @@
+Collector-Script: java-info
+Author: Vincent Fourmond <fourmond@debian.org>
+Info: This script extracts information from manifests of JAR files
+Type: binary, udeb
+Version: 1
+Needs-Info: unpacked
diff --git a/debian/control b/debian/control
index bf628cf..aebe7e5 100644
--- a/debian/control
+++ b/debian/control
@@ -51,6 +51,7 @@ Depends: ${misc:Depends},
          diffstat,
          dpkg-dev,
          file,
+	 unzip,
          gettext,
          intltool-debian,
          libapt-pkg-perl,
diff --git a/lib/Lintian/Collect/Binary.pm b/lib/Lintian/Collect/Binary.pm
index 2dd6b58..0f328b9 100644
--- a/lib/Lintian/Collect/Binary.pm
+++ b/lib/Lintian/Collect/Binary.pm
@@ -287,6 +287,32 @@ sub objdump_info {
     return $self->{objdump_info};
 }
 
+
+# Returns the information from collect/objdump-info
+sub java_info {
+    my ($self) = @_;
+    return $self->{java_info} if exists $self->{java_info};
+
+    my %java_info;
+    open(my $idx, '<', 'java-info')
+        or fail("cannot open java-info: $!");
+    my $file;
+    while (<$idx>) {
+        chomp;
+        next if m/^\s*$/o;
+
+        if (m#^-- \./(.+)$#) {
+            $file = $1;
+            $java_info{$file} = {};
+        }
+        elsif (m#^  (\S+):\s(.*)$#) {
+            $java_info{$file}->{$1} = $2;
+        }
+    }
+    $self->{java_info} = \%java_info;
+    return $self->{java_info};
+}
+
 # Return a Lintian::Relation object for the given relationship field.  In
 # addition to all the normal relationship fields, the following special
 # field names are supported: all (pre-depends, depends, recommends, and

Reply to: