Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions checker/src/main/java/dev/cel/checker/Env.java
Original file line number Diff line number Diff line change
Expand Up @@ -242,12 +242,12 @@ private static CelStandardDeclarations newStandardDeclarations(CelOptions celOpt
}
break;
default:
if (!celOptions.enableHeterogeneousNumericComparisons()
&& overload instanceof Comparison) {
Comparison comparison = (Comparison) overload;
if (comparison.isHeterogeneousComparison()) {
return false;
}
// Heterogeneous numeric comparisons require UnsignedLong at runtime so uint
// values do not share Long with int and dispatch to signed int64 overloads.
if (!celOptions.enableUnsignedLongs()
&& overload instanceof Comparison
&& ((Comparison) overload).isHeterogeneousComparison()) {
return false;
}
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import com.google.testing.junit.testparameterinjector.TestParameters;
import dev.cel.checker.CelStandardDeclarations.StandardFunction;
import dev.cel.checker.CelStandardDeclarations.StandardFunction.Overload.Arithmetic;
import dev.cel.checker.CelStandardDeclarations.StandardFunction.Overload.Comparison;
import dev.cel.checker.CelStandardDeclarations.StandardIdentifier;
import dev.cel.common.CelOptions;
import dev.cel.common.CelValidationException;
Expand Down Expand Up @@ -327,14 +328,36 @@ public void standardEnvironment_subsetEnvironment() throws Exception {
@TestParameters("{expression: '2u <= 1'}")
@TestParameters("{expression: '2u <= 1.0'}")
@TestParameters("{expression: '1.0 <= 2u'}")
public void heterogeneousEqualityDisabled_mixedTypeComparisons_throws(String expression) {
public void standardEnvironment_excludeHeterogeneousComparisons_throws(String expression) {
CelCompiler celCompiler =
CelCompilerFactory.standardCelCompilerBuilder()
.setOptions(CelOptions.current().enableHeterogeneousNumericComparisons(false).build())
.setStandardDeclarations(
CelStandardDeclarations.newBuilder()
.filterFunctions(
(function, overload) ->
!(overload instanceof Comparison
&& ((Comparison) overload).isHeterogeneousComparison()))
.build())
.build();
CelValidationException e =
assertThrows(CelValidationException.class, () -> celCompiler.compile(expression).getAst());

assertThat(e).hasMessageThat().contains("found no matching overload for");
}

@Test
@TestParameters("{expression: '1 < 2.0'}")
@TestParameters("{expression: '1 < 2u'}")
@TestParameters("{expression: '2u < 1.0'}")
public void unsignedLongsDisabled_mixedTypeComparisons_throws(String expression) {
CelCompiler celCompiler =
CelCompilerFactory.standardCelCompilerBuilder()
.setOptions(CelOptions.current().enableUnsignedLongs(false).build())
.build();

CelValidationException e =
assertThrows(CelValidationException.class, () -> celCompiler.compile(expression).getAst());

assertThat(e).hasMessageThat().contains("found no matching overload for");
}

Expand Down
35 changes: 21 additions & 14 deletions common/src/main/java/dev/cel/common/CelOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package dev.cel.common;

import com.google.auto.value.AutoValue;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.errorprone.annotations.CheckReturnValue;
import com.google.errorprone.annotations.Immutable;

Expand Down Expand Up @@ -80,7 +81,13 @@ public enum ProtoUnsetFieldOptions {

public abstract boolean enableTimestampEpoch();

public abstract boolean enableHeterogeneousNumericComparisons();
/**
* @deprecated Cross-type numeric comparisons are always enabled.
*/
@Deprecated
public boolean enableHeterogeneousNumericComparisons() {
return true;
}

public abstract boolean enableNamespacedDeclarations();

Expand Down Expand Up @@ -148,7 +155,6 @@ public static Builder newBuilder() {
.enableCompileTimeOverloadResolution(false)
.enableHomogeneousLiterals(false)
.enableTimestampEpoch(false)
.enableHeterogeneousNumericComparisons(false)
.enableNamespacedDeclarations(true)
.enableJsonFieldNames(false)
// Evaluation options
Expand Down Expand Up @@ -183,7 +189,6 @@ public static Builder current() {
.enableUnsignedLongs(true)
.enableRegexPartialMatch(true)
.enableTimestampEpoch(true)
.enableHeterogeneousNumericComparisons(true)
.errorOnDuplicateMapKeys(true)
.evaluateCanonicalTypesToNativeValues(true)
.errorOnIntWrap(true)
Expand Down Expand Up @@ -320,20 +325,22 @@ public abstract static class Builder {
public abstract Builder enableTimestampEpoch(boolean value);

/**
* Enable the {@code less_equals_double_int64} and other cross-type numeric comparisons for
* {@code double}, {@code int64}, and {@code uint64} values.
*
* <p>This option is enabled by default in {@link CelOptions#current}.
*
* <p>TODO: Remove this feature once it has been auto-enabled.
*
* @deprecated This option is now enabled by default. If you are passing {@code true}, simply
* remove this method call. If you are passing {@code false} to disable this feature, subset
* the environment instead using {@code dev.cel.checker.CelStandardDeclarations} and {@code
* @deprecated Cross-type numeric comparisons are always enabled ({@code false} throws {@link
* IllegalArgumentException}). Remove calls passing {@code true}, or subset using {@code
* dev.cel.checker.CelStandardDeclarations} and {@code
* dev.cel.runtime.CelStandardFunctions}.
*/
@Deprecated
public abstract Builder enableHeterogeneousNumericComparisons(boolean value);
@CanIgnoreReturnValue
public Builder enableHeterogeneousNumericComparisons(boolean value) {
if (!value) {
throw new IllegalArgumentException(
"Misconfigured CelOptions: enableHeterogeneousNumericComparisons cannot be disabled."
+ " Subset the environment instead using CelStandardDeclarations and"
+ " CelStandardFunctions.");
}
return this;
}

/**
* Enables the usage of namespaced functions and identifiers. This causes the type-checker to
Expand Down
26 changes: 26 additions & 0 deletions common/src/test/java/dev/cel/common/CelOptionsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package dev.cel.common;

import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;

import org.junit.Test;
import org.junit.runner.RunWith;
Expand All @@ -37,4 +38,29 @@ public void current_defaults() {
assertThat(CelOptions.current().build().enablePrattParser()).isFalse();
assertThat(CelOptions.current().build().enableIeee754ContainerEquality()).isTrue();
}

@Test
@SuppressWarnings("deprecation") // Testing deprecated compatibility methods
public void enableHeterogeneousNumericComparisons_true_isNoOp() {
CelOptions.Builder builder = CelOptions.newBuilder();

assertThat(builder.enableHeterogeneousNumericComparisons(true)).isSameInstanceAs(builder);
assertThat(CelOptions.DEFAULT.enableHeterogeneousNumericComparisons()).isTrue();
assertThat(CelOptions.LEGACY.enableHeterogeneousNumericComparisons()).isTrue();
}

@Test
@SuppressWarnings("deprecation") // Testing deprecated compatibility methods
public void enableHeterogeneousNumericComparisons_false_throws() {
CelOptions.Builder builder = CelOptions.DEFAULT.toBuilder();

IllegalArgumentException e =
assertThrows(
IllegalArgumentException.class,
() -> builder.enableHeterogeneousNumericComparisons(false));

assertThat(e)
.hasMessageThat()
.contains("enableHeterogeneousNumericComparisons cannot be disabled");
}
}
13 changes: 2 additions & 11 deletions runtime/src/main/java/dev/cel/runtime/CelRuntimeImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -445,20 +445,11 @@ private static void assertAllowedCelOptions(CelOptions celOptions) {
throw new IllegalArgumentException(
prefix + "unwrapWellKnownTypesOnFunctionDispatch cannot be disabled.");
}

// Disallowed options in favor of subsetting
String subsettingError = "Subset the environment instead using setStandardFunctions method.";

if (!celOptions.enableTimestampEpoch()) {
throw new IllegalArgumentException(
prefix + "enableTimestampEpoch cannot be disabled. " + subsettingError);
}

if (!celOptions.enableHeterogeneousNumericComparisons()) {
throw new IllegalArgumentException(
prefix
+ "enableHeterogeneousNumericComparisons cannot be disabled. "
+ subsettingError);
+ "enableTimestampEpoch cannot be disabled. Subset the environment instead using"
+ " setStandardFunctions method.");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ private ImmutableSet<CelFunctionBinding> newStandardFunctionBindings(
}
break;
default:
if (!options.enableHeterogeneousNumericComparisons()) {
if (!options.enableUnsignedLongs()) {
return !CelStandardFunctions.isHeterogeneousComparison(
standardOverload);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,17 +187,17 @@ public void standardEnvironment_subsetEnvironment() throws Exception {
@TestParameters("{expression: '2u <= 1'}")
@TestParameters("{expression: '2u <= 1.0'}")
@TestParameters("{expression: '1.0 <= 2u'}")
public void heterogeneousEqualityDisabled_mixedTypeComparisons_throws(String expression) {
public void unsignedLongsDisabled_mixedTypeComparisons_throws(String expression)
throws Exception {
CelCompiler celCompiler = CelCompilerFactory.standardCelCompilerBuilder().build();
CelRuntime celRuntime =
CelRuntimeFactory.legacyCelRuntimeBuilder()
.setOptions(CelOptions.current().enableHeterogeneousNumericComparisons(false).build())
.setOptions(CelOptions.current().enableUnsignedLongs(false).build())
.build();
CelRuntime.Program program = celRuntime.createProgram(celCompiler.compile(expression).getAst());

CelEvaluationException e = assertThrows(CelEvaluationException.class, program::eval);

CelEvaluationException e =
assertThrows(
CelEvaluationException.class,
() -> celRuntime.createProgram(celCompiler.compile(expression).getAst()).eval());
assertThat(e).hasMessageThat().contains("No matching overload for function");
}

Expand Down
Loading