Pārlūkot izejas kodu

dpkg-source (2.0/3.0 (quilt)): refuse binary files in debian subdir

* scripts/Dpkg/Source/Functions.pm (is_binary): New function
to check if a file is binary by using diff against it.
* scripts/Dpkg/Source/Package/V2.pm (do_build): Check that all files from
the debian sub-directory are non-binary and only allow whitelisted binary
files.
* man/dpkg-source.1: Document this behaviour.
Raphael Hertzog 18 gadi atpakaļ
vecāks
revīzija
62a1700ddb

+ 9 - 0
ChangeLog

@@ -1,3 +1,12 @@
+2008-05-08  Raphael Hertzog  <hertzog@debian.org>
+
+	* scripts/Dpkg/Source/Functions.pm (is_binary): New function
+	to check if a file is binary by using diff against it.
+	* scripts/Dpkg/Source/Package/V2.pm: Check that all files from the
+	debian sub-directory are non-binary and only allow whitelisted
+	binary files.
+	* man/dpkg-source.1: Document this behaviour.
+
 2008-05-08  Raphael Hertzog  <hertzog@debian.org>
 2008-05-08  Raphael Hertzog  <hertzog@debian.org>
 
 
 	* scripts/Dpkg/Changelog/Debian.pm (parse): Bugfix in creation of
 	* scripts/Dpkg/Changelog/Debian.pm (parse): Bugfix in creation of

+ 3 - 0
debian/changelog

@@ -36,6 +36,9 @@ dpkg (1.14.19) UNRELEASED; urgency=low
     ::V3::quilt instead of ::V3_0::quilt.
     ::V3::quilt instead of ::V3_0::quilt.
   * Fix changelog parser to not fail when an unexpected changelog entry
   * Fix changelog parser to not fail when an unexpected changelog entry
     appears without the preceding heading line. Closes: #478925
     appears without the preceding heading line. Closes: #478925
+  * Change the "2.0" and "3.0 (quilt)" source packages to refuse by default
+    binary files in the debian sub-directory. They have to be whitelisted
+    through debian/source/include-binaries. Closes: #473041
   
   
   [ Helge Kreutzmann ]
   [ Helge Kreutzmann ]
   * Minor fixes and clarifications to man pages.
   * Minor fixes and clarifications to man pages.

+ 3 - 1
man/dpkg-source.1

@@ -378,7 +378,9 @@ and the diff (if non-empty) is stored in
 on a binary file is not representable in a diff and will thus lead to a
 on a binary file is not representable in a diff and will thus lead to a
 failure unless the maintainer deliberately decided to include that
 failure unless the maintainer deliberately decided to include that
 modified binary file in the debian tarball (by listing it in
 modified binary file in the debian tarball (by listing it in
-\fBdebian/source/include-binaries\fP).
+\fBdebian/source/include-binaries\fP). The build will also fail if it
+finds binary files in the debian sub-directory unless they have been
+whitelisted through \fBdebian/source/include-binaries\fP.
 
 
 The updated debian directory and the list of modified binaries is then
 The updated debian directory and the list of modified binaries is then
 used to regenerate the debian tarball.
 used to regenerate the debian tarball.

+ 27 - 1
scripts/Dpkg/Source/Functions.pm

@@ -5,10 +5,11 @@ use warnings;
 
 
 use Exporter;
 use Exporter;
 our @ISA = qw(Exporter);
 our @ISA = qw(Exporter);
-our @EXPORT_OK = qw(erasedir fixperms);
+our @EXPORT_OK = qw(erasedir fixperms is_binary);
 
 
 use Dpkg::ErrorHandling qw(syserr subprocerr failure);
 use Dpkg::ErrorHandling qw(syserr subprocerr failure);
 use Dpkg::Gettext;
 use Dpkg::Gettext;
+use Dpkg::IPC;
 
 
 use POSIX;
 use POSIX;
 
 
@@ -49,5 +50,30 @@ sub fixperms {
     subprocerr("chmod -R $modes_set $dir") if $?;
     subprocerr("chmod -R $modes_set $dir") if $?;
 }
 }
 
 
+sub is_binary($) {
+    my ($file) = @_;
+
+    # Use diff to check if it's a binary file
+    my $diffgen;
+    my $diff_pid = fork_and_exec(
+        'exec' => [ 'diff', '-u', '--', '/dev/null', $file ],
+        'env' => { LC_ALL => 'C', LANG => 'C', TZ => 'UTC0' },
+        'to_pipe' => \$diffgen
+    );
+    my $result = 0;
+    while (<$diffgen>) {
+        if (m/^binary/i) {
+            $result = 1;
+            last;
+        } elsif (m/^[-+\@ ]/) {
+            $result = 0;
+            last;
+        }
+    }
+    close($diffgen) or syserr("close on diff pipe");
+    wait_child($diff_pid, nocheck => 1, cmdline => "diff -u -- /dev/null $file");
+    return $result;
+}
+
 # vim: set et sw=4 ts=8
 # vim: set et sw=4 ts=8
 1;
 1;

+ 19 - 2
scripts/Dpkg/Source/Package/V2.pm

@@ -29,7 +29,7 @@ use Dpkg::Source::Archive;
 use Dpkg::Source::Patch;
 use Dpkg::Source::Patch;
 use Dpkg::Version qw(check_version);
 use Dpkg::Version qw(check_version);
 use Dpkg::Exit;
 use Dpkg::Exit;
-use Dpkg::Source::Functions qw(erasedir);
+use Dpkg::Source::Functions qw(erasedir is_binary);
 
 
 use POSIX;
 use POSIX;
 use File::Basename;
 use File::Basename;
@@ -308,6 +308,23 @@ sub do_build {
             $self->register_error();
             $self->register_error();
         }
         }
     };
     };
+    # Check if the debian directory contains unwanted binary files
+    my $unwanted_binaries = 0;
+    my $check_binary = sub {
+        my $fn = File::Spec->abs2rel($_, $dir);
+        if (-f $_ and is_binary($_)) {
+            if ($include_binaries or $auth_bin_files{$fn}) {
+                push @binary_files, $fn;
+            } else {
+                errormsg(_g("unwanted binary file: %s"), $fn);
+                $unwanted_binaries++;
+            }
+        }
+    };
+    find({ wanted => $check_binary, no_chdir => 1 }, File::Spec->catdir($dir, "debian"));
+    error(_g("detected %d unwanted binary file(s) " .
+        "(add them in debian/source/include-binaries to allow their " .
+        "inclusion)."), $unwanted_binaries) if $unwanted_binaries;
 
 
     # Create a patch
     # Create a patch
     my ($difffh, $tmpdiff) = tempfile("$basenamerev.diff.XXXXXX",
     my ($difffh, $tmpdiff) = tempfile("$basenamerev.diff.XXXXXX",
@@ -360,7 +377,7 @@ sub do_build {
     $tar->create(options => \@tar_ignore, 'chdir' => $dir);
     $tar->create(options => \@tar_ignore, 'chdir' => $dir);
     $tar->add_directory("debian");
     $tar->add_directory("debian");
     foreach my $binary (@binary_files) {
     foreach my $binary (@binary_files) {
-        $tar->add_file($binary);
+        $tar->add_file($binary) unless $binary =~ m{^debian/};
     }
     }
     $tar->finish();
     $tar->finish();