以下功能与我在$pattern变量中提供的正则表达式中断.如果我更改正则表达式我很好,所以我认为这是问题.我没有看到这个问题,但是即使打开了它,我也没有收到标准的 PHP错误.
function parseAPIResults($results){
//Takes results from getAPIResults,returns array.

    $pattern = '/\[(.|\n)+\]/';
    $resultsArray = preg_match($pattern,$results,$matches);

}

Firefox 6: The connection was reset

Chrome 14: Error 101 (net::ERR_CONNECTION_RESET): The connection was
reset.

IE 8: Internet Explorer cannot display the webpage

更新:
Apache / PHP可能会崩溃.以下是运行脚本时的Apache错误日志:

[Sat Oct 01 11:41:40 2011] [notice] Parent: child process exited with
status 255 — Restarting.
[Sat Oct 01 11:41:40 2011] [notice]
Apache/2.2.11 (Win32) PHP/5.3.0 configured — resuming normal
operations

在Windows 7上运行WAMP 2.0.

简单的问题.复杂的答案!

是的,由于堆栈溢出,这类正则表达式会重复(并且默默地)使Apache / PHP崩溃,从而导致未处理的分段错误!

背景:

PHP preg_ *系列正则表达式功能使用了Philip Hazel强大的PCRE library.使用这个库,有一类正则表达式需要对其内部match()函数进行大量的递归调用,并且这会占用很多堆栈空间(并且所使用的堆栈空间与主题字符串的大小成正比)匹配).因此,如果主题串太长,则会发生堆栈溢出和相应的分段故障.这个行为在PCRE documentation年底的标题为:pcrestack的部分描述.

PHP Bug 1:PHP集:pcre.recursion_limit太大.

PCRE文档描述了如何通过将递归深度限制为大致等于链接应用程序的堆栈大小的安全值除以500来避免堆栈溢出分段错误.当递归深度按照推荐适当限制时,库不会生成一个堆栈溢出,而是正常退出并显示错误代码.在PHP下,这个最大递归深度用pcre.recursion_limit配置变量指定,(不幸的是)默认值设置为100,000.这个值是TOO BIG!以下是各种可执行堆栈大小的pcre.recursion_limit的安全值表:

Stacksize   pcre.recursion_limit
 64 MB      134217
 32 MB      67108
 16 MB      33554
  8 MB      16777
  4 MB      8388
  2 MB      4194
  1 MB      2097
512 KB      1048
256 KB      524

因此,对于具有256KB的(相对较小)的堆栈大小的Apache Web服务器(httpd.exe)的Win32构建,pcre.recursion_limit的正确值应设置为524.这可以通过以下行PHP代码:

ini_set("pcre.recursion_limit","524"); // PHP default is 100,000.

当此代码添加到PHP脚本时,不会发生堆栈溢出,而是生成有意义的错误代码.那就是它应该会产生一个错误代码! (但不幸的是,由于另一个PHP错误,preg_match()不会.)

PHP Bug 2:preg_match()不会返回FALSE错误.

preg_match()的PHP文档表示错误返回FALSE.不幸的是,PHP 5.3.3及更低版本有一个错误(#52732),其中preg_match()不会返回FALSE错误(它反而返回int(0),这是在不匹配的情况下返回的相同的值).在PHP 5.3.4版本中修复了这个错误.

解:

假设您将继续使用WAMP 2.0(使用PHP 5.3.0),解决方案需要考虑上述两个错误.这是我会推荐的:

>需要将pcre.recursion_limit减少到一个安全的值:524.
>只要preg_match()返回除int(1)以外的任何东西,需要明确检查PCRE错误.
>如果preg_match()返回int(1),则匹配成功.
>如果preg_match()返回int(0),则匹配不成功,或者出现错误.

这是您的脚本(旨在从命令行运行)的修改版本,用于确定导致递归限制错误的主题字符串长度:

<?PHP
// This test script is designed to be run from the command line.
// It measures the subject string length that results in a
// PREG_RECURSION_LIMIT_ERROR error in the preg_match() function.

echo("Entering TEST.PHP...\n");

// Set and display pcre.recursion_limit. (set to stacksize / 500).
// Under Win32 httpd.exe has a stack = 256KB and 8MB for PHP.exe.
//ini_set("pcre.recursion_limit","524");       // Stacksize = 256KB.
ini_set("pcre.recursion_limit","16777");   // Stacksize = 8MB.
echo(sprintf("PCRE pcre.recursion_limit is set to %s\n",ini_get("pcre.recursion_limit")));

function parseAPIResults($results){
    $pattern = "/\[(.|\n)+\]/";
    $resultsArray = preg_match($pattern,$matches);
    if ($resultsArray === 1) {
        $msg = 'Successful match.';
    } else {
        // Either an unsuccessful match,or a PCRE error occurred.
        $pcre_err = preg_last_error();  // PHP 5.2 and above.
        if ($pcre_err === PREG_NO_ERROR) {
            $msg = 'Successful non-match.';
        } else {
            // preg_match error!
            switch ($pcre_err) {
                case PREG_INTERNAL_ERROR:
                    $msg = 'PREG_INTERNAL_ERROR';
                    break;
                case PREG_BACKTRACK_LIMIT_ERROR:
                    $msg = 'PREG_BACKTRACK_LIMIT_ERROR';
                    break;
                case PREG_RECURSION_LIMIT_ERROR:
                    $msg = 'PREG_RECURSION_LIMIT_ERROR';
                    break;
                case PREG_BAD_UTF8_ERROR:
                    $msg = 'PREG_BAD_UTF8_ERROR';
                    break;
                case PREG_BAD_UTF8_OFFSET_ERROR:
                    $msg = 'PREG_BAD_UTF8_OFFSET_ERROR';
                    break;
                default:
                    $msg = 'Unrecognized PREG error';
                    break;
            }
        }
    }
    return($msg);
}

// Build a matching test string of increasing size.
function buildTestString() {
    static $content = "";
    $content .= "A";
    return '['. $content .']';
}

// Find subject string length that results in error.
for (;;) { // Infinite loop. Break out.
    $str = buildTestString();
    $msg = parseAPIResults($str);
    printf("Length =%10d\r",strlen($str));
    if ($msg !== 'Successful match.') break;
}

echo(sprintf("\nPCRE_ERROR = \"%s\" at subject string length = %d\n",$msg,strlen($str)));

echo("Exiting TEST.PHP...");

?>

当您运行此脚本时,它会连续读取主题字符串的当前长度.如果pcre.recursion_limit的默认值过高,则允许您测量导致可执行文件崩溃的字符串长度.

注释:

>在调查这个问题的答案之前,我不知道在PHPE库发生错误时,preg_match()无法返回FALSE的PHP错误.这个bug肯定会引起大量的使用preg_match的代码! (我当然会做一个自己的PHP代码的清单.)
>在Windows下,Apache Webserver可执行文件(httpd.exe)的堆栈大小为256KB. PHP命令行可执行文件(PHP.exe)的堆栈大小为8MB. pcre.recursion_limit的安全值应根据脚本在(524和16777)下运行的可执行文件进行设置.
>在* nix系统下,Apache Web服务器和命令行可执行文件通常使用8MB的堆栈大小来构建,因此不会经常遇到此问题.
> PHP开发人员应将pcre.recursion_limit的默认值设置为安全值.
> PHP开发人员应该将preg_match()修补程序应用于PHP版本5.2.
> Windows可执行文件的堆栈大小可以使用CFF Explorer免费程序手动修改.您可以使用此程序来增加Apache httpd.exe可执行文件的堆栈大小. (这在XP下工作,但Vista和Win7可能会抱怨)

php – RegExp在preg_match函数中返回浏览器错误的更多相关文章

  1. HTML5数字输入仅接受整数的实现代码

    这篇文章主要介绍了HTML5数字输入仅接受整数的实现代码,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  2. xcode – 如何在LLDB断点条件下使用堆栈内容?

    问题:我有一种情况,我们在发布期间有媒体播放,并且objc_exception_throw()在此期间大约有5次点击,但总是被捕获,并且它在媒体播放器对象的南边.我厌倦了(a)必须手动连续n次,或者(b)在播放完成之前必须禁用断点.我尝试过的:>使断点忽略前五次命中(问题:它并不总是正好五次)>使用我的目标作为模块创建我自己的符号断点(问题:没有改变)我想做什么:想到的一个解决方案是在断点命中时评

  3. ios – 如何在Xcode堆栈跟踪中查找NSInternalInconsistencyException的来源

    我没有在此堆栈跟踪中的任何位置看到任何可识别的文件名,方法调用或行号.或者,如果不是简单地读取堆栈跟踪并且涉及其他技术,那么开发人员应该采取哪些适当的下一步来追踪此类错误的来源?

  4. ios – 非常规形状的NSTextContainer示例?

    嗨,我正在使用iOS7的新TextKitAPI,我正在尝试生成一个不规则形状的UITextView.到目前为止,我在视图控制器中:然后在我的子类NSTextContainer中,我想将一个mutablePath绘制为文本容器的形状,但不知道如何实现这一点.我有:对于如何使其工作有点困惑.我找不到具有不规则形状的NSTextContainer的任何示例.解决方法不需要构建TextKit堆栈的所有代码

  5. ios – UINavigationBar -pushNavigationItem在将新控制器推送到UINavigationController堆栈时从不调用

    解决方法我找到了原因:它调用–pushNavigationItem:项不调用–pushNavigationItem:animated!

  6. ios – 使用大写符号在字符串swift中获取URL的正则表达式

    我尝试在文本中获取URL.所以,在此之前,我使用了这样一个表达式:但是当用户输入带有大写符号的URL时(例如Http://Google.com,它与它不匹配)我遇到了问题.我试过了:但什么都没发生.解决方法您可以使用正则表达式中的i内联标志关闭区分大小写,有关可用正则表达式功能的详细信息,请参阅FoundationFrameworkReference.(?ismwx-ismwx)Flagsetti

  7. 阅读iOS Webkit崩溃堆栈跟踪

    b)有没有任何其他见解,任何人都可以看到我得到的堆栈跟踪建议?解决方法我最终根据上面描述的理论进行了代码更改.在做出这些改变之后,我没有看到崩溃再次发生.所以原始理论看起来是正确的.

  8. ios – UICollectionView神秘崩溃

    我有一个UICollectionView,我用从Internet下载的图像填充单元格.为此我使用SDWebImage.我的代码如下所示:我相信我已经正确地设置了它.但应用程序完全随机崩溃,有时会留下此堆栈跟踪:日志区域中没有其他消息.我尝试设置异常断点,但每次发生此崩溃时,都会显示此堆栈跟踪.有谁知道可能是什么问题?解决方法如果有人在寻找答案,我已经解决了问题,并回答了与同一问题有关的另一个问题.你可以找到它here.希望它有所帮助!

  9. ios – 如何在Xcode 7中使用对象库的Stack View

    我最近安装了Xcode7beta并找到了一些东西像对象一样的新对象库水平堆栈视图和垂直堆栈视图.Wheniputsomecontrolsinsideit,stackviewseemstoberesizableaccordingtothecontrolsize.Whenipresentmorecontrolsthestackseemstobeadjustautomaticallyasofthesta

  10. ios – 多个NavigationControllers之间的导航

    (这可以通过我们在常见的VC之间使用segue来实现,我是对的吗?)据我所知,NavigationController代表了一堆ViewControllers,我们可以在其中弹出并推送这些VC.那么现在我们将第一个NavigationController的VC的“位置”从第二个改为VC,接下来会发生什么?如果是这样,是否意味着第一个NavigationController的VC堆栈是否已从内存中删除?

随机推荐

  1. PHP个人网站架设连环讲(一)

    先下一个OmnihttpdProffesinalV2.06,装上就有PHP4beta3可以用了。PHP4给我们带来一个简单的方法,就是使用SESSION(会话)级变量。但是如果不是PHP4又该怎么办?我们可以假设某人在15分钟以内对你的网页的请求都不属于一个新的人次,这样你可以做个计数的过程存在INC里,在每一个页面引用,访客第一次进入时将访问时间送到cookie里。以后每个页面被访问时都检查cookie上次访问时间值。

  2. PHP函数学习之PHP函数点评

    PHP函数使用说明,应用举例,精简点评,希望对您学习php有所帮助

  3. ecshop2.7.3 在php5.4下的各种错误问题处理

    将方法内的函数,分拆为2个部分。这个和gd库没有一点关系,是ecshop程序的问题。会出现这种问题,不外乎就是当前会员的session或者程序对cookie的处理存在漏洞。进过本地测试,includes\modules\integrates\ecshop.php这个整合自身会员的类中没有重写integrate.php中的check_cookie()方法导致,验证cookie时返回的username为空,丢失了登录状态,在ecshop.php中重写了此方法就可以了。把他加到ecshop.php的最后面去就可

  4. NT IIS下用ODBC连接数据库

    $connection=intodbc_connect建立数据库连接,$query_string="查询记录的条件"如:$query_string="select*fromtable"用$cur=intodbc_exec检索数据库,将记录集放入$cur变量中。再用while{$var1=odbc_result;$var2=odbc_result;...}读取odbc_exec()返回的数据集$cur。最后是odbc_close关闭数据库的连接。odbc_result()函数是取当前记录的指定字段值。

  5. PHP使用JpGraph绘制折线图操作示例【附源码下载】

    这篇文章主要介绍了PHP使用JpGraph绘制折线图操作,结合实例形式分析了php使用JpGraph的相关操作技巧与注意事项,并附带源码供读者下载参考,需要的朋友可以参考下

  6. zen_cart实现支付前生成订单的方法

    这篇文章主要介绍了zen_cart实现支付前生成订单的方法,结合实例形式详细分析了zen_cart支付前生成订单的具体步骤与相关实现技巧,需要的朋友可以参考下

  7. Thinkphp5框架实现获取数据库数据到视图的方法

    这篇文章主要介绍了Thinkphp5框架实现获取数据库数据到视图的方法,涉及thinkPHP5数据库配置、读取、模型操作及视图调用相关操作技巧,需要的朋友可以参考下

  8. PHP+jquery+CSS制作头像登录窗(仿QQ登陆)

    本篇文章介绍了PHP结合jQ和CSS制作头像登录窗(仿QQ登陆),实现了类似QQ的登陆界面,很有参考价值,有需要的朋友可以了解一下。

  9. 基于win2003虚拟机中apache服务器的访问

    下面小编就为大家带来一篇基于win2003虚拟机中apache服务器的访问。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  10. Yii2中组件的注册与创建方法

    这篇文章主要介绍了Yii2之组件的注册与创建的实现方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下

返回
顶部