瀏覽代碼

Dpkg::Version: fix boolean evaluation of the object

In a boolean context, the object evaluates like the version string if
the version is valid, otherwise it evaluates like undef. Document
this behaviour and add non-regression test to ensure it's kept.

This implicitly fix dpkg-shlibdeps who relies on the boolean evaluation
of the object to decide whether or not a minimal version specification
is needed or not.
Raphaël Hertzog 16 年之前
父節點
當前提交
5b9f353b29
共有 3 個文件被更改,包括 24 次插入4 次删除
  1. 5 0
      debian/changelog
  2. 11 3
      scripts/Dpkg/Version.pm
  3. 8 1
      scripts/t/100_Dpkg_Version.t

+ 5 - 0
debian/changelog

@@ -5,6 +5,11 @@ dpkg (1.15.7.2) UNRELEASED; urgency=low
     $XDG_CONFIG_HOME/dpkg/buildflags.conf by default.
   * Update deb-substvars(5) to codify how variables containing multiple
     lines must be managed.
+  * Fix boolean evaluation of Dpkg::Version so that version 0 evaluates to
+    false and dpkg-shlibdeps can strip the minimal version specification.
+    Closes: #579724
+    Document this behaviour in the API and add non-regression test to ensure
+    it's kept.
 
   [ Guillem Jover ]
   * Add powerpcspe support to ostable and triplettable.

+ 11 - 3
scripts/Dpkg/Version.pm

@@ -44,7 +44,7 @@ use overload
     '<=>' => \&comparison,
     'cmp' => \&comparison,
     '""'  => \&as_string,
-    'bool' => sub { return $_[0]->is_valid(); },
+    'bool' => sub { return $_[0]->as_string() if $_[0]->is_valid(); },
     'fallback' => 1;
 
 =encoding utf8
@@ -107,6 +107,12 @@ sub new {
     return bless $self, $class;
 }
 
+=item boolean evaluation
+
+When the Dpkg::Version object is used in a boolean evaluation (for example
+in "if ($v)" or "$v || 'default'") it returns its string representation
+if the version stored is valid ($v->is_valid()) and undef otherwise.
+
 =item $v->is_valid()
 
 Returns true if the version is valid, false otherwise.
@@ -194,8 +200,10 @@ If $a or $b are not valid version numbers, it dies with an error.
 
 sub version_compare($$) {
     my ($a, $b) = @_;
-    my $va = Dpkg::Version->new($a, check => 1) || error(_g("%s is not a valid version"), "$a");
-    my $vb = Dpkg::Version->new($b, check => 1) || error(_g("%s is not a valid version"), "$b");
+    my $va = Dpkg::Version->new($a, check => 1);
+    defined($va) || error(_g("%s is not a valid version"), "$a");
+    my $vb = Dpkg::Version->new($b, check => 1);
+    defined($vb) || error(_g("%s is not a valid version"), "$b");
     return $va <=> $vb;
 }
 

+ 8 - 1
scripts/t/100_Dpkg_Version.t

@@ -28,7 +28,7 @@ my @ops = ("<", "<<", "lt",
 	   ">=", "ge",
 	   ">", ">>", "gt");
 
-plan tests => scalar(@tests) * (3 * scalar(@ops) + 4) + 8;
+plan tests => scalar(@tests) * (3 * scalar(@ops) + 4) + 11;
 
 sub dpkg_vercmp {
      my ($a, $cmp, $b) = @_;
@@ -82,11 +82,18 @@ ok($empty->as_string() eq "", "Dpkg::Version->new('')->as_string() eq ''");
 ok(!$empty->is_valid(), "empty version is invalid");
 my $ver = Dpkg::Version->new("10a:5.2");
 ok(!$ver->is_valid(), "bad epoch is invalid");
+ok(!$ver, "bool eval of invalid leads to false");
 ok($ver eq '10a:5.2', "invalid still same string 1/2");
 $ver = Dpkg::Version->new('5.2@3-2');
 ok($ver eq '5.2@3-2', "invalid still same string 2/2");
 ok(!$ver->is_valid(), "illegal character is invalid");
 
+# Other tests
+$ver = Dpkg::Version->new('1.2.3-4');
+is($ver || 'default', '1.2.3-4', "bool eval returns string representation");
+$ver = Dpkg::Version->new('0');
+is($ver || 'default', 'default', "bool eval of version 0 is still false...");
+
 # Comparisons
 foreach my $case (@tests) {
     my ($a, $b, $res) = split " ", $case;