diff --git a/its/autoscan/src/test/resources/autoscan/autoscan-diff-by-rules.json b/its/autoscan/src/test/resources/autoscan/autoscan-diff-by-rules.json index 7d7c6ce259b..e84b3b6dec5 100644 --- a/its/autoscan/src/test/resources/autoscan/autoscan-diff-by-rules.json +++ b/its/autoscan/src/test/resources/autoscan/autoscan-diff-by-rules.json @@ -1706,7 +1706,7 @@ { "ruleKey": "S3655", "hasTruePositives": true, - "falseNegatives": 0, + "falseNegatives": 8, "falsePositives": 0 }, { @@ -2492,7 +2492,7 @@ { "ruleKey": "S5960", "hasTruePositives": false, - "falseNegatives": 3, + "falseNegatives": 4, "falsePositives": 0 }, { diff --git a/its/autoscan/src/test/resources/autoscan/diffs/diff_S3655.json b/its/autoscan/src/test/resources/autoscan/diffs/diff_S3655.json index 5ffa5cfccc8..34bf040483c 100644 --- a/its/autoscan/src/test/resources/autoscan/diffs/diff_S3655.json +++ b/its/autoscan/src/test/resources/autoscan/diffs/diff_S3655.json @@ -1,6 +1,6 @@ { "ruleKey": "S3655", "hasTruePositives": true, - "falseNegatives": 0, + "falseNegatives": 8, "falsePositives": 0 -} \ No newline at end of file +} diff --git a/its/autoscan/src/test/resources/autoscan/diffs/diff_S5960.json b/its/autoscan/src/test/resources/autoscan/diffs/diff_S5960.json index 68b30cb1649..d5ead00a529 100644 --- a/its/autoscan/src/test/resources/autoscan/diffs/diff_S5960.json +++ b/its/autoscan/src/test/resources/autoscan/diffs/diff_S5960.json @@ -1,6 +1,6 @@ { "ruleKey": "S5960", "hasTruePositives": false, - "falseNegatives": 3, + "falseNegatives": 4, "falsePositives": 0 -} \ No newline at end of file +} diff --git a/java-checks-test-sources/default/src/main/java/symbolicexecution/checks/OptionalGetBeforeIsPresentCheck_jdk11.java b/java-checks-test-sources/default/src/main/java/symbolicexecution/checks/OptionalGetBeforeIsPresentCheck_jdk11.java index 2645adb5602..954a6171209 100644 --- a/java-checks-test-sources/default/src/main/java/symbolicexecution/checks/OptionalGetBeforeIsPresentCheck_jdk11.java +++ b/java-checks-test-sources/default/src/main/java/symbolicexecution/checks/OptionalGetBeforeIsPresentCheck_jdk11.java @@ -1,6 +1,8 @@ package symbolicexecution.checks; import java.util.Optional; +import org.junit.Assert; +import org.junit.jupiter.api.Assertions; abstract class OptionalGetBeforeIsPresentCheck_jdk11 { @@ -49,4 +51,125 @@ private void usingIsEmpty5() { } op.get(); // Noncompliant {{Call "op.isPresent()" or "!op.isEmpty()" before accessing the value.}} } + + void test_junit5_1(Optional op){ + Assertions.assertTrue(op.isPresent(), "Hello"); + op.get(); // Compliant + } + + void test_junit5_2(Optional op){ + Assertions.assertTrue(op.isEmpty(), "Hello"); + op.get(); // Noncompliant {{Call "op.isPresent()" or "!op.isEmpty()" before accessing the value.}} + } + + void test_junit5_3(Optional op){ + Assertions.assertFalse(op.isPresent()); + op.get(); // Noncompliant {{Call "op.isPresent()" or "!op.isEmpty()" before accessing the value.}} + } + + void test_junit5_4(Optional op){ + Assertions.assertFalse(op.isEmpty()); + op.get(); // Compliant + } + + void test_junit5_5(Optional op, int i){ + Assertions.assertFalse(i < 0); + op.get(); // Noncompliant {{Call "op.isPresent()" or "!op.isEmpty()" before accessing the value.}} + } + + void test_junit5_6(Optional op){ + Assertions.assertTrue(op.isPresent(), () -> "Hello"); + op.get(); // Compliant + } + + void test_junit5_7(Optional op){ + Assertions.assertFalse(op.isEmpty(), () -> "Hello"); + op.get(); // Compliant + } + + void test_junit5_8(Optional op, int i){ + Assertions.assertFalse(i < 0, () -> "Hello"); + op.get(); // Noncompliant {{Call "op.isPresent()" or "!op.isEmpty()" before accessing the value.}} + } + + void test_junit5_9(Optional op){ + Assertions.fail(); + op.get(); // Compliant + } + + void test_junit5_10(Optional op){ + Assertions.fail("Hello"); + op.get(); // Compliant + } + + void test_junit5_11(Optional op){ + Assertions.fail("Hello", new Exception()); + op.get(); // Compliant + } + + void test_junit5_12(Optional op){ + Assertions.fail(new Exception()); + op.get(); // Compliant + } + + void test_junit5_13(Optional op){ + Assertions.fail(() -> "Hello"); + op.get(); // Compliant + } + + void test_junit5_14(Optional op){ + Assertions.assertTrue(op.isPresent()); + op.get(); // Compliant + } + + void test_junit5_15(Optional op){ + Assertions.assertFalse(op.isPresent(), "Hello"); + op.get(); // Noncompliant + } + + void test_junit4_1(Optional op){ + Assert.assertTrue("Hello", op.isPresent()); + op.get(); // Compliant + } + + void test_junit4_2(Optional op){ + Assert.assertTrue("Hello", op.isEmpty()); + op.get(); // Noncompliant {{Call "op.isPresent()" or "!op.isEmpty()" before accessing the value.}} + } + + void test_junit4_3(Optional op){ + Assert.assertFalse(op.isPresent()); + op.get(); // Noncompliant {{Call "op.isPresent()" or "!op.isEmpty()" before accessing the value.}} + } + + void test_junit4_4(Optional op){ + Assert.assertFalse(op.isEmpty()); + op.get(); // Compliant + } + + void test_junit4_5(Optional op, int i){ + Assert.assertFalse(i < 0); + op.get(); // Noncompliant {{Call "op.isPresent()" or "!op.isEmpty()" before accessing the value.}} + } + + void test_junit4_6(Optional op){ + Assert.fail(); + op.get(); // Compliant + } + + void test_junit4_7(Optional op){ + Assert.fail("Hello"); + op.get(); // Compliant + } + + void test_junit4_8(Optional op){ + Assert.assertTrue(op.isPresent()); + op.get(); // Compliant + } + + void test_junit4_9(Optional op){ + Assert.assertFalse("", op.isEmpty()); + op.get(); // Compliant + } + } diff --git a/java-symbolic-execution/src/main/java/org/sonar/java/se/xproc/BehaviorCache.java b/java-symbolic-execution/src/main/java/org/sonar/java/se/xproc/BehaviorCache.java index 255a55e4280..5559246db28 100644 --- a/java-symbolic-execution/src/main/java/org/sonar/java/se/xproc/BehaviorCache.java +++ b/java-symbolic-execution/src/main/java/org/sonar/java/se/xproc/BehaviorCache.java @@ -130,7 +130,9 @@ static class HardcodedMethodBehaviors { "org.apache.commons.lang3.json", "org.apache.logging.log4j.core.util.json", "org.eclipse.core.runtime.json", - "org.springframework.util.json" + "org.springframework.util.json", + "org.junit.jupiter.api.json", + "org.junit.json" }; private static final Type LIST_OF_METHOD_BEHAVIORS_TYPE = new TypeToken>() {}.getType(); diff --git a/java-symbolic-execution/src/main/resources/org/sonar/java/se/xproc/org.junit.json b/java-symbolic-execution/src/main/resources/org/sonar/java/se/xproc/org.junit.json new file mode 100644 index 00000000000..505b51bfc1d --- /dev/null +++ b/java-symbolic-execution/src/main/resources/org/sonar/java/se/xproc/org.junit.json @@ -0,0 +1,112 @@ +[ + { + "signature": "org.junit.Assert#assertTrue(Z)V", + "varArgs": false, + "declaredExceptions": [], + "yields": [ + { + "parametersConstraints": [ + ["TRUE"] + ], + "resultIndex": -1, + "resultConstraint": null + }, + { + "parametersConstraints": [ + ["FALSE"] + ], + "exception": ["java.lang.AssertionError"] + } + ] + }, + { + "signature": "org.junit.Assert#assertTrue(Ljava/lang/String;Z)V", + "varArgs": false, + "declaredExceptions": [], + "yields": [ + { + "parametersConstraints": [ + [], + ["TRUE"] + ], + "resultIndex": -1, + "resultConstraint": null + }, + { + "parametersConstraints": [ + [], + ["FALSE"] + ], + "exception": ["java.lang.AssertionError"] + } + ] + }, + { + "signature": "org.junit.Assert#assertFalse(Z)V", + "varArgs": false, + "declaredExceptions": [], + "yields": [ + { + "parametersConstraints": [ + ["FALSE"] + ], + "resultIndex": -1, + "resultConstraint": null + }, + { + "parametersConstraints": [ + ["TRUE"] + ], + "exception": ["java.lang.AssertionError"] + } + ] + }, + { + "signature": "org.junit.Assert#assertFalse(Ljava/lang/String;Z)V", + "varArgs": false, + "declaredExceptions": [], + "yields": [ + { + "parametersConstraints": [ + [], + ["FALSE"] + ], + "resultIndex": -1, + "resultConstraint": null + }, + { + "parametersConstraints": [ + [], + ["TRUE"] + ], + "exception": ["java.lang.AssertionError"] + } + ] + }, + { + "signature": "org.junit.Assert#fail()V", + "varArgs": false, + "declaredExceptions": [], + "yields": [ + { + "parametersConstraints": [ + [] + ], + "exception": ["java.lang.AssertionError"] + } + ] + }, + { + "signature": "org.junit.Assert#fail(Ljava/lang/String;)V", + "varArgs": false, + "declaredExceptions": [], + "yields": [ + { + "parametersConstraints": [ + [] + ], + "exception": ["java.lang.AssertionError"] + } + ] + } +] diff --git a/java-symbolic-execution/src/main/resources/org/sonar/java/se/xproc/org.junit.jupiter.api.json b/java-symbolic-execution/src/main/resources/org/sonar/java/se/xproc/org.junit.jupiter.api.json new file mode 100644 index 00000000000..e44dde9b3b5 --- /dev/null +++ b/java-symbolic-execution/src/main/resources/org/sonar/java/se/xproc/org.junit.jupiter.api.json @@ -0,0 +1,196 @@ +[ + { + "signature": "org.junit.jupiter.api.Assertions#assertTrue(Z)V", + "varArgs": false, + "declaredExceptions": [], + "yields": [ + { + "parametersConstraints": [ + ["TRUE"] + ], + "resultIndex": -1, + "resultConstraint": null + }, + { + "parametersConstraints": [ + ["FALSE"] + ], + "exception": ["java.lang.AssertionError"] + } + ] + }, + { + "signature": "org.junit.jupiter.api.Assertions#assertTrue(ZLjava/lang/String;)V", + "varArgs": false, + "declaredExceptions": [], + "yields": [ + { + "parametersConstraints": [ + ["TRUE"], + [] + ], + "resultIndex": -1, + "resultConstraint": null + }, + { + "parametersConstraints": [ + ["FALSE"], + [] + ], + "exception": ["java.lang.AssertionError"] + } + ] + }, + { + "signature": "org.junit.jupiter.api.Assertions#assertTrue(ZLjava/util/function/Supplier;)V", + "varArgs": false, + "declaredExceptions": [], + "yields": [ + { + "parametersConstraints": [ + ["TRUE"], + [] + ], + "resultIndex": -1, + "resultConstraint": null + }, + { + "parametersConstraints": [ + ["FALSE"], + [] + ], + "exception": ["java.lang.AssertionError"] + } + ] + }, + { + "signature": "org.junit.jupiter.api.Assertions#assertFalse(Z)V", + "varArgs": false, + "declaredExceptions": [], + "yields": [ + { + "parametersConstraints": [ + ["FALSE"] + ], + "resultIndex": -1, + "resultConstraint": null + }, + { + "parametersConstraints": [ + ["TRUE"] + ], + "exception": ["java.lang.AssertionError"] + } + ] + }, + { + "signature": "org.junit.jupiter.api.Assertions#assertFalse(ZLjava/lang/String;)V", + "varArgs": false, + "declaredExceptions": [], + "yields": [ + { + "parametersConstraints": [ + ["FALSE"], + [] + ], + "resultIndex": -1, + "resultConstraint": null + }, + { + "parametersConstraints": [ + ["TRUE"], + [] + ], + "exception": ["java.lang.AssertionError"] + } + ] + }, + { + "signature": "org.junit.jupiter.api.Assertions#assertFalse(ZLjava/util/function/Supplier;)V", + "varArgs": false, + "declaredExceptions": [], + "yields": [ + { + "parametersConstraints": [ + ["FALSE"], + [] + ], + "resultIndex": -1, + "resultConstraint": null + }, + { + "parametersConstraints": [ + ["TRUE"], + [] + ], + "exception": ["java.lang.AssertionError"] + } + ] + }, + { + "signature": "org.junit.jupiter.api.Assertions#fail()Ljava/lang/Object;", + "varArgs": false, + "declaredExceptions": [], + "yields": [ + { + "parametersConstraints": [ + [] + ], + "exception": ["java.lang.AssertionError"] + } + ] + }, + { + "signature": "org.junit.jupiter.api.Assertions#fail(Ljava/lang/String;)Ljava/lang/Object;", + "varArgs": false, + "declaredExceptions": [], + "yields": [ + { + "parametersConstraints": [ + [] + ], + "exception": ["java.lang.AssertionError"] + } + ] + }, + { + "signature": "org.junit.jupiter.api.Assertions#fail(Ljava/lang/String;Ljava/lang/Throwable;)Ljava/lang/Object;", + "varArgs": false, + "declaredExceptions": [], + "yields": [ + { + "parametersConstraints": [ + [], + [] + ], + "exception": ["java.lang.AssertionError"] + } + ] + }, + { + "signature": "org.junit.jupiter.api.Assertions#fail(Ljava/lang/Throwable;)Ljava/lang/Object;", + "varArgs": false, + "declaredExceptions": [], + "yields": [ + { + "parametersConstraints": [ + [] + ], + "exception": ["java.lang.AssertionError"] + } + ] + }, + { + "signature": "org.junit.jupiter.api.Assertions#fail(Ljava/util/function/Supplier;)Ljava/lang/Object;", + "varArgs": false, + "declaredExceptions": [], + "yields": [ + { + "parametersConstraints": [ + [] + ], + "exception": ["java.lang.AssertionError"] + } + ] + } +] diff --git a/java-symbolic-execution/src/test/java/org/sonar/java/se/xproc/BehaviorCacheTest.java b/java-symbolic-execution/src/test/java/org/sonar/java/se/xproc/BehaviorCacheTest.java index d8946dd710e..36dda8620da 100644 --- a/java-symbolic-execution/src/test/java/org/sonar/java/se/xproc/BehaviorCacheTest.java +++ b/java-symbolic-execution/src/test/java/org/sonar/java/se/xproc/BehaviorCacheTest.java @@ -198,8 +198,8 @@ void hardcoded_behaviors() throws Exception { } assertThat(behaviorCache.behaviors).isEmpty(); - assertThat(behaviorCache.hardcodedBehaviors()).hasSize(238); - assertThat(logTester.logs(Level.DEBUG)).containsOnly("[SE] Loaded 238 hardcoded method behaviors."); + assertThat(behaviorCache.hardcodedBehaviors()).hasSize(255); + assertThat(logTester.logs(Level.DEBUG)).containsOnly("[SE] Loaded 255 hardcoded method behaviors."); } @Test