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

Cole-Greer pushed a commit to branch 3.8-dev
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git


The following commit(s) were added to refs/heads/3.8-dev by this push:
     new d929579f05 CTR: Fix integer range literal parsing to reject overflow 
and endpoint cases
d929579f05 is described below

commit d929579f051f2358445e8b1e18d52c35a32b66c7
Author: Cole Greer <[email protected]>
AuthorDate: Wed Oct 28 17:19:05 2026 -0700

    CTR: Fix integer range literal parsing to reject overflow and endpoint cases
    
    The range size guard used signed int arithmetic (Math.abs(start - end)),
    which int subtraction overflow and Math.abs(Integer.MIN_VALUE) could slip
    past, and the inclusive int loop wrapped around for ranges at the int
    min/max bounds. Compute the width in long for the limit check and drive
    the loop by that bounded count.
    
    Assisted-by: Kiro:claude-opus-4.8
---
 CHANGELOG.asciidoc                                 |  1 +
 .../language/grammar/GenericLiteralVisitor.java    | 26 +++++++++-------------
 .../grammar/GeneralLiteralVisitorTest.java         | 12 +++++++++-
 3 files changed, 22 insertions(+), 17 deletions(-)

diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index f568cbec14..0858931f70 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -28,6 +28,7 @@ 
image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
 This release also includes changes from prior 3.7.x releases.
 
 * Fixed `AddPropertyStep` not passing the old property to `EventStrategy` 
listeners when the cardinality was not specified in `property()`.
+* Fixed integer range literal parsing in Gremlin-Lang where certain ranges 
bypassed the range size limit.
 
 [[release-3-8-2]]
 === TinkerPop 3.8.2 (Release Date: September 1, 2026)
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/GenericLiteralVisitor.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/GenericLiteralVisitor.java
index fe43ad24f7..9a92081d7c 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/GenericLiteralVisitor.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/GenericLiteralVisitor.java
@@ -189,28 +189,22 @@ public class GenericLiteralVisitor extends 
DefaultGremlinBaseVisitor<Object> {
      * @return : return an object which is type of array of object, and each 
object is a Integer inside the range.
      */
     private static Object createIntegerRange(final int start, final int end, 
final String range) {
-        final List<Object> results = new ArrayList<>();
-        int total_result_count = Math.abs(start - end);
+        // Compute the gap between endpoints in long arithmetic so the limit 
check cannot be bypassed by
+        // int subtraction overflow (e.g. MIN..MAX) or by 
Math.abs(Integer.MIN_VALUE) remaining negative.
+        final long total_result_count = Math.abs((long) start - (long) end);
 
         // validate result count not exceeding limit
         if (total_result_count > TOTAL_INTEGER_RANGE_RESULT_COUNT_LIMIT) {
             throw new IllegalArgumentException("Range " + range + " is too 
wide. Current limit is " + TOTAL_INTEGER_RANGE_RESULT_COUNT_LIMIT + " items");
         }
 
-        if (start <= end) {
-            // handle start <= end
-            int cur = start;
-            while (cur <= end) {
-                results.add(cur);
-                cur++;
-            }
-        } else {
-            // handle start > end
-            int cur = start;
-            while (cur >= end) {
-                results.add(cur);
-                cur--;
-            }
+        final List<Object> results = new ArrayList<>((int) 
total_result_count+1);
+
+        final int step = (start <= end) ? 1 : -1;
+        int cur = start;
+        for (int i = 0; i <= total_result_count; i++) {
+            results.add(cur);
+            cur += step;
         }
 
         return results;
diff --git 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/language/grammar/GeneralLiteralVisitorTest.java
 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/language/grammar/GeneralLiteralVisitorTest.java
index f590f6212d..e3478ec3b7 100644
--- 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/language/grammar/GeneralLiteralVisitorTest.java
+++ 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/language/grammar/GeneralLiteralVisitorTest.java
@@ -80,6 +80,12 @@ public class GeneralLiteralVisitorTest {
                     {1, 1000000},
                     {1, 1},
                     {1000000, 1},
+                    // endpoint cases where an inclusive int loop would wrap 
around past the endpoint
+                    {Integer.MAX_VALUE, Integer.MAX_VALUE},
+                    {Integer.MIN_VALUE, Integer.MIN_VALUE},
+                    {Integer.MAX_VALUE - 1, Integer.MAX_VALUE},
+                    {Integer.MIN_VALUE, Integer.MIN_VALUE + 1},
+                    {Integer.MIN_VALUE + 1, Integer.MIN_VALUE},
             });
         }
 
@@ -119,6 +125,10 @@ public class GeneralLiteralVisitorTest {
             return Arrays.asList(new Object[][]{
                     {0, 10000000},
                     {10000000, 1},
+                    // widths that overflow signed int arithmetic and used to 
slip past the guard:
+                    // Math.abs(start - end) == Integer.MIN_VALUE (stays 
negative), and start - end overflow
+                    {-1073741824, 1073741824},
+                    {Integer.MIN_VALUE, Integer.MAX_VALUE},
             });
         }
 
@@ -127,7 +137,7 @@ public class GeneralLiteralVisitorTest {
          */
         @Test(expected = IllegalArgumentException.class)
         public void shouldNotParse() {
-            assertThat(Math.abs(end - start), 
greaterThanOrEqualTo(GenericLiteralVisitor.TOTAL_INTEGER_RANGE_RESULT_COUNT_LIMIT));
+            assertThat(Math.abs((long) start - (long) end), 
greaterThanOrEqualTo((long) 
GenericLiteralVisitor.TOTAL_INTEGER_RANGE_RESULT_COUNT_LIMIT));
             parseGenericLiteralRange(String.format("%d..%d", start, end));
         }
     }

Reply via email to