Skip to content

Commit 97e572c

Browse files
committed
[LANG-1802] Fix collision in CharRange.hashCode()
1 parent 745a700 commit 97e572c

File tree

3 files changed

+17
-1
lines changed

3 files changed

+17
-1
lines changed

src/changes/changes.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ The <action> type attribute can be add,update,fix,remove.
7373
<action type="fix" dev="ggregory" due-to="David Du, Gary Gregory">Speed up StringUtils.getDigits(String) #1515.</action>
7474
<action type="fix" dev="ggregory" due-to="David Du, Gary Gregory">Remove redundant length check in StringUtils.isBlank(CharSequence) #1516.</action>
7575
<action issue="LANG-1800" type="fix" dev="ggregory" due-to="IcoreE">Incorrect grammar and unclear wording in RandomStringUtils#random method #1520.</action>
76+
<action issue="LANG-1802" type="fix" dev="ggregory" due-to="Gary Gregory, IcoreE">Fix collision in CharRange.hashCode().</action>
7677
<!-- ADD -->
7778
<!-- UPDATE -->
7879
<action type="update" dev="ggregory" due-to="Gary Gregory, Dependabot">Bump org.apache.commons:commons-parent from 92 to 93 #1498.</action>

src/main/java/org/apache/commons/lang3/CharRange.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ public char getStart() {
314314
*/
315315
@Override
316316
public int hashCode() {
317-
return 83 + start + 7 * end + (negated ? 1 : 0);
317+
return Objects.hash(end, negated, start);
318318
}
319319

320320
/**

src/test/java/org/apache/commons/lang3/CharRangeTest.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,21 @@ void testHashCode() {
311311
assertNotEquals(rangenotbf.hashCode(), rangeae.hashCode());
312312
}
313313

314+
/**
315+
* Tests https://issues.apache.org/jira/browse/LANG-1802
316+
*/
317+
@Test
318+
void testHashCodeLang1802() {
319+
// case A:hash=99
320+
final CharRange a1 = CharRange.isNotIn((char) 1, (char) 2); // 1,2,true → 83+1+14+1=99
321+
final CharRange a2 = CharRange.isIn((char) 2, (char) 2); // 2,2,false → 83+2+14+0=99
322+
assertNotEquals(a1.hashCode(), a2.hashCode()); // Collision
323+
// case B:hash=123
324+
final CharRange b1 = CharRange.isIn((char) 5, (char) 5); // 5,5,false →83+5+35+0=123
325+
final CharRange b2 = CharRange.isNotIn((char) 4, (char) 5); // 4,5,true →83+4+35+1=123
326+
assertNotEquals(b1.hashCode(), b2.hashCode()); // Collision
327+
}
328+
314329
@Test
315330
void testIterator() {
316331
final CharRange a = CharRange.is('a');

0 commit comments

Comments
 (0)