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

commit bd40b4511ca092bac23423bff9fbdc2a12e9dd24
Author: Gary Gregory <[email protected]>
AuthorDate: Sun Dec 14 09:20:45 2025 -0500

    Fix race condition in Range.hashCode()
---
 src/changes/changes.xml                           |  1 +
 src/main/java/org/apache/commons/lang3/Range.java | 17 ++++++-----------
 2 files changed, 7 insertions(+), 11 deletions(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 526f8264c..225dd6eb4 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -75,6 +75,7 @@ The <action> type attribute can be add,update,fix,remove.
     <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>
     <action                   type="fix" dev="ggregory" due-to="Gary 
Gregory">Fix race condition in Fraction.hashCode().</action>
+    <action                   type="fix" dev="ggregory" due-to="Gary 
Gregory">Fix race condition in Range.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/Range.java 
b/src/main/java/org/apache/commons/lang3/Range.java
index 488f8e3eb..4193ca8c7 100644
--- a/src/main/java/org/apache/commons/lang3/Range.java
+++ b/src/main/java/org/apache/commons/lang3/Range.java
@@ -30,6 +30,7 @@
  *
  * @param <T> The type of range values.
  * @since 3.0
+ * @since 3.20.1 {@code serialVersionUID} changed from {@code 1L} to {@code 
2L}.
  */
 public class Range<T> implements Serializable {
 
@@ -54,8 +55,9 @@ public int compare(final Object obj1, final Object obj2) {
      * Serialization version.
      *
      * @see java.io.Serializable
+     * @since 3.20.1 {@code serialVersionUID} changed from {@code 1L} to 
{@value}.
      */
-    private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = 2L;
 
     /**
      * Creates a range with the specified minimum and maximum values (both 
inclusive).
@@ -191,7 +193,7 @@ public static <T> Range<T> of(final T fromInclusive, final 
T toInclusive, final
     /**
      * Cached output hashCode (class is immutable).
      */
-    private transient int hashCode;
+    private final int hashCode;
 
     /**
      * The maximum value in this range (inclusive).
@@ -233,6 +235,7 @@ public static <T> Range<T> of(final T fromInclusive, final 
T toInclusive, final
             this.minimum = element2;
             this.maximum = element1;
         }
+        this.hashCode = Objects.hash(minimum, maximum);
     }
 
     /**
@@ -383,15 +386,7 @@ public T getMinimum() {
      */
     @Override
     public int hashCode() {
-        int result = hashCode;
-        if (hashCode == 0) {
-            result = 17;
-            result = 37 * result + getClass().hashCode();
-            result = 37 * result + minimum.hashCode();
-            result = 37 * result + maximum.hashCode();
-            hashCode = result;
-        }
-        return result;
+        return hashCode;
     }
 
     /**

Reply via email to