[SCM] Debian package checker branch, master, updated. 7f71195c6cad53edbc36f98afc68484086f0c298
The following commit has been merged in the master branch:
commit 7f71195c6cad53edbc36f98afc68484086f0c298
Author: Adam D. Barratt <adam@adam-barratt.org.uk>
Date: Fri Jun 27 20:32:51 2008 +0100
Enhance symbol checking support
+ Implement syntax and sanity checking for symbols files
(Closes: #452216)
+ Check symbols files for dependencies that are not satisfied by
the package itself
diff --git a/checks/shared-libs b/checks/shared-libs
index 54b70b4..9ee576a 100644
--- a/checks/shared-libs
+++ b/checks/shared-libs
@@ -57,6 +57,7 @@ my $postinst = "control/postinst";
my $preinst = "control/preinst";
my $prerm = "control/prerm";
my $shlibs_control_file = "control/shlibs";
+my $symbols_control_file = "control/symbols";
my %SONAME;
my %INTERP;
my %STACK;
@@ -287,6 +288,18 @@ if (open (VERSION, '<', 'fields/version')) {
close VERSION;
chomp $version;
}
+my $provides = $pkg . "( = $version)";
+if (open (PROVIDES, '<', 'fields/provides')) {
+ my $line = <PROVIDES>;
+ close PROVIDES;
+ chomp $line;
+ $provides .= ", $line";
+}
+$provides = Dep::parse($provides);
+
+my %shlibs_control;
+my %symbols_control;
+
@shlibs = grep { !m,^lib/libnss_[^.]+\.so(\.[0-9]+)$, } keys %SONAME;
if ($#shlibs == -1) {
# no shared libraries included in package, thus shlibs control file should
@@ -306,7 +319,6 @@ if ($#shlibs == -1) {
}
} else {
my %shlibs_control_used;
- my %shlibs_control;
my @shlibs_depends;
open(SHLIBS, '<', $shlibs_control_file)
or fail("cannot open shlibs control file $shlibs_control_file for reading: $!");
@@ -333,13 +345,7 @@ if ($#shlibs == -1) {
my $shlib_name;
for my $shlib (@shlibs) {
$shlib_name = $SONAME{$shlib};
- # libfoo.so.X.X
- if ($shlib_name =~ m/(.+)\.so\.(.*)$/) {
- $shlib_name = "$1 $2";
- # libfoo-X.X.so
- } elsif ($shlib_name =~ m/(.+)\-(\w[\w\.]*)\.so$/) {
- $shlib_name = "$1 $2";
- }
+ $shlib_name = format_soname($shlib_name);
$shlibs_control_used{$shlib_name} = 1;
$shlibs_control_used{"udeb: ".$shlib_name} = 1;
unless (exists $shlibs_control{$shlib_name}) {
@@ -361,14 +367,6 @@ if ($#shlibs == -1) {
#
# Deduplicate the list of dependencies before warning so that we don't
# dupliate warnings.
- my $provides = $pkg . "( = $version)";
- if (open (PROVIDES, '<', 'fields/provides')) {
- my $line = <PROVIDES>;
- close PROVIDES;
- chomp $line;
- $provides .= ", $line";
- }
- $provides = Dep::parse($provides);
my %seen;
@shlibs_depends = grep { !$seen{$_}++ } @shlibs_depends;
for my $depend (@shlibs_depends) {
@@ -380,21 +378,99 @@ if ($#shlibs == -1) {
}
# 5th step: check symbols control file
-if (open(IN, '<', 'control/symbols')) {
+if ($#shlibs == -1) {
+ # no shared libraries included in package, thus symbols control file should
+ # not be present
+ if (-f $symbols_control_file) {
+ tag "pkg-has-symbols-control-file-but-no-shared-libs", "";
+ }
+} elsif (not -f $symbols_control_file) {
+ if ($type ne 'udeb') {
+ for my $shlib (@shlibs) {
+ # skip it if it's not a public shared library
+ next unless $ldconfig_dirs->known(dirname($shlib));
+ tag "no-symbols-control-file", "$shlib";
+ }
+ }
+} elsif (open(IN, '<', $symbols_control_file)) {
my $version_wo_rev = $version;
$version_wo_rev =~ s/^(.+)-([^-]+)$/$1/;
my ($full_version_count, $full_version_sym) = (0, undef);
my ($debian_revision_count, $debian_revision_sym) = (0, undef);
+ my ($soname, $dep_package, $dep);
+ my %symbols_control_used;
+ my @symbols_depends;
+ my $dep_templates = 0;
+ my $meta_info_seen = 0;
+
while (<IN>) {
- next if not /^\s+(\S+)\s(\S+)(?:\s(\d+))?/;
- my ($sym, $v, $dep_order) = ($1, $2, $3);
- if (($v eq $version) and ($version =~ /-/)) {
- $full_version_sym ||= $sym;
- $full_version_count++;
- }
- if (($v =~ /-/) and (not $v =~ /~$/) and ($v ne $version_wo_rev)) {
- $debian_revision_sym ||= $sym;
- $debian_revision_count++;
+ chomp;
+ next if m/^\s*$/ or /^#/;
+
+ if (m/^([^\s|*]\S+)\s(\S+)(?:\s(\S+))?/) {
+ # soname, main dependency template
+
+ ($soname, $dep_package, $dep) = ($1, $2, $3);
+ $dep ||= '';
+ $soname = format_soname($soname);
+
+ if ($symbols_control{$soname}) {
+ tag "duplicate-entry-in-symbols-control-file", $soname;
+ } else {
+ $symbols_control{$soname} = 1;
+ push @symbols_depends, $dep_package . ' ' . $dep;
+ }
+
+ $dep_templates = 0;
+ $meta_info_seen = 0;
+ } elsif (m/^\|\s+(\S+)\s(\S+(\s\S+)?)$/) {
+ # alternative dependency template
+
+ if ($meta_info_seen or not defined $soname) {
+ tag "syntax-error-in-symbols-file", $.;
+ }
+
+ ($dep_package, $dep) = ($1, $2);
+ push @symbols_depends, $dep_package . ' ' . $dep;
+ $dep_templates++;
+ } elsif (m/^\*\s(\S+):\s(\S+)/) {
+ # meta-information
+
+ # This should probably be in a hash, but there's
+ # only one supported value currently
+ tag "unknown-meta-field-in-symbols-file", "$1, line $."
+ unless $1 eq 'Build-Depends-Package';
+ tag "syntax-error-in-symbols-file", $.
+ if $dep_templates > 0;
+
+ $meta_info_seen = 1;
+ } elsif (m/^\s+(\S+)\s(\S+)(?:\s(\S+(\s\S+)?))?$/) {
+ # Symbol definition
+
+ tag "syntax-error-in-symbols-file", $.
+ unless defined $soname;
+
+ my ($sym, $v, $dep_order) = ($1, $2, $3);
+ $dep_order ||= '';
+
+ if (($v eq $version) and ($version =~ /-/)) {
+ $full_version_sym ||= $sym;
+ $full_version_count++;
+ }
+ if (($v =~ /-/) and (not $v =~ /~$/) and ($v ne $version_wo_rev)) {
+ $debian_revision_sym ||= $sym;
+ $debian_revision_count++;
+ }
+
+ if (length $dep_order) {
+ if ($dep_order !~ /^\d+$/ or $dep_order > $dep_templates) {
+ tag "invalid-template-id-in-symbols-file", $.;
+ }
+ }
+ } else {
+ # Unparseable line
+
+ tag "syntax-error-in-symbols-file", $.;
}
}
close IN;
@@ -405,7 +481,7 @@ if (open(IN, '<', 'control/symbols')) {
$others = " and $full_version_count others";
}
tag "symbols-file-contains-current-version-with-debian-revision",
- "on symbol $full_version_sym$others"
+ "on symbol $full_version_sym$others";
}
if ($debian_revision_count) {
$debian_revision_count--;
@@ -416,8 +492,47 @@ if (open(IN, '<', 'control/symbols')) {
tag "symbols-file-contains-debian-revision",
"on symbol $debian_revision_sym$others";
}
+ my $shlib_name;
+ for my $shlib (@shlibs) {
+ $shlib_name = $SONAME{$shlib};
+ $shlib_name = format_soname($shlib_name);
+ $symbols_control_used{$shlib_name} = 1;
+ $symbols_control_used{"udeb: ".$shlib_name} = 1;
+ unless (exists $symbols_control{$shlib_name}) {
+ # skip it if it's not a public shared library
+ next unless $ldconfig_dirs->known(dirname($shlib));
+ tag "shlib-missing-in-symbols-control-file", $shlib_name, 'for', $shlib;
+ }
+ }
+ for $shlib_name (keys %symbols_control) {
+ tag "unused-shlib-entry-in-symbols-control-file", $shlib_name
+ unless $symbols_control_used{$shlib_name};
+ }
+
+ # Check that all of the packages listed as dependencies in the symbols
+ # file are satisfied by the current package or its Provides.
+ # Normally, packages should only declare dependencies in their symbols
+ # files that they themselves can satisfy.
+ #
+ # Deduplicate the list of dependencies before warning so that we don't
+ # dupliate warnings.
+ my %seen;
+ @symbols_depends = grep { !$seen{$_}++ } @symbols_depends;
+ for my $depend (@symbols_depends) {
+ unless (Dep::implies($provides, Dep::parse($depend))) {
+ tag "symbols-declares-dependency-on-other-package", $depend;
+ }
+ }
}
+# Compare the contents of the shlibs and symbols control files
+if (keys %shlibs_control and keys %symbols_control) {
+ for my $key (keys %symbols_control) {
+ unless (exists $shlibs_control{$key}) {
+ tag "symbols-declared-but-not-shlib", $key;
+ }
+ }
+}
# 6th step: check pre- and post- control files
if (-f $preinst) {
@@ -491,6 +606,20 @@ sub abs_path {
return $path;
}
+sub format_soname {
+ my $soname = shift;
+
+ # libfoo.so.X.X
+ if ($soname =~ m/(.+)\.so\.(.*)$/) {
+ $soname = "$1 $2";
+ # libfoo-X.X.so
+ } elsif ($soname =~ m/(.+)\-(\w[\w\.]*)\.so$/) {
+ $soname = "$1 $2";
+ }
+
+ return $soname
+}
+
1;
# Local Variables:
diff --git a/checks/shared-libs.desc b/checks/shared-libs.desc
index d58919e..df27cb7 100644
--- a/checks/shared-libs.desc
+++ b/checks/shared-libs.desc
@@ -230,3 +230,77 @@ Info: Debian revisions should be stripped from versions in symbols files.
be stripped because the symbol really appearead between two specific
Debian revisions, you should postfix the version with a single "~"
(example: 1.0-3~ if the symbol appeared in 1.0-3).
+
+Tag: syntax-error-in-symbols-file
+Type: error
+Info: The symbols file contains an entry that does not follow the syntax
+ rules for symbols files.
+ .
+ This may be due to the entry appearing out of sequence.
+Ref: deb-symbols(5)
+
+Tag: duplicate-entry-in-symbols-control-file
+Type: error
+Info: The symbols control file contains a duplicate entry.
+
+Tag: no-symbols-control-file
+Type: info
+Info: Although the package includes a shared library, the package does not
+ have a symbols control file.
+
+Tag: pkg-has-symbols-control-file-but-no-shared-libs
+Type: error
+Info: Although the package does not include any shared libraries, it does
+ have a symbols control file. If you did include a shared library, check that
+ the SONAME of the library is set and that it matches the contents of the
+ symbols file.
+ .
+ SONAMEs are set with something like <tt>gcc -Wl,-soname,libfoo.so.0</tt>,
+ where 0 is the major version of the library. If your package uses libtool,
+ then libtool invoked with the right options should be doing this.
+
+Tag: shlib-missing-in-symbols-control-file
+Type: warning
+Info: The package contains a shared library that is not listed in the
+ symbols control file. This may not be a problem if, for example,
+ the library is a C++ library.
+
+Tag: unused-shlib-entry-in-symbols-control-file
+Type: warning
+Info: The symbols control file contains an entry for a shared library that
+ is not installed by this package.
+
+Tag: symbols-declares-dependency-on-other-package
+Type: warning
+Info: This package declares in its symbols control file a dependency on
+ some other package (and not one listed in the Provides of this package).
+ .
+ Packages should normally only list in their symbols control file the
+ shared libraries included in that package, and therefore the dependencies
+ listed there should normally be satisfied by either the package itself or
+ one of its Provides.
+ .
+ In unusual circumstances where it's necessary to declare more complex
+ dependencies in the symbols control file, please add a lintian override
+ for this warning.
+Ref: policy 8.6
+
+Tag: invalid-template-id-in-symbols-file
+Type: error
+Info: The symbol definition refers to an alternative dependency template
+ which is not defined for the library containing the symbol.
+ .
+ The first alternative dependency template for a library the id number
+ of 1, with the ids of subsequent alternative templates increasing in
+ sequence.
+
+Tag: unknown-meta-field-in-symbols-file
+Type: error
+Info: The symbols control file contains an unknown meta-information field.
+ .
+ A list of currently supported fields may be found in deb-control(5).
+
+Tag: symbols-declared-but-not-shlib
+Type: error
+Info: The symbols control file contains dependency and symbol information
+ for a shared library which is not listed in the shlibs control file.
diff --git a/debian/changelog b/debian/changelog
index 0c75909..728fd9a 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -33,6 +33,11 @@ lintian (1.24.2) unstable; urgency=low
Patch by Adam D. Barratt.
+ [ADB] Update bashism regexes to add new checks, improve performance
and reduce false positives.
+ * checks/shared-libs{,.desc}:
+ + [ADB] Implement syntax and sanity checking for symbols files
+ (Closes: #452216)
+ + [ADB] Check symbols files for dependencies that are not satisfied by
+ the package itself (Closes: #461575)
* checks/watch-file{,.desc}:
+ [FL] Check for more Debian specific strings in version
number. Issue an info tag if the watch file uses
diff --git a/testset/debug/debian/_symbols b/testset/debug/debian/_symbols
new file mode 100644
index 0000000..a91ce05
--- /dev/null
+++ b/testset/debug/debian/_symbols
@@ -0,0 +1,22 @@
+ This line should flag a syntax error
+# but this one shouldn't
+| although this one should, but for a different reason
+ and so should this
+
+libhello.so.0 libhello0 #MINVER#
+| libhello0c2 (>= 1.2)
+| hello-dbg
+ hello@Base 1.0
+* Build-Dep-Foo: bar
+ hello2@Base 2.0 3
+ hello3@Base 2.0 1
+ hello3@Base 2.0 A
+ dummy
+
+libhello.so.2 libhello2 #MINVER#
+* Build-Depends-Package: libbar
+| libhello2 (>= 1:2.3)
+ hello@Base 2.0
+
+libhello.so.0 libhello0 #MINVER#
+ duplicate@Base 1.0
diff --git a/testset/debug/debian/rules b/testset/debug/debian/rules
index a1327fe..a40c380 100755
--- a/testset/debug/debian/rules
+++ b/testset/debug/debian/rules
@@ -65,6 +65,21 @@ binary-arch: build-stamp install
dh_makeshlibs -X debug
dh_installdeb
dh_shlibdeps -X debug
+
+ # We do this by hand as otherwise dpkg-gensymbols
+ # will error due to the broken symbols file
+ # and abort the build; similarly the file in
+ # the source tree is _symbols so that dpkg
+ # doesn't attempt to sanity check it
+ install -d $(CURDIR)/debian/libhello0/DEBIAN
+ install -m 644 $(CURDIR)/debian/_symbols \
+ $(CURDIR)/debian/libhello0/DEBIAN/symbols
+ # hello doesn't contain any shlibs, but we
+ # make it contain a symbols file
+ install -d $(CURDIR)/debian/hello/DEBIAN
+ install -m 644 $(CURDIR)/debian/_symbols \
+ $(CURDIR)/debian/hello/DEBIAN/symbols
+
dh_gencontrol
dh_md5sums
dh_builddeb
diff --git a/testset/tags.debug b/testset/tags.debug
index df79fac..134cfcb 100644
--- a/testset/tags.debug
+++ b/testset/tags.debug
@@ -1,10 +1,24 @@
E: debug source: build-depends-indep-without-arch-indep
E: debug source: version-substvar-for-external-package libhello0-dbg -> libhello
+E: hello: pkg-has-symbols-control-file-but-no-shared-libs
E: hello: statically-linked-binary ./usr/bin/hello.dbg
E: hello: unstripped-binary-or-object ./usr/bin/hello.dbg
E: libhello0-dbg: binary-with-bad-dynamic-table ./usr/lib/libhello.so.dbg
E: libhello0-dbg: missing-dependency-on-libc needed by ./usr/lib/debug/lib/libhello.so.0.0 and 1 others
E: libhello0-dbg: sharedobject-in-library-directory-missing-soname usr/lib/libhello.so.dbg
+E: libhello0: duplicate-entry-in-symbols-control-file libhello 0
+E: libhello0: invalid-template-id-in-symbols-file 11
+E: libhello0: invalid-template-id-in-symbols-file 13
+E: libhello0: invalid-template-id-in-symbols-file 4
+E: libhello0: symbols-declared-but-not-shlib libhello 2
+E: libhello0: syntax-error-in-symbols-file 1
+E: libhello0: syntax-error-in-symbols-file 10
+E: libhello0: syntax-error-in-symbols-file 14
+E: libhello0: syntax-error-in-symbols-file 18
+E: libhello0: syntax-error-in-symbols-file 3
+E: libhello0: syntax-error-in-symbols-file 4
+E: libhello0: syntax-error-in-symbols-file 8
+E: libhello0: unknown-meta-field-in-symbols-file Build-Dep-Foo, line 10
W: debug source: ancient-standards-version 3.7.0 (current is 3.8.0)
W: debug source: changelog-should-not-mention-nmu
W: debug source: debhelper-script-needs-versioned-build-depends dh_icons (>= 5.0.51~)
@@ -14,3 +28,7 @@ W: hello: binary-without-manpage usr/bin/hello.dbg
W: libhello0-dbg: dbg-package-missing-depends libhello0
W: libhello0-dbg: debug-file-should-use-detached-symbols ./usr/lib/debug/lib/libhello.so.0.0
W: libhello0-dbg: shared-lib-without-dependency-information ./usr/lib/libhello.so.dbg
+W: libhello0: symbols-declares-dependency-on-other-package libhello0c2 (>= 1.2)
+W: libhello0: symbols-declares-dependency-on-other-package libhello2 #MINVER#
+W: libhello0: symbols-declares-dependency-on-other-package libhello2 (>= 1:2.3)
+W: libhello0: unused-shlib-entry-in-symbols-control-file libhello 2
--
Debian package checker
Reply to: