[java] Infinite loop when parsing invalid code nested in lambdas

- fixes #3117
- backports part of StatementExpression production from pmd7
This commit is contained in:
Andreas Dangel
2021-03-04 20:16:37 +01:00
parent 5650b720b3
commit 4bfd72e658
4 changed files with 46 additions and 3 deletions

View File

@ -16,6 +16,9 @@ This is a {{ site.pmd.release_type }} release.
### Fixed Issues
* java
* [#3117](https://github.com/pmd/pmd/issues/3117): \[java] Infinite loop when parsing invalid code nested in lambdas
### API Changes
### External Contributions

View File

@ -237,6 +237,11 @@ options {
TRACK_TOKENS = true;
NODE_PACKAGE="net.sourceforge.pmd.lang.java.ast";
// disable the calculation of expected tokens when a parse error occurs
// depending on the possible allowed next tokens, this
// could be expensive (see https://github.com/pmd/pmd/issues/3117)
//ERROR_REPORTING = false;
//DEBUG_PARSER = true;
//DEBUG_LOOKAHEAD = true;
//DEBUG_TOKEN_MANAGER = true;
@ -2131,9 +2136,9 @@ void StatementExpression() :
|
PreDecrementExpression()
|
LOOKAHEAD( PrimaryExpression() AssignmentOperator() ) PrimaryExpression() AssignmentOperator() Expression()
|
PostfixExpression()
// using PostfixExpression here allows us to skip the part of the production tree
// between Expression() and PostfixExpression()
PostfixExpression() [ AssignmentOperator() Expression() ]
}
void SwitchStatement():

View File

@ -226,6 +226,13 @@ public class ParserCornersTest {
java8.parseResource("GitHubBug309.java");
}
@Test(timeout = 30000)
public void testInfiniteLoopInLookahead() {
expect.expect(ParseException.class);
// https://github.com/pmd/pmd/issues/3117
java8.parseResource("InfiniteLoopInLookahead.java");
}
/**
* This triggered bug #1484 UnusedLocalVariable - false positive -
* parenthesis

View File

@ -0,0 +1,28 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
import java.util.*;
public class InfiniteLoopInLookahead {
public void exam1(List resList) {
resList.forEach(a -> {
resList.forEach(b -> {
resList.forEach(c -> {
resList.forEach(d -> {
resList.forEach(e -> {
resList.forEach(f -> {
resList.forEach(g -> {
resList.forEach(h -> {
resList // note: missing semicolon -> parse error here...
});
});
});
});
});
});
});
});
}
}