Skip to content

Commit 1c42a95

Browse files
committed
Override string_to_bytes
Signed-off-by: Sri Krishna <[email protected]>
1 parent 3c060a2 commit 1c42a95

File tree

3 files changed

+39
-10
lines changed

3 files changed

+39
-10
lines changed

conformance/expected-failures.yaml

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +0,0 @@
1-
standard_rules/bytes:
2-
- pattern/invalid/not_utf8
3-
# input: [ type.googleapis.com/buf.validate.conformance.cases.BytesPattern ]:{val:"\x99"}
4-
# want: runtime error: value must be valid UTF-8 to apply regexp
5-
# got: validation error (1 violation)
6-
# 1. rule_id: "bytes.pattern"
7-
# message: "value must match regex pattern `^[\\x00-\\x7F]+$`"
8-
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_BYTES}
9-
# rule: "bytes.pattern" elements:{field_number:15 field_name:"bytes" field_type:TYPE_MESSAGE} elements:{field_number:4 field_name:"pattern" field_type:TYPE_STRING}

src/main/java/build/buf/protovalidate/CustomOverload.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121
import dev.cel.common.types.SimpleType;
2222
import dev.cel.runtime.CelEvaluationException;
2323
import dev.cel.runtime.CelRuntime.CelFunctionBinding;
24+
import java.nio.charset.CharsetDecoder;
25+
import java.nio.charset.CodingErrorAction;
26+
import java.nio.charset.StandardCharsets;
2427
import java.util.ArrayList;
2528
import java.util.Arrays;
2629
import java.util.Collections;
@@ -47,6 +50,7 @@ static List<CelFunctionBinding> create() {
4750
ArrayList<CelFunctionBinding> bindings = new ArrayList<>();
4851
bindings.addAll(
4952
Arrays.asList(
53+
celBytesToString(),
5054
celGetField(),
5155
celFormat(),
5256
celStartsWithBytes(),
@@ -70,6 +74,26 @@ static List<CelFunctionBinding> create() {
7074
return Collections.unmodifiableList(bindings);
7175
}
7276

77+
/**
78+
* This implementes that standard {@code bytes_to_string} function. We override it because the CEL
79+
* library doesn't validate that the bytes are valid utf-8.
80+
*/
81+
private static CelFunctionBinding celBytesToString() {
82+
return CelFunctionBinding.from(
83+
"bytes_to_string",
84+
ByteString.class,
85+
v -> {
86+
CharsetDecoder dec = StandardCharsets.UTF_8.newDecoder();
87+
dec.onMalformedInput(CodingErrorAction.REPORT);
88+
dec.onUnmappableCharacter(CodingErrorAction.REPORT);
89+
try {
90+
return dec.decode(v.asReadOnlyByteBuffer()).toString();
91+
} catch (Exception e) {
92+
throw new CelEvaluationException("invalid UTF-8 in bytes, cannot convert to string", e);
93+
}
94+
});
95+
}
96+
7397
/**
7498
* Creates a custom function overload for the "getField" operation.
7599
*

src/main/java/build/buf/protovalidate/ValidateLibrary.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
import dev.cel.parser.CelStandardMacro;
2323
import dev.cel.runtime.CelRuntimeBuilder;
2424
import dev.cel.runtime.CelRuntimeLibrary;
25+
import dev.cel.runtime.CelStandardFunctions;
26+
import dev.cel.runtime.CelStandardFunctions.StandardFunction;
27+
import dev.cel.runtime.CelStandardFunctions.StandardFunction.Overload.Conversions;
2528

2629
/**
2730
* Custom {@link CelCompilerLibrary} and {@link CelRuntimeLibrary}. Provides all the custom
@@ -54,6 +57,17 @@ public void setCheckerOptions(CelCheckerBuilder checkerBuilder) {
5457

5558
@Override
5659
public void setRuntimeOptions(CelRuntimeBuilder runtimeBuilder) {
57-
runtimeBuilder.addFunctionBindings(CustomOverload.create());
60+
runtimeBuilder
61+
.addFunctionBindings(CustomOverload.create())
62+
.setStandardEnvironmentEnabled(false)
63+
.setStandardFunctions(
64+
CelStandardFunctions.newBuilder()
65+
.filterFunctions(
66+
// CEL doesn't validate, that the bytes are valid utf-8, so we provide out own
67+
// implementation.
68+
(function, overload) ->
69+
function != StandardFunction.STRING
70+
|| !overload.equals(Conversions.BYTES_TO_STRING))
71+
.build());
5872
}
5973
}

0 commit comments

Comments
 (0)