Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Global regex match timeout works in console application, but not in ASP.NET MVC app

I'm trying to use .NET 4.5's new regular expression match timeout, specifically the global variant via AppDomain.CurrentDomain.SetData with the "REGEX_DEFAULT_MATCH_TIMEOUT" property (the variant whereby you pass a TimeSpan to the regex constructor works fine).

When I create a new console application with this main method:

static void Main(string[] args)
{
    AppDomain.CurrentDomain.SetData("REGEX_DEFAULT_MATCH_TIMEOUT",
        TimeSpan.FromSeconds(3));

    var m = System.Text.RegularExpressions.Regex.Match(
        "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "^(x+x+)+y$");
}

it works as expected: After three seconds, it throws a RegexMatchTimeoutException.

However if I create an empty MVC 4 app, add a HomeController and this action method:

public ActionResult Index()
{
    AppDomain.CurrentDomain.SetData("REGEX_DEFAULT_MATCH_TIMEOUT",
        TimeSpan.FromSeconds(3));

    var m = System.Text.RegularExpressions.Regex.Match(
        "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "^(x+x+)+y$");

    return View();
}

and visit http://localhost:XXXXX/ no exception is thrown and the match attempt continues. (If you wait long enough, it'll eventually finish, and then complain about the missing view. That takes veeery long though.)

Calling SetData in Global.asax's Application_Start() instead of within the controller action doesn't make the timeout happen either.

like image 979
balpha Avatar asked Apr 01 '13 10:04

balpha


1 Answers

I guess that difference between these two samples is that in your Console Application second line is the first access to the RegEx object and this is where you initialize this type. In MVC - my guess that RegEx class is used before your Index action.

I tried to verify this behavior with simple Console Application and got the same result as you had in MVC:

var m = System.Text.RegularExpressions.Regex.Match(
    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "x");

AppDomain.CurrentDomain.SetData("REGEX_DEFAULT_MATCH_TIMEOUT", 
    TimeSpan.FromSeconds(3));

var m2 = System.Text.RegularExpressions.Regex.Match(
    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "^(x+x+)+y$");

So, you just need to make sure that you will initialize this property before somebody else will use it. You can specify this configuration with web.config: http://msdn.microsoft.com/en-us/library/system.web.configuration.httpruntimesection.defaultregexmatchtimeout.aspx in httpRuntime section.

like image 59
outcoldman Avatar answered Oct 07 '22 02:10

outcoldman