diff --git a/conformance/src/test/java/dev/cel/conformance/BUILD.bazel b/conformance/src/test/java/dev/cel/conformance/BUILD.bazel index 375cd8bfa..c8cc06cb0 100644 --- a/conformance/src/test/java/dev/cel/conformance/BUILD.bazel +++ b/conformance/src/test/java/dev/cel/conformance/BUILD.bazel @@ -175,7 +175,6 @@ _TESTS_TO_SKIP_PLANNER = [ "timestamps/timestamp_range/sub_time_duration_under", # Skip until fixed. - "fields/qualified_identifier_resolution/map_value_repeat_key_heterogeneous", "optionals/optionals/map_null_entry_no_such_key", "optionals/optionals/map_present_key_invalid_field", "parse/receiver_function_names", diff --git a/runtime/src/main/java/dev/cel/runtime/planner/EvalCreateMap.java b/runtime/src/main/java/dev/cel/runtime/planner/EvalCreateMap.java index c09c19987..f6f73e842 100644 --- a/runtime/src/main/java/dev/cel/runtime/planner/EvalCreateMap.java +++ b/runtime/src/main/java/dev/cel/runtime/planner/EvalCreateMap.java @@ -59,13 +59,26 @@ public Object eval(GlobalResolver resolver, ExecutionFrame frame) throws CelEval keyInterpretable.exprId()); } - Object val = values[i].eval(resolver, frame); + boolean isDuplicate = !keysSeen.add(key); + if (!isDuplicate) { + if (key instanceof Long) { + long longVal = (Long) key; + if (longVal >= 0) { + isDuplicate = keysSeen.contains(UnsignedLong.valueOf(longVal)); + } + } else if (key instanceof UnsignedLong) { + UnsignedLong ulongVal = (UnsignedLong) key; + isDuplicate = keysSeen.contains(ulongVal.longValue()); + } + } - if (!keysSeen.add(key)) { + if (isDuplicate) { throw new LocalizedEvaluationException( CelDuplicateKeyException.of(key), keyInterpretable.exprId()); } + Object val = values[i].eval(resolver, frame); + if (isOptional[i]) { if (!(val instanceof Optional)) { throw new IllegalArgumentException(