Search in sources :

Example 1 with ObjectConstraint

use of org.sonar.java.se.constraint.ObjectConstraint in project sonar-java by SonarSource.

the class MapComputeIfAbsentOrPresentCheck method checkPreStatement.

@Override
public ProgramState checkPreStatement(CheckerContext context, Tree syntaxNode) {
    if (syntaxNode.is(Tree.Kind.METHOD_INVOCATION)) {
        MethodInvocationTree mit = (MethodInvocationTree) syntaxNode;
        if (MAP_PUT.matches(mit) && !isMethodInvocationThrowingCheckedException(mit.arguments().get(1))) {
            ProgramState ps = context.getState();
            SymbolicValue keySV = ps.peekValue(1);
            SymbolicValue mapSV = ps.peekValue(2);
            mapGetInvocations.get(mapSV).stream().filter(getOnSameMap -> getOnSameMap.withSameKey(keySV)).findAny().ifPresent(getOnSameMap -> {
                ObjectConstraint constraint = ps.getConstraint(getOnSameMap.value, ObjectConstraint.class);
                if (constraint != null && isInsideIfStatementWithNullCheckWithoutElse(mit)) {
                    checkIssues.add(new CheckIssue(context.getNode(), getOnSameMap.mit, mit, getOnSameMap.value, constraint));
                }
            });
        }
    }
    return super.checkPreStatement(context, syntaxNode);
}
Also used : MethodInvocationTree(org.sonar.plugins.java.api.tree.MethodInvocationTree) ObjectConstraint(org.sonar.java.se.constraint.ObjectConstraint) ProgramState(org.sonar.java.se.ProgramState) SymbolicValue(org.sonar.java.se.symbolicvalues.SymbolicValue)

Example 2 with ObjectConstraint

use of org.sonar.java.se.constraint.ObjectConstraint in project sonar-java by SonarSource.

the class OptionalGetBeforeIsPresentCheck method setOptionalConstraint.

private static List<ProgramState> setOptionalConstraint(CheckerContext context, Tree syntaxNode) {
    ProgramState programState = context.getState();
    if (!syntaxNode.is(Tree.Kind.METHOD_INVOCATION)) {
        return Collections.singletonList(programState);
    }
    MethodInvocationTree mit = (MethodInvocationTree) syntaxNode;
    SymbolicValue peekValue = programState.peekValue();
    Preconditions.checkNotNull(peekValue);
    if (OPTIONAL_EMPTY.matches(mit)) {
        return peekValue.setConstraint(programState, OptionalConstraint.NOT_PRESENT);
    }
    if (OPTIONAL_OF.matches(mit)) {
        return peekValue.setConstraint(programState, OptionalConstraint.PRESENT);
    }
    if (OPTIONAL_OF_NULLABLE.matches(mit)) {
        ProgramState psPriorMethodInvocation = context.getNode().programState;
        SymbolicValue paramSV = psPriorMethodInvocation.peekValue(0);
        ObjectConstraint paramConstraint = psPriorMethodInvocation.getConstraint(paramSV, ObjectConstraint.class);
        if (paramConstraint != null) {
            // Optional.ofNullable(null) returns an empty Optional
            return peekValue.setConstraint(programState, paramConstraint == ObjectConstraint.NULL ? OptionalConstraint.NOT_PRESENT : OptionalConstraint.PRESENT);
        }
    }
    return Collections.singletonList(programState);
}
Also used : MethodInvocationTree(org.sonar.plugins.java.api.tree.MethodInvocationTree) ObjectConstraint(org.sonar.java.se.constraint.ObjectConstraint) ProgramState(org.sonar.java.se.ProgramState) SymbolicValue(org.sonar.java.se.symbolicvalues.SymbolicValue)

Example 3 with ObjectConstraint

use of org.sonar.java.se.constraint.ObjectConstraint in project sonar-java by SonarSource.

the class NullDereferenceCheck method checkConstraint.

private ProgramState checkConstraint(CheckerContext context, Tree syntaxNode, SymbolicValue currentVal) {
    ProgramState programState = context.getState();
    ObjectConstraint constraint = programState.getConstraint(currentVal, ObjectConstraint.class);
    if (constraint != null && constraint.isNull()) {
        NullDereferenceIssue issue = new NullDereferenceIssue(context.getNode(), currentVal, syntaxNode);
        detectedIssues.peek().add(issue);
        // we reported the issue and stopped the exploration, but we still need to create a yield for x-procedural calls
        context.addExceptionalYield(currentVal, programState, JAVA_LANG_NPE, this);
        return null;
    }
    constraint = programState.getConstraint(currentVal, ObjectConstraint.class);
    if (constraint == null) {
        // a NPE will be triggered if the current value would have been null
        context.addExceptionalYield(currentVal, programState.addConstraint(currentVal, ObjectConstraint.NULL), JAVA_LANG_NPE, this);
        // We dereferenced the target value for the member select, so we can assume it is not null when not already known
        return programState.addConstraint(currentVal, ObjectConstraint.NOT_NULL);
    }
    return programState;
}
Also used : ObjectConstraint(org.sonar.java.se.constraint.ObjectConstraint) ProgramState(org.sonar.java.se.ProgramState)

Example 4 with ObjectConstraint

use of org.sonar.java.se.constraint.ObjectConstraint in project sonar-java by SonarSource.

the class BytecodeEGWalkerTest method generateMethodBehavior.

@Test
public void generateMethodBehavior() throws Exception {
    MethodBehavior methodBehavior = getMethodBehavior("fun(ZLjava/lang/Object;)Ljava/lang/Object;");
    assertThat(methodBehavior.yields()).hasSize(2);
    SymbolicValue svFirstArg = new SymbolicValue();
    SymbolicValue svsecondArg = new SymbolicValue();
    SymbolicValue svResult = new SymbolicValue();
    List<SymbolicValue> invocationArguments = Lists.newArrayList(svFirstArg, svsecondArg);
    List<ObjectConstraint> collect = methodBehavior.yields().stream().map(my -> {
        Collection<ProgramState> ps = my.statesAfterInvocation(invocationArguments, Lists.newArrayList(), ProgramState.EMPTY_STATE, () -> svResult).collect(Collectors.toList());
        assertThat(ps).hasSize(1);
        ProgramState next = ps.iterator().next();
        return next.getConstraint(svResult, ObjectConstraint.class);
    }).collect(Collectors.toList());
    assertThat(collect).hasSize(2).containsOnly(ObjectConstraint.NOT_NULL, ObjectConstraint.NULL);
    List<HappyPathYield> nullConstraintOnResult = methodBehavior.happyPathYields().filter(my -> ObjectConstraint.NULL.equals(my.resultConstraint().get(ObjectConstraint.class))).collect(Collectors.toList());
    assertThat(nullConstraintOnResult).hasSize(1);
    HappyPathYield nullConstraintResult = nullConstraintOnResult.get(0);
    Collection<ProgramState> ps = nullConstraintResult.statesAfterInvocation(invocationArguments, Lists.newArrayList(), ProgramState.EMPTY_STATE, () -> svResult).collect(Collectors.toList());
    assertThat(ps).hasSize(1);
    ObjectConstraint constraint = ps.iterator().next().getConstraint(svsecondArg, ObjectConstraint.class);
    assertThat(constraint).isSameAs(ObjectConstraint.NULL);
}
Also used : BytecodeTestClass(org.sonar.java.bytecode.se.testdata.BytecodeTestClass) ObjectConstraint(org.sonar.java.se.constraint.ObjectConstraint) Iterables(com.google.common.collect.Iterables) BeforeClass(org.junit.BeforeClass) ProgramState(org.sonar.java.se.ProgramState) MethodYield(org.sonar.java.se.xproc.MethodYield) CompilationUnitTree(org.sonar.plugins.java.api.tree.CompilationUnitTree) ExceptionEnqueue(org.sonar.java.bytecode.se.testdata.ExceptionEnqueue) DivisionByZeroCheck(org.sonar.java.se.checks.DivisionByZeroCheck) Lists(com.google.common.collect.Lists) Assertions.assertThat(org.fest.assertions.Assertions.assertThat) FinalBytecodeTestClass(org.sonar.java.bytecode.se.testdata.FinalBytecodeTestClass) SymbolicValue(org.sonar.java.se.symbolicvalues.SymbolicValue) MethodBehavior(org.sonar.java.se.xproc.MethodBehavior) BooleanConstraint(org.sonar.java.se.constraint.BooleanConstraint) JavaParser(org.sonar.java.ast.parser.JavaParser) Collection(java.util.Collection) SquidClassLoader(org.sonar.java.bytecode.loader.SquidClassLoader) MaxRelationBytecode(org.sonar.java.bytecode.se.testdata.MaxRelationBytecode) FileUtils(org.apache.commons.io.FileUtils) Test(org.junit.Test) Type(org.sonar.plugins.java.api.semantic.Type) Collectors(java.util.stream.Collectors) File(java.io.File) List(java.util.List) Rule(org.junit.Rule) LogTester(org.sonar.api.utils.log.LogTester) SemanticModel(org.sonar.java.resolve.SemanticModel) ByteStreams(com.google.common.io.ByteStreams) BehaviorCache(org.sonar.java.se.xproc.BehaviorCache) Constraint(org.sonar.java.se.constraint.Constraint) ExceptionalYield(org.sonar.java.se.xproc.ExceptionalYield) HappyPathYield(org.sonar.java.se.xproc.HappyPathYield) LoggerLevel(org.sonar.api.utils.log.LoggerLevel) HappyPathYield(org.sonar.java.se.xproc.HappyPathYield) MethodBehavior(org.sonar.java.se.xproc.MethodBehavior) Collection(java.util.Collection) ObjectConstraint(org.sonar.java.se.constraint.ObjectConstraint) ProgramState(org.sonar.java.se.ProgramState) SymbolicValue(org.sonar.java.se.symbolicvalues.SymbolicValue) Test(org.junit.Test)

Example 5 with ObjectConstraint

use of org.sonar.java.se.constraint.ObjectConstraint in project sonar-java by SonarSource.

the class MethodBehaviorTest method method_behavior_yields.

@Test
public void method_behavior_yields() {
    SymbolicExecutionVisitor sev = createSymbolicExecutionVisitor("src/test/resources/se/MethodYields.java");
    MethodBehavior mb = getMethodBehavior(sev, "method");
    List<MethodYield> yields = mb.yields();
    assertThat(yields).hasSize(3);
    List<HappyPathYield> trueResults = mb.happyPathYields().filter(my -> BooleanConstraint.TRUE.equals(my.resultConstraint().get(BooleanConstraint.class))).collect(Collectors.toList());
    assertThat(trueResults).hasSize(1);
    HappyPathYield trueResult = trueResults.get(0);
    // 'a' has constraint "null"
    assertThat(((ObjectConstraint) trueResult.parametersConstraints.get(0).get(ObjectConstraint.class)).isNull()).isTrue();
    // no constraint on 'b'
    assertThat(((ObjectConstraint) trueResult.parametersConstraints.get(0).get(ObjectConstraint.class)).isNull()).isTrue();
    // result SV is a different SV than 'a' and 'b'
    assertThat(trueResult.resultIndex()).isEqualTo(-1);
    List<HappyPathYield> falseResults = mb.happyPathYields().filter(my -> BooleanConstraint.FALSE.equals(my.resultConstraint().get(BooleanConstraint.class))).collect(Collectors.toList());
    assertThat(falseResults).hasSize(2);
    // for both "False" results, 'a' has the constraint "not null"
    assertThat(falseResults.stream().filter(my -> !((ObjectConstraint) my.parametersConstraints.get(0).get(ObjectConstraint.class)).isNull()).count()).isEqualTo(2);
    // 1) 'b' has constraint "false", result is 'b'
    assertThat(falseResults.stream().filter(my -> BooleanConstraint.FALSE.equals(my.parametersConstraints.get(1).get(BooleanConstraint.class)) && my.resultIndex() == 1).count()).isEqualTo(1);
    // 2) 'b' is "true", result is a different SV than 'a' and 'b'
    assertThat(falseResults.stream().filter(my -> BooleanConstraint.TRUE.equals(my.parametersConstraints.get(1).get(BooleanConstraint.class)) && my.resultIndex() == -1).count()).isEqualTo(1);
}
Also used : ObjectConstraint(org.sonar.java.se.constraint.ObjectConstraint) SETestUtils.createSymbolicExecutionVisitor(org.sonar.java.se.SETestUtils.createSymbolicExecutionVisitor) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) Test(org.junit.Test) Collectors(java.util.stream.Collectors) ConstraintsByDomain(org.sonar.java.se.constraint.ConstraintsByDomain) SETestUtils.getMethodBehavior(org.sonar.java.se.SETestUtils.getMethodBehavior) List(java.util.List) Pair(org.sonar.java.se.Pair) SemanticModel(org.sonar.java.resolve.SemanticModel) SymbolicExecutionVisitor(org.sonar.java.se.SymbolicExecutionVisitor) SETestUtils.createSymbolicExecutionVisitorAndSemantic(org.sonar.java.se.SETestUtils.createSymbolicExecutionVisitorAndSemantic) BooleanConstraint(org.sonar.java.se.constraint.BooleanConstraint) Constraint(org.sonar.java.se.constraint.Constraint) Nullable(javax.annotation.Nullable) SETestUtils.getMethodBehavior(org.sonar.java.se.SETestUtils.getMethodBehavior) BooleanConstraint(org.sonar.java.se.constraint.BooleanConstraint) 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

ObjectConstraint (org.sonar.java.se.constraint.ObjectConstraint)6 ProgramState (org.sonar.java.se.ProgramState)4 SymbolicValue (org.sonar.java.se.symbolicvalues.SymbolicValue)4 List (java.util.List)2 Collectors (java.util.stream.Collectors)2 Test (org.junit.Test)2 SemanticModel (org.sonar.java.resolve.SemanticModel)2 BooleanConstraint (org.sonar.java.se.constraint.BooleanConstraint)2 Constraint (org.sonar.java.se.constraint.Constraint)2 MethodInvocationTree (org.sonar.plugins.java.api.tree.MethodInvocationTree)2 Iterables (com.google.common.collect.Iterables)1 Lists (com.google.common.collect.Lists)1 ByteStreams (com.google.common.io.ByteStreams)1 File (java.io.File)1 Collection (java.util.Collection)1 Nullable (javax.annotation.Nullable)1 FileUtils (org.apache.commons.io.FileUtils)1 Assertions.assertThat (org.assertj.core.api.Assertions.assertThat)1 Assertions.assertThat (org.fest.assertions.Assertions.assertThat)1 BeforeClass (org.junit.BeforeClass)1