You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by el...@apache.org on 2025/01/30 02:42:33 UTC

(maven) 01/01: Handle non-BMP characters

This is an automated email from the ASF dual-hosted git repository.

elharo pushed a commit to branch MNG-8241
in repository https://gitbox.apache.org/repos/asf/maven.git

commit bd998355594fff3ec4be6ff906803845ea92ab08
Author: Elliotte Rusty Harold <el...@ibiblio.org>
AuthorDate: Wed Jan 29 20:42:22 2025 -0600

    Handle non-BMP characters
---
 .../maven/artifact/versioning/ComparableVersion.java    | 17 +++++++++++++++--
 .../artifact/versioning/ComparableVersionTest.java      | 17 +++++++++++++++++
 2 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/compat/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/ComparableVersion.java b/compat/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/ComparableVersion.java
index 2ed439d375..6ce4002c21 100644
--- a/compat/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/ComparableVersion.java
+++ b/compat/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/ComparableVersion.java
@@ -656,7 +656,19 @@ public final void parseVersion(String version) {
         int startIndex = 0;
 
         for (int i = 0; i < version.length(); i++) {
-            char c = version.charAt(i);
+            char character = version.charAt(i);
+            int c = character;
+            if (Character.isHighSurrogate( character )) {
+                // read the next character as a low surrogate and combine into a single int
+                try {
+                    char low = version.charAt( i + 1);
+                    char[] both = {character, low};
+                    c = Character.codePointAt( both, 0 );
+                    i++;
+                } catch (IndexOutOfBoundsException ex) {
+                    // high surrogate without low surrogate. Not a lot we can do here except treat it as a regular character
+                }
+            }
 
             if (c == '.') {
                 if (i == startIndex) {
@@ -687,7 +699,8 @@ public final void parseVersion(String version) {
                     stack.push(list);
                 }
                 isCombination = false;
-            } else if (Character.isDigit(c)) {
+                // TODO we might not want to use isDigit here; just check for ASCII digits only
+            } else if (Character.isDigit(c) && Character.isBmpCodePoint( c )) {
                 if (!isDigit && i > startIndex) {
                     // X1
                     isCombination = true;
diff --git a/compat/maven-artifact/src/test/java/org/apache/maven/artifact/versioning/ComparableVersionTest.java b/compat/maven-artifact/src/test/java/org/apache/maven/artifact/versioning/ComparableVersionTest.java
index da4c247baa..af9558b15f 100644
--- a/compat/maven-artifact/src/test/java/org/apache/maven/artifact/versioning/ComparableVersionTest.java
+++ b/compat/maven-artifact/src/test/java/org/apache/maven/artifact/versioning/ComparableVersionTest.java
@@ -222,6 +222,23 @@ void testLeadingZeroes() {
         checkVersionsOrder("0.2", "1.0.7");
     }
 
+    @Test
+    void testDigitGreaterThanNonAscii() {
+        ComparableVersion c1 = new ComparableVersion("1");
+        ComparableVersion c2 = new ComparableVersion( "é" );
+        assertTrue(c1.compareTo(c2) > 0, "expected " + "1" + " > " + "\uD835\uDFE4" );
+        assertTrue(c2.compareTo(c1) < 0, "expected " + "\uD835\uDFE4" + " < " + "1" );
+    }
+
+    @Test
+    void testDigitGreaterThanNonBmpCharacters() {
+        ComparableVersion c1 = new ComparableVersion("1");
+        // MATHEMATICAL SANS-SERIF DIGIT TWO
+        ComparableVersion c2 = new ComparableVersion( "\uD835\uDFE4" );
+        assertTrue(c1.compareTo(c2) > 0, "expected " + "1" + " > " + "\uD835\uDFE4" );
+        assertTrue(c2.compareTo(c1) < 0, "expected " + "\uD835\uDFE4" + " < " + "1" );
+    }
+
     @Test
     void testGetCanonical() {
         // MNG-7700