lintian: r1113 - in trunk: checks debian testset testset/scripts testset/scripts/debian
Author: rra
Date: 2008-01-05 06:57:31 +0100 (Sat, 05 Jan 2008)
New Revision: 1113
Added:
trunk/testset/scripts/jruby-broken
trunk/testset/scripts/sh-broken
Modified:
trunk/checks/scripts
trunk/checks/scripts.desc
trunk/debian/changelog
trunk/testset/scripts/debian/rules
trunk/testset/tags.scripts
Log:
* checks/scripts{.desc,}:
+ [RA] Rewrite script path and dependency checking. Remove scripts
and packages no longer in the archive. Add new versions of
versioned scripts and packages. Fix the dependencies for pike
interpreters. (Closes: #458896)
+ [RA] Reformat long descriptions and collapse some tags.
+ [RA] For consistent results, only syntax-check sh and bash scripts.
Also ignore all dpatch files, not just those in /usr/src.
Modified: trunk/checks/scripts
===================================================================
--- trunk/checks/scripts 2008-01-05 05:51:39 UTC (rev 1112)
+++ trunk/checks/scripts 2008-01-05 05:57:31 UTC (rev 1113)
@@ -28,170 +28,145 @@
use Tags;
use Util;
-sub run {
+# This is a map of all known interpreters. The key is the interpreter name
+# (the binary invoked on the #! line). The value is an anonymous array of one
+# or two elements. The first, mandatory argument is the path on a Debian
+# system where that interpreter would be installed. The second, optional
+# argument is the dependency that provides that interpreter. If the second
+# argument isn't given, the package name is assumed to be the same as the
+# interpreter name. (Saves some typing.)
+#
+# Some interpreters list empty dependencies (as opposed to undefined ones).
+# Those interpreters should not have any dependency for one reason or another
+# (usually because they're essential packages or aren't used in a normal way).
+#
+# Do not list versioned patterns here (such as pythonX.Y, rubyX.Y, etc.). For
+# those, see %versioned_interpreters below.
+our %interpreters =
+ (ash => [ '/bin' ],
+ awk => [ '/usr/bin', '' ],
+ bash => [ '/bin', '' ],
+ bltwish => [ '/usr/bin', 'blt' ],
+ csh => [ '/bin', 'tcsh | csh | c-shell' ],
+ dash => [ '/bin' ],
+ expect => [ '/usr/bin' ],
+ expectk => [ '/usr/bin' ],
+ fish => [ '/usr/bin' ],
+ gawk => [ '/usr/bin' ],
+ gbr2 => [ '/usr/bin', 'gambas2-runtime' ],
+ gbx => [ '/usr/bin', 'gambas-runtime' ],
+ gbx2 => [ '/usr/bin', 'gambas2-runtime' ],
+ gforth => [ '/usr/bin' ],
+ gnuplot => [ '/usr/bin' ],
+ gosh => [ '/usr/bin', 'gauche' ],
+ 'install-menu' => [ '/usr/bin', '' ],
+ jed => [ '/usr/bin' ],
+ 'jed-script' => [ '/usr/bin', 'jed | xjed' ],
+ ksh => [ '/bin', 'mksh | pdksh' ],
+ lefty => [ '/usr/bin', 'graphviz' ],
+ magicfilter => [ '/usr/sbin' ],
+ make => [ '/usr/bin', 'make | build-essential' ],
+ mawk => [ '/usr/bin' ],
+ ocamlrun => [ '/usr/bin', 'ocaml | ocaml-base-nox' ],
+ pagsh => [ '/usr/bin', 'openafs-client | heimdal-clients' ],
+ parrot => [ '/usr/bin' ],
+ perl => [ '/usr/bin', '' ],
+ python => [ '/usr/bin', 'python | python-minimal' ],
+ pforth => [ '/usr/bin' ],
+ rc => [ '/usr/bin' ],
+ regina => [ '/usr/bin', 'regina-rexx' ],
+ rexx => [ '/usr/bin', 'regina-rexx' ],
+ ruby => [ '/usr/bin' ],
+ runhugs => [ '/usr/bin', 'hugs | hugs98' ],
+ sed => [ '/bin', '' ],
+ sh => [ '/bin', '' ],
+ slsh => [ '/usr/bin' ],
+ speedy => [ '/usr/bin', 'speedy-cgi-perl' ],
+ tcl => [ '/usr/bin', 'tclx8.3' ],
+ tcsh => [ '/usr/bin' ],
+ tixwish => [ '/usr/bin', 'tix' ],
+ trs => [ '/usr/bin', 'konwert' ],
+ xjed => [ '/usr/bin', 'xjed' ],
+ yforth => [ '/usr/bin', 'yforth' ],
+ zsh => [ '/bin' ],
+ );
-# Don't forget to edit the scripts.desc file if you change these!
+# The more complex case of interpreters that may have a version number.
+#
+# This is a hash from the base interpreter name to a list. The base
+# interpreter name may appear by itself or followed by some combination of
+# dashes, digits, and periods. The values are the directory in which the
+# interpreter is found, the dependency to add for a version-less interpreter,
+# a regular expression to match versioned interpreters and extract the version
+# number, the package dependency for a versioned interpreter, and the list of
+# known versions.
+#
+# An interpreter with a version must have a dependency on the specific package
+# formed by taking the fourth element of the list and replacing $1 with the
+# version number. An interpreter without a version is rejected if the second
+# element is undef; otherwise, the package must depend on the disjunction of
+# the second argument (if non-empty) and all the packages formed by taking the
+# list of known versions (the fifth element and on) and replacing $1 in the
+# fourth argument with them.
+#
+# For example:
+#
+# lua => [ '/usr/bin', 'lua', qr/^lua([\d.]+)$/, 'lua$1', qw(40 50 5.1) ]
+#
+# says that any lua interpreter must be in /usr/bin, a package using
+# /usr/bin/lua50 must depend on lua50, and a package using just /usr/bin/lua
+# must satisfy lua | lua40 | lusa50 | lua5.1.
+#
+# The list of known versions is the largest maintenance headache here, but
+# it's only used for the unversioned dependency handling, and then only when
+# someone uses the unversioned script but depends on a specific version for
+# some reason. So it's not a huge problem if it's a little out of date.
+our %versioned_interpreters =
+ (guile => [ '/usr/bin', 'guile',
+ qr/^guile-([\d.]+)$/, 'guile-$1', qw(1.6 1.8)
+ ],
+ jruby => [ '/usr/bin', undef,
+ qr/^jruby([\d.]+)$/, 'jruby$1', qw(0.9 1.0)
+ ],
+ lua => [ '/usr/bin', 'lua',
+ qr/^lua([\d.]+)$/, 'lua$1', qw(40 50 5.1)
+ ],
+ octave => [ '/usr/bin', 'octave',
+ qr/^octave([\d.]+)$/, 'octave$1', qw(2.1 2.9 3.0)
+ ],
+ php => [ '/usr/bin', '',
+ qr/^php(\d+)$/, 'php$1-cli', qw(5)
+ ],
+ pike => [ '/usr/bin', '',
+ qr/^pike([\d.]+)$/, 'pike$1 | pike$1-core', qw(7.6 7.7)
+ ],
+ python => [ '/usr/bin', undef,
+ qr/^python([\d.]+)$/, 'python$1 | python$1-minimal',
+ qw(2.4 2.5)
+ ],
+ ruby => [ '/usr/bin', undef,
+ qr/^ruby([\d.]+)$/, 'ruby$1', qw(1.8 1.9)
+ ],
+ scsh => [ '/usr/bin', 'scsh',
+ qr/^scsh-([\d.]+)$/, 'scsh-$1', qw(0.6)
+ ],
+ tclsh => [ '/usr/bin', 'tclsh',
+ qr/^tclsh([\d.]+)$/, 'tcl$1', qw(8.3 8.4 8.5)
+ ],
+ wish => [ '/usr/bin', 'wish',
+ qr/^wish([\d.]+)$/, 'tk$1', qw(8.3 8.4 8.5)
+ ],
+ );
-my %valid_interpreters = (
- 'ash' => '/bin/ash',
- 'awk' => '/usr/bin/awk',
- 'bash' => '/bin/bash',
- 'bltwish' => '/usr/bin/bltwish',
- 'burlap' => '/usr/bin/burlap',
- 'csh' => '/bin/csh',
- 'dash' => '/bin/dash',
- 'expect' => '/usr/bin/expect',
- 'expectk' => '/usr/bin/expectk',
- 'fish' => '/usr/bin/fish',
- 'gawk' => '/usr/bin/gawk',
- 'gbr2' => '/usr/bin/gbr2',
- 'gbx' => '/usr/bin/gbx',
- 'gbx2' => '/usr/bin/gbx2',
- 'gforth' => '/usr/bin/gforth',
- 'gnuplot' => '/usr/bin/gnuplot',
- 'gosh' => '/usr/bin/gosh',
- 'guile' => '/usr/bin/guile',
- 'install-menu' => '/usr/bin/install-menu',
- 'jed' => '/usr/bin/jed',
- 'jed-script' => '/usr/bin/jed-script',
- 'jruby0.9' => '/usr/bin/jruby0.9',
- 'jruby1.0' => '/usr/bin/jruby1.0',
- 'js' => '/usr/bin/js',
- 'kforth' => '/usr/bin/kforth',
- 'ksh' => '/bin/ksh',
- 'lefty' => '/usr/bin/lefty',
- 'lua40' => '/usr/bin/lua40',
- 'lua50' => '/usr/bin/lua50',
- 'lua5.1' => '/usr/bin/lua5.1',
- 'magicfilter' => '/usr/sbin/magicfilter',
- 'make' => '/usr/bin/make',
- 'mawk' => '/usr/bin/mawk',
- 'nawk' => '/usr/bin/nawk',
- 'ocaml' => '/usr/bin/ocamlrun',
- 'ocamlrun' => '/usr/bin/ocamlrun',
- 'octave' => '/usr/bin/octave',
- 'pagsh' => '/usr/bin/pagsh',
- 'parrot' => '/usr/bin/parrot',
- 'perl' => '/usr/bin/perl',
- 'perl-5.005' => '/usr/bin/perl-5.005',
- 'perl-5.004' => '/usr/bin/perl-5.004',
- 'pforth' => '/usr/bin/pforth',
- 'php' => '/usr/bin/php',
- 'php3' => '/usr/bin/php3',
- 'php4' => '/usr/bin/php4',
- 'php5' => '/usr/bin/php5',
- 'pike' => '/usr/bin/pike',
- 'pike7' => '/usr/bin/pike7',
- 'pike7.6' => '/usr/bin/pike7.6',
- 'python' => '/usr/bin/python',
- 'python1.5' => '/usr/bin/python1.5',
- 'python2.1' => '/usr/bin/python2.1',
- 'python2.2' => '/usr/bin/python2.2',
- 'python2.3' => '/usr/bin/python2.3',
- 'python2.4' => '/usr/bin/python2.4',
- 'python2.5' => '/usr/bin/python2.5',
- 'rexx' => '/usr/bin/rexx',
- 'regina' => '/usr/bin/regina',
- 'rc' => '/usr/bin/rc',
- 'runhugs1.4' => '/usr/bin/runhugs1.4',
- 'runhugs98' => '/usr/bin/runhugs98',
- 'runhugs' => '/usr/bin/runhugs',
- 'ruby' => '/usr/bin/ruby',
- 'ruby1.6' => '/usr/bin/ruby1.6',
- 'ruby1.8' => '/usr/bin/ruby1.8',
- 'ruby1.9' => '/usr/bin/ruby1.9',
- 'scsh' => '/usr/bin/scsh',
- 'sed' => '/bin/sed',
- 'sh' => '/bin/sh',
- 'slsh' => '/usr/bin/slsh',
- 'speedy' => '/usr/bin/speedy',
- 'tcl' => '/usr/bin/tcl',
- 'tclsh' => '/usr/bin/tclsh',
- 'tclsh8.3' => '/usr/bin/tclsh8.3',
- 'tclsh8.4' => '/usr/bin/tclsh8.4',
- 'tcsh' => '/usr/bin/tcsh',
- 'tixwish' => '/usr/bin/tixwish',
- 'trs' => '/usr/bin/trs',
- 'wish' => '/usr/bin/wish',
- 'wish8.0' => '/usr/bin/wish8.0',
- 'wish8.3' => '/usr/bin/wish8.3',
- 'wish8.4' => '/usr/bin/wish8.4',
- 'xjed' => '/usr/bin/xjed',
- 'yforth' => '/usr/bin/yforth',
- 'zsh' => '/bin/zsh'
- );
-
-my %interpreter_dependencies = (
- 'ash' => 'ash',
- 'bltwish' => 'blt',
- 'burlap' => 'felt',
- 'csh' => 'c-shell | tcsh | csh',
- 'dash' => 'dash',
- 'expect' => 'expect',
- 'expectk' => 'expectk',
- 'fish' => 'fish',
- 'gawk' => 'gawk',
- 'gbr2' => 'gambas2-runtime',
- 'gbx' => 'gambas-runtime',
- 'gbx2' => 'gambas2-runtime',
- 'gforth' => 'gforth',
- 'gnuplot' => 'gnuplot',
- 'gosh' => 'gauche',
- 'guile' => 'guile',
- 'jed' => 'jed',
- 'jed-script' => 'jed | xjed',
- 'jruby0.9' => 'jruby0.9',
- 'jruby1.0' => 'jruby1.0',
- 'js' => 'ngs-js',
- 'kforth' => 'kforth',
- 'ksh' => 'pdksh',
- 'lefty' => 'graphviz',
- 'lua40' => 'lua40',
- 'lua50' => 'lua50',
- 'lua5.1' => 'lua5.1',
- 'magicfilter' => 'magicfilter',
- 'make' => 'make | build-essential',
- 'mawk' => 'mawk',
- 'ocaml' => 'ocaml',
- 'octave' => 'octave | octave2.1 | octave2.9',
- 'pagsh' => 'openafs-client | heimdal-clients',
- 'parrot' => 'parrot',
- 'perl-5.005' => 'perl-5.005',
- 'perl-5.004' => 'perl-5.004',
- 'pforth' => 'pforth',
- 'php' => 'php4-cli | php5-cli',
- 'php3' => 'php3-cgi',
- 'php4' => 'php4-cli',
- 'php5' => 'php5-cli',
- 'pike' => 'pike',
- 'pike7' => 'pike7',
- 'pike7.6' => 'pike7.6',
- 'rc' => 'rc',
- 'regina' => 'regina-rexx',
- 'rexx' => 'regina-rexx',
- 'runhugs1.4' => 'hugs',
- 'runhugs98' => 'hugs98',
- 'scsh' => 'scsh',
- 'slsh' => 'slsh',
- 'speedy' => 'speedy-cgi-perl',
- 'tcl' => 'tclx8.3',
- 'tcsh' => 'tcsh',
- 'tixwish' => 'tix',
- 'trs' => 'konwert',
- 'xjed' => 'xjed',
- 'yforth' => 'yforth',
- 'zsh' => 'zsh'
- );
-
# Any of the following packages can satisfy an update-inetd dependency.
-my $update_inetd
+our $update_inetd
= join (' | ', qw(update-inetd inet-superserver openbsd-inetd rlinetd));
# Appearance of one of these regexes in a maintainer script means that there
# must be a dependency (or pre-dependency) on the given package. The tag
# reported is maintainer-script-needs-depends-on-%s, so be sure to update
# scripts.desc when adding a new rule.
-my @depends_needed = (
+our @depends_needed = (
[ adduser => '\badduser\b' ],
[ gconf2 => '\bgconf-schemas\b' ],
[ $update_inetd => '\bupdate-inetd\b' ],
@@ -199,6 +174,8 @@
[ 'xml-core' => '\bupdate-xmlcatalog\b' ],
);
+sub run {
+
my %executable = ();
my %suid = ();
my %ELF = ();
@@ -235,18 +212,17 @@
close(FILEINFO);
my $all_deps = '';
-foreach my $depfield ('suggests', 'recommends', 'depends', 'pre-depends',
- 'provides') {
- $deps{$depfield} = '';
- if (open(IN, '<', "fields/$depfield")) {
+for my $field (qw/suggests recommends depends pre-depends provides/) {
+ $deps{$field} = '';
+ if (open(IN, '<', "fields/$field")) {
$_ = join('', <IN>);
close(IN);
chomp;
- $deps{$depfield} = $_;
+ $deps{$field} = $_;
$all_deps .= ', ' if $all_deps;
$all_deps .= $_;
}
- $deps{$depfield} = Dep::parse($deps{$depfield});
+ $deps{$field} = Dep::parse($deps{$field});
}
$all_deps .= ', ' if $all_deps;
$all_deps .= $pkg;
@@ -284,83 +260,62 @@
next;
}
- # either they use an absolute path or they call it as '/usr/bin/env interp'
+ # Either they use an absolute path or they use '/usr/bin/env interp'.
tag("interpreter-not-absolute", $filename, "#!$interpreter")
- unless $is_absolute;
+ unless $is_absolute;
tag("script-not-executable", $filename)
- unless ($executable{$filename} or
- $filename =~ m,usr/(lib|share)/.*\.pm, or
- $filename =~ m,usr/(lib|share)/ruby/.*\.rb, or
- $filename =~ m,\.in$, or
- $filename =~ m,etc/menu-methods, or
- $filename =~ m,etc/X11/Xsession.d,);
+ unless ($executable{$filename}
+ or $filename =~ m,usr/(lib|share)/.*\.pm,
+ or $filename =~ m,usr/(lib|share)/ruby/.*\.rb,
+ or $filename =~ m,\.in$,
+ or $filename =~ m,etc/menu-methods,
+ or $filename =~ m,etc/X11/Xsession.d,);
- if (exists $valid_interpreters{$base}) {
- unless ($interpreter eq $valid_interpreters{$base} or
- defined $calls_env) {
- # save us from some copy and paste
- if ($base =~ /^(ruby|python)(?:\d\.\d)?$/) {
- tag("wrong-path-for-$1", $filename, "#!$interpreter");
- } else {
- tag("wrong-path-for-interpreter",
- "#!$interpreter != $valid_interpreters{$base}",
- "($filename)");
- }
- }
+ # Warn about csh scripts.
+ tag("csh-considered-harmful", $filename)
+ if (($base eq 'csh' or $base eq 'tcsh')
+ and $executable{$filename}
+ and $filename !~ m,^./etc/csh/login.d/,);
- # Do not complain about dependencies for non-executable scripts.
- if ($executable{$filename}) {
- if (exists $interpreter_dependencies{$base}) {
- my @deps = split(/,/,$interpreter_dependencies{$base});
- if ($base eq 'php') {
- tag("php-script-but-no-php-cli-dep", $filename)
- unless Dep::implies($deps{all}, Dep::parse($interpreter_dependencies{$base}));
- } elsif ($base =~ /^(php\d?|(m|g)awk)/) {
- tag("$base-script-but-no-$deps[0]-dep", $filename)
- unless Dep::implies($deps{all}, Dep::parse($interpreter_dependencies{$base}));
- } else {
- tag("missing-dep-for-interpreter",
- "$base => $deps[0]", "($filename)")
- unless (Dep::implies($deps{all}, Dep::parse($interpreter_dependencies{$base})) ||
- ($base eq "csh" && $filename =~ m,^./etc/csh/login.d/,) ||
- ($base eq "fish" && $filename =~ m,^./etc/fish.d/,));
+ # Syntax-check most shell scripts, but don't syntax-check scripts that end
+ # in .dpatch. bash -n doesn't stop checking at exit 0 and goes on to blow
+ # up on the patch itself.
+ if ($base =~ /^(?:(?:b|d)?a|k|z)?sh$/) {
+ if (-x "$interpreter" && ! script_is_evil_and_wrong("unpacked/$filename")) {
+ if ($filename !~ m,\.dpatch$,) {
+ if (check_script_syntax($interpreter, "unpacked/$filename")) {
+ tag("shell-script-fails-syntax-check", $filename);
}
- } elsif ($base =~ /^python(\d.\d)?$/) {
- my $ver = $1 ? $1 : "";
- tag("python-script-but-no-python-dep", $filename)
- unless Dep::implies($deps{all}, Dep::parse("python$ver | python${ver}-minimal"));
- } elsif ($base =~ /^ruby(\d.\d)?$/) {
- my $ver = $1 ? $1 : "";
- tag("ruby-script-but-no-ruby-dep", $filename)
- unless Dep::implies($deps{all}, Dep::parse("ruby$ver"));
- } elsif ($base eq 'perl' && $suid{$filename}) {
- tag("suid-perl-script-but-no-perl-suid-dep", $filename)
- unless Dep::implies($deps{all}, Dep::parse('perl-suid'));
- } elsif ($base =~ m/^tclsh(\d+\.\d+)?$/) {
- my $ver = $1 ? $1 : "";
- if ($ver) {
- tag("tclsh-script-but-no-tclsh-dep", "$filename $base")
- unless Dep::implies($deps{all}, Dep::parse("tcl$ver"));
- } else {
- tag("tclsh-script-but-no-tclsh-dep", "$filename $base")
- unless Dep::implies($deps{all}, Dep::parse("tcl8.3 | tcl8.4 | tclsh"));
- }
- } elsif ($base =~ m/^wish(\d+\.\d+)?$/) {
- my $ver = $1 ? $1 : "";
- if ($ver) {
- tag("wish-script-but-no-wish-dep", "$filename $base")
- unless Dep::implies($deps{all}, Dep::parse("tk$ver"));
- } else {
- tag("wish-script-but-no-wish-dep", "$filename $base")
- unless Dep::implies($deps{all}, Dep::parse("tk8.3 | tk8.4 | wish"));
- }
}
}
+ }
+
+ # Try to find the expected path of the script to check. First check
+ # %interpreters and %versioned_interpreters. If not found there, see if
+ # it ends in a version number and the base is found in
+ # %versioned_interpreters.
+ my $data = $interpreters{$base};
+ my $versioned = 0;
+ if (not defined $data) {
+ $data = $versioned_interpreters{$base};
+ undef $data if ($data && not defined ($data->[1]));
+ if (not defined ($data) and $base =~ /^(.*[^\d.-])-?[\d.]+$/) {
+ $data = $versioned_interpreters{$1};
+ undef $data unless $base =~ /$data->[2]/;
+ }
+ $versioned = 1;
+ }
+ if ($data) {
+ my $expected = $data->[0] . '/' . $base;
+ unless ($interpreter eq $expected or defined $calls_env) {
+ tag("wrong-path-for-interpreter",
+ "#!$interpreter != $expected", "($filename)");
+ }
} elsif ($interpreter =~ m,/usr/local/,) {
tag("interpreter-in-usr-local", $filename, "#!$interpreter");
- } elsif ($executable{'.' . $interpreter}) { # each key is './path/to/exe'
- # Package installs the interpreter itself, so it's probably ok.
- # Don't emit any tag for this.
+ } elsif ($executable{'.' . $interpreter}) {
+ # Package installs the interpreter itself, so it's probably ok. Don't
+ # emit any tag for this.
} elsif ($base eq 'suidperl') {
tag("calls-suidperl-directly", $filename);
} elsif ($interpreter eq '/bin/env') {
@@ -369,22 +324,63 @@
tag("unusual-interpreter", $filename, "#!$interpreter");
}
- tag("csh-considered-harmful", $filename)
- if (($base eq 'csh' or $base eq 'tcsh') and $executable{$filename}
- and $filename !~ m,^./etc/csh/login.d/,);
-
- # Don't syntax-check scripts in /usr/src that end in .dpatch. bash -n
- # doesn't stop checking at exit 0 and goes on to blow up on the patch
- # itself.
- if ($base =~ /^(?:(?:b|d)?a|k|z)?sh$/) {
- if (-x "$interpreter" && ! script_is_evil_and_wrong("unpacked/$filename")) {
- if ($filename !~ m,^./usr/src/.*\.dpatch$,) {
- if (check_script_syntax($interpreter, "unpacked/$filename")) {
- tag("shell-script-fails-syntax-check", $filename);
- }
+ # If we found the interpreter and the script is executable, check
+ # dependencies. This should be the last thing we do in the loop so that
+ # we can use next for an early exit and reduce the nesting.
+ next unless ($data && $executable{$filename});
+ if (!$versioned) {
+ my $depends = $data->[1];
+ if (not defined $depends) {
+ $depends = $base;
+ }
+ if ($depends && !Dep::implies($deps{all}, Dep::parse($depends))) {
+ if ($base =~ /^(python|ruby|(m|g)awk)$/) {
+ tag("$base-script-but-no-$base-dep", $filename);
+ } elsif ($base eq 'csh' && $filename =~ m,^\./etc/csh/login.d/,) {
+ # Initialization files for csh.
+ } elsif ($base eq 'fish' && $filename =~ m,^./etc/fish.d/,) {
+ # Initialization files for fish.
+ } else {
+ tag('missing-dep-for-interpreter', "$base => $depends",
+ "($filename)");
}
}
- next;
+ if ($base eq 'perl' && $suid{$filename}) {
+ tag("suid-perl-script-but-no-perl-suid-dep", $filename)
+ unless Dep::implies($deps{all}, Dep::parse('perl-suid'));
+ }
+ } elsif ($versioned_interpreters{$base}) {
+ my @versions = @$data[4 .. @$data - 1];
+ my @depends = map {
+ my $d = $data->[3];
+ $d =~ s/\$1/$_/g;
+ $d;
+ } @versions;
+ my $depends = join (' | ', $data->[1], @depends);
+ unless (Dep::implies($deps{all}, Dep::parse($depends))) {
+ if ($base eq 'php') {
+ tag('php-script-but-no-php-cli-dep', $filename);
+ } elsif ($base =~ /^(wish|tclsh)/) {
+ tag("$1-script-but-no-$1-dep", $filename);
+ } else {
+ tag("missing-dep-for-interpreter", "$base => $depends",
+ "($filename)");
+ }
+ }
+ } else {
+ my ($version) = ($base =~ /$data->[2]/);
+ my $depends = $data->[3];
+ $depends =~ s/\$1/$version/g;
+ unless (Dep::implies($deps{all}, Dep::parse($depends))) {
+ if ($base =~ /^php/) {
+ tag('php-script-but-no-php-cli-dep', $filename);
+ } elsif ($base =~ /^(python|ruby)/) {
+ tag("$1-script-but-no-$1-dep", $filename);
+ } else {
+ tag("missing-dep-for-interpreter", "$base => $depends",
+ "($filename)");
+ }
+ }
}
}
close(SCRIPTS);
@@ -424,24 +420,27 @@
tag("interpreter-not-absolute", $filename, "#!$interpreter")
unless ($interpreter =~ m|^/|);
- if (exists $valid_interpreters{$base}) {
- tag("wrong-path-for-$base", $filename, "#!$interpreter")
- unless ($interpreter eq $valid_interpreters{$base});
- tag $file eq 'config'?
- "forbidden-config-interpreter":"unusual-control-interpreter",
- "#!$interpreter"
- unless ($base eq 'sh'
- or $base eq 'bash'
- or $base eq 'perl');
-
- if (exists $interpreter_dependencies{$base}) {
- tag("interpreter-without-predep", $filename,
- "#!$interpreter")
- unless Dep::implies($deps{'pre-depends'}, Dep::parse($interpreter_dependencies{$base}));
- } elsif ($base eq 'python') {
- tag("interpreter-without-predep", $filename, "#!$interpreter")
- unless Dep::implies($deps{'pre-depends'}, Dep::parse('python | python-base'));
+ if (exists $interpreters{$base}) {
+ my $data = $interpreters{$base};
+ my $expected = $data->[0] . '/' . $base;
+ tag("wrong-path-for-interpreter", "#!$interpreter != $expected",
+ "($filename)")
+ unless ($interpreter eq $expected);
+ unless ($base eq 'sh' or $base eq 'bash' or $base eq 'perl') {
+ my $tag;
+ if ($file eq 'config') {
+ $tag = 'forbidden-config-interpreter';
+ } else {
+ $tag = 'unusual-control-interpreter';
+ }
+ tag($tag, "#!$interpreter");
}
+ unless (defined ($data->[1]) and not $data->[1]) {
+ my $depends = $data->[1] || $base;
+ unless (Dep::implies($deps{'pre-depends'}, Dep::parse($depends))) {
+ tag("interpreter-without-predep", $filename, "#!$interpreter");
+ }
+ }
} elsif ($interpreter =~ m|/usr/local/|) {
tag("interpreter-in-usr-local", $filename, "#!$interpreter");
} else {
@@ -456,12 +455,12 @@
my $shellscript = $base =~ /^((b|d)?a|t?c|(pd)?k)?sh$/ ? 1 : 0;
+ # Only syntax-check scripts we can check with bash.
my $checkbashisms;
if ($shellscript) {
- # perhaps just do it when $base eq "sh" instead?
$checkbashisms = $base eq "sh" ? 1 : 0;
- if (-x $valid_interpreters{$base}) {
- if (check_script_syntax($interpreter, $filename)) {
+ if ($base eq 'sh' or $base eq 'bash') {
+ if (check_script_syntax("/bin/$base", $filename)) {
tag("maintainer-shell-script-fails-syntax-check", $file);
}
}
Modified: trunk/checks/scripts.desc
===================================================================
--- trunk/checks/scripts.desc 2008-01-05 05:51:39 UTC (rev 1112)
+++ trunk/checks/scripts.desc 2008-01-05 05:57:31 UTC (rev 1113)
@@ -32,7 +32,7 @@
Tag: unusual-interpreter
Type: warning
Info: This package contains a script for an interpreter that the Lintian
- maintainers have not thought of. It could be a typo for a common
+ maintainers have not heard of. It could be a typo for a common
interpreter. If not, please file a wishlist bug on lintian so that the
Lintian maintainers can add this interpreter to their list.
@@ -45,53 +45,36 @@
Tag: forbidden-config-interpreter
Type: error
-Info: This package contains a 'config' script for pre-configuring the package,
- however, at that time only essential packages are guaranteed to be installed,
- so you cannot use a non-essential interpreter
+Info: This package contains a <tt>config</tt> script for pre-configuring
+ the package. During pre-configuration, however, only essential packages
+ are guaranteed to be installed, so you cannot use a non-essential
+ interpreter.
Tag: unusual-control-interpreter
Type: info
-Info: This package contains a control script for an interpreter that
- is not normally used for control scripts.
+Info: This package contains a control script for an interpreter that is
+ not normally used for control scripts.
Tag: interpreter-in-usr-local
Type: error
-Info: This package contains a script that looks for an interpreter
- in a directory in /usr/local. Since Debian does not install anything
- in /usr/local, this is the wrong place to look.
+Info: This package contains a script that looks for an interpreter in a
+ directory in /usr/local. Since Debian does not install anything in
+ /usr/local, this is the wrong place to look.
Tag: interpreter-without-predep
Type: error
-Info: The package contains a control script that uses an unusual interpreter,
- but does not declare a pre-dependency on the package that provides this
- interpreter.
+Info: The package contains a control script that uses an unusual
+ interpreter, but does not declare a pre-dependency on the package that
+ provides this interpreter.
.
- A perusal of &packaging; section 6.2 shows that any of the control scripts
- can be called while the package is not configured. Therefore, a
+ A perusal of &packaging; section 6.2 shows that any of the control
+ scripts can be called while the package is not configured. Therefore, a
pre-dependency is required to ensure that the interpreter is always
available when the script is invoked.
.
- Please do not add a pre-dependency without following the policy for doing so.
- (Policy section 3.5).
+ Please do not add a pre-dependency without following the policy for doing
+ so. (Policy section 3.5).
-Tag: gawk-script-but-no-gawk-dep
-Type: error
-Info: Packages that use gawk scripts must depend on the gawk package.
- If they don't need gawk-specific features, and can just as easily work
- with mawk, then they should be awk scripts instead.
- .
- In some cases a weaker relationship, such as Suggests or Recommends, will
- be more appropriate.
-
-Tag: mawk-script-but-no-mawk-dep
-Type: error
-Info: Packages that use mawk scripts must depend on the mawk package.
- If they don't need mawk-specific features, and can just as easily work
- with gawk, then they should be awk scripts instead.
- .
- In some cases a weaker relationship, such as Suggests or Recommends, will
- be more appropriate.
-
Tag: missing-dep-for-interpreter
Type: error
Info: You used an interpreter for a script that is not in an essential
@@ -115,99 +98,91 @@
In some cases a weaker relationship, such as Suggests or Recommends, will
be more appropriate.
-Tag: php-script-but-no-php-cli-dep
+Tag: wrong-path-for-interpreter
Type: error
-Info: Packages that use PHP scripts with /usr/bin/php as interpreter must
- depend on a php-cli package (such as php4-cli or php5-cli). Note that a
- dependency on a php-cgi package (such as php5-cgi) is needlessly strict,
- and forces the user to install a package that isn't needed.
+Info: The interpreter you used is installed at another location on Debian
+ systems.
+
+Tag: gawk-script-but-no-gawk-dep
+Type: error
+Info: Packages that use gawk scripts must depend on the gawk package.
+ If they don't need gawk-specific features, and can just as easily work
+ with mawk, then they should be awk scripts instead.
.
In some cases a weaker relationship, such as Suggests or Recommends, will
be more appropriate.
-Tag: php4-script-but-no-php4-cli-dep
+Tag: mawk-script-but-no-mawk-dep
Type: error
-Info: Packages that use PHP4 scripts must depend on the php4-cli package. Note
- that a dependency on php4-cgi is needlessly strict, and forces the user to
- install a package that isn't needed.
+Info: Packages that use mawk scripts must depend on the mawk package.
+ If they don't need mawk-specific features, and can just as easily work
+ with gawk, then they should be awk scripts instead.
.
In some cases a weaker relationship, such as Suggests or Recommends, will
be more appropriate.
-Tag: php5-script-but-no-php5-cli-dep
+Tag: php-script-but-no-php-cli-dep
Type: error
-Info: Packages that use PHP5 scripts must depend on the php5-cli package. Note
- that a dependency on php5-cgi is needlessly strict, and forces the user to
- install a package that isn't needed.
+Info: Packages with PHP scripts must depend on a php-cli package such as
+ php5-cli. Note that a dependency on a php-cgi package (such as php5-cgi)
+ is needlessly strict and forces the user to install a package that isn't
+ needed.
.
In some cases a weaker relationship, such as Suggests or Recommends, will
be more appropriate.
-Tag: wrong-path-for-python
-Type: error
-Info: Python is installed as /usr/bin/python on Debian systems.
- .
- Specific Python versions are installed as /usr/bin/pythonX.Y
-
-Tag: wrong-path-for-ruby
-Type: error
-Info: Ruby is installed as /usr/bin/ruby on Debian systems.
- .
- Specific Ruby versions are installed as /usr/bin/rubyX.Y
-
-Tag: wrong-path-for-interpreter
-Type: error
-Info: The interpreter you used is installed at another location on Debian systems.
-
Tag: python-script-but-no-python-dep
Type: error
-Info: Packages with scripts that are executed with python must depend on the
- package python. Those that have scripts executed with a versioned python
- package need a dependency on the equivalent version of python.
+Info: Packages with Python scripts must depend on the package python.
+ Those that have scripts executed with a versioned python package need a
+ dependency on the equivalent version of python.
.
- For example, if a script in the package uses #!/usr/bin/python, then the
- package needs a dependency on "python". If a script uses
- #!/usr/bin/python2.2, then the package need a dependency on "python2.2".
+ For example, if a script in the package uses <tt>#!/usr/bin/python</tt>,
+ the package needs a dependency on "python". If a script uses
+ <tt>#!/usr/bin/python2.5</tt>, the package need a dependency on
+ "python2.5".
.
In some cases a weaker relationship, such as Suggests or Recommends, will
be more appropriate.
Tag: ruby-script-but-no-ruby-dep
Type: error
-Info: Packages with scripts that are executed with ruby must depend on the
- package ruby. Those that have scripts executed with a versioned ruby
- package need a dependency on the equivalent version of ruby.
+Info: Packages with Ruby scripts must depend on the package ruby. Those
+ that have Ruby scripts that run under a specific version of Ruby need a
+ dependency on the equivalent version of Ruby.
.
- For example, if a script in the package uses #!/usr/bin/ruby, then the
- package needs a dependency on "ruby". If a script uses
- #!/usr/bin/ruby1.6, then the package need a dependency on "ruby1.6".
+ For example, if a script in the package uses <tt>#!/usr/bin/ruby</tt>,
+ the package needs a dependency on "ruby". If a script uses
+ <tt>#!/usr/bin/ruby1.9</tt>, then the package need a dependency on
+ "ruby1.9".
.
In some cases a weaker relationship, such as Suggests or Recommends, will
be more appropriate.
Tag: wish-script-but-no-wish-dep
Type: error
-Info: Packages that use wish scripts must depend on the virtual package wish
- or, if they require a specific version of wish or tk, that version of tk.
+Info: Packages that include wish scripts must depend on the virtual
+ package wish or, if they require a specific version of wish or tk, that
+ version of tk.
.
In some cases a weaker relationship, such as Suggests or Recommends, will
be more appropriate.
Tag: tclsh-script-but-no-tclsh-dep
Type: error
-Info: Packages that use wish scripts must depend on the virtual package
- tclsh or, if they require a specific version of wish or tk, that version
- of tcl.
+Info: Packages that include tclsh scripts must depend on the virtual
+ package tclsh or, if they require a specific version of tcl, that
+ version of tcl.
.
In some cases a weaker relationship, such as Suggests or Recommends, will
be more appropriate.
Tag: calls-suidperl-directly
Type: error
-Info: Since perl version 5.8.3-3, /usr/bin/suidperl shouldn't be called directly
- anymore (and doing so will lead to errors in most cases) but the script should
- just use /usr/bin/perl as interpreter which will call suidperl automatically if
- the script has the suid permission bit set.
+Info: Since perl version 5.8.3-3, /usr/bin/suidperl shouldn't be called
+ directly anymore (and doing so will lead to errors in most cases) but the
+ script should just use /usr/bin/perl as interpreter which will call
+ suidperl automatically if the script has the suid permission bit set.
Tag: shell-script-fails-syntax-check
Type: error
@@ -226,20 +201,19 @@
Tag: possibly-insecure-handling-of-tmp-files-in-maintainer-script
Type: warning
-Info: The maintainer script seems to access a file in <tt>/tmp</tt> or some
- other temporary directory. Since creating temporary files in a
+Info: The maintainer script seems to access a file in <tt>/tmp</tt> or
+ some other temporary directory. Since creating temporary files in a
world-writable directory is very dangerous, this is likely to be a
- security bug. It's suggested that you use the <tt>tempfile</tt> or
- <tt>mktemp</tt> utilities to create temporary files in these
- directories.
+ security bug. Use the <tt>tempfile</tt> or <tt>mktemp</tt> utilities to
+ create temporary files in these directories.
Ref: policy 10.4
Tag: killall-is-dangerous
Type: warning
Info: The maintainer script seems to call <tt>killall</tt>. Since this
utility kills processes by name, it may well end up killing unrelated
- processes. Most uses of <tt>killall</tt> should use
- <tt>start-stop-daemon</tt> instead.
+ processes. Most uses of <tt>killall</tt> should use <tt>invoke-rc.d</tt>
+ instead.
Tag: mknod-in-maintainer-script
Type: error
@@ -279,9 +253,8 @@
Tag: suidregister-used-in-maintainer-script
Type: error
-Info: This script calls suidregister which is no longer needed, a new
- command 'dpkg-statoverride' gives admins more flexibility. Please see
- the documentation of suidmanager and dpkg-statoverride for details.
+Info: This script calls suidregister, a long-obsolete program that has
+ been replaced by dpkg-statoverride.
Tag: maintainer-script-needs-depends-on-update-inetd
Type: warning
@@ -320,24 +293,25 @@
Tag: update-alternatives-remove-called-in-postrm
Type: warning
-Info: 'update-alternatives --remove <alternative> foo' is called in the
- postrm. This can be dangerous because at the time the postrm is executed
- foo has already been deleted and update-alternatives will ignore it while
- constructing its list of available alternatives. Then, if the
- /etc/alternatives symlink points at foo, update-alternatives won't
- recognize it and will mark the symlink as something site-specific. As
- such, the symlink will no longer be updated automatically and will be
- left dangling until `update-alternatives --auto <alternative>' is
- run by hand.
+Info: <tt>update-alternatives --remove <alternative> foo</tt> is
+ called in the postrm. This can be dangerous because at the time the
+ postrm is executed foo has already been deleted and update-alternatives
+ will ignore it while constructing its list of available alternatives.
+ Then, if the /etc/alternatives symlink points at foo, update-alternatives
+ won't recognize it and will mark the symlink as something site-specific.
+ As such, the symlink will no longer be updated automatically and will be
+ left dangling until <tt>update-alternatives --auto
+ <alternative></tt> is run by hand.
.
- update-alternatives --remove should be called in the prerm instead.
+ <tt>update-alternatives --remove</tt> should be called in the prerm
+ instead.
Tag: deprecated-chown-usage
Type: warning
-Info: 'chown user.group' is called in one of the maintainer scripts.
- This should be avoided, as the correct syntax is 'chown user:group'.
- Using "." as a separator is still supported by the GNU tools, but it will
- fail as soon as a system uses the "." in user or group names.
+Info: <tt>chown user.group</tt> is called in one of the maintainer
+ scripts. The correct syntax is <tt>chown user:group</tt>. Using "." as a
+ separator is still supported by the GNU tools, but it will fail as soon
+ as a system uses the "." in user or group names.
Tag: maintainer-script-hides-init-failure
Type: warning
Modified: trunk/debian/changelog
===================================================================
--- trunk/debian/changelog 2008-01-05 05:51:39 UTC (rev 1112)
+++ trunk/debian/changelog 2008-01-05 05:57:31 UTC (rev 1113)
@@ -65,10 +65,17 @@
* checks/patch-systems:
+ [RA] dpatch permits multiple patches to be listed on the same line
of 00list. Patch by Chris Lamb. (Closes: #457523)
- * checks/scripts:
+ * checks/scripts{.desc,}:
+ [RA] Add lua40 and lua5.1. Thanks, Enrico Tassi. (Closes: #457219)
+ [RA] Improve recognition of heredocs.
+ [RA] Recognize quoted strings that start at beginning of the line.
+ + [RA] Rewrite script path and dependency checking. Remove scripts
+ and packages no longer in the archive. Add new versions of
+ versioned scripts and packages. Fix the dependencies for pike
+ interpreters. (Closes: #458896)
+ + [RA] Reformat long descriptions and collapse some tags.
+ + [RA] For consistent results, only syntax-check sh and bash scripts.
+ Also ignore all dpatch files, not just those in /usr/src.
* checks/shared-libs{.desc,}:
+ [RA] New check for version numbers in symbol files. Based on a
patch from Raphael Hertzog. (Closes: #457067)
Modified: trunk/testset/scripts/debian/rules
===================================================================
--- trunk/testset/scripts/debian/rules 2008-01-05 05:51:39 UTC (rev 1112)
+++ trunk/testset/scripts/debian/rules 2008-01-05 05:57:31 UTC (rev 1113)
@@ -23,6 +23,7 @@
install -m 755 csh-foo $(tmp)/etc/csh/login.d/
install -m 755 envfoo $(tmp)/usr/bin/
install -m 755 fish-foo $(tmp)/etc/fish.d/
+ install -m 755 jruby-broken $(tmp)/usr/bin/
install -m 755 pyfoo $(tmp)/usr/bin/
install -m 755 py2foo $(tmp)/usr/bin/
install -m 755 perlfoo $(tmp)/usr/bin/
@@ -30,6 +31,7 @@
install -m 755 make-foo $(tmp)/usr/bin/
install -m 755 lefty-foo $(tmp)/usr/bin/
install -m 4751 perlfoo $(tmp)/usr/bin/suidperlfoo2
+ install -m 755 sh-broken $(tmp)/usr/bin/
install -m 4555 suidperlfoo $(tmp)/usr/bin/
install -m 755 tkfoo $(tmp)/usr/bin/
install -m 755 wishfoo $(tmp)/usr/bin/
Added: trunk/testset/scripts/jruby-broken
===================================================================
--- trunk/testset/scripts/jruby-broken (rev 0)
+++ trunk/testset/scripts/jruby-broken 2008-01-05 05:57:31 UTC (rev 1113)
@@ -0,0 +1,2 @@
+#!/usr/bin/jruby
+# There's no non-versioned jruby, so this should be an error.
Added: trunk/testset/scripts/sh-broken
===================================================================
--- trunk/testset/scripts/sh-broken (rev 0)
+++ trunk/testset/scripts/sh-broken 2008-01-05 05:57:31 UTC (rev 1113)
@@ -0,0 +1,2 @@
+#!/bin/sh
+if fi
Modified: trunk/testset/tags.scripts
===================================================================
--- trunk/testset/tags.scripts 2008-01-05 05:51:39 UTC (rev 1112)
+++ trunk/testset/tags.scripts 2008-01-05 05:57:31 UTC (rev 1113)
@@ -8,14 +8,14 @@
E: scripts: init.d-script-has-duplicate-lsb-section /etc/init.d/lsb-broken
E: scripts: init.d-script-has-unterminated-lsb-section /etc/init.d/lsb-broken:15
E: scripts: missing-dep-for-interpreter lefty => graphviz (./usr/bin/lefty-foo)
+E: scripts: php-script-but-no-php-cli-dep ./usr/share/scripts/php5foo
E: scripts: php-script-but-no-php-cli-dep ./usr/share/scripts/phpfoo
-E: scripts: php5-script-but-no-php5-cli-dep ./usr/share/scripts/php5foo
E: scripts: python-script-but-no-python-dep ./usr/bin/py2foo
E: scripts: python-script-but-no-python-dep ./usr/bin/pyfoo
-E: scripts: shell-script-fails-syntax-check ./usr/share/scripts/gccbug.dpatch
+E: scripts: shell-script-fails-syntax-check ./usr/bin/sh-broken
E: scripts: suid-perl-script-but-no-perl-suid-dep ./usr/bin/suidperlfoo2
+E: scripts: wrong-path-for-interpreter #!/bin/ruby1.8 != /usr/bin/ruby1.8 (./usr/bin/rubyfoo)
E: scripts: wrong-path-for-interpreter #!/usr/local/bin/lefty != /usr/bin/lefty (./usr/bin/lefty-foo)
-E: scripts: wrong-path-for-ruby ./usr/bin/rubyfoo #!/bin/ruby1.8
I: scripts: no-md5sums-control-file
W: scripts source: ancient-standards-version 3.2.1 (current is 3.7.3)
W: scripts source: binary-arch-rules-but-pkg-is-arch-indep
@@ -27,6 +27,7 @@
W: scripts source: source-nmu-has-incorrect-version-number 6
W: scripts source: uses-dh-python-with-no-pycompat
W: scripts: binary-without-manpage usr/bin/envfoo
+W: scripts: binary-without-manpage usr/bin/jruby-broken
W: scripts: binary-without-manpage usr/bin/lefty-foo
W: scripts: binary-without-manpage usr/bin/make-foo
W: scripts: binary-without-manpage usr/bin/perl-bizarre-1
@@ -36,6 +37,7 @@
W: scripts: binary-without-manpage usr/bin/py2foo
W: scripts: binary-without-manpage usr/bin/pyfoo
W: scripts: binary-without-manpage usr/bin/rubyfoo
+W: scripts: binary-without-manpage usr/bin/sh-broken
W: scripts: binary-without-manpage usr/bin/suidperlfoo
W: scripts: binary-without-manpage usr/bin/suidperlfoo2
W: scripts: binary-without-manpage usr/bin/test.sh
@@ -61,3 +63,4 @@
W: scripts: script-with-language-extension usr/bin/test.sh
W: scripts: setuid-binary usr/bin/suidperlfoo 4555 root/root
W: scripts: setuid-binary usr/bin/suidperlfoo2 4751 root/root
+W: scripts: unusual-interpreter ./usr/bin/jruby-broken #!/usr/bin/jruby
Reply to: