Skip to content

Commit

Permalink
Prevent StackOverflowError when filtering exception cause loops (#1922)
Browse files Browse the repository at this point in the history
  • Loading branch information
Vampire authored Mar 18, 2024
1 parent e1dafcf commit ebfd0b6
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,14 @@
import org.spockframework.util.InternalIdentifiers;

import java.util.ArrayList;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static java.util.Collections.newSetFromMap;

/**
* Filters an exception's stack trace. Removes internal Groovy and Spock methods, and
* restores the original names of feature methods (as specified in source code).
Expand Down Expand Up @@ -58,6 +62,14 @@ public StackTraceFilter(IMethodNameMapper mapper) {

@Override
public void filter(Throwable throwable) {
filter(throwable, newSetFromMap(new IdentityHashMap<>()));
}

private void filter(Throwable throwable, Set<Throwable> seen) {
if (!seen.add(throwable)) {
return;
}

List<StackTraceElement> filteredTrace = new ArrayList<>();

for (StackTraceElement elem : throwable.getStackTrace()) {
Expand All @@ -74,7 +86,7 @@ public void filter(Throwable throwable) {

throwable.setStackTrace(filteredTrace.toArray(STACK_TRACE_ELEMENTS));

if (throwable.getCause() != null) filter(throwable.getCause());
if (throwable.getCause() != null) filter(throwable.getCause(), seen);
}

private boolean isInitializerOrFixtureMethod(StackTraceElement elem) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -364,4 +364,33 @@ org.spockframework.runtime.foo.Baz|bar|0
org.spockframework.runtime.foo.Baz|bar|0
"""
}

def "exception cause loops do not cause StackOverflowError"() {
when:
runner.runFeatureBody """
when:
def e = new Exception()
def cause = new Exception(e)
e.initCause(cause)
throw e
then:
thrown(RuntimeException)
"""

then:
WrongExceptionThrownError e = thrown()

stackTraceLooksLike e.cause, """
apackage.ASpec|a feature|2
"""

stackTraceLooksLike e.cause.cause, """
apackage.ASpec|a feature|3
"""

stackTraceLooksLike e.cause.cause.cause, """
apackage.ASpec|a feature|2
"""
}
}

0 comments on commit ebfd0b6

Please sign in to comment.