EditorConfigLanguage
EditorConfigLanguage copied to clipboard
Catastrophic Backtracking (100% CPU + VS hang) in EditorConfigDocument.ParseAsync's _suppress Regex, caused by comma in input
Installed product versions
- Visual Studio: Visual Studio 2019 v16.10.0
- This extension: 1.17.288
Description
- I started typing a command into an
.editorconfigfile and as soon as I typed a comma ","devenv.exesuddenly started using 100% CPU on all of my processor cores. - I attached a CLRv4 debugger and saw a load of worker threads were stuck in
System.Text.RegularExpressions.RegexInterpreter.GoviaEditorConfig.EditorConfigDocument.ParseAsync.
(Updated) Steps to recreate
After some digging, I found out the _suppress regex can get stuck on certain inputs. Here's a reliable repro I've made in Linqpad 6:
// Copied from https://github.com/madskristensen/EditorConfigLanguage/blob/ebec9b5d3069c9c6a0adbdcf2e642ef2d9d8317f/src/Parser/EditorConfigDocumentParser.cs
Regex suppressRegex = new Regex(@"^(?<comment>#\s*suppress\s*):?\s*(?<errors>(\w{0,5}\s*)+)$", RegexOptions.IgnoreCase);
String goodLine = @"# Suppressed because we do use antiforgery tokens as configured in Startup.cs";
Match goodMatch = suppressRegex.Match( goodLine ); // Works fine
goodMatch.Dump();
String badLine = @"# Suppressed because we do use antiforgery tokens, as configured in Startup.cs";
Match badMatch = suppressRegex.Match( badLine ); // <-- Program will get stuck here.
badMatch.Dump();
I tried it on Regex101.com on the same input data and it reported a Catastrophic Backtracking error.
(Real-life) Steps to recreate
-
Have an editor config like this:
root = true # All files [*] indent_style = tab [*.csproj] indent_style = space indent_size = 2 # Code files [*.cs] indent_size = 4 insert_final_newline = true charset = utf-8 # CA1055: URI return values should not be strings dotnet_diagnostic.CA1055.severity = silent # CA1056: URI properties should not be strings dotnet_diagnostic.CA1056.severity = silent # CA5395: Action method needs to specify the HTTP request kind explictly # https://github.com/dotnet/aspnetcore/issues/33102 dotnet_diagnostic.CA5395.severity = none # CA1707: Identifiers should not contain underscores dotnet_diagnostic.CA1707.severity = none # CA5391: Use antiforgery tokens in ASP.NET Core MVC controllers dotnet_code_quality.CA5391.exclude_aspnet_core_mvc_controllerbase = true -
Manually type a new comment line underneath the
# CA5391line (and beforedotnet_code_quality.CA5391):# Suppressed because we do use antiforgery tokens as configured in Startup.cs -
Insert a comma after "tokens" and before "as configured":
# Suppressed because we do use antiforgery tokens, as configured in Startup.cs -
devenv.exewill now hog your CPU.
Stack traces

> System.dll!System.Text.RegularExpressions.RegexInterpreter.Go() Unknown Non-user code. Skipped loading symbols.
System.dll!System.Text.RegularExpressions.RegexRunner.Scan(System.Text.RegularExpressions.Regex regex, string text, int textbeg, int textend, int textstart, int prevlen, bool quick = false, System.TimeSpan timeout) Unknown Non-user code. Skipped loading symbols.
System.dll!System.Text.RegularExpressions.Regex.Run(bool quick, int prevlen, string input, int beginning, int length, int startat) Unknown Non-user code. Skipped loading symbols.
System.dll!System.Text.RegularExpressions.Regex.Match(string input, int startat) Unknown Non-user code. Skipped loading symbols.
System.dll!System.Text.RegularExpressions.Regex.Match(string input) Unknown Non-user code. Skipped loading symbols.
EditorConfig.dll!EditorConfig.EditorConfigDocument.ParseAsync.AnonymousMethod__26_0() Unknown Non-user code. Skipped loading symbols.
mscorlib.dll!System.Threading.Tasks.Task.InnerInvoke() Unknown Non-user code. Skipped loading symbols.
mscorlib.dll!System.Threading.Tasks.Task.Execute() Unknown Non-user code. Skipped loading symbols.
mscorlib.dll!System.Threading.Tasks.Task.ExecutionContextCallback(object obj) Unknown Non-user code. Skipped loading symbols.
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Unknown Non-user code. Skipped loading symbols.
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Unknown Non-user code. Skipped loading symbols.
mscorlib.dll!System.Threading.Tasks.Task.ExecuteWithThreadLocal(ref System.Threading.Tasks.Task currentTaskSlot = Id = 1189516, Status = Running, Method = Inspecting the state of an object in the debuggee of type System.Delegate is not supported in this context.) Unknown Non-user code. Skipped loading symbols.
mscorlib.dll!System.Threading.Tasks.Task.ExecuteEntry(bool bPreventDoubleExecution) Unknown Non-user code. Skipped loading symbols.
mscorlib.dll!System.Threading.Tasks.Task.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() Unknown Non-user code. Skipped loading symbols.
mscorlib.dll!System.Threading.ThreadPoolWorkQueue.Dispatch() Unknown Non-user code. Skipped loading symbols.
mscorlib.dll!System.Threading._ThreadPoolWaitCallback.PerformWaitCallback() Unknown Non-user code. Skipped loading symbols.
and
> System.dll!System.Text.RegularExpressions.RegexCharClass.CharInCategoryGroup(char ch, System.Globalization.UnicodeCategory chcategory = LowercaseLetter, string category = "\0\0\n\0\u0002\u0004\u0005\u0003\u0001\u0006\t\u0013\0", ref int i = 7) Unknown Non-user code. Skipped loading symbols.
System.dll!System.Text.RegularExpressions.RegexCharClass.CharInCategory(char ch, string set = "\0\0\n\0\u0002\u0004\u0005\u0003\u0001\u0006\t\u0013\0", int start, int mySetLength, int myCategoryLength) Unknown Non-user code. Skipped loading symbols.
System.dll!System.Text.RegularExpressions.RegexCharClass.CharInClassInternal(char ch, string set, int start, int mySetLength, int myCategoryLength) Unknown Non-user code. Skipped loading symbols.
System.dll!System.Text.RegularExpressions.RegexCharClass.CharInClassRecursive(char ch, string set, int start) Unknown Non-user code. Skipped loading symbols.
System.dll!System.Text.RegularExpressions.RegexCharClass.CharInClass(char ch, string set) Unknown Non-user code. Skipped loading symbols.
System.dll!System.Text.RegularExpressions.RegexInterpreter.Go() Unknown Non-user code. Skipped loading symbols.
System.dll!System.Text.RegularExpressions.RegexRunner.Scan(System.Text.RegularExpressions.Regex regex, string text, int textbeg, int textend, int textstart, int prevlen, bool quick = false, System.TimeSpan timeout) Unknown Non-user code. Skipped loading symbols.
System.dll!System.Text.RegularExpressions.Regex.Run(bool quick, int prevlen, string input, int beginning, int length, int startat) Unknown Non-user code. Skipped loading symbols.
System.dll!System.Text.RegularExpressions.Regex.Match(string input, int startat) Unknown Non-user code. Skipped loading symbols.
System.dll!System.Text.RegularExpressions.Regex.Match(string input) Unknown Non-user code. Skipped loading symbols.
EditorConfig.dll!EditorConfig.EditorConfigDocument.ParseAsync.AnonymousMethod__26_0() Unknown Non-user code. Skipped loading symbols.
mscorlib.dll!System.Threading.Tasks.Task.InnerInvoke() Unknown Non-user code. Skipped loading symbols.
mscorlib.dll!System.Threading.Tasks.Task.Execute() Unknown Non-user code. Skipped loading symbols.
mscorlib.dll!System.Threading.Tasks.Task.ExecutionContextCallback(object obj) Unknown Non-user code. Skipped loading symbols.
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Unknown Non-user code. Skipped loading symbols.
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Unknown Non-user code. Skipped loading symbols.
mscorlib.dll!System.Threading.Tasks.Task.ExecuteWithThreadLocal(ref System.Threading.Tasks.Task currentTaskSlot = Id = 1189518, Status = Running, Method = "Void <ParseAsync>b__26_0()") Unknown Non-user code. Skipped loading symbols.
mscorlib.dll!System.Threading.Tasks.Task.ExecuteEntry(bool bPreventDoubleExecution) Unknown Non-user code. Skipped loading symbols.
mscorlib.dll!System.Threading.Tasks.Task.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() Unknown Non-user code. Skipped loading symbols.
mscorlib.dll!System.Threading.ThreadPoolWorkQueue.Dispatch() Unknown Non-user code. Skipped loading symbols.
mscorlib.dll!System.Threading._ThreadPoolWaitCallback.PerformWaitCallback() Unknown Non-user code. Skipped loading symbols.