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 4a021ec2f [LANG-1802] Fix collision in CharRange.hashCode()
4a021ec2f is described below
commit 4a021ec2ffb7bbf5f1e2b73557f20c22a60a337a
Author: Gary Gregory <[email protected]>
AuthorDate: Sun Dec 14 08:11:42 2025 -0500
[LANG-1802] Fix collision in CharRange.hashCode()
More tests
---
.../org/apache/commons/lang3/CharRangeTest.java | 44 ++++++++++++++++++----
1 file changed, 36 insertions(+), 8 deletions(-)
diff --git a/src/test/java/org/apache/commons/lang3/CharRangeTest.java
b/src/test/java/org/apache/commons/lang3/CharRangeTest.java
index 75018b9ca..173843149 100644
--- a/src/test/java/org/apache/commons/lang3/CharRangeTest.java
+++ b/src/test/java/org/apache/commons/lang3/CharRangeTest.java
@@ -316,14 +316,42 @@ void testHashCode() {
*/
@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 various combinations of different ranges
+ final CharRange range1 = CharRange.is('a');
+ final CharRange range2 = CharRange.is('b');
+ final CharRange range3 = CharRange.isIn('a', 'z');
+ final CharRange range4 = CharRange.isIn('b', 'z');
+ final CharRange range5 = CharRange.isNot('a');
+ final CharRange range6 = CharRange.isNotIn('a', 'z');
+ final CharRange range7 = CharRange.isNotIn('b', 'z');
+ final CharRange range8 = CharRange.isIn((char) 1, (char) 2);
+ final CharRange range9 = CharRange.isNotIn((char) 1, (char) 2);
+ // Previously problematic cases from LANG-1802 should now have
different hash codes
+ final CharRange a1 = CharRange.isNotIn((char) 1, (char) 2);
+ final CharRange a2 = CharRange.isIn((char) 2, (char) 2);
+ assertNotEquals(a1, a2, "Different ranges should not be equal");
+ assertNotEquals(a1.hashCode(), a2.hashCode(), "Different ranges should
have different hash codes");
+ final CharRange b1 = CharRange.isIn((char) 5, (char) 5);
+ final CharRange b2 = CharRange.isNotIn((char) 4, (char) 5);
+ assertNotEquals(b1, b2, "Different ranges should not be equal");
+ assertNotEquals(b1.hashCode(), b2.hashCode(), "Different ranges should
have different hash codes");
+ // Test that negated and non-negated ranges with same bounds have
different hash codes
+ final CharRange normal = CharRange.isIn('x', 'y');
+ final CharRange negated = CharRange.isNotIn('x', 'y');
+ assertNotEquals(normal, negated, "Negated and normal ranges should not
be equal");
+ assertNotEquals(normal.hashCode(), negated.hashCode(), "Negated and
normal ranges should have different hash codes");
+ // Test that ranges with different start/end produce different hash
codes
+ assertNotEquals(range1.hashCode(), range2.hashCode(), "is('a') vs
is('b')");
+ assertNotEquals(range1.hashCode(), range3.hashCode(), "is('a') vs
isIn('a','z')");
+ assertNotEquals(range3.hashCode(), range4.hashCode(), "isIn('a','z')
vs isIn('b','z')");
+ assertNotEquals(range1.hashCode(), range5.hashCode(), "is('a') vs
isNot('a')");
+ assertNotEquals(range3.hashCode(), range6.hashCode(), "isIn('a','z')
vs isNotIn('a','z')");
+ assertNotEquals(range6.hashCode(), range7.hashCode(),
"isNotIn('a','z') vs isNotIn('b','z')");
+ assertNotEquals(range8.hashCode(), range9.hashCode(), "isIn(1,2) vs
isNotIn(1,2)");
+ // Test that equal ranges have equal hash codes
+ final CharRange sameAsRange1 = CharRange.is('a');
+ assertEquals(range1, sameAsRange1, "Equal ranges should be equal");
+ assertEquals(range1.hashCode(), sameAsRange1.hashCode(), "Equal ranges
should have equal hash codes");
}
@Test