@@ -68,6 +68,8 @@ absl::Span<const cel::Type> SortableTypes() {
6868 return kTypes ;
6969}
7070
71+ constexpr int64_t kMaxRangeSize = 1000000 ;
72+
7173// Slow distinct() implementation that uses Equal() to compare values in O(n^2).
7274absl::Status ListDistinctHeterogeneousImpl (
7375 const ListValue& list,
@@ -223,10 +225,20 @@ absl::StatusOr<Value> ListFlatten(
223225 return std::move (*builder).Build ();
224226}
225227
226- absl::StatusOr<ListValue> ListRange (
227- int64_t end, const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
228+ absl::StatusOr<Value> ListRange (
229+ int64_t end, int64_t max_range_size,
230+ const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
228231 google::protobuf::MessageFactory* absl_nonnull message_factory,
229232 google::protobuf::Arena* absl_nonnull arena) {
233+ if (end < 0 ) {
234+ return ErrorValue (absl::InvalidArgumentError (absl::StrFormat (
235+ " lists.range: size must be non-negative, got %d" , end)));
236+ }
237+ if (end > max_range_size) {
238+ return ErrorValue (absl::InvalidArgumentError (
239+ absl::StrFormat (" lists.range: size %d exceeds maximum allowed (%d)" ,
240+ end, max_range_size)));
241+ }
230242 auto builder = NewListValueBuilder (arena);
231243 builder->Reserve (end);
232244 for (int64_t i = 0 ; i < end; ++i) {
@@ -512,11 +524,27 @@ absl::Status RegisterListFlattenFunction(FunctionRegistry& registry) {
512524 return absl::OkStatus ();
513525}
514526
515- absl::Status RegisterListRangeFunction (FunctionRegistry& registry) {
516- return UnaryFunctionAdapter<absl::StatusOr<Value>,
517- int64_t >::RegisterGlobalOverload (" lists.range" ,
518- &ListRange,
519- registry);
527+ absl::Status RegisterListRangeFunction (
528+ FunctionRegistry& registry,
529+ const ListsExtensionOptions& extension_options) {
530+ constexpr int64_t kMaxRangeSize = 1000000 ;
531+ int64_t effective_limit = kMaxRangeSize ;
532+ if (extension_options.max_range_size > 0 &&
533+ extension_options.max_range_size < effective_limit) {
534+ effective_limit = extension_options.max_range_size ;
535+ }
536+ return UnaryFunctionAdapter<absl::StatusOr<Value>, int64_t >::
537+ RegisterGlobalOverload (
538+ " lists.range" ,
539+ [effective_limit](
540+ int64_t end,
541+ const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
542+ google::protobuf::MessageFactory* absl_nonnull message_factory,
543+ google::protobuf::Arena* absl_nonnull arena) -> absl::StatusOr<Value> {
544+ return ListRange (end, effective_limit, descriptor_pool,
545+ message_factory, arena);
546+ },
547+ registry);
520548}
521549
522550absl::Status RegisterListReverseFunction (FunctionRegistry& registry) {
@@ -657,23 +685,23 @@ absl::Status ConfigureParser(ParserBuilder& builder, int version) {
657685
658686} // namespace
659687
660- absl::Status RegisterListsFunctions (FunctionRegistry& registry,
661- const RuntimeOptions& options,
662- int version ) {
688+ absl::Status RegisterListsFunctions (
689+ FunctionRegistry& registry, const RuntimeOptions& options,
690+ const ListsExtensionOptions& extension_options ) {
663691 CEL_RETURN_IF_ERROR (RegisterListSliceFunction (registry));
664- if (version == 0 ) {
692+ if (extension_options. version == 0 ) {
665693 return absl::OkStatus ();
666694 }
667695
668696 // Since version 1
669697 CEL_RETURN_IF_ERROR (RegisterListFlattenFunction (registry));
670- if (version == 1 ) {
698+ if (extension_options. version == 1 ) {
671699 return absl::OkStatus ();
672700 }
673701
674702 // Since version 2
675703 CEL_RETURN_IF_ERROR (RegisterListDistinctFunction (registry));
676- CEL_RETURN_IF_ERROR (RegisterListRangeFunction (registry));
704+ CEL_RETURN_IF_ERROR (RegisterListRangeFunction (registry, extension_options ));
677705 CEL_RETURN_IF_ERROR (RegisterListReverseFunction (registry));
678706 CEL_RETURN_IF_ERROR (RegisterListSortFunction (registry));
679707 return absl::OkStatus ();
@@ -684,18 +712,23 @@ absl::Status RegisterListsMacros(MacroRegistry& registry, const ParserOptions&,
684712 return registry.RegisterMacros (lists_macros (version));
685713}
686714
687- CheckerLibrary ListsCheckerLibrary (int version) {
715+ CheckerLibrary ListsCheckerLibrary (
716+ const ListsExtensionOptions& extension_options) {
688717 return {.id = " cel.lib.ext.lists" ,
689- .configure = [version](TypeCheckerBuilder& builder) {
718+ .configure = [version = extension_options.version ](
719+ TypeCheckerBuilder& builder) {
690720 return RegisterListsCheckerDecls (builder, version);
691721 }};
692722}
693723
694- CompilerLibrary ListsCompilerLibrary (int version) {
695- auto lib = CompilerLibrary::FromCheckerLibrary (ListsCheckerLibrary (version));
696- lib.configure_parser = [version](ParserBuilder& builder) {
697- return ConfigureParser (builder, version);
698- };
724+ CompilerLibrary ListsCompilerLibrary (
725+ const ListsExtensionOptions& extension_options) {
726+ auto lib = CompilerLibrary::FromCheckerLibrary (
727+ ListsCheckerLibrary (extension_options));
728+ lib.configure_parser =
729+ [version = extension_options.version ](ParserBuilder& builder) {
730+ return ConfigureParser (builder, version);
731+ };
699732 return lib;
700733}
701734
0 commit comments