summaryrefslogtreecommitdiffstats
path: root/Bugzilla/Version.pm
diff options
context:
space:
mode:
authorFrédéric Buclin <LpSolit@gmail.com>2013-12-02 17:04:12 +0100
committerFrédéric Buclin <LpSolit@gmail.com>2013-12-02 17:04:12 +0100
commit26724018067fca77977e343263487bf2b6b25ba2 (patch)
tree4c8331dc298671c8d4aa5136ded475e43ff504ff /Bugzilla/Version.pm
parente21cee47ced69277073d3d2395e8a7cb64e71c14 (diff)
downloadbugzilla-26724018067fca77977e343263487bf2b6b25ba2.tar.gz
bugzilla-26724018067fca77977e343263487bf2b6b25ba2.tar.xz
Bug 938300: vers_cmp() incorrectly compares module versions
r=sgreen a=justdave
Diffstat (limited to 'Bugzilla/Version.pm')
-rw-r--r--Bugzilla/Version.pm98
1 files changed, 93 insertions, 5 deletions
diff --git a/Bugzilla/Version.pm b/Bugzilla/Version.pm
index 1dcd2b141..c6b178a8a 100644
--- a/Bugzilla/Version.pm
+++ b/Bugzilla/Version.pm
@@ -10,9 +10,10 @@ package Bugzilla::Version;
use 5.10.1;
use strict;
-use parent qw(Bugzilla::Object);
+use parent qw(Bugzilla::Object Exporter);
+
+@Bugzilla::Version::EXPORT = qw(vers_cmp);
-use Bugzilla::Install::Util qw(vers_cmp);
use Bugzilla::Util;
use Bugzilla::Error;
@@ -200,6 +201,53 @@ sub _check_product {
return Bugzilla->user->check_can_admin_product($product->name);
}
+###############################
+##### Functions ####
+###############################
+
+# This is taken straight from Sort::Versions 1.5, which is not included
+# with perl by default.
+sub vers_cmp {
+ my ($a, $b) = @_;
+
+ # Remove leading zeroes - Bug 344661
+ $a =~ s/^0*(\d.+)/$1/;
+ $b =~ s/^0*(\d.+)/$1/;
+
+ my @A = ($a =~ /([-.]|\d+|[^-.\d]+)/g);
+ my @B = ($b =~ /([-.]|\d+|[^-.\d]+)/g);
+
+ my ($A, $B);
+ while (@A and @B) {
+ $A = shift @A;
+ $B = shift @B;
+ if ($A eq '-' and $B eq '-') {
+ next;
+ } elsif ( $A eq '-' ) {
+ return -1;
+ } elsif ( $B eq '-') {
+ return 1;
+ } elsif ($A eq '.' and $B eq '.') {
+ next;
+ } elsif ( $A eq '.' ) {
+ return -1;
+ } elsif ( $B eq '.' ) {
+ return 1;
+ } elsif ($A =~ /^\d+$/ and $B =~ /^\d+$/) {
+ if ($A =~ /^0/ || $B =~ /^0/) {
+ return $A cmp $B if $A cmp $B;
+ } else {
+ return $A <=> $B if $A <=> $B;
+ }
+ } else {
+ $A = uc $A;
+ $B = uc $B;
+ return $A cmp $B if $A cmp $B;
+ }
+ }
+ return @A <=> @B;
+}
+
1;
__END__
@@ -243,11 +291,51 @@ below.
=item C<bug_count()>
- Description: Returns the total of bugs that belong to the version.
+=over
+
+=item B<Description>
+
+Returns the total of bugs that belong to the version.
+
+=item B<Params>
+
+none
+
+=item B<Returns>
+
+Integer with the number of bugs.
+
+=back
+
+=back
+
+=head1 FUNCTIONS
+
+=over
+
+=item C<vers_cmp($a, $b)>
+
+=over
+
+=item B<Description>
+
+This is a comparison function, like you would use in C<sort>, except that
+it compares two version numbers. So, for example, 2.10 would be greater
+than 2.2.
+
+It's based on versioncmp from L<Sort::Versions>, with some Bugzilla-specific
+fixes.
- Params: none.
+=item B<Params>
- Returns: Integer with the number of bugs.
+C<$a> and C<$b> - The versions you want to compare.
+
+=item B<Returns>
+
+C<-1> if C<$a> is less than C<$b>, C<0> if they are equal, or C<1> if C<$a>
+is greater than C<$b>.
+
+=back
=back