Skip to content

Fix deep scan results dropped after wildcard or multi index tokens - #1084

Open
fudianchn wants to merge 1 commit into
json-path:masterfrom
fudianchn:fix-deep-scan-wildcard-property
Open

fudianchn wants to merge 1 commit into
json-path:masterfrom
fudianchn:fix-deep-scan-wildcard-property

Conversation

@fudianchn

@fudianchn fudianchn commented Sep 13, 2026

Copy link
Copy Markdown

AI disclosure: this change was prepared with AI coding agents, reviewed and revised line by line by me.

What

$..*.title returns the four book titles again. $..[0,2].author returns authors 0 and 2. $..[2].author still returns only author 2. A wildcard fed by a deep scan used to drop every result, so $..*.* returned 13 instead of 31 elements.

Why

Since 2.7.0 a deep scan over an array dropped every leaf result behind a wildcard or multi index token, returning an empty list.

How

New method acceptsUpstreamArrayIndex replaces the string comparison in the leaf filter. Only ArrayIndexToken restricts, by its real indexes. Wildcard, slice, scan, property and predicate tokens accept every element. A token without a previous link is mounted by a function parameter evaluation (see Length), so it accepts every element instead of dereferencing the missing link.

Root cause

PR #715 added a filter that compares the path fragment of the token before the leaf with the fed array index. "[*]" never equals "[0]", and "[0,2]" never equals either, so the results were dropped.

Testing

  • DeepScanTest: $..*.title and $..[0,2].author fail on main and pass with the fix; the $..[2].author guard (issue Unexpected result when executing a jsonpath on json array #273) passes on both.
  • Function parameter family: $..*.length() threw NullPointerException in the first version of this fix and now returns 31 like the completed scan results; $..[0].length() and $..[*].length() return 18 and 31.
  • Snapshots: $..*.* returns 31, $..[1:3].author accepts all four authors, $..[-1].author stays empty (pre-existing negative index gap).
  • Module suite: 937 tests pass, ./gradlew build green.

Not covered:

  • Deep scan plus slice accepts every element instead of the exact [from,to) range; exact filtering needs the array length at the leaf, left out.
  • Negative indexes before the leaf never match; multi property leaves do not filter. Both pre-existing.

Verification of the original issue

JsonPath.read(json, "$..*.title") on the books example: [] on 2.7.0 and main, the four titles with this fix.

Fixes #1052

A deep scan iterating an array feeds every element to the token that
follows and records the element index in the leaf token. The leaf filter
introduced with 2.7.0 accepted a result only when the path fragment of
the token before the leaf literally equaled "[<index>]". That comparison
can never succeed for wildcard tokens ("[*]"), so paths like
$..*.title returned an empty list since 2.7.0, and multi index tokens
like $..[0,2] were dropped the same way.

Replace the string comparison with acceptsUpstreamArrayIndex, which only
explicit array index tokens restrict by their actual indexes. Wildcard,
slice, scan, property and predicate tokens accept every element, so
$..*.title returns all four book titles again while $..[2].author
still returns only the third author. A token without a previous link is
mounted by a function parameter evaluation (see Length) and has no path
constraint to apply, so it accepts every element instead of failing.

Fixes json-path#1052

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.

Jsonpath $..*.title does not work anymore since 2.7.0

1 participant