Skip to content

Commit 4bb05db

Browse files
authored
deps: bump up cel-cpp to v0.11.0 (#39334)
## Description This PR bumps up the version of `cel-cpp` to v0.11.0. There are some major changes where we now have `cel::expr::ParsedExpr` instead of `google::api::expr::v1alpha1::ParsedExpr`. We are doing the conversion in the code to keep it backward compatible. We should remove it in a follow-up PR by migrating everything to use `cel::expr::ParsedExpr` instead. --- **Commit Message:** deps: bump up `cel-cpp` to v0.11.0 **Additional Description:** Bump up the version of `cel-cpp` to v0.11.0 **Risk Level:** Low **Testing:** CI **Docs Changes:** N/A **Release Notes:** N/A --------- Signed-off-by: Rohit Agrawal <[email protected]>
1 parent 858fef7 commit 4bb05db

File tree

24 files changed

+570
-166
lines changed

24 files changed

+570
-166
lines changed

bazel/foreign_cc/cel-cpp.patch

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
From d88b2a2d81e62335708057b3a044abada46de2a3 Mon Sep 17 00:00:00 2001
2+
From: Rohit Agrawal <[email protected]>
3+
Date: Tue, 6 May 2025 17:30:08 +0900
4+
Subject: [PATCH] Patches for cel-cpp v0.11.0
5+
6+
Signed-off-by: Rohit Agrawal <[email protected]>
7+
---
8+
common/internal/byte_string.cc | 8 ++++++++
9+
common/value.h | 2 +-
10+
common/values/value_variant.h | 10 ++++++++++
11+
runtime/type_registry.h | 4 ++--
12+
4 files changed, 21 insertions(+), 3 deletions(-)
13+
14+
diff --git a/common/internal/byte_string.cc b/common/internal/byte_string.cc
15+
index e01c797f8..12345678a 100644
16+
--- a/common/internal/byte_string.cc
17+
+++ b/common/internal/byte_string.cc
18+
@@ -104,6 +104,14 @@
19+
20+
ByteString::ByteString(Allocator<> allocator, absl::string_view string) {
21+
ABSL_DCHECK_LE(string.size(), max_size());
22+
+
23+
+ // Check for null data pointer in the string_view
24+
+ if (string.data() == nullptr) {
25+
+ // Handle null data by creating an empty ByteString
26+
+ SetSmallEmpty(allocator.arena());
27+
+ return;
28+
+ }
29+
+
30+
auto* arena = allocator.arena();
31+
if (string.size() <= kSmallByteStringCapacity) {
32+
SetSmall(arena, string);
33+
diff --git a/common/value.h b/common/value.h
34+
index 06a03c13d..9f5d77980 100644
35+
--- a/common/value.h
36+
+++ b/common/value.h
37+
@@ -2733,7 +2733,7 @@
38+
absl::Nonnull<const google::protobuf::DescriptorPool*> descriptor_pool,
39+
absl::Nonnull<google::protobuf::MessageFactory*> message_factory,
40+
absl::Nonnull<google::protobuf::Arena*> arena) const {
41+
- ABSL_DCHECK_GT(qualifiers.size(), 0);
42+
+ ABSL_DCHECK_GT(static_cast<int>(qualifiers.size()), 0);
43+
ABSL_DCHECK(descriptor_pool != nullptr);
44+
ABSL_DCHECK(message_factory != nullptr);
45+
ABSL_DCHECK(arena != nullptr);
46+
diff --git a/common/values/value_variant.h b/common/values/value_variant.h
47+
index 61c19ce5f..fc7969bc8 100644
48+
--- a/common/values/value_variant.h
49+
+++ b/common/values/value_variant.h
50+
@@ -732,6 +732,13 @@
51+
const bool rhs_trivial =
52+
(rhs.flags_ & ValueFlags::kNonTrivial) == ValueFlags::kNone;
53+
if (lhs_trivial && rhs_trivial) {
54+
+ // We need to suppress the compiler warnings about memory manipulation.
55+
+ // The memcpy usage here is intentional for performance optimization
56+
+ // Only suppress this warning on GCC, as Clang doesn't have this warning
57+
+#if defined(__GNUC__) && !defined(__clang__)
58+
+#pragma GCC diagnostic push
59+
+#pragma GCC diagnostic ignored "-Wclass-memaccess"
60+
+#endif
61+
alignas(ValueVariant) std::byte tmp[sizeof(ValueVariant)];
62+
// NOLINTNEXTLINE(bugprone-undefined-memory-manipulation)
63+
std::memcpy(tmp, std::addressof(lhs), sizeof(ValueVariant));
64+
@@ -740,6 +747,9 @@
65+
sizeof(ValueVariant));
66+
// NOLINTNEXTLINE(bugprone-undefined-memory-manipulation)
67+
std::memcpy(std::addressof(rhs), tmp, sizeof(ValueVariant));
68+
+#if defined(__GNUC__) && !defined(__clang__)
69+
+#pragma GCC diagnostic pop
70+
+#endif
71+
} else {
72+
SlowSwap(lhs, rhs, lhs_trivial, rhs_trivial);
73+
}
74+
diff --git a/runtime/type_registry.h b/runtime/type_registry.h
75+
index 2b247946c..3e5ad423b 100644
76+
--- a/runtime/type_registry.h
77+
+++ b/runtime/type_registry.h
78+
@@ -77,8 +77,8 @@
79+
// Move-only
80+
TypeRegistry(const TypeRegistry& other) = delete;
81+
TypeRegistry& operator=(TypeRegistry& other) = delete;
82+
- TypeRegistry(TypeRegistry&& other) = default;
83+
- TypeRegistry& operator=(TypeRegistry&& other) = default;
84+
+ TypeRegistry(TypeRegistry&& other) = delete;
85+
+ TypeRegistry& operator=(TypeRegistry&& other) = delete;
86+
87+
// Registers a type such that it can be accessed by name, i.e. `type(foo) ==
88+
// my_type`. Where `my_type` is the type being registered.

bazel/repositories.bzl

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,29 @@ def _com_github_facebook_zstd():
506506

507507
def _com_google_cel_cpp():
508508
external_http_archive(
509-
"com_google_cel_cpp",
509+
name = "com_google_cel_cpp",
510+
patch_args = ["-p1"],
511+
patches = ["@envoy//bazel/foreign_cc:cel-cpp.patch"],
512+
)
513+
514+
# Load required dependencies that cel-cpp expects.
515+
external_http_archive("com_google_cel_spec")
516+
517+
# cel-cpp references ``@antlr4-cpp-runtime//:antlr4-cpp-runtime`` but it internally
518+
# defines ``antlr4_runtimes`` with a cpp target.
519+
# We are creating a repository alias to avoid duplicating the ANTLR4 dependency.
520+
native.new_local_repository(
521+
name = "antlr4-cpp-runtime",
522+
path = ".",
523+
build_file_content = """
524+
package(default_visibility = ["//visibility:public"])
525+
526+
# Alias to cel-cpp's embedded ANTLR4 runtime.
527+
alias(
528+
name = "antlr4-cpp-runtime",
529+
actual = "@antlr4_runtimes//:cpp",
530+
)
531+
""",
510532
)
511533

512534
def _com_github_google_perfetto():

bazel/repository_locations.bzl

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1301,12 +1301,44 @@ REPOSITORY_LOCATIONS_SPEC = dict(
13011301
license = "googleurl",
13021302
license_url = "https://quiche.googlesource.com/googleurl/+/{version}/LICENSE",
13031303
),
1304+
com_google_cel_spec = dict(
1305+
project_name = "Common Expression Language (CEL) spec",
1306+
project_desc = "Common Expression Language (CEL) spec and conformance tests",
1307+
project_url = "https://opensource.google/projects/cel",
1308+
version = "0.24.0",
1309+
sha256 = "5cba6b0029e727d1f4d8fd134de4e747cecc0bc293d026017d7edc48058d09f7",
1310+
strip_prefix = "cel-spec-{version}",
1311+
urls = ["https://github.com/google/cel-spec/archive/v{version}.tar.gz"],
1312+
use_category = ["dataplane_ext"],
1313+
extensions = [
1314+
"envoy.access_loggers.extension_filters.cel",
1315+
"envoy.access_loggers.wasm",
1316+
"envoy.bootstrap.wasm",
1317+
"envoy.rate_limit_descriptors.expr",
1318+
"envoy.filters.http.ext_proc",
1319+
"envoy.filters.http.rate_limit_quota",
1320+
"envoy.filters.http.rbac",
1321+
"envoy.filters.http.wasm",
1322+
"envoy.filters.network.rbac",
1323+
"envoy.filters.network.wasm",
1324+
"envoy.stat_sinks.wasm",
1325+
"envoy.formatter.cel",
1326+
"envoy.matching.inputs.cel_data_input",
1327+
"envoy.matching.matchers.cel_matcher",
1328+
"envoy.tracers.opentelemetry",
1329+
"envoy.tracers.opentelemetry.samplers.cel",
1330+
],
1331+
release_date = "2025-05-09",
1332+
cpe = "N/A",
1333+
license = "Apache-2.0",
1334+
license_url = "https://github.com/google/cel-spec/blob/v{version}/LICENSE",
1335+
),
13041336
com_google_cel_cpp = dict(
13051337
project_name = "Common Expression Language (CEL) C++ library",
13061338
project_desc = "Common Expression Language (CEL) C++ library",
13071339
project_url = "https://opensource.google/projects/cel",
1308-
version = "0.10.0",
1309-
sha256 = "dd06b708a9f4c3728e76037ec9fb14fc9f6d9c9980e5d5f3a1d047f3855a8b98",
1340+
version = "0.11.0",
1341+
sha256 = "777f6780a3cc72264c3cc3279cc92affbaefb2bdc01aaff88463cca5b6167e1d",
13101342
strip_prefix = "cel-cpp-{version}",
13111343
urls = ["https://github.com/google/cel-cpp/archive/v{version}.tar.gz"],
13121344
use_category = ["dataplane_ext"],
@@ -1328,7 +1360,7 @@ REPOSITORY_LOCATIONS_SPEC = dict(
13281360
"envoy.tracers.opentelemetry",
13291361
"envoy.tracers.opentelemetry.samplers.cel",
13301362
],
1331-
release_date = "2024-10-25",
1363+
release_date = "2025-04-03",
13321364
cpe = "N/A",
13331365
license = "Apache-2.0",
13341366
license_url = "https://github.com/google/cel-cpp/blob/v{version}/LICENSE",

source/extensions/access_loggers/filters/cel/cel.cc

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,25 @@ namespace CEL {
99
namespace Expr = Envoy::Extensions::Filters::Common::Expr;
1010

1111
CELAccessLogExtensionFilter::CELAccessLogExtensionFilter(
12-
const ::Envoy::LocalInfo::LocalInfo& local_info, Expr::BuilderInstanceSharedPtr builder,
13-
const google::api::expr::v1alpha1::Expr& input_expr)
12+
const ::Envoy::LocalInfo::LocalInfo& local_info,
13+
Extensions::Filters::Common::Expr::BuilderInstanceSharedPtr builder,
14+
const cel::expr::Expr& input_expr)
1415
: local_info_(local_info), builder_(builder), parsed_expr_(input_expr) {
15-
compiled_expr_ = Expr::createExpression(builder_->builder(), parsed_expr_);
16+
compiled_expr_ =
17+
Extensions::Filters::Common::Expr::createExpression(builder_->builder(), parsed_expr_);
1618
}
1719

1820
bool CELAccessLogExtensionFilter::evaluate(const Formatter::HttpFormatterContext& log_context,
1921
const StreamInfo::StreamInfo& stream_info) const {
20-
Protobuf::Arena arena;
21-
auto eval_status = Expr::evaluate(*compiled_expr_, arena, &local_info_, stream_info,
22-
&log_context.requestHeaders(), &log_context.responseHeaders(),
23-
&log_context.responseTrailers());
24-
if (!eval_status.has_value() || eval_status.value().IsError()) {
22+
ProtobufWkt::Arena arena;
23+
const auto result = Extensions::Filters::Common::Expr::evaluate(
24+
*compiled_expr_.get(), arena, &local_info_, stream_info, &log_context.requestHeaders(),
25+
&log_context.responseHeaders(), &log_context.responseTrailers());
26+
if (!result.has_value() || result.value().IsError()) {
2527
return false;
2628
}
27-
auto result = eval_status.value();
28-
return result.IsBool() ? result.BoolOrDie() : false;
29+
auto eval_result = result.value();
30+
return eval_result.IsBool() ? eval_result.BoolOrDie() : false;
2931
}
3032

3133
} // namespace CEL

source/extensions/access_loggers/filters/cel/cel.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,15 @@ class CELAccessLogExtensionFilter : public AccessLog::Filter {
2121
public:
2222
CELAccessLogExtensionFilter(const ::Envoy::LocalInfo::LocalInfo& local_info,
2323
Extensions::Filters::Common::Expr::BuilderInstanceSharedPtr,
24-
const google::api::expr::v1alpha1::Expr&);
24+
const cel::expr::Expr&);
2525

2626
bool evaluate(const Formatter::HttpFormatterContext& log_context,
2727
const StreamInfo::StreamInfo& stream_info) const override;
2828

2929
private:
3030
const ::Envoy::LocalInfo::LocalInfo& local_info_;
3131
Extensions::Filters::Common::Expr::BuilderInstanceSharedPtr builder_;
32-
const google::api::expr::v1alpha1::Expr parsed_expr_;
32+
const cel::expr::Expr parsed_expr_;
3333
Extensions::Filters::Common::Expr::ExpressionPtr compiled_expr_;
3434
};
3535

source/extensions/common/wasm/foreign.cc

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ RegisterForeignFunction registerClearRouteCacheForeignFunction(
138138
class ExpressionFactory : public Logger::Loggable<Logger::Id::wasm> {
139139
protected:
140140
struct ExpressionData {
141-
google::api::expr::v1alpha1::ParsedExpr parsed_expr_;
141+
cel::expr::ParsedExpr parsed_expr_;
142142
Filters::Common::Expr::ExpressionPtr compiled_expr_;
143143
};
144144

@@ -203,16 +203,21 @@ class CreateExpressionFactory : public ExpressionFactory {
203203
auto token = expr_context.createToken();
204204
auto& handler = expr_context.getExpression(token);
205205

206-
handler.parsed_expr_ = parse_status.value();
206+
const auto& parsed_expr = parse_status.value();
207+
handler.parsed_expr_ = parsed_expr;
208+
209+
std::vector<absl::Status> warnings;
207210
auto cel_expression_status = expr_context.builder()->CreateExpression(
208-
&handler.parsed_expr_.expr(), &handler.parsed_expr_.source_info());
211+
&handler.parsed_expr_.expr(), &handler.parsed_expr_.source_info(), &warnings);
212+
209213
if (!cel_expression_status.ok()) {
210214
ENVOY_LOG(info, "expr_create compile error: {}", cel_expression_status.status().message());
211215
expr_context.deleteExpression(token);
212216
return WasmResult::BadArgument;
213217
}
214218

215219
handler.compiled_expr_ = std::move(cel_expression_status.value());
220+
216221
auto result = reinterpret_cast<uint32_t*>(alloc_result(sizeof(uint32_t)));
217222
*result = token;
218223
return WasmResult::Ok;

source/extensions/filters/common/expr/evaluator.cc

Lines changed: 12 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -149,35 +149,21 @@ BuilderInstanceSharedPtr getBuilder(Server::Configuration::CommonFactoryContext&
149149
[] { return std::make_shared<BuilderInstance>(createBuilder(nullptr)); });
150150
}
151151

152-
// Converts from CEL canonical to CEL v1alpha1
153-
absl::optional<google::api::expr::v1alpha1::Expr>
154-
getExpr(const ::xds::type::v3::CelExpression& expression) {
155-
::cel::expr::Expr expr;
152+
absl::optional<cel::expr::Expr> getExpr(const ::xds::type::v3::CelExpression& expression) {
156153
if (expression.has_cel_expr_checked()) {
157-
expr = expression.cel_expr_checked().expr();
154+
return expression.cel_expr_checked().expr();
158155
} else if (expression.has_cel_expr_parsed()) {
159-
expr = expression.cel_expr_parsed().expr();
156+
return expression.cel_expr_parsed().expr();
160157
} else {
161158
return {};
162159
}
163-
164-
std::string data;
165-
if (!expr.SerializeToString(&data)) {
166-
return {};
167-
}
168-
169-
// Parse the string into the target namespace message
170-
google::api::expr::v1alpha1::Expr v1alpha1Expr;
171-
if (!v1alpha1Expr.ParseFromString(data)) {
172-
return {};
173-
}
174-
175-
return v1alpha1Expr;
176160
}
177161

178-
ExpressionPtr createExpression(Builder& builder, const google::api::expr::v1alpha1::Expr& expr) {
179-
google::api::expr::v1alpha1::SourceInfo source_info;
180-
auto cel_expression_status = builder.CreateExpression(&expr, &source_info);
162+
ExpressionPtr createExpression(Builder& builder, const cel::expr::Expr& expr) {
163+
cel::expr::SourceInfo source_info;
164+
std::vector<absl::Status> warnings;
165+
166+
auto cel_expression_status = builder.CreateExpression(&expr, &source_info, &warnings);
181167
if (!cel_expression_status.ok()) {
182168
throw CelException(
183169
absl::StrCat("failed to create an expression: ", cel_expression_status.status().message()));
@@ -186,11 +172,11 @@ ExpressionPtr createExpression(Builder& builder, const google::api::expr::v1alph
186172
}
187173

188174
absl::optional<CelValue> evaluate(const Expression& expr, Protobuf::Arena& arena,
189-
const LocalInfo::LocalInfo* local_info,
175+
const ::Envoy::LocalInfo::LocalInfo* local_info,
190176
const StreamInfo::StreamInfo& info,
191-
const Http::RequestHeaderMap* request_headers,
192-
const Http::ResponseHeaderMap* response_headers,
193-
const Http::ResponseTrailerMap* response_trailers) {
177+
const ::Envoy::Http::RequestHeaderMap* request_headers,
178+
const ::Envoy::Http::ResponseHeaderMap* response_headers,
179+
const ::Envoy::Http::ResponseTrailerMap* response_trailers) {
194180
auto activation =
195181
createActivation(local_info, info, request_headers, response_headers, response_trailers);
196182
auto eval_status = expr.Evaluate(*activation, &arena);

source/extensions/filters/common/expr/evaluator.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "eval/public/cel_value.h"
1919

2020
#include "xds/type/v3/cel.pb.h"
21+
#include "cel/expr/syntax.pb.h"
2122

2223
#if defined(__GNUC__)
2324
#pragma GCC diagnostic pop
@@ -94,13 +95,11 @@ BuilderPtr createBuilder(Protobuf::Arena* arena);
9495
// Gets the singleton expression builder. Must be called on the main thread.
9596
BuilderInstanceSharedPtr getBuilder(Server::Configuration::CommonFactoryContext& context);
9697

97-
// Converts from CEL canonical to CEL v1alpha1
98-
absl::optional<google::api::expr::v1alpha1::Expr>
99-
getExpr(const ::xds::type::v3::CelExpression& expression);
98+
absl::optional<cel::expr::Expr> getExpr(const ::xds::type::v3::CelExpression& expression);
10099

101-
// Creates an interpretable expression from a protobuf representation.
100+
// Creates an interpretable expression from the new CEL expr format.
102101
// Throws an exception if fails to construct a runtime expression.
103-
ExpressionPtr createExpression(Builder& builder, const google::api::expr::v1alpha1::Expr& expr);
102+
ExpressionPtr createExpression(Builder& builder, const cel::expr::Expr& expr);
104103

105104
// Evaluates an expression for a request. The arena is used to hold intermediate computational
106105
// results and potentially the final value.

source/extensions/filters/common/rbac/matchers.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
#include "source/extensions/filters/common/rbac/matcher_interface.h"
1515
#include "source/extensions/path/match/uri_template/uri_template_match.h"
1616

17+
#include "cel/expr/syntax.pb.h"
18+
1719
namespace Envoy {
1820
namespace Extensions {
1921
namespace Filters {
@@ -187,7 +189,20 @@ class PolicyMatcher : public Matcher, NonCopyable {
187189
ProtobufMessage::ValidationVisitor& validation_visitor,
188190
Server::Configuration::CommonFactoryContext& context)
189191
: permissions_(policy.permissions(), validation_visitor, context),
190-
principals_(policy.principals(), context), condition_(policy.condition()) {
192+
principals_(policy.principals(), context), condition_([&policy]() {
193+
if (policy.has_condition()) {
194+
std::string serialized;
195+
if (!policy.condition().SerializeToString(&serialized)) {
196+
throw EnvoyException("Failed to serialize RBAC policy condition");
197+
}
198+
cel::expr::Expr new_expr;
199+
if (!new_expr.ParseFromString(serialized)) {
200+
throw EnvoyException("Failed to convert RBAC policy condition to new format");
201+
}
202+
return new_expr;
203+
}
204+
return cel::expr::Expr{};
205+
}()) {
191206
if (policy.has_condition()) {
192207
expr_ = Expr::createExpression(*builder, condition_);
193208
}
@@ -199,7 +214,7 @@ class PolicyMatcher : public Matcher, NonCopyable {
199214
private:
200215
const OrMatcher permissions_;
201216
const OrMatcher principals_;
202-
const google::api::expr::v1alpha1::Expr condition_;
217+
const cel::expr::Expr condition_;
203218
Expr::ExpressionPtr expr_;
204219
};
205220

0 commit comments

Comments
 (0)