@@ -307,12 +307,18 @@ struct SourceTextTraits<absl::Cord> {
307307
308308template <typename T>
309309absl::StatusOr<SourcePtr> NewSourceImpl (std::string description, const T& text,
310- const size_t text_size) {
310+ const size_t text_size,
311+ const size_t max_codepoints) {
311312 if (ABSL_PREDICT_FALSE (
312313 text_size >
313314 static_cast <size_t >(std::numeric_limits<int32_t >::max ()))) {
314315 return absl::InvalidArgumentError (" expression larger than 2GiB limit" );
315316 }
317+ if ((text_size >> 2 ) > max_codepoints) {
318+ // If byte size is 4 times the codepoint limit, then definitely exceeded.
319+ return absl::InvalidArgumentError (absl::StrCat (
320+ " expression is larger than codepoint limit " , max_codepoints));
321+ }
316322 using Traits = SourceTextTraits<T>;
317323 size_t index = 0 ;
318324 typename Traits::iterator_type it = Traits::Begin (text);
@@ -324,6 +330,10 @@ absl::StatusOr<SourcePtr> NewSourceImpl(std::string description, const T& text,
324330 std::vector<char32_t > data32;
325331 absl::InlinedVector<SourcePosition, 1 > line_offsets;
326332 while (index < text_size) {
333+ if (offset >= max_codepoints) {
334+ return absl::InvalidArgumentError (absl::StrCat (
335+ " expression is larger than codepoint limit " , max_codepoints));
336+ }
327337 std::tie (code_point, code_units) = cel::internal::Utf8Decode (it);
328338 if (ABSL_PREDICT_FALSE (code_point ==
329339 cel::internal::kUnicodeReplacementCharacter &&
@@ -375,6 +385,10 @@ absl::StatusOr<SourcePtr> NewSourceImpl(std::string description, const T& text,
375385 std::move (description), std::move (line_offsets), Traits::ToVector (text));
376386latin1:
377387 while (index < text_size) {
388+ if (offset >= max_codepoints) {
389+ return absl::InvalidArgumentError (absl::StrCat (
390+ " expression is larger than codepoint limit " , max_codepoints));
391+ }
378392 std::tie (code_point, code_units) = internal::Utf8Decode (it);
379393 if (ABSL_PREDICT_FALSE (code_point ==
380394 internal::kUnicodeReplacementCharacter &&
@@ -420,6 +434,10 @@ absl::StatusOr<SourcePtr> NewSourceImpl(std::string description, const T& text,
420434 std::move (description), std::move (line_offsets), std::move (data8));
421435basic:
422436 while (index < text_size) {
437+ if (offset >= max_codepoints) {
438+ return absl::InvalidArgumentError (absl::StrCat (
439+ " expression is larger than codepoint limit " , max_codepoints));
440+ }
423441 std::tie (code_point, code_units) = internal::Utf8Decode (it);
424442 if (ABSL_PREDICT_FALSE (code_point ==
425443 internal::kUnicodeReplacementCharacter &&
@@ -453,6 +471,10 @@ absl::StatusOr<SourcePtr> NewSourceImpl(std::string description, const T& text,
453471 std::move (description), std::move (line_offsets), std::move (data16));
454472supplemental:
455473 while (index < text_size) {
474+ if (offset >= max_codepoints) {
475+ return absl::InvalidArgumentError (absl::StrCat (
476+ " expression is larger than codepoint limit " , max_codepoints));
477+ }
456478 std::tie (code_point, code_units) = internal::Utf8Decode (it);
457479 if (ABSL_PREDICT_FALSE (code_point ==
458480 internal::kUnicodeReplacementCharacter &&
@@ -631,16 +653,27 @@ absl::Span<const SourcePosition> SourceSubrange::line_offsets() const {
631653 return absl::MakeConstSpan (line_offsets_);
632654}
633655
656+ static size_t ClampLimit (int value) {
657+ if (value < 0 ) {
658+ return std::numeric_limits<size_t >::max ();
659+ }
660+ return static_cast <size_t >(value);
661+ }
662+
634663absl::StatusOr<absl_nonnull SourcePtr> NewSource (absl::string_view content,
635- std::string description) {
664+ std::string description,
665+ const SourceOptions& options) {
636666 return common_internal::NewSourceImpl (std::move (description), content,
637- content.size ());
667+ content.size (),
668+ ClampLimit (options.max_codepoint_size ));
638669}
639670
640671absl::StatusOr<absl_nonnull SourcePtr> NewSource (const absl::Cord& content,
641- std::string description) {
672+ std::string description,
673+ const SourceOptions& options) {
642674 return common_internal::NewSourceImpl (std::move (description), content,
643- content.size ());
675+ content.size (),
676+ ClampLimit (options.max_codepoint_size ));
644677}
645678
646679} // namespace cel
0 commit comments