c++ - 限制 C++ 目标上的递归
问题描述
在对使用 antlr 制作的语言进行模糊测试时,模糊器报告了一个使用大量括号的缓慢测试用例。
语法中的一条规则有点像:
paren_expression: '(' expression ')';
即使它被报告为一个缓慢的单元,它也是一个更大的问题的基础,即在使用足够多的括号时能够稍微容易地使应用程序崩溃(并且它在默认情况下具有较小堆栈大小的窗口上确实如此)。
根据我的搜索,没有选项可以生成检查堆栈深度并在合理深度后退出的代码,并且从 C++ 中的堆栈溢出中恢复并不是一件好事或可移植的事情。
那么,在这种情况下可以做些什么呢?因输入错误而崩溃并不是很好。
解决方案
您可以添加一个谓词来检查嵌套表达式的深度,并在它超过某个数字时让谓词失败。
例如,您最多允许 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++ 编写它。
推荐阅读
- swift - 使用 2D 数组的 UIButton 网格
- html - 圆形滚动条
- facebook - 调用 {page-id}/Posts 端点返回权限错误,但应用程序已获得该权限的批准
- amazon-web-services - AWS Lambda 函数在 Cloudwatch 中没有日志
- php - php代码中的字体质量差(imagettftext)
- javascript - Ext Ajax 请求异步问题
- python - 如何从 Python 以编程方式运行 Lilypond,而不是调用 Lilypond 可执行文件来生成乐谱?
- cryptography - 如何使 base64 .p12 可用?
- powerbi - 将 Power BI 仪表板导出为 PDF 时的背景
- sql - LogParser 检索 IIS 日志中的值