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

1

11

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.

Goingson answered 1/4, 2013 at 10:49 Comment(2)
Could you try to initialize new regex object msdn.microsoft.com/en-us/library/hh160196.aspx and try to set Match Timeout only for this regex? If it will not work too - I will suggest you to submit a bug on connect.microsoft.comAdulterous
@Adulterous As I said in my question, the constructor variant works fine.Goingson
A
9

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.

Adulterous answered 1/4, 2013 at 16:17 Comment(1)
Wow, that's... unexpected. Works with web.config indeed -- thanks!Goingson

© 2022 - 2024 — McMap. All rights reserved.