Skip to content
Open
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
9 changes: 3 additions & 6 deletions bundle/src/test/java/dev/cel/bundle/CelImplTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@
import dev.cel.runtime.CelAttribute.Qualifier;
import dev.cel.runtime.CelAttributePattern;
import dev.cel.runtime.CelEvaluationException;
import dev.cel.runtime.CelEvaluationExceptionBuilder;
import dev.cel.runtime.CelFunctionBinding;
import dev.cel.runtime.CelRuntime;
import dev.cel.runtime.CelRuntime.Program;
Expand Down Expand Up @@ -742,13 +741,13 @@ public void program_withThrowingFunction() throws Exception {
"throws",
ImmutableList.of(),
(args) -> {
throw new CelEvaluationException("this method always throws");
throw new RuntimeException("this method always throws");
}))
.setResultType(SimpleType.BOOL)
.build();
CelRuntime.Program program = cel.createProgram(cel.compile("throws()").getAst());
CelEvaluationException e = Assert.assertThrows(CelEvaluationException.class, program::eval);
assertThat(e).hasMessageThat().contains("this method always throws");
assertThat(e.getCause()).hasMessageThat().contains("this method always throws");
}

@Test
Expand All @@ -770,9 +769,7 @@ public void program_withThrowingFunctionShortcircuited() throws Exception {
"throws",
ImmutableList.of(),
(args) -> {
throw CelEvaluationExceptionBuilder.newBuilder("this method always throws")
.setCause(new RuntimeException("reason"))
.build();
throw new RuntimeException("this method always throws");
}))
.setResultType(SimpleType.BOOL)
.build();
Expand Down
2 changes: 2 additions & 0 deletions extensions/src/main/java/dev/cel/extensions/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ java_library(
deps = [
"//checker:checker_builder",
"//common:compiler_common",
"//common:error_codes",
"//common:runtime_exception",
"//common/internal",
"//common/types",
"//compiler:compiler_builder",
Expand Down
136 changes: 76 additions & 60 deletions extensions/src/main/java/dev/cel/extensions/CelStringExtensions.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@
import com.google.common.collect.Lists;
import com.google.errorprone.annotations.Immutable;
import dev.cel.checker.CelCheckerBuilder;
import dev.cel.common.CelErrorCode;
import dev.cel.common.CelFunctionDecl;
import dev.cel.common.CelOverloadDecl;
import dev.cel.common.CelRuntimeException;
import dev.cel.common.internal.CelCodePointArray;
import dev.cel.common.types.ListType;
import dev.cel.common.types.SimpleType;
import dev.cel.compiler.CelCompilerLibrary;
import dev.cel.runtime.CelEvaluationException;
import dev.cel.runtime.CelEvaluationExceptionBuilder;
import dev.cel.runtime.CelFunctionBinding;
import dev.cel.runtime.CelRuntimeBuilder;
import dev.cel.runtime.CelRuntimeLibrary;
Expand Down Expand Up @@ -253,7 +253,7 @@ String getFunction() {
}

private static final CelExtensionLibrary<CelStringExtensions> LIBRARY =
new CelExtensionLibrary<CelStringExtensions>() {
new CelExtensionLibrary<>() {
private final CelStringExtensions version0 = new CelStringExtensions();

@Override
Expand Down Expand Up @@ -291,56 +291,59 @@ public void setRuntimeOptions(CelRuntimeBuilder runtimeBuilder) {
functions.forEach(function -> runtimeBuilder.addFunctionBindings(function.functionBindings));
}

private static String charAt(String s, long i) throws CelEvaluationException {
private static String charAt(String s, long i) {
int index;
try {
index = Math.toIntExact(i);
} catch (ArithmeticException e) {
throw CelEvaluationExceptionBuilder.newBuilder(
"charAt failure: Index must not exceed the int32 range: %d", i)
.setCause(e)
.build();
throw new CelRuntimeException(
new IllegalArgumentException(
String.format("charAt failure: Index must not exceed the int32 range: %d", i), e),
CelErrorCode.INDEX_OUT_OF_BOUNDS);
}

CelCodePointArray codePointArray = CelCodePointArray.fromString(s);
if (index == codePointArray.length()) {
return "";
}
if (index < 0 || index > codePointArray.length()) {
throw CelEvaluationExceptionBuilder.newBuilder(
"charAt failure: Index out of range: %d", index)
.build();
throw new CelRuntimeException(
new IllegalArgumentException(
String.format("charAt failure: Index out of range: %d", index)),
CelErrorCode.INDEX_OUT_OF_BOUNDS);
}

return codePointArray.slice(index, index + 1).toString();
}

private static Long indexOf(String str, String substr) throws CelEvaluationException {
private static Long indexOf(String str, String substr) {
Object[] params = {str, substr, 0L};
return indexOf(params);
}

/**
* @param args Object array with indices of: [0: string], [1: substring], [2: offset]
*/
private static Long indexOf(Object[] args) throws CelEvaluationException {
private static Long indexOf(Object[] args) {
String str = (String) args[0];
String substr = (String) args[1];
long offsetInLong = (Long) args[2];
int offset;
try {
offset = Math.toIntExact(offsetInLong);
} catch (ArithmeticException e) {
throw CelEvaluationExceptionBuilder.newBuilder(
"indexOf failure: Offset must not exceed the int32 range: %d", offsetInLong)
.setCause(e)
.build();
throw new CelRuntimeException(
new IllegalArgumentException(
String.format(
"indexOf failure: Offset must not exceed the int32 range: %d", offsetInLong),
e),
CelErrorCode.INDEX_OUT_OF_BOUNDS);
}

return indexOf(str, substr, offset);
}

private static Long indexOf(String str, String substr, int offset) throws CelEvaluationException {
private static Long indexOf(String str, String substr, int offset) {
if (substr.isEmpty()) {
return (long) offset;
}
Expand All @@ -349,9 +352,10 @@ private static Long indexOf(String str, String substr, int offset) throws CelEva
CelCodePointArray substrCpa = CelCodePointArray.fromString(substr);

if (offset < 0 || offset >= strCpa.length()) {
throw CelEvaluationExceptionBuilder.newBuilder(
"indexOf failure: Offset out of range: %d", offset)
.build();
throw new CelRuntimeException(
new IllegalArgumentException(
String.format("indexOf failure: Offset out of range: %d", offset)),
CelErrorCode.INDEX_OUT_OF_BOUNDS);
}

return safeIndexOf(strCpa, substrCpa, offset);
Expand Down Expand Up @@ -384,7 +388,7 @@ private static String join(List<String> stringList, String separator) {
return Joiner.on(separator).join(stringList);
}

private static Long lastIndexOf(String str, String substr) throws CelEvaluationException {
private static Long lastIndexOf(String str, String substr) {
CelCodePointArray strCpa = CelCodePointArray.fromString(str);
CelCodePointArray substrCpa = CelCodePointArray.fromString(substr);
if (substrCpa.isEmpty()) {
Expand All @@ -398,16 +402,15 @@ private static Long lastIndexOf(String str, String substr) throws CelEvaluationE
return lastIndexOf(strCpa, substrCpa, (long) strCpa.length() - 1);
}

private static Long lastIndexOf(Object[] args) throws CelEvaluationException {
private static Long lastIndexOf(Object[] args) {
CelCodePointArray strCpa = CelCodePointArray.fromString((String) args[0]);
CelCodePointArray substrCpa = CelCodePointArray.fromString((String) args[1]);
long offset = (long) args[2];

return lastIndexOf(strCpa, substrCpa, offset);
}

private static Long lastIndexOf(CelCodePointArray str, CelCodePointArray substr, long offset)
throws CelEvaluationException {
private static Long lastIndexOf(CelCodePointArray str, CelCodePointArray substr, long offset) {
if (substr.isEmpty()) {
return offset;
}
Expand All @@ -416,16 +419,19 @@ private static Long lastIndexOf(CelCodePointArray str, CelCodePointArray substr,
try {
off = Math.toIntExact(offset);
} catch (ArithmeticException e) {
throw CelEvaluationExceptionBuilder.newBuilder(
"lastIndexOf failure: Offset must not exceed the int32 range: %d", offset)
.setCause(e)
.build();
throw new CelRuntimeException(
new IllegalArgumentException(
String.format(
"lastIndexOf failure: Offset must not exceed the int32 range: %d", offset),
e),
CelErrorCode.INDEX_OUT_OF_BOUNDS);
}

if (off < 0 || off >= str.length()) {
throw CelEvaluationExceptionBuilder.newBuilder(
"lastIndexOf failure: Offset out of range: %d", offset)
.build();
throw new CelRuntimeException(
new IllegalArgumentException(
String.format("lastIndexOf failure: Offset out of range: %d", offset)),
CelErrorCode.INDEX_OUT_OF_BOUNDS);
}

if (off > str.length() - substr.length()) {
Expand All @@ -452,16 +458,18 @@ private static String replaceAll(Object[] objects) {
return replace((String) objects[0], (String) objects[1], (String) objects[2], -1);
}

private static String replace(Object[] objects) throws CelEvaluationException {
private static String replace(Object[] objects) {
Long indexInLong = (Long) objects[3];
int index;
try {
index = Math.toIntExact(indexInLong);
} catch (ArithmeticException e) {
throw CelEvaluationExceptionBuilder.newBuilder(
"replace failure: Index must not exceed the int32 range: %d", indexInLong)
.setCause(e)
.build();
throw new CelRuntimeException(
new IllegalArgumentException(
String.format(
"replace failure: Index must not exceed the int32 range: %d", indexInLong),
e),
CelErrorCode.INDEX_OUT_OF_BOUNDS);
}

return replace((String) objects[0], (String) objects[1], (String) objects[2], index);
Expand Down Expand Up @@ -510,16 +518,18 @@ private static List<String> split(String str, String separator) {
/**
* @param args Object array with indices of: [0: string], [1: separator], [2: limit]
*/
private static List<String> split(Object[] args) throws CelEvaluationException {
private static List<String> split(Object[] args) {
long limitInLong = (Long) args[2];
int limit;
try {
limit = Math.toIntExact(limitInLong);
} catch (ArithmeticException e) {
throw CelEvaluationExceptionBuilder.newBuilder(
"split failure: Limit must not exceed the int32 range: %d", limitInLong)
.setCause(e)
.build();
throw new CelRuntimeException(
new IllegalArgumentException(
String.format(
"split failure: Limit must not exceed the int32 range: %d", limitInLong),
e),
CelErrorCode.INDEX_OUT_OF_BOUNDS);
}

return split((String) args[0], (String) args[1], limit);
Expand Down Expand Up @@ -575,25 +585,27 @@ private static List<String> explode(String str, int limit) {
return exploded;
}

private static Object substring(String s, long i) throws CelEvaluationException {
private static Object substring(String s, long i) {
int beginIndex;
try {
beginIndex = Math.toIntExact(i);
} catch (ArithmeticException e) {
throw CelEvaluationExceptionBuilder.newBuilder(
"substring failure: Index must not exceed the int32 range: %d", i)
.setCause(e)
.build();
throw new CelRuntimeException(
new IllegalArgumentException(
String.format("substring failure: Index must not exceed the int32 range: %d", i), e),
CelErrorCode.INDEX_OUT_OF_BOUNDS);
}

CelCodePointArray codePointArray = CelCodePointArray.fromString(s);

boolean indexIsInRange = beginIndex <= codePointArray.length() && beginIndex >= 0;
if (!indexIsInRange) {
throw CelEvaluationExceptionBuilder.newBuilder(
"substring failure: Range [%d, %d) out of bounds",
beginIndex, codePointArray.length())
.build();
throw new CelRuntimeException(
new IllegalArgumentException(
String.format(
"substring failure: Range [%d, %d) out of bounds",
beginIndex, codePointArray.length())),
CelErrorCode.INDEX_OUT_OF_BOUNDS);
}

if (beginIndex == codePointArray.length()) {
Expand All @@ -606,7 +618,7 @@ private static Object substring(String s, long i) throws CelEvaluationException
/**
* @param args Object array with indices of [0: string], [1: beginIndex], [2: endIndex]
*/
private static String substring(Object[] args) throws CelEvaluationException {
private static String substring(Object[] args) {
Long beginIndexInLong = (Long) args[1];
Long endIndexInLong = (Long) args[2];
int beginIndex;
Expand All @@ -615,11 +627,13 @@ private static String substring(Object[] args) throws CelEvaluationException {
beginIndex = Math.toIntExact(beginIndexInLong);
endIndex = Math.toIntExact(endIndexInLong);
} catch (ArithmeticException e) {
throw CelEvaluationExceptionBuilder.newBuilder(
"substring failure: Indices must not exceed the int32 range: [%d, %d)",
beginIndexInLong, endIndexInLong)
.setCause(e)
.build();
throw new CelRuntimeException(
new IllegalArgumentException(
String.format(
"substring failure: Indices must not exceed the int32 range: [%d, %d)",
beginIndexInLong, endIndexInLong),
e),
CelErrorCode.INDEX_OUT_OF_BOUNDS);
}

String s = (String) args[0];
Expand All @@ -631,9 +645,11 @@ private static String substring(Object[] args) throws CelEvaluationException {
&& beginIndex <= codePointArray.length()
&& endIndex <= codePointArray.length();
if (!indicesIsInRange) {
throw CelEvaluationExceptionBuilder.newBuilder(
"substring failure: Range [%d, %d) out of bounds", beginIndex, endIndex)
.build();
throw new CelRuntimeException(
new IllegalArgumentException(
String.format(
"substring failure: Range [%d, %d) out of bounds", beginIndex, endIndex)),
CelErrorCode.INDEX_OUT_OF_BOUNDS);
}

if (beginIndex == endIndex) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
public interface CelFunctionOverload {

/** Evaluate a set of arguments throwing a {@code CelException} on error. */
Object apply(Object[] args) throws CelEvaluationException;
Object apply(Object[] args);

/**
* Helper interface for describing unary functions where the type-parameter is used to improve
Expand All @@ -31,7 +31,7 @@ public interface CelFunctionOverload {
@Immutable
@FunctionalInterface
interface Unary<T> {
Object apply(T arg) throws CelEvaluationException;
Object apply(T arg);
}

/**
Expand All @@ -41,6 +41,6 @@ interface Unary<T> {
@Immutable
@FunctionalInterface
interface Binary<T1, T2> {
Object apply(T1 arg1, T2 arg2) throws CelEvaluationException;
Object apply(T1 arg1, T2 arg2);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.primitives.UnsignedLong;
import dev.cel.common.CelErrorCode;
import dev.cel.common.CelRuntimeException;
import dev.cel.expr.conformance.proto3.TestAllTypes;
import java.util.Optional;
import org.junit.Assert;
Expand Down Expand Up @@ -83,8 +84,8 @@ public void findOverload_badInput_throwsException() throws Exception {
UnsignedLong.class,
(arg) -> {
if (arg.equals(UnsignedLong.MAX_VALUE)) {
throw new CelEvaluationException(
"numeric overflow", null, CelErrorCode.NUMERIC_OVERFLOW);
throw new CelRuntimeException(
new ArithmeticException("numeric overflow"), CelErrorCode.NUMERIC_OVERFLOW);
}
return arg.plus(UnsignedLong.ONE);
}));
Expand All @@ -94,9 +95,9 @@ public void findOverload_badInput_throwsException() throws Exception {
assertThat(overload).isPresent();
assertThat(overload.get().getOverloadId()).isEqualTo("increment_uint");
assertThat(overload.get().getParameterTypes()).containsExactly(UnsignedLong.class);
CelEvaluationException e =
CelRuntimeException e =
Assert.assertThrows(
CelEvaluationException.class,
CelRuntimeException.class,
() -> overload.get().getDefinition().apply(new Object[] {UnsignedLong.MAX_VALUE}));
assertThat(e.getErrorCode()).isEqualTo(CelErrorCode.NUMERIC_OVERFLOW);
}
Expand Down
Loading
Loading