Skip to content

Normalize negative indices in bounded array slice expressions - #1081

Open
fudianchn wants to merge 1 commit into
json-path:masterfrom
fudianchn:fix-slice-between-negative-indices
Open

Normalize negative indices in bounded array slice expressions#1081
fudianchn wants to merge 1 commit into
json-path:masterfrom
fudianchn:fix-slice-between-negative-indices

Conversation

@fudianchn

Copy link
Copy Markdown

Problem

ArraySliceToken.sliceBetween only clamped the upper bound (to = Math.min(length, to)), so a negative from or to was never resolved against the array length — unlike sliceFrom and sliceTo, which both do index = length + index for negatives.

Consequently, e.g. $[-2:4] on a 5-element array looped i from -2 to 3, and since handleArrayIndex wraps negatives Python-style, it produced [3,4,0,1,2,3] (a duplicated/shifted result). $[1:-1] returned an empty list because Math.min(length, -1) made from >= to (#1076).

Fix

Mirror the sibling normalization (sliceFrom/sliceTo) in sliceBetween:

+        if (from < 0) {
+            from = length + from;
+        }
+        from = Math.max(0, from);
+        if (to < 0) {
+            to = length + to;
+        }
         to = Math.min(length, to);

Verification

The slice logic in isolation (matching sliceBetween + handleArrayIndex's negative wrap):

$[-2:4]  OLD: [3, 4, 0, 1, 2, 3]   ← bug (wraps + duplicates)
$[-2:4]  NEW: [3]                   ← correct
$[1:-1]  OLD: []                    ← bug (empty)
$[1:-1]  NEW: [1, 2, 3]            ← correct
$[1:3]   OLD/NEW: [1, 2]           ← unchanged

Added slice_between_with_negative_from / slice_between_with_negative_to to ArraySlicingTest. (The repo's Gradle build was too heavy to run locally — the slice logic is verified above and the tests codify it for CI.)

Closes #1076

ArraySliceToken.sliceBetween only clamped the upper bound
(`to = Math.min(length, to)`), so a negative `from` or `to` was not
resolved against the array length — unlike sliceFrom and sliceTo, which
both do `index = length + index` for negatives. As a result e.g. `$[-2:4]`
on a 5-element array looped from -2 and wrapped around to
`[3,4,0,1,2,3]` (duplicated), and `$[1:-1]` returned an empty list (json-path#1076).

Mirror the sibling normalization in sliceBetween so negative `from`/`to`
are resolved against the length before slicing.

Closes json-path#1076

Signed-off-by: 付典 <fudianchn@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Array slice [from:to] with a negative from wraps around and returns duplicate elements

1 participant