Search in sources :

Example 6 with SECheck

use of org.sonar.java.se.checks.SECheck in project sonar-java by SonarSource.

the class MethodYieldTest method yields_are_not_generated_by_check.

@Test
public void yields_are_not_generated_by_check() {
    MethodYield yield = newMethodYield(mockMethodBehavior(1, false));
    assertThat(yield.generatedByCheck(null)).isFalse();
    assertThat(yield.generatedByCheck(new SECheck() {
    })).isFalse();
}
Also used : SECheck(org.sonar.java.se.checks.SECheck) Test(org.junit.Test)

Example 7 with SECheck

use of org.sonar.java.se.checks.SECheck in project sonar-java by SonarSource.

the class MethodYieldTest method constraints_on_varargs.

@Test
public void constraints_on_varargs() throws Exception {
    ActionParser<Tree> p = JavaParser.createParser();
    CompilationUnitTree cut = (CompilationUnitTree) p.parse(new File("src/test/files/se/VarArgsYields.java"));
    SemanticModel semanticModel = SemanticModel.createFor(cut, new SquidClassLoader(new ArrayList<>()));
    SymbolicExecutionVisitor sev = new SymbolicExecutionVisitor(Lists.newArrayList(new SECheck[] {}), new BehaviorCache(new SquidClassLoader(new ArrayList<>())));
    JavaFileScannerContext context = mock(JavaFileScannerContext.class);
    when(context.getTree()).thenReturn(cut);
    when(context.getSemanticModel()).thenReturn(semanticModel);
    sev.scanFile(context);
    MethodSymbol methodSymbol = ((MethodTree) ((ClassTree) cut.types().get(0)).members().get(0)).symbol();
    MethodBehavior mb = getMethodBehavior(sev, "varArgMethod");
    List<MethodYield> yields = mb.yields();
    assertThat(yields).hasSize(5);
    assertThat(mb.exceptionalPathYields()).hasSize(4);
    MethodYield yield = mb.happyPathYields().findFirst().get();
    // check that we have NOT_NULL constraint on the first argument
    assertThat(yield.parametersConstraints.get(0).get(ObjectConstraint.class)).isEqualTo(ObjectConstraint.NOT_NULL);
    // check that we have NOT_NULL constraint on the variadic argument
    assertThat(yield.parametersConstraints.get(1).get(ObjectConstraint.class)).isEqualTo(ObjectConstraint.NOT_NULL);
    List<IdentifierTree> usages = methodSymbol.usages();
    assertThat(usages).hasSize(6);
    List<List<Type>> arguments = usages.stream().map(MethodYieldTest::getMethodIncoationArgumentsTypes).collect(Collectors.toList());
    ProgramState ps = ProgramState.EMPTY_STATE;
    ProgramState psResult;
    SymbolicValue svFirstArg = new SymbolicValue();
    SymbolicValue svVarArg1 = new SymbolicValue();
    SymbolicValue svVarArg2 = new SymbolicValue();
    SymbolicValue svResult = new SymbolicValue();
    // apply constraint NotNull to parameter
    Collection<ProgramState> arrayOfA = yield.statesAfterInvocation(Lists.newArrayList(svFirstArg, svVarArg1), arguments.get(0), ps, () -> svResult).collect(Collectors.toList());
    assertThat(arrayOfA).hasSize(1);
    psResult = arrayOfA.iterator().next();
    assertThat(psResult.getConstraint(svFirstArg, ObjectConstraint.class)).isEqualTo(ObjectConstraint.NOT_NULL);
    assertThat(psResult.getConstraint(svVarArg1, ObjectConstraint.class)).isEqualTo(ObjectConstraint.NOT_NULL);
    // apply constraint NotNull to parameter (B[] is a subtype of A[])
    Collection<ProgramState> arrayOfB = yield.statesAfterInvocation(Lists.newArrayList(svFirstArg, svVarArg1), arguments.get(1), ps, () -> svResult).collect(Collectors.toList());
    assertThat(arrayOfB).hasSize(1);
    psResult = arrayOfB.iterator().next();
    assertThat(psResult.getConstraint(svFirstArg, ObjectConstraint.class)).isEqualTo(ObjectConstraint.NOT_NULL);
    assertThat(psResult.getConstraint(svVarArg1, ObjectConstraint.class)).isEqualTo(ObjectConstraint.NOT_NULL);
    // no constraint, as 'a' is not an array
    Collection<ProgramState> objectA = yield.statesAfterInvocation(Lists.newArrayList(svFirstArg, svVarArg1), arguments.get(2), ps, () -> svResult).collect(Collectors.toList());
    assertThat(objectA).hasSize(1);
    psResult = objectA.iterator().next();
    assertThat(psResult.getConstraint(svFirstArg, ObjectConstraint.class)).isEqualTo(ObjectConstraint.NOT_NULL);
    assertThat(psResult.getConstraint(svVarArg1, ObjectConstraint.class)).isNull();
    // no constraint, as 'a' and 'b' can not receive the constraint of the array
    Collection<ProgramState> objectsAandB = yield.statesAfterInvocation(Lists.newArrayList(svFirstArg, svVarArg1, svVarArg2), arguments.get(3), ps, () -> svResult).collect(Collectors.toList());
    assertThat(objectsAandB).hasSize(1);
    psResult = objectsAandB.iterator().next();
    assertThat(psResult.getConstraint(svFirstArg, ObjectConstraint.class)).isEqualTo(ObjectConstraint.NOT_NULL);
    assertThat(psResult.getConstraint(svVarArg1, ObjectConstraint.class)).isNull();
    assertThat(psResult.getConstraint(svVarArg2, ObjectConstraint.class)).isNull();
    // no param, we only learn something about the argument which is not variadic
    Collection<ProgramState> noParam = yield.statesAfterInvocation(Lists.newArrayList(svFirstArg), arguments.get(4), ps, () -> svResult).collect(Collectors.toList());
    assertThat(noParam).hasSize(1);
    psResult = noParam.iterator().next();
    assertThat(psResult.getConstraint(svFirstArg, ObjectConstraint.class)).isEqualTo(ObjectConstraint.NOT_NULL);
    // null param, contradiction, no resulting program state
    ps = ProgramState.EMPTY_STATE.addConstraint(svFirstArg, ObjectConstraint.NULL);
    Collection<ProgramState> nullParam = yield.statesAfterInvocation(Lists.newArrayList(svFirstArg, svVarArg1), arguments.get(5), ps, () -> svResult).collect(Collectors.toList());
    assertThat(nullParam).isEmpty();
}
Also used : MethodTree(org.sonar.plugins.java.api.tree.MethodTree) ArrayList(java.util.ArrayList) ClassTree(org.sonar.plugins.java.api.tree.ClassTree) IdentifierTree(org.sonar.plugins.java.api.tree.IdentifierTree) ProgramState(org.sonar.java.se.ProgramState) SquidClassLoader(org.sonar.java.bytecode.loader.SquidClassLoader) SECheck(org.sonar.java.se.checks.SECheck) JavaFileScannerContext(org.sonar.plugins.java.api.JavaFileScannerContext) CompilationUnitTree(org.sonar.plugins.java.api.tree.CompilationUnitTree) ClassTree(org.sonar.plugins.java.api.tree.ClassTree) IdentifierTree(org.sonar.plugins.java.api.tree.IdentifierTree) ExpressionTree(org.sonar.plugins.java.api.tree.ExpressionTree) Tree(org.sonar.plugins.java.api.tree.Tree) MethodInvocationTree(org.sonar.plugins.java.api.tree.MethodInvocationTree) MethodTree(org.sonar.plugins.java.api.tree.MethodTree) List(java.util.List) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) SymbolicValue(org.sonar.java.se.symbolicvalues.SymbolicValue) CompilationUnitTree(org.sonar.plugins.java.api.tree.CompilationUnitTree) SemanticModel(org.sonar.java.resolve.SemanticModel) SETestUtils.createSymbolicExecutionVisitor(org.sonar.java.se.SETestUtils.createSymbolicExecutionVisitor) SymbolicExecutionVisitor(org.sonar.java.se.SymbolicExecutionVisitor) MethodSymbol(org.sonar.plugins.java.api.semantic.Symbol.MethodSymbol) SETestUtils.mockMethodBehavior(org.sonar.java.se.SETestUtils.mockMethodBehavior) SETestUtils.getMethodBehavior(org.sonar.java.se.SETestUtils.getMethodBehavior) File(java.io.File) Test(org.junit.Test)

Example 8 with SECheck

use of org.sonar.java.se.checks.SECheck in project sonar-java by SonarSource.

the class JavaAstScannerTest method should_swallow_log_and_report_checks_exceptions_for_symbolic_execution.

@Test
public void should_swallow_log_and_report_checks_exceptions_for_symbolic_execution() {
    JavaAstScanner scanner = new JavaAstScanner(JavaParser.createParser(), null);
    logTester.clear();
    SonarComponents sonarComponent = new SonarComponents(null, context.fileSystem(), null, null, null, null);
    context.setRuntime(SonarRuntimeImpl.forSonarLint(Version.create(6, 7)));
    sonarComponent.setSensorContext(context);
    scanner.setVisitorBridge(new VisitorsBridge(Collections.singletonList(new SECheck() {

        @Override
        public void init(MethodTree methodTree, CFG cfg) {
            throw new NullPointerException("nobody expect the spanish inquisition !");
        }
    }), new ArrayList<>(), sonarComponent, SymbolicExecutionMode.ENABLED_WITHOUT_X_FILE));
    scanner.scan(ImmutableList.of(new File("src/test/resources/se/MethodBehavior.java")));
    assertThat(logTester.logs(LoggerLevel.ERROR)).hasSize(1);
    assertThat(logTester.logs(LoggerLevel.ERROR).get(0)).startsWith("Unable to run check class org.sonar.java.se.SymbolicExecutionVisitor");
    assertThat(sonarComponent.analysisErrors).hasSize(1);
    assertThat(sonarComponent.analysisErrors.get(0).getKind()).isSameAs(AnalysisError.Kind.SE_ERROR);
}
Also used : SonarComponents(org.sonar.java.SonarComponents) SECheck(org.sonar.java.se.checks.SECheck) MethodTree(org.sonar.plugins.java.api.tree.MethodTree) CFG(org.sonar.java.cfg.CFG) ArrayList(java.util.ArrayList) VisitorsBridge(org.sonar.java.model.VisitorsBridge) DefaultInputFile(org.sonar.api.batch.fs.internal.DefaultInputFile) File(java.io.File) Test(org.junit.Test)

Example 9 with SECheck

use of org.sonar.java.se.checks.SECheck in project sonar-java by SonarSource.

the class CheckerDispatcherTest method test_only_one_execution_of_post_statement_by_check.

@Test
public void test_only_one_execution_of_post_statement_by_check() {
    List<SECheck> checks = Lists.newArrayList(new NullDereferenceCheck(), new CheckTest(), new CheckTest(), new CheckTest());
    CheckerDispatcher checkerDispatcher = new CheckerDispatcher(mockExplodedGraphWalker(), checks);
    checkerDispatcher.executeCheckPostStatement(mock(Tree.class));
    for (SECheck check : checks) {
        if (check instanceof CheckTest) {
            assertThat(((CheckTest) check).postStatementExecution).isEqualTo(1);
        }
    }
}
Also used : SECheck(org.sonar.java.se.checks.SECheck) NullDereferenceCheck(org.sonar.java.se.checks.NullDereferenceCheck) Tree(org.sonar.plugins.java.api.tree.Tree) Test(org.junit.Test)

Example 10 with SECheck

use of org.sonar.java.se.checks.SECheck in project sonar-java by SonarSource.

the class ExceptionalCheckBasedYieldTest method creation_of_new_yield.

@Test
public void creation_of_new_yield() {
    String methodName = "method";
    SymbolicExecutionVisitor sev;
    MethodBehavior mb;
    Pair<SymbolicExecutionVisitor, SemanticModel> visitorAndSemantic = createSymbolicExecutionVisitorAndSemantic(FILENAME);
    sev = visitorAndSemantic.a;
    SemanticModel semanticModel = visitorAndSemantic.b;
    mb = getMethodBehavior(sev, methodName);
    // no creation of custom yields, 3 method yields
    assertThat(mb.yields()).hasSize(3);
    assertThat(mb.happyPathYields()).hasSize(1);
    assertThat(mb.happyPathYields().filter(y -> y.parametersConstraints.get(0).get(BooleanConstraint.class) == null)).hasSize(1);
    assertThat(mb.happyPathYields().filter(y -> y.parametersConstraints.get(0).get(BooleanConstraint.class) == BooleanConstraint.TRUE)).hasSize(0);
    assertThat(mb.happyPathYields().filter(y -> y.parametersConstraints.get(0).get(BooleanConstraint.class) == BooleanConstraint.FALSE)).hasSize(0);
    assertThat(mb.exceptionalPathYields()).hasSize(2);
    assertThat(mb.exceptionalPathYields()).as("All the exceptional yields are runtime exceptions").allMatch(y -> y.exceptionType(semanticModel).isUnknown());
    assertThat(mb.exceptionalPathYields().filter(y -> y.parametersConstraints.get(0).get(BooleanConstraint.class) == BooleanConstraint.TRUE)).hasSize(1);
    assertThat(mb.exceptionalPathYields().filter(y -> y.parametersConstraints.get(0).get(BooleanConstraint.class) == BooleanConstraint.FALSE)).hasSize(1);
    // new rule discard any call to plantFlowers(true) by creating a new yield
    SECheck check = new TestSECheck();
    sev = createSymbolicExecutionVisitor(FILENAME, check);
    mb = getMethodBehavior(sev, methodName);
    assertThat(mb.yields()).hasSize(4);
    // 2nd param can never be null
    assertThat(mb.yields().stream().filter(y -> y.parametersConstraints.get(0).isEmpty() && y.parametersConstraints.get(1).get(ObjectConstraint.class) == ObjectConstraint.NULL)).hasSize(1);
    assertThat(mb.yields().stream().filter(y -> y.parametersConstraints.get(1).get(ObjectConstraint.class) != ObjectConstraint.NULL)).hasSize(3);
    // happyPath with first parameter being true is discarded
    assertThat(mb.happyPathYields()).hasSize(2);
    // still 2 exceptional path
    assertThat(mb.exceptionalPathYields()).hasSize(2);
    assertThat(mb.exceptionalPathYields().filter(y -> y.exceptionType(semanticModel).isUnknown())).hasSize(1);
    assertThat(mb.exceptionalPathYields().filter(y -> y.exceptionType(semanticModel).isClass())).hasSize(1);
    assertThat(mb.exceptionalPathYields().filter(y -> y.parametersConstraints.get(0).get(BooleanConstraint.class) == BooleanConstraint.FALSE)).hasSize(1);
    ExceptionalYield exceptionalYield = mb.exceptionalPathYields().filter(y -> y.parametersConstraints.get(0).get(BooleanConstraint.class) == BooleanConstraint.TRUE).findFirst().get();
    assertThat(exceptionalYield).isInstanceOf(ExceptionalCheckBasedYield.class);
    ExceptionalCheckBasedYield seCheckExceptionalYield = (ExceptionalCheckBasedYield) exceptionalYield;
    assertThat(seCheckExceptionalYield.check()).isEqualTo(TestSECheck.class);
    assertThat(seCheckExceptionalYield.exceptionType(semanticModel)).isNotNull();
    assertThat(seCheckExceptionalYield.exceptionType(semanticModel).is("java.lang.UnsupportedOperationException")).isTrue();
    assertThat(seCheckExceptionalYield.exceptionType(semanticModel).isSubtypeOf("java.lang.RuntimeException")).isTrue();
    assertThat(seCheckExceptionalYield.generatedByCheck(check)).isTrue();
    assertThat(seCheckExceptionalYield.generatedByCheck(new SECheck() {
    })).isFalse();
    assertThat(seCheckExceptionalYield.parameterCausingExceptionIndex()).isEqualTo(0);
}
Also used : SECheck(org.sonar.java.se.checks.SECheck) SemanticModel(org.sonar.java.resolve.SemanticModel) SETestUtils.mockMethodBehavior(org.sonar.java.se.SETestUtils.mockMethodBehavior) SETestUtils.getMethodBehavior(org.sonar.java.se.SETestUtils.getMethodBehavior) ObjectConstraint(org.sonar.java.se.constraint.ObjectConstraint) SETestUtils.createSymbolicExecutionVisitor(org.sonar.java.se.SETestUtils.createSymbolicExecutionVisitor) SymbolicExecutionVisitor(org.sonar.java.se.SymbolicExecutionVisitor) Test(org.junit.Test)

Aggregations

SECheck (org.sonar.java.se.checks.SECheck)12 Test (org.junit.Test)11 SETestUtils.getMethodBehavior (org.sonar.java.se.SETestUtils.getMethodBehavior)4 MethodTree (org.sonar.plugins.java.api.tree.MethodTree)4 Tree (org.sonar.plugins.java.api.tree.Tree)4 ArrayList (java.util.ArrayList)3 SETestUtils.createSymbolicExecutionVisitor (org.sonar.java.se.SETestUtils.createSymbolicExecutionVisitor)3 SETestUtils.mockMethodBehavior (org.sonar.java.se.SETestUtils.mockMethodBehavior)3 SymbolicValue (org.sonar.java.se.symbolicvalues.SymbolicValue)3 MethodInvocationTree (org.sonar.plugins.java.api.tree.MethodInvocationTree)3 File (java.io.File)2 CFG (org.sonar.java.cfg.CFG)2 SemanticModel (org.sonar.java.resolve.SemanticModel)2 SymbolicExecutionVisitor (org.sonar.java.se.SymbolicExecutionVisitor)2 ImmutableList (com.google.common.collect.ImmutableList)1 HashSet (java.util.HashSet)1 List (java.util.List)1 ArgumentMatchers.anyString (org.mockito.ArgumentMatchers.anyString)1 DefaultInputFile (org.sonar.api.batch.fs.internal.DefaultInputFile)1 SonarComponents (org.sonar.java.SonarComponents)1