为什么这个Javascript match()函数崩溃我的浏览器?

时间:2012-10-10 18:28:29

标签: javascript regex crash

我做了什么:

  • 确保Firebug正常工作。
  • 在isWrappedInParens()函数中放置一个断点。
  • 导航到我的网络应用程序。
  • 触发对isWrappedInParens()的调用。
  • 单步执行isWrappedInParens()。一切都很顺利,但它没有超过代表“CRASH POINT”的代码行。
  • 我也尝试过没有Firebug运行或有断点,但它仍然冻结。

我注意到了什么:

  • 在大多数情况下,isWrappedInParens()工作正常。
  • 当它不起作用时,Firefox会冻结。不过,我仍然可以最小化/扩展/关闭窗口。
  • 我也注意到当测试字符串稍短(括号少)时,firefox挂起但最终正确完成(~30秒)。

崩溃FIREFOX的示例字符

// Note that this is not wrapped in parentheses,
// since it is two separate sets of nested parentheses
var test = "(the OR (and) OR (and) OR (and)) AND ((to) OR (to) OR (to))";

背景

  • 浏览器:Firefox 3.6.18
  • webapp是一个码头应用程序。

CODE

isWrappedInParens = function(str){
    if(_.isNull(str)) {
        return false;
    }
    str = str.trim();

    var pattern = /^[(](([(][^()]+[)]|[^()]+)|[(]([(][^()]+[)]|[^()]+)+[)])+[)]$/;

    var matchesPattern;
    try{
        matchesPattern = str.match(pattern) || null; //CRASH POINT!!!!!!!!!!!
    }catch(err){
        return false; //Note that no error is ever caught from freezing
    }

    var isWrapped = !_.isUndefined(matchesPattern) && !_.isNull(matchesPattern);
    return isWrapped;
}

地址来自:

// Atoms, building blocks for the expressions
var parenAtom = "[(][^()]+[)]";
var nonParenAtom = "[^()]+";

// Expressions, building blocks for the final regular expression
var baseCase = "(" + parenAtom + "|" + nonParenAtom + ")";
var nestedCase = "[(]_base_[)]"
    .replace("_base_", baseCase);

// Regular Expression
var wholeCase = "^[(](_base_|_nested_)+[)]$"
    .replace("_base_", baseCase)
    .replace("_nested_", nestedCase);
var pattern = new RegExp(wholeCase, "");

1 个答案:

答案 0 :(得分:1)

来自我的评论:

  

查看Firefox错误数据库,发现了许多正则表达式错误,并将其松散地归类为“指数行为”错误。其中大多数已在较新版本的浏览器中修复。

In this bug Brendan Eich有一些关于这个问题的评论,他列出了其他几个错误(有些很老)。另一个评论暗示Firefox 4中的“正则表达式大修”,表明很多变化都发生在那时。