From 5103b301547226801c41c158dea4ee751bfb5a7d Mon Sep 17 00:00:00 2001 From: Sokwhan Huh Date: Thu, 26 Feb 2026 16:15:47 -0800 Subject: [PATCH] Fix optionals to properly error on invalid qualification PiperOrigin-RevId: 875937520 --- .../test/java/dev/cel/conformance/BUILD.bazel | 2 -- .../cel/runtime/planner/StringQualifier.java | 32 +++++++++++++------ 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/conformance/src/test/java/dev/cel/conformance/BUILD.bazel b/conformance/src/test/java/dev/cel/conformance/BUILD.bazel index c8cc06cb0..717f7aaa0 100644 --- a/conformance/src/test/java/dev/cel/conformance/BUILD.bazel +++ b/conformance/src/test/java/dev/cel/conformance/BUILD.bazel @@ -175,8 +175,6 @@ _TESTS_TO_SKIP_PLANNER = [ "timestamps/timestamp_range/sub_time_duration_under", # Skip until fixed. - "optionals/optionals/map_null_entry_no_such_key", - "optionals/optionals/map_present_key_invalid_field", "parse/receiver_function_names", "proto2/extensions_get/package_scoped_test_all_types_ext", "proto2/extensions_get/package_scoped_repeated_test_all_types", diff --git a/runtime/src/main/java/dev/cel/runtime/planner/StringQualifier.java b/runtime/src/main/java/dev/cel/runtime/planner/StringQualifier.java index 4ceaa0e51..293ca5c7d 100644 --- a/runtime/src/main/java/dev/cel/runtime/planner/StringQualifier.java +++ b/runtime/src/main/java/dev/cel/runtime/planner/StringQualifier.java @@ -15,6 +15,7 @@ package dev.cel.runtime.planner; import dev.cel.common.exceptions.CelAttributeNotFoundException; +import dev.cel.common.values.OptionalValue; import dev.cel.common.values.SelectableValue; import java.util.Map; @@ -31,21 +32,34 @@ public String value() { @Override @SuppressWarnings("unchecked") // Qualifications on maps/structs must be a string public Object qualify(Object obj) { + if (obj instanceof OptionalValue) { + OptionalValue opt = (OptionalValue) obj; + if (!opt.isZeroValue()) { + Object inner = opt.value(); + if (!(inner instanceof SelectableValue) && !(inner instanceof Map)) { + throw CelAttributeNotFoundException.forFieldResolution(value); + } + } + } + if (obj instanceof SelectableValue) { return ((SelectableValue) obj).select(value); - } else if (obj instanceof Map) { - Map map = (Map) obj; - if (!map.containsKey(value)) { - throw CelAttributeNotFoundException.forMissingMapKey(value); - } + } + if (obj instanceof Map) { + Map map = (Map) obj; Object mapVal = map.get(value); - if (mapVal == null) { - throw CelAttributeNotFoundException.of( - String.format("Map value cannot be null for key: %s", value)); + if (mapVal != null) { + return mapVal; + } + + if (!map.containsKey(value)) { + throw CelAttributeNotFoundException.forMissingMapKey(value); } - return map.get(value); + + throw CelAttributeNotFoundException.of( + String.format("Map value cannot be null for key: %s", value)); } throw CelAttributeNotFoundException.forFieldResolution(value);