Repository: maven
Updated Branches:
  refs/heads/master 09d64bdf5 -> 14e4885de


[MNG-5568] fixed edge case version parsing bug causing inconsistent
comparison results

Project: http://git-wip-us.apache.org/repos/asf/maven/repo
Commit: http://git-wip-us.apache.org/repos/asf/maven/commit/14e4885d
Tree: http://git-wip-us.apache.org/repos/asf/maven/tree/14e4885d
Diff: http://git-wip-us.apache.org/repos/asf/maven/diff/14e4885d

Branch: refs/heads/master
Commit: 14e4885de9729c88715b4036a740733c0476e472
Parents: 09d64bd
Author: Hervé Boutemy <[email protected]>
Authored: Sun Nov 30 23:26:12 2014 +0100
Committer: Hervé Boutemy <[email protected]>
Committed: Sun Nov 30 23:26:12 2014 +0100

----------------------------------------------------------------------
 .../artifact/versioning/ComparableVersion.java  | 33 ++++++++----------
 .../versioning/ComparableVersionTest.java       | 36 +++++++++++++++-----
 2 files changed, 42 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/maven/blob/14e4885d/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/ComparableVersion.java
----------------------------------------------------------------------
diff --git 
a/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/ComparableVersion.java
 
b/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/ComparableVersion.java
index df8543b..bc9797c 100644
--- 
a/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/ComparableVersion.java
+++ 
b/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/ComparableVersion.java
@@ -269,14 +269,16 @@ public class ComparableVersion
 
         void normalize()
         {
-            for ( ListIterator<Item> iterator = listIterator( size() ); 
iterator.hasPrevious(); )
+            for ( int i = size() - 1; i >= 0; i-- )
             {
-                Item item = iterator.previous();
-                if ( item.isNull() )
+                Item lastItem = get( i );
+
+                if ( lastItem.isNull() )
                 {
-                    iterator.remove(); // remove null trailing items: 0, "", 
empty list
+                    // remove null trailing items: 0, "", empty list
+                    remove( i );
                 }
-                else
+                else if ( !( lastItem instanceof ListItem ) )
                 {
                     break;
                 }
@@ -393,19 +395,8 @@ public class ComparableVersion
                 }
                 startIndex = i + 1;
 
-                if ( isDigit )
-                {
-                    list.normalize(); // 1.0-* = 1-*
-
-                    if ( ( i + 1 < version.length() ) && Character.isDigit( 
version.charAt( i + 1 ) ) )
-                    {
-                        // new ListItem only if previous were digits and new 
char is a digit,
-                        // ie need to differentiate only 1.1 from 1-1
-                        list.add( list = new ListItem() );
-
-                        stack.push( list );
-                    }
-                }
+                list.add( list = new ListItem() );
+                stack.push( list );
             }
             else if ( Character.isDigit( c ) )
             {
@@ -413,6 +404,9 @@ public class ComparableVersion
                 {
                     list.add( new StringItem( version.substring( startIndex, i 
), true ) );
                     startIndex = i;
+
+                    list.add( list = new ListItem() );
+                    stack.push( list );
                 }
 
                 isDigit = true;
@@ -423,6 +417,9 @@ public class ComparableVersion
                 {
                     list.add( parseItem( true, version.substring( startIndex, 
i ) ) );
                     startIndex = i;
+
+                    list.add( list = new ListItem() );
+                    stack.push( list );
                 }
 
                 isDigit = false;

http://git-wip-us.apache.org/repos/asf/maven/blob/14e4885d/maven-artifact/src/test/java/org/apache/maven/artifact/versioning/ComparableVersionTest.java
----------------------------------------------------------------------
diff --git 
a/maven-artifact/src/test/java/org/apache/maven/artifact/versioning/ComparableVersionTest.java
 
b/maven-artifact/src/test/java/org/apache/maven/artifact/versioning/ComparableVersionTest.java
index 7e37625..6cf372f 100644
--- 
a/maven-artifact/src/test/java/org/apache/maven/artifact/versioning/ComparableVersionTest.java
+++ 
b/maven-artifact/src/test/java/org/apache/maven/artifact/versioning/ComparableVersionTest.java
@@ -38,6 +38,7 @@ public class ComparableVersionTest
         String canonical = ret.getCanonical();
         String parsedCanonical = new ComparableVersion( canonical 
).getCanonical();
 
+        System.out.println( "canonical( " + version + " ) = " + canonical );
         assertEquals( "canonical( " + version + " ) = " + canonical + " -> 
canonical: " + parsedCanonical, canonical,
                       parsedCanonical );
 
@@ -104,6 +105,7 @@ public class ComparableVersionTest
 
     public void testVersionsEqual()
     {
+        newComparable( "1.0-alpha" );
         checkVersionsEqual( "1", "1" );
         checkVersionsEqual( "1", "1.0" );
         checkVersionsEqual( "1", "1.0.0" );
@@ -112,18 +114,16 @@ public class ComparableVersionTest
         checkVersionsEqual( "1", "1.0-0" );
         checkVersionsEqual( "1.0", "1.0-0" );
         // no separator between number and character
-        checkVersionsEqual( "1a", "1.a" );
         checkVersionsEqual( "1a", "1-a" );
         checkVersionsEqual( "1a", "1.0-a" );
         checkVersionsEqual( "1a", "1.0.0-a" );
-        checkVersionsEqual( "1.0a", "1.0.a" );
-        checkVersionsEqual( "1.0.0a", "1.0.0.a" );
-        checkVersionsEqual( "1x", "1.x" );
+        checkVersionsEqual( "1.0a", "1-a" );
+        checkVersionsEqual( "1.0.0a", "1-a" );
         checkVersionsEqual( "1x", "1-x" );
         checkVersionsEqual( "1x", "1.0-x" );
         checkVersionsEqual( "1x", "1.0.0-x" );
-        checkVersionsEqual( "1.0x", "1.0.x" );
-        checkVersionsEqual( "1.0.0x", "1.0.0.x" );
+        checkVersionsEqual( "1.0x", "1-x" );
+        checkVersionsEqual( "1.0.0x", "1-x" );
 
         // aliases
         checkVersionsEqual( "1ga", "1" );
@@ -131,9 +131,9 @@ public class ComparableVersionTest
         checkVersionsEqual( "1cr", "1rc" );
 
         // special "aliases" a, b and m for alpha, beta and milestone
-        checkVersionsEqual( "1a1", "1alpha1" );
-        checkVersionsEqual( "1b2", "1beta2" );
-        checkVersionsEqual( "1m3", "1milestone3" );
+        checkVersionsEqual( "1a1", "1-alpha-1" );
+        checkVersionsEqual( "1b2", "1-beta-2" );
+        checkVersionsEqual( "1m3", "1-milestone-3" );
 
         // case insensitive
         checkVersionsEqual( "1X", "1x" );
@@ -183,6 +183,24 @@ public class ComparableVersionTest
         checkVersionsOrder( "2.0.1-xyz", "2.0.1-123" );
     }
 
+    /**
+     * Test <a href="https://jira.codehaus.org/browse/MNG-5568";>MNG-5568</a> 
edge case
+     * which was showing transitive inconsistency: since A > B and B > C then 
we should have A > C
+     * otherwise sorting a list of ComparableVersions() will in some cases 
throw runtime exception;
+     * see Netbeans issues <a 
href="https://netbeans.org/bugzilla/show_bug.cgi?id=240845";>240845</a> and
+     * <a 
href="https://netbeans.org/bugzilla/show_bug.cgi?id=226100";>226100</a>
+     */
+    public void testMng5568()
+    {
+        String a = "6.1.0";
+        String b = "6.1.0rc3";
+        String c = "6.1H.5-beta"; // this is the unusual version string, with 
'H' in the middle
+
+        checkVersionsOrder( b, a ); // classical
+        checkVersionsOrder( b, c ); // now b < c, but before MNG-5568, we had 
b > c
+        checkVersionsOrder( a, c );
+    }
+
     public void testLocaleIndependent()
     {
         Locale orig = Locale.getDefault();

Reply via email to