Skip to content

Commit

Permalink
Fix IndexOutOfBoundsException in MethodYield.getConstraint (#3669)
Browse files Browse the repository at this point in the history
  • Loading branch information
alban-auzeill authored Jun 25, 2021
1 parent 7c4a26f commit 197e5bd
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,7 @@ private TypeSymbol variableEnclosingClass(IVariableBinding variableBinding) {
node = node.parent();
switch (node.kind()) {
case CLASS:
case RECORD:
case ENUM:
// variable declaration in a static or instance initializer
// or local variable declaration in recovered method
Expand Down
17 changes: 17 additions & 0 deletions java-frontend/src/test/java/org/sonar/java/model/JSymbolTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,23 @@ void enclosingClass() {
.hasEnclosingClass(cu.sema.typeSymbol(c1.typeBinding));
}

@Test
void record_enclosingClass() {
JavaTree.CompilationUnitTreeImpl cu = test("record C1(int f) { record C2(int p) { } }");
ClassTreeImpl c1 = (ClassTreeImpl) cu.types().get(0);
VariableTreeImpl f = (VariableTreeImpl) c1.recordComponents().get(0);
ClassTreeImpl c2 = (ClassTreeImpl) c1.members().get(0);
VariableTreeImpl p = (VariableTreeImpl) c2.recordComponents().get(0);

assertThat(cu.sema.variableSymbol(f.variableBinding))
.as("of field")
.hasEnclosingClass(cu.sema.typeSymbol(c1.typeBinding));

assertThat(cu.sema.variableSymbol(p.variableBinding))
.as("of method parameter")
.hasEnclosingClass(cu.sema.typeSymbol(c2.typeBinding));
}

@Test
void variable_in_class_initializer() {
JavaTree.CompilationUnitTreeImpl cu = test("enum E { C; { int i; } }");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
import org.sonar.plugins.java.api.tree.BlockTree;
import org.sonar.plugins.java.api.tree.CaseGroupTree;
import org.sonar.plugins.java.api.tree.CaseLabelTree;
import org.sonar.plugins.java.api.tree.ClassTree;
import org.sonar.plugins.java.api.tree.ConditionalExpressionTree;
import org.sonar.plugins.java.api.tree.DoWhileStatementTree;
import org.sonar.plugins.java.api.tree.ExpressionTree;
Expand Down Expand Up @@ -361,7 +362,7 @@ private Iterable<ProgramState> startingStates(MethodTree tree, ProgramState curr
boolean nullableParameters = isGloballyAnnotatedParameterNullable(methodTree.symbol());
boolean hasMethodBehavior = methodBehavior != null;

for (final VariableTree variableTree : tree.parameters()) {
for (final VariableTree variableTree : methodOrRecordConstructorParameters(tree)) {
final SymbolicValue sv = constraintManager.createSymbolicValue(variableTree);
Symbol variableSymbol = variableTree.symbol();
if (hasMethodBehavior) {
Expand All @@ -386,6 +387,14 @@ private Iterable<ProgramState> startingStates(MethodTree tree, ProgramState curr
return stateStream.collect(Collectors.toList());
}

private static List<VariableTree> methodOrRecordConstructorParameters(MethodTree methodTree) {
Tree parent = methodTree.parent();
if (parent.kind() == Tree.Kind.RECORD && methodTree.openParenToken() == null) {
return ((ClassTree) parent).recordComponents();
}
return methodTree.parameters();
}

private static void throwMaximumStartingStates(MethodTree tree) {
String message = String.format("reached maximum number of %d starting states for method %s in class %s",
MAX_STARTING_STATES, tree.simpleName().name(), tree.symbol().owner().name());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.sonar.java.checks;

public record RecordConstructorParameters(List<Message> messages) {

public RecordConstructorParameters {
requireNonNull(messages == null && messages.isEmtpy()); // Noncompliant {{A "NullPointerException" could be thrown; "messages" is nullable here.}}
}

public RecordConstructorParameters() {
this(new ArrayList<>());
}

public static RecordConstructorParameters create(List<Message> messages) {
if (messages == null) {
return new RecordConstructorParameters();
}
return new RecordConstructorParameters(messages);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,15 @@ void exception_catched_in_loop() throws Exception {
.verifyIssues();
}

@Test
void record_constructor_parameters() throws Exception {
SECheckVerifier.newVerifier()
.onFile("src/test/files/se/RecordConstructorParameters.java")
.withChecks(seChecks())
.withClassPath(SETestUtils.CLASS_PATH)
.verifyIssues();
}

@Test
void constraints_on_fields() throws Exception {
SECheckVerifier.newVerifier()
Expand Down

0 comments on commit 197e5bd

Please sign in to comment.