我有一个旧式文本过滤器,该过滤器使用preg_replace_callback
进行解析。但是,当解析的文本过于复杂时,代码会死掉,除了此PHP日志条目WARNING: [pool www] child ... exited on signal 11
之外,没有给出任何错误消息。
为说明问题,请在$rows
变量中使用值10和20运行以下代码:
<?php
function my_callback(&$matches) {
return $matches[0];
}
$regex = '#^\{\|(.*?)(?:^\|\+(.*?))?(^(?:((?R))|.)*?)^\|}#msi';
$columns = '';
$rows = 10; // 20 causes WSOD with no error given
for ($i=0; $i<20; $i++) {
$columns .= "| style=\"width:6em\" | $i\n";
}
$body = "{|\n" . implode("|-\n", array_fill(0, $rows, $columns)) . "\n|}";
print preg_replace_callback($regex, 'my_callback', $body);
我如何增加代码达到的相应资源限制(假设有一些限制)?任何帮助,高度赞赏!
答案 0 :(得分:0)
经过深入挖掘,结果发现这是insufficient size of PCRE stack的变体。要进行调试,需要在cli PHP上运行程序,并且可以在最后一行使用preg_last_error()
来获取错误消息(在这种情况下为6)。
解决方案是重新编译PCRE以使用更大的堆栈,或者重写REGEX以使用更少的内存(有效地放弃递归)。