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

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-lang.git


The following commit(s) were added to refs/heads/master by this push:
     new 97e572cb7 [LANG-1802] Fix collision in CharRange.hashCode()
97e572cb7 is described below

commit 97e572cb7e104b09573bba1881a764d9bac81bc8
Author: Gary Gregory <[email protected]>
AuthorDate: Sun Dec 14 08:01:35 2025 -0500

    [LANG-1802] Fix collision in CharRange.hashCode()
---
 src/changes/changes.xml                                   |  1 +
 src/main/java/org/apache/commons/lang3/CharRange.java     |  2 +-
 src/test/java/org/apache/commons/lang3/CharRangeTest.java | 15 +++++++++++++++
 3 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index f6bd5dc72..5ebee078d 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -73,6 +73,7 @@ The <action> type attribute can be add,update,fix,remove.
     <action                   type="fix" dev="ggregory" due-to="David Du, Gary 
Gregory">Speed up StringUtils.getDigits(String) #1515.</action>
     <action                   type="fix" dev="ggregory" due-to="David Du, Gary 
Gregory">Remove redundant length check in StringUtils.isBlank(CharSequence) 
#1516.</action>
     <action issue="LANG-1800" type="fix" dev="ggregory" 
due-to="IcoreE">Incorrect grammar and unclear wording in 
RandomStringUtils#random method #1520.</action>
+    <action issue="LANG-1802" type="fix" dev="ggregory" due-to="Gary Gregory, 
IcoreE">Fix collision in CharRange.hashCode().</action>
     <!-- ADD -->
     <!-- UPDATE -->
     <action                   type="update" dev="ggregory" due-to="Gary 
Gregory, Dependabot">Bump org.apache.commons:commons-parent from 92 to 93 
#1498.</action>
diff --git a/src/main/java/org/apache/commons/lang3/CharRange.java 
b/src/main/java/org/apache/commons/lang3/CharRange.java
index 13b8109bd..220ec2bbf 100644
--- a/src/main/java/org/apache/commons/lang3/CharRange.java
+++ b/src/main/java/org/apache/commons/lang3/CharRange.java
@@ -314,7 +314,7 @@ public char getStart() {
      */
     @Override
     public int hashCode() {
-        return 83 + start + 7 * end + (negated ? 1 : 0);
+        return Objects.hash(end, negated, start);
     }
 
     /**
diff --git a/src/test/java/org/apache/commons/lang3/CharRangeTest.java 
b/src/test/java/org/apache/commons/lang3/CharRangeTest.java
index 9bbbd745d..75018b9ca 100644
--- a/src/test/java/org/apache/commons/lang3/CharRangeTest.java
+++ b/src/test/java/org/apache/commons/lang3/CharRangeTest.java
@@ -311,6 +311,21 @@ void testHashCode() {
         assertNotEquals(rangenotbf.hashCode(), rangeae.hashCode());
     }
 
+    /**
+     * Tests https://issues.apache.org/jira/browse/LANG-1802
+     */
+    @Test
+    void testHashCodeLang1802() {
+        // case A:hash=99
+        final CharRange a1 = CharRange.isNotIn((char) 1, (char) 2); // 
1,2,true → 83+1+14+1=99
+        final CharRange a2 = CharRange.isIn((char) 2, (char) 2); // 2,2,false 
→ 83+2+14+0=99
+        assertNotEquals(a1.hashCode(), a2.hashCode()); // Collision
+        // case B:hash=123
+        final CharRange b1 = CharRange.isIn((char) 5, (char) 5); // 5,5,false 
→83+5+35+0=123
+        final CharRange b2 = CharRange.isNotIn((char) 4, (char) 5); // 
4,5,true →83+4+35+1=123
+        assertNotEquals(b1.hashCode(), b2.hashCode()); // Collision
+    }
+
     @Test
     void testIterator() {
         final CharRange a = CharRange.is('a');

Reply via email to