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

[SCM] Debian package checker branch, master, updated. 2.5.12-134-gc954636



The following commit has been merged in the master branch:
commit c954636c95cba071f77ec12d4044011620abc892
Author: Niels Thykier <niels@thykier.net>
Date:   Tue May 28 14:07:53 2013 +0200

    lintian: Bounds check the exit code in END
    
    lintian is documented to exit with 0, 1 or 2.  However, in pratise
    lintian would in many common cases exit with another value.  A trival
    example being passing wrong arguments:
    
      $ lintian --bad-arg 2>/dev/null ; echo $?
      255
    
    In particular, if the perl interpreter dies from an uncaught
    exception, perl will determine the error code based on $! and $?.
    
    This patch will have the END handler modify the exit code so that it
    is always one of 0, 1 or 2.  It is not a flawless solution as $! (or
    $? >> 8) could be 1 causing lintian in rare cases to exit with 1 when
    2 would have been more appropriate.
    
    Most of the bad exit codes comes from the frontend itself (especially
    prior to loading the Lintian modules).
    
    Signed-off-by: Niels Thykier <niels@thykier.net>

diff --git a/.perlcriticrc b/.perlcriticrc
index 5888d47..170054a 100644
--- a/.perlcriticrc
+++ b/.perlcriticrc
@@ -48,4 +48,4 @@ allow_last_statement_to_be_comma_separated_in_map_and_grep = 1
 [-ValuesAndExpressions::ProhibitConstantPragma]
 
 [Variables::RequireLocalizedPunctuationVars]
-allow = %ENV %SIG $!
+allow = %ENV %SIG $! $?
diff --git a/debian/changelog b/debian/changelog
index defe8fd..814fe70 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -136,6 +136,8 @@ lintian (2.5.13) UNRELEASED; urgency=low
       subprocesses.  These are ":"-separated lists of dirs used by
       Lintian.  The first being a list of raw include dirs and the
       second being a list of helpers dirs in these include dirs.
+    + [NT] Fix a bug where the exit code from lintian would
+      sometimes be an undocumented value (>= 3).
 
   * helpers/coll:
     + [NT] New directory containing some helpers that used to be in
diff --git a/frontend/lintian b/frontend/lintian
index b0100a9..26053e3 100755
--- a/frontend/lintian
+++ b/frontend/lintian
@@ -1681,16 +1681,54 @@ sub _update_profile {
 # {{{ Exit handler.
 
 sub END {
-    # Prevent Lab->close from affecting the exit code.
-    local $?;
 
     $SIG{'INT'} = 'DEFAULT';
     $SIG{'QUIT'} = 'DEFAULT';
 
-    # Kill any remaining jobs.
-    $unpacker->kill_jobs if $unpacker;
+    # We have to ensure that our exit code is 0, 1 or 2.  Quote from
+    # "perldoc -f die":
+    #
+    # """
+    # If an uncaught exception results in interpreter exit, the exit
+    # code is determined from the values of $! and $? with this
+    # pseudocode:
+    #
+    #   exit $! if $!; # errno
+    #   exit $? >> 8 if $? >> 8; # child exit status
+    #   exit 255;
+    # """
+    #
+    # So, here in the END handler, we abuse the fact that we can alter
+    # the exit code by changing $?.  It is not a perfect solution
+    # (e.g.  if $! is 1, then we might still exit 1 instead of 2), but
+    # it is definitely better than exiting with undocumented exit codes.
+    if ($? != 0 && $? != 2) {
+        # If $? is not 1, then we definitely want $? to be 2.  If
+        # $exit_code != 1, then either we got an uncaught exception
+        # before the first policy violation or we already saw an
+        # internal error that we caught.  Either way, we want to
+        # exit with 2 in this case.
+        #
+        # Sadly, this is unreliable if we saw a policy violation and
+        # then cause an uncaught internal error (where e.g. $! is 1).
+        # In this case we will still exit 1 instead of 2 as we should.
+        # Nevertheless, this is probably a lot more reliable than
+        # Lintian <= 2.5.12 was.
+        if ($? != 1 || $exit_code != 1) {
+            $? = 2;
+        }
+    }
+
+    if (1) {
+        # Prevent LAB->close and $unpacker->kill_jobs from affecting
+        # the exit code.
+        local $?;
 
-    $LAB->close if $LAB;
+        # Kill any remaining jobs.
+        $unpacker->kill_jobs if $unpacker;
+
+        $LAB->close if $LAB;
+    };
 }
 
 sub interrupted {

-- 
Debian package checker


Reply to: