aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/sksl/SkSLParser.cpp33
-rw-r--r--src/sksl/SkSLParser.h6
2 files changed, 38 insertions, 1 deletions
diff --git a/src/sksl/SkSLParser.cpp b/src/sksl/SkSLParser.cpp
index 2699d9c113..7eac0ce567 100644
--- a/src/sksl/SkSLParser.cpp
+++ b/src/sksl/SkSLParser.cpp
@@ -73,6 +73,31 @@
namespace SkSL {
+#define MAX_PARSE_DEPTH 50
+
+class AutoDepth {
+public:
+ AutoDepth(Parser* p)
+ : fParser(p) {
+ fParser->fDepth++;
+ }
+
+ ~AutoDepth() {
+ fParser->fDepth--;
+ }
+
+ bool checkValid() {
+ if (fParser->fDepth > MAX_PARSE_DEPTH) {
+ fParser->error(fParser->peek().fPosition, "exceeded max parse depth");
+ return false;
+ }
+ return true;
+ }
+
+private:
+ Parser* fParser;
+};
+
Parser::Parser(std::string text, SymbolTable& types, ErrorReporter& errors)
: fPushback(Position(-1, -1), Token::INVALID_TOKEN, "")
, fTypes(types)
@@ -920,6 +945,10 @@ std::unique_ptr<ASTDiscardStatement> Parser::discardStatement() {
/* LBRACE statement* RBRACE */
std::unique_ptr<ASTBlock> Parser::block() {
+ AutoDepth depth(this);
+ if (!depth.checkValid()) {
+ return nullptr;
+ }
Token start;
if (!this->expect(Token::LBRACE, "'{'", &start)) {
return nullptr;
@@ -959,6 +988,10 @@ std::unique_ptr<ASTExpressionStatement> Parser::expressionStatement() {
/* assignmentExpression */
std::unique_ptr<ASTExpression> Parser::expression() {
+ AutoDepth depth(this);
+ if (!depth.checkValid()) {
+ return nullptr;
+ }
return this->assignmentExpression();
}
diff --git a/src/sksl/SkSLParser.h b/src/sksl/SkSLParser.h
index d1ae0d0e9f..f9dcde244f 100644
--- a/src/sksl/SkSLParser.h
+++ b/src/sksl/SkSLParser.h
@@ -197,12 +197,16 @@ private:
bool identifier(std::string* dest);
-
void* fScanner;
YY_BUFFER_STATE fBuffer;
+ // current parse depth, used to enforce a recursion limit to try to keep us from overflowing the
+ // stack on pathological inputs
+ int fDepth = 0;
Token fPushback;
SymbolTable& fTypes;
ErrorReporter& fErrors;
+
+ friend class AutoDepth;
};
} // namespace