From c0062ebb7cc9d5ce04136046e5e93ebb8b228b79 Mon Sep 17 00:00:00 2001 From: kavyaNamballa <163406073+kavyaNamballa@users.noreply.github.com> Date: Tue, 24 Jun 2025 23:18:28 +0530 Subject: [PATCH 1/2] fix/1043 empty array handling in filter expressions to return false for empty results --- .../com/jayway/jsonpath/internal/filter/ValueNodes.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ValueNodes.java b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ValueNodes.java index 3f459a8c1..e0ae8fbf4 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ValueNodes.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ValueNodes.java @@ -678,7 +678,14 @@ public ValueNode evaluate(Predicate.PredicateContext ctx) { try { Configuration c = Configuration.builder().jsonProvider(ctx.configuration().jsonProvider()).options(Option.REQUIRE_PROPERTIES).build(); Object result = path.evaluate(ctx.item(), ctx.root(), c).getValue(false); - return result == JsonProvider.UNDEFINED ? FALSE : TRUE; + if (result == JsonProvider.UNDEFINED) { + return FALSE; + } + // If the result is an empty array, return FALSE for exists checks + if (ctx.configuration().jsonProvider().isArray(result) && ctx.configuration().jsonProvider().length(result) == 0) { + return FALSE; + } + return TRUE; } catch (PathNotFoundException e) { return FALSE; } From 50437086bea23787d48a8ca1dd93d60e27ff8938 Mon Sep 17 00:00:00 2001 From: kavyaNamballa <163406073+kavyaNamballa@users.noreply.github.com> Date: Tue, 14 Jul 2026 14:13:32 +0530 Subject: [PATCH 2/2] added test for the empty array handling fix --- .../com/jayway/jsonpath/ExistsCheckTest.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 json-path/src/test/java/com/jayway/jsonpath/ExistsCheckTest.java diff --git a/json-path/src/test/java/com/jayway/jsonpath/ExistsCheckTest.java b/json-path/src/test/java/com/jayway/jsonpath/ExistsCheckTest.java new file mode 100644 index 000000000..f6a0b8fba --- /dev/null +++ b/json-path/src/test/java/com/jayway/jsonpath/ExistsCheckTest.java @@ -0,0 +1,26 @@ +package com.jayway.jsonpath; + +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ExistsCheckTest extends BaseTest { + + @Test + public void deep_products_exists_returns_only_store_b() { + String json = "[" + + "{\"id\":1,\"name\":\"Store A\",\"departments\":[{\"id\":10,\"name\":\"Electronics\",\"products\":[{\"id\":101,\"name\":\"TV\",\"in_stock\":true},{\"id\":102,\"name\":\"Laptop\",\"in_stock\":false}]},{\"id\":11,\"name\":\"Clothing\",\"products\":[{\"id\":201,\"name\":\"Shirt\",\"in_stock\":true},{\"id\":202,\"name\":\"Jeans\",\"in_stock\":true}]}]} ," + + "{\"id\":2,\"name\":\"Store B\",\"departments\":[{\"id\":12,\"name\":\"Grocery\",\"products\":[{\"id\":301,\"name\":\"Milk\",\"in_stock\":false},{\"id\":302,\"name\":\"Eggs\",\"in_stock\":true}]}]}" + + "]"; + + Object doc = Configuration.defaultConfiguration().jsonProvider().parse(json); + + List res1 = JsonPath.read(doc, "$[?(@..products[?(@.id==302)])].name"); + assertThat(res1).containsExactly("Store B"); + + List res2 = JsonPath.read(doc, "$[?(@.departments[?(@.products[?(@.id==302)])])].name"); + assertThat(res2).containsExactly("Store B"); + } +}