Added skslc parse recursion limit

The fuzzer discovered that a long chain of left-parentheses would cause a stack overflow due to excessive recursion. While it is not in general possible to guarantee that we do not exceed stack limits (because the system can be configured with an arbitrarily small stack), setting a reasonable recursion limit will at least keep the fuzzer from continually finding more "bugs" like this.

BUG=skia:5899
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2459573003

Review-Url: https://codereview.chromium.org/2459573003
This commit is contained in:
ethannicholas 2016-10-27 10:54:02 -07:00 committed by Commit bot
parent 18fa6421e9
commit cad6416ccb
2 changed files with 38 additions and 1 deletions

View File

@ -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();
}

View File

@ -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