-
Notifications
You must be signed in to change notification settings - Fork 326
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix stack overflow in FilterExpression.ValidForProperties #3946
Conversation
@engyebrahim please add description to this PR, and prefix the linked issue by Fix or Fixes if you want to automatically close it. If the PR is still in progress please make it a draft. |
{ | ||
valid = _condition.ValidForProperties(properties, propertyProvider); | ||
if (!valid) | ||
//Push root's right child and then root to stack then Set root as root's left child |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
//Push root's right child and then root to stack then Set root as root's left child | |
// Push root's right child and then root to stack then Set root as root's left child. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe that entire comment is unnecessary, and more complicated than the code :)
src/Microsoft.TestPlatform.Common/Filtering/FilterExpression.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.TestPlatform.Common/Filtering/FilterExpression.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.TestPlatform.Common/Filtering/FilterExpression.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.TestPlatform.Common/Filtering/FilterExpression.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.TestPlatform.Common/Filtering/FilterExpression.cs
Outdated
Show resolved
Hide resolved
The filtering logic is now a bit more unclear than it was before. And even before I did not really get fully how it works. Now that you probably have understanding of what is going on, could you please add comments with explanation of how it works to the code? Could you also add a test with a very long filter that would otherwise stack overflow please? |
Even though you could theoretically measure how many iterations it would take I think it is safe to assume that 100k entries test filter should be fast to process, and enough to test that we don't stackoverflow. (measuring how many recursive calls are possible for a simple method: static int MeasureStack(int count)
{
try
{
RuntimeHelpers.EnsureSufficientExecutionStack();
return MeasureStack(++count);
} catch (InsufficientExecutionStackException)
{
return count;
}
} Currently this is about 15k calls for .NET for this method. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please add a test that was causing the stack overflow before so that we don't regress.
src/Microsoft.TestPlatform.Common/Filtering/FilterExpression.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.TestPlatform.Common/Filtering/FilterExpression.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.TestPlatform.Common/Filtering/FilterExpression.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.TestPlatform.Common/Filtering/FilterExpression.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.TestPlatform.Common/Filtering/FilterExpression.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.TestPlatform.Common/Filtering/FilterExpression.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.TestPlatform.Common/Filtering/FilterExpression.cs
Outdated
Show resolved
Hide resolved
test/Microsoft.TestPlatform.Common.UnitTests/Filtering/FastFilterTests.cs
Outdated
Show resolved
Hide resolved
test/Microsoft.TestPlatform.Common.UnitTests/Filtering/FastFilterTests.cs
Outdated
Show resolved
Hide resolved
test/Microsoft.TestPlatform.Common.UnitTests/Filtering/FastFilterTests.cs
Outdated
Show resolved
Hide resolved
test/Microsoft.TestPlatform.Common.UnitTests/Filtering/FastFilterTests.cs
Outdated
Show resolved
Hide resolved
test/Microsoft.TestPlatform.Common.UnitTests/Filtering/FastFilterTests.cs
Outdated
Show resolved
Hide resolved
test/Microsoft.TestPlatform.Common.UnitTests/Filtering/FastFilterTests.cs
Outdated
Show resolved
Hide resolved
{ | ||
StringBuilder testCaseFilter = new("Category=Test1"); | ||
|
||
for (int i = 0; i < 1e5; i++) // creating a 100k filter cases string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for (int i = 0; i < 1e5; i++) // creating a 100k filter cases string | |
// Create filter with 100k conditions. | |
for (int i = 0; i < 100_000; i++) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just a nitpick.
Description
fixed the stack overflow in FilterExpression.ValidForProperties by replacing the recursion by iterative code (stacks and loops)
issue