Lower the size of the input expression to 100k codepoints · google/cel-cpp@d20e1ef
11#include "parser/parser.h"
223+#include "absl/status/status.h"
34#include "absl/status/statusor.h"
45#include "absl/strings/str_format.h"
56#include "absl/strings/str_replace.h"
67#include "absl/types/optional.h"
78#include "parser/cel_grammar.inc/cel_grammar/CelLexer.h"
89#include "parser/cel_grammar.inc/cel_grammar/CelParser.h"
10+#include "parser/options.h"
911#include "parser/source_factory.h"
1012#include "parser/visitor.h"
1113#include "antlr4-runtime.h"
@@ -126,19 +128,15 @@ class RecoveryLimitErrorStrategy : public antlr4::DefaultErrorStrategy {
126128127129absl::StatusOr<ParsedExpr> Parse(const std::string& expression,
128130const std::string& description,
129-int max_recursion_depth,
130-int error_recovery_limit) {
131-return ParseWithMacros(expression, Macro::AllMacros(), description,
132- max_recursion_depth, error_recovery_limit);
131+const ParserOptions& options) {
132+return ParseWithMacros(expression, Macro::AllMacros(), description, options);
133133}
134134135135absl::StatusOr<ParsedExpr> ParseWithMacros(const std::string& expression,
136136const std::vector<Macro>& macros,
137137const std::string& description,
138-int max_recursion_depth,
139-int error_recovery_limit) {
140-auto result = EnrichedParse(expression, macros, description,
141- max_recursion_depth, error_recovery_limit);
138+const ParserOptions& options) {
139+auto result = EnrichedParse(expression, macros, description, options);
142140if (result.ok()) {
143141return result->parsed_expr();
144142 }
@@ -147,14 +145,19 @@ absl::StatusOr<ParsedExpr> ParseWithMacros(const std::string& expression,
147145148146absl::StatusOr<VerboseParsedExpr> EnrichedParse(
149147const std::string& expression, const std::vector<Macro>& macros,
150-const std::string& description, int max_recursion_depth,
151-int error_recovery_limit) {
148+const std::string& description, const ParserOptions& options) {
152149 ANTLRInputStream input(expression);
150+if (input.size() > options.expression_size_codepoint_limit) {
151+return absl::InvalidArgumentError(absl::StrCat(
152+"expression size exceeds codepoint limit.", " input size: ",
153+ input.size(), ", limit: ", options.expression_size_codepoint_limit));
154+ }
153155 CelLexer lexer(&input);
154156 CommonTokenStream tokens(&lexer);
155157 CelParser parser(&tokens);
156- ExprRecursionListener listener(max_recursion_depth);
157- ParserVisitor visitor(description, expression, max_recursion_depth, macros);
158+ ExprRecursionListener listener(options.max_recursion_depth);
159+ ParserVisitor visitor(description, expression, options.max_recursion_depth,
160+ macros);
158161159162 lexer.removeErrorListeners();
160163 parser.removeErrorListeners();
@@ -165,7 +168,7 @@ absl::StatusOr<VerboseParsedExpr> EnrichedParse(
165168// Limit the number of error recovery attempts to prevent bad expressions
166169// from consuming lots of cpu / memory.
167170 std::shared_ptr<RecoveryLimitErrorStrategy> error_strategy(
168-new RecoveryLimitErrorStrategy(error_recovery_limit));
171+new RecoveryLimitErrorStrategy(options.error_recovery_limit));
169172 parser.setErrorHandler(error_strategy);
170173171174 CelParser::StartContext* root;