首页 > 解决方案 > 限制 C++ 目标上的递归

问题描述

在对使用 antlr 制作的语言进行模糊测试时,模糊器报告了一个使用大量括号的缓慢测试用例。

语法中的一条规则有点像:

paren_expression: '(' expression ')';

即使它被报告为一个缓慢的单元,它也是一个更大的问题的基础,即在使用足够多的括号时能够稍微容易地使应用程序崩溃(并且它在默认情况下具有较小堆栈大小的窗口上确实如此)。

根据我的搜索,没有选项可以生成检查堆栈深度并在合理深度后退出的代码,并且从 C++ 中的堆栈溢出中恢复并不是一件好事或可移植的事情。

那么,在这种情况下可以做些什么呢?因输入错误而崩溃并不是很好。

标签: c++antlrantlr4

解决方案


您可以添加一个谓词来检查嵌套表达式的深度,并在它超过某个数字时让谓词失败。

例如,您最多允许 3 个嵌套表达式,您可以这样做:

grammar T;

@members {
  private int depth = 0;
}

parse
 : expr EOF
 ;

expr
 : '(' expr ')' {++depth <= 3}?
 | INT
 ;

INT
 : [0-9]+
 ;

编码:

TLexer lexer = new TLexer(CharStreams.fromString("(((42)))"));
TParser parser = new TParser(new CommonTokenStream(lexer));
parser.parse();

会解析得很好,但是代码:

TLexer lexer = new TLexer(CharStreams.fromString("((((42))))"));
TParser parser = new TParser(new CommonTokenStream(lexer));
parser.parse();

会抛出异常。

谓词 ( {...}?) 和@members块内的部分是特定于目标的代码(在这种情况下是 Java)。您必须用 C++ 编写它。


推荐阅读