Skip to content

Commit 02052f3

Browse files
l46kokcopybara-github
authored andcommitted
Safely ignore enums in native type extensions
Ref: #1077 PiperOrigin-RevId: 929234496
1 parent a6f2930 commit 02052f3

3 files changed

Lines changed: 51 additions & 5 deletions

File tree

extensions/src/main/java/dev/cel/extensions/CelNativeTypesExtensions.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ public final class CelNativeTypesExtensions implements CelCompilerLibrary, CelRu
8282
private static final ImmutableSet<String> OBJECT_METHOD_NAMES =
8383
stream(Object.class.getDeclaredMethods()).map(Method::getName).collect(toImmutableSet());
8484

85+
// Set of all standard java.lang.Enum method names.
86+
private static final ImmutableSet<String> ENUM_METHOD_NAMES =
87+
stream(Enum.class.getDeclaredMethods()).map(Method::getName).collect(toImmutableSet());
88+
8589
private static final ImmutableMap<Class<?>, CelType> JAVA_TO_CEL_TYPE_MAP =
8690
ImmutableMap.<Class<?>, CelType>builder()
8791
.put(boolean.class, SimpleType.BOOL)
@@ -606,6 +610,10 @@ private static boolean isGetter(Method method) {
606610
if (OBJECT_METHOD_NAMES.contains(name)) {
607611
return false;
608612
}
613+
if (Enum.class.isAssignableFrom(method.getDeclaringClass())
614+
&& ENUM_METHOD_NAMES.contains(name)) {
615+
return false;
616+
}
609617
if (name.startsWith("get")) {
610618
return name.length() > 3;
611619
}

extensions/src/main/java/dev/cel/extensions/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1122,6 +1122,7 @@ The type-mapping between Java and CEL is as follows:
11221122

11231123
* This is only supported for the planner runtime (e.g., `CelRuntimeFactory.plannerRuntimeBuilder()`).
11241124
* Native Java arrays (except `byte[]`) are not supported. Use `java.util.List` instead.
1125+
* Java `enum` properties are not currently supported and will be safely ignored during scanning.
11251126
* If there is a name collision with a Protobuf type, the protobuf type will take precedence.
11261127
* Instantiating new struct values (e.g., `Account{id: 1234}`) requires the class to have a no-argument constructor (public, protected, package-private, or private).
11271128
* Final fields are supported only in a **read-only** capacity; they cannot be populated when instantiating new struct values.

extensions/src/test/java/dev/cel/extensions/CelNativeTypesExtensionsTest.java

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ public final class CelNativeTypesExtensionsTest {
8989
TestNestedSimplePojo.class,
9090
TestGetterFieldTypeMismatchPojo.class,
9191
TestAbstractPojo.class,
92-
TestURLPojo.class);
92+
TestURLPojo.class,
93+
PojoWithEnum.class);
9394

9495
private static final Cel CEL =
9596
CelFactory.plannerCelBuilder()
@@ -564,16 +565,24 @@ public void nativeTypes_prefixLessGetter_success() throws Exception {
564565
.setContainer(CelContainer.ofName("dev.cel.extensions.CelNativeTypesExtensionsTest"))
565566
.addLibraries(extensions)
566567
.build();
567-
CelAbstractSyntaxTree ast =
568+
CelAbstractSyntaxTree valueAst =
568569
celCompiler
569570
.compile(
570571
"dev.cel.extensions.CelNativeTypesExtensionsTest.TestPrefixLessGetterPojo{}.value")
571572
.getAst();
572-
CelRuntime.Program program = celRuntime.createProgram(ast);
573+
CelAbstractSyntaxTree nameAst =
574+
celCompiler
575+
.compile(
576+
"dev.cel.extensions.CelNativeTypesExtensionsTest.TestPrefixLessGetterPojo{}.name")
577+
.getAst();
578+
CelRuntime.Program valueProgram = celRuntime.createProgram(valueAst);
579+
CelRuntime.Program nameProgram = celRuntime.createProgram(nameAst);
573580

574-
Object result = program.eval();
581+
Object valueResult = valueProgram.eval();
582+
Object nameResult = nameProgram.eval();
575583

576-
assertThat(result).isEqualTo("hello");
584+
assertThat(valueResult).isEqualTo("hello");
585+
assertThat(nameResult).isEqualTo("my_name");
577586
}
578587

579588
@Test
@@ -1201,10 +1210,15 @@ public static final class TestPrivateFieldPojo {
12011210

12021211
public static class TestPrefixLessGetterPojo {
12031212
private String value = "hello";
1213+
private String name = "my_name";
12041214

12051215
public String value() {
12061216
return value;
12071217
}
1218+
1219+
public String name() {
1220+
return name;
1221+
}
12081222
}
12091223

12101224
public static class TestParentPojo {
@@ -1346,4 +1360,27 @@ public String getMismatchField() {
13461360
return "mismatch";
13471361
}
13481362
}
1363+
1364+
public enum TestEnum {
1365+
FOO,
1366+
BAR;
1367+
}
1368+
1369+
public static class PojoWithEnum {
1370+
private TestEnum enumVal = TestEnum.FOO;
1371+
1372+
public TestEnum getEnumVal() {
1373+
return enumVal;
1374+
}
1375+
1376+
public void setEnumVal(TestEnum val) {
1377+
this.enumVal = val;
1378+
}
1379+
}
1380+
1381+
@Test
1382+
public void nativeTypes_enumSafelyIgnored() throws Exception {
1383+
assertThat(eval("PojoWithEnum{}.enumVal")).isNotNull();
1384+
}
1385+
13491386
}

0 commit comments

Comments
 (0)