preg_replace_callback导致PHP死亡

时间:2018-10-17 15:31:59

标签: php

我有一个旧式文本过滤器,该过滤器使用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);

我如何增加代码达到的相应资源限制(假设有一些限制)?任何帮助,高度赞赏!

1 个答案:

答案 0 :(得分:0)

经过深入挖掘,结果发现这是insufficient size of PCRE stack的变体。要进行调试,需要在cli PHP上运行程序,并且可以在最后一行使用preg_last_error()来获取错误消息(在这种情况下为6)。

解决方案是重新编译PCRE以使用更大的堆栈,或者重写REGEX以使用更少的内存(有效地放弃递归)。

相关问题