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 3e21d84caf8..f6b92127a6e 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 @@ -2,7 +2,7 @@ { "ruleKey": "S100", "hasTruePositives": true, - "falseNegatives": 0, + "falseNegatives": 1, "falsePositives": 2 }, { @@ -38,7 +38,7 @@ { "ruleKey": "S112", "hasTruePositives": true, - "falseNegatives": 16, + "falseNegatives": 6, "falsePositives": 0 }, { @@ -128,17 +128,11 @@ { "ruleKey": "S1068", "hasTruePositives": true, - "falseNegatives": 2, - "falsePositives": 0 - }, - { - "ruleKey": "S1075", - "hasTruePositives": true, "falseNegatives": 0, "falsePositives": 0 }, { - "ruleKey": "S1104", + "ruleKey": "S1075", "hasTruePositives": true, "falseNegatives": 0, "falsePositives": 0 @@ -218,13 +212,13 @@ { "ruleKey": "S1128", "hasTruePositives": true, - "falseNegatives": 34, + "falseNegatives": 30, "falsePositives": 0 }, { "ruleKey": "S1130", "hasTruePositives": true, - "falseNegatives": 30, + "falseNegatives": 11, "falsePositives": 0 }, { @@ -261,13 +255,7 @@ "ruleKey": "S1144", "hasTruePositives": true, "falseNegatives": 1, - "falsePositives": 0 - }, - { - "ruleKey": "S1149", - "hasTruePositives": true, - "falseNegatives": 0, - "falsePositives": 0 + "falsePositives": 1 }, { "ruleKey": "S1150", @@ -338,7 +326,7 @@ { "ruleKey": "S1172", "hasTruePositives": true, - "falseNegatives": 25, + "falseNegatives": 32, "falsePositives": 0 }, { @@ -355,8 +343,8 @@ }, { "ruleKey": "S1181", - "hasTruePositives": false, - "falseNegatives": 10, + "hasTruePositives": true, + "falseNegatives": 3, "falsePositives": 0 }, { @@ -375,7 +363,7 @@ "ruleKey": "S1186", "hasTruePositives": true, "falseNegatives": 0, - "falsePositives": 0 + "falsePositives": 1 }, { "ruleKey": "S1190", @@ -515,12 +503,6 @@ "falseNegatives": 0, "falsePositives": 0 }, - { - "ruleKey": "S1444", - "hasTruePositives": true, - "falseNegatives": 0, - "falsePositives": 0 - }, { "ruleKey": "S1450", "hasTruePositives": true, @@ -542,7 +524,7 @@ { "ruleKey": "S1481", "hasTruePositives": true, - "falseNegatives": 7, + "falseNegatives": 8, "falsePositives": 0 }, { @@ -559,7 +541,7 @@ }, { "ruleKey": "S1598", - "hasTruePositives": false, + "hasTruePositives": true, "falseNegatives": 0, "falsePositives": 0 }, @@ -590,7 +572,7 @@ { "ruleKey": "S1612", "hasTruePositives": true, - "falseNegatives": 1, + "falseNegatives": 9, "falsePositives": 0 }, { @@ -626,7 +608,7 @@ { "ruleKey": "S1710", "hasTruePositives": false, - "falseNegatives": 0, + "falseNegatives": 1, "falsePositives": 0 }, { @@ -695,12 +677,6 @@ "falseNegatives": 0, "falsePositives": 0 }, - { - "ruleKey": "S1874", - "hasTruePositives": true, - "falseNegatives": 102, - "falsePositives": 0 - }, { "ruleKey": "S1905", "hasTruePositives": true, @@ -709,19 +685,19 @@ }, { "ruleKey": "S1940", - "hasTruePositives": true, + "hasTruePositives": false, "falseNegatives": 0, "falsePositives": 0 }, { "ruleKey": "S1948", "hasTruePositives": true, - "falseNegatives": 0, + "falseNegatives": 1, "falsePositives": 0 }, { "ruleKey": "S1989", - "hasTruePositives": false, + "hasTruePositives": true, "falseNegatives": 6, "falsePositives": 0 }, @@ -782,13 +758,13 @@ { "ruleKey": "S2077", "hasTruePositives": true, - "falseNegatives": 10, + "falseNegatives": 48, "falsePositives": 0 }, { "ruleKey": "S2092", "hasTruePositives": true, - "falseNegatives": 42, + "falseNegatives": 96, "falsePositives": 0 }, { @@ -860,7 +836,7 @@ { "ruleKey": "S2119", "hasTruePositives": true, - "falseNegatives": 0, + "falseNegatives": 3, "falsePositives": 0 }, { @@ -929,6 +905,12 @@ "falseNegatives": 0, "falsePositives": 0 }, + { + "ruleKey": "S2143", + "hasTruePositives": true, + "falseNegatives": 0, + "falsePositives": 0 + }, { "ruleKey": "S2147", "hasTruePositives": true, @@ -968,7 +950,7 @@ { "ruleKey": "S2160", "hasTruePositives": true, - "falseNegatives": 1, + "falseNegatives": 2, "falsePositives": 0 }, { @@ -1040,7 +1022,7 @@ { "ruleKey": "S2187", "hasTruePositives": true, - "falseNegatives": 12, + "falseNegatives": 15, "falsePositives": 1 }, { @@ -1070,7 +1052,7 @@ { "ruleKey": "S2209", "hasTruePositives": true, - "falseNegatives": 17, + "falseNegatives": 4, "falsePositives": 0 }, { @@ -1081,9 +1063,9 @@ }, { "ruleKey": "S2226", - "hasTruePositives": false, + "hasTruePositives": true, "falseNegatives": 5, - "falsePositives": 0 + "falsePositives": 1 }, { "ruleKey": "S2229", @@ -1093,8 +1075,8 @@ }, { "ruleKey": "S2230", - "hasTruePositives": true, - "falseNegatives": 15, + "hasTruePositives": false, + "falseNegatives": 22, "falsePositives": 0 }, { @@ -1124,7 +1106,7 @@ { "ruleKey": "S2245", "hasTruePositives": true, - "falseNegatives": 24, + "falseNegatives": 17, "falsePositives": 0 }, { @@ -1181,12 +1163,6 @@ "falseNegatives": 0, "falsePositives": 0 }, - { - "ruleKey": "S2293", - "hasTruePositives": true, - "falseNegatives": 1, - "falsePositives": 0 - }, { "ruleKey": "S2326", "hasTruePositives": true, @@ -1232,13 +1208,13 @@ { "ruleKey": "S2440", "hasTruePositives": true, - "falseNegatives": 4, + "falseNegatives": 2, "falsePositives": 0 }, { "ruleKey": "S2441", "hasTruePositives": true, - "falseNegatives": 0, + "falseNegatives": 1, "falsePositives": 0 }, { @@ -1286,7 +1262,7 @@ { "ruleKey": "S2638", "hasTruePositives": true, - "falseNegatives": 9, + "falseNegatives": 20, "falsePositives": 0 }, { @@ -1295,12 +1271,6 @@ "falseNegatives": 0, "falsePositives": 0 }, - { - "ruleKey": "S2647", - "hasTruePositives": true, - "falseNegatives": 3, - "falsePositives": 0 - }, { "ruleKey": "S2674", "hasTruePositives": true, @@ -1352,7 +1322,7 @@ { "ruleKey": "S2699", "hasTruePositives": true, - "falseNegatives": 151, + "falseNegatives": 161, "falsePositives": 1 }, { @@ -1388,7 +1358,7 @@ { "ruleKey": "S2789", "hasTruePositives": true, - "falseNegatives": 37, + "falseNegatives": 35, "falsePositives": 0 }, { @@ -1400,7 +1370,7 @@ { "ruleKey": "S2885", "hasTruePositives": true, - "falseNegatives": 2, + "falseNegatives": 0, "falsePositives": 0 }, { @@ -1424,7 +1394,7 @@ { "ruleKey": "S2970", "hasTruePositives": false, - "falseNegatives": 65, + "falseNegatives": 68, "falsePositives": 0 }, { @@ -1434,37 +1404,43 @@ "falsePositives": 0 }, { - "ruleKey": "S3008", + "ruleKey": "S3010", "hasTruePositives": true, "falseNegatives": 0, "falsePositives": 0 }, { - "ruleKey": "S3010", + "ruleKey": "S3011", "hasTruePositives": true, "falseNegatives": 0, "falsePositives": 0 }, { - "ruleKey": "S3011", + "ruleKey": "S3012", "hasTruePositives": true, "falseNegatives": 0, "falsePositives": 0 }, { - "ruleKey": "S3012", + "ruleKey": "S3014", + "hasTruePositives": true, + "falseNegatives": 1, + "falsePositives": 0 + }, + { + "ruleKey": "S3020", "hasTruePositives": true, "falseNegatives": 0, "falsePositives": 0 }, { - "ruleKey": "S3014", + "ruleKey": "S3024", "hasTruePositives": true, "falseNegatives": 0, "falsePositives": 0 }, { - "ruleKey": "S3020", + "ruleKey": "S3033", "hasTruePositives": true, "falseNegatives": 0, "falsePositives": 0 @@ -1499,6 +1475,18 @@ "falseNegatives": 0, "falsePositives": 0 }, + { + "ruleKey": "S3051", + "hasTruePositives": true, + "falseNegatives": 0, + "falsePositives": 0 + }, + { + "ruleKey": "S3063", + "hasTruePositives": true, + "falseNegatives": 0, + "falsePositives": 0 + }, { "ruleKey": "S3064", "hasTruePositives": true, @@ -1526,7 +1514,7 @@ { "ruleKey": "S3252", "hasTruePositives": true, - "falseNegatives": 2, + "falseNegatives": 1, "falsePositives": 0 }, { @@ -1544,7 +1532,7 @@ { "ruleKey": "S3330", "hasTruePositives": true, - "falseNegatives": 51, + "falseNegatives": 81, "falsePositives": 0 }, { @@ -1574,13 +1562,13 @@ { "ruleKey": "S3415", "hasTruePositives": false, - "falseNegatives": 280, + "falseNegatives": 286, "falsePositives": 0 }, { "ruleKey": "S3416", "hasTruePositives": true, - "falseNegatives": 6, + "falseNegatives": 5, "falsePositives": 0 }, { @@ -1604,7 +1592,7 @@ { "ruleKey": "S3577", "hasTruePositives": true, - "falseNegatives": 46, + "falseNegatives": 48, "falsePositives": 0 }, { @@ -1626,9 +1614,9 @@ "falsePositives": 0 }, { - "ruleKey": "S3740", + "ruleKey": "S3706", "hasTruePositives": true, - "falseNegatives": 50, + "falseNegatives": 0, "falsePositives": 0 }, { @@ -1640,7 +1628,7 @@ { "ruleKey": "S3752", "hasTruePositives": true, - "falseNegatives": 23, + "falseNegatives": 24, "falsePositives": 0 }, { @@ -1664,7 +1652,7 @@ { "ruleKey": "S3878", "hasTruePositives": true, - "falseNegatives": 27, + "falseNegatives": 26, "falsePositives": 0 }, { @@ -1709,6 +1697,12 @@ "falseNegatives": 0, "falsePositives": 0 }, + { + "ruleKey": "S4030", + "hasTruePositives": true, + "falseNegatives": 0, + "falsePositives": 0 + }, { "ruleKey": "S4032", "hasTruePositives": true, @@ -1808,7 +1802,7 @@ { "ruleKey": "S4423", "hasTruePositives": true, - "falseNegatives": 7, + "falseNegatives": 10, "falsePositives": 0 }, { @@ -1838,19 +1832,19 @@ { "ruleKey": "S4454", "hasTruePositives": true, - "falseNegatives": 1, + "falseNegatives": 2, "falsePositives": 0 }, { "ruleKey": "S4488", "hasTruePositives": false, - "falseNegatives": 14, + "falseNegatives": 20, "falsePositives": 0 }, { "ruleKey": "S4502", "hasTruePositives": false, - "falseNegatives": 5, + "falseNegatives": 11, "falsePositives": 0 }, { @@ -1904,13 +1898,13 @@ { "ruleKey": "S4682", "hasTruePositives": true, - "falseNegatives": 8, + "falseNegatives": 2, "falsePositives": 0 }, { "ruleKey": "S4684", "hasTruePositives": false, - "falseNegatives": 9, + "falseNegatives": 11, "falsePositives": 0 }, { @@ -1922,13 +1916,13 @@ { "ruleKey": "S4738", "hasTruePositives": false, - "falseNegatives": 68, + "falseNegatives": 70, "falsePositives": 0 }, { "ruleKey": "S4790", "hasTruePositives": true, - "falseNegatives": 37, + "falseNegatives": 43, "falsePositives": 0 }, { @@ -1982,7 +1976,7 @@ { "ruleKey": "S5122", "hasTruePositives": true, - "falseNegatives": 18, + "falseNegatives": 26, "falsePositives": 0 }, { @@ -2041,8 +2035,8 @@ }, { "ruleKey": "S5344", - "hasTruePositives": false, - "falseNegatives": 15, + "hasTruePositives": true, + "falseNegatives": 23, "falsePositives": 0 }, { @@ -2138,13 +2132,13 @@ { "ruleKey": "S5693", "hasTruePositives": false, - "falseNegatives": 16, + "falseNegatives": 20, "falsePositives": 0 }, { "ruleKey": "S5738", "hasTruePositives": true, - "falseNegatives": 0, + "falseNegatives": 3, "falsePositives": 0 }, { @@ -2162,7 +2156,7 @@ { "ruleKey": "S5778", "hasTruePositives": false, - "falseNegatives": 31, + "falseNegatives": 44, "falsePositives": 0 }, { @@ -2186,7 +2180,7 @@ { "ruleKey": "S5786", "hasTruePositives": true, - "falseNegatives": 63, + "falseNegatives": 35, "falsePositives": 0 }, { @@ -2204,7 +2198,7 @@ { "ruleKey": "S5804", "hasTruePositives": false, - "falseNegatives": 9, + "falseNegatives": 12, "falsePositives": 0 }, { @@ -2216,7 +2210,7 @@ { "ruleKey": "S5810", "hasTruePositives": false, - "falseNegatives": 16, + "falseNegatives": 20, "falsePositives": 0 }, { @@ -2240,7 +2234,7 @@ { "ruleKey": "S5838", "hasTruePositives": false, - "falseNegatives": 274, + "falseNegatives": 251, "falsePositives": 0 }, { @@ -2282,7 +2276,7 @@ { "ruleKey": "S5852", "hasTruePositives": true, - "falseNegatives": 3, + "falseNegatives": 0, "falsePositives": 0 }, { @@ -2330,7 +2324,7 @@ { "ruleKey": "S5866", "hasTruePositives": true, - "falseNegatives": 1, + "falseNegatives": 2, "falsePositives": 0 }, { @@ -2366,13 +2360,13 @@ { "ruleKey": "S5960", "hasTruePositives": false, - "falseNegatives": 4, + "falseNegatives": 3, "falsePositives": 0 }, { "ruleKey": "S5961", "hasTruePositives": false, - "falseNegatives": 5, + "falseNegatives": 6, "falsePositives": 0 }, { @@ -2420,7 +2414,7 @@ { "ruleKey": "S5998", "hasTruePositives": true, - "falseNegatives": 3, + "falseNegatives": 5, "falsePositives": 0 }, { @@ -2499,7 +2493,7 @@ "ruleKey": "S6204", "hasTruePositives": true, "falseNegatives": 0, - "falsePositives": 0 + "falsePositives": 1 }, { "ruleKey": "S6205", @@ -2690,12 +2684,12 @@ { "ruleKey": "S6437", "hasTruePositives": true, - "falseNegatives": 57, + "falseNegatives": 63, "falsePositives": 0 }, { "ruleKey": "S6485", - "hasTruePositives": false, + "hasTruePositives": true, "falseNegatives": 0, "falsePositives": 0 }, @@ -2720,7 +2714,7 @@ { "ruleKey": "S6804", "hasTruePositives": false, - "falseNegatives": 7, + "falseNegatives": 52, "falsePositives": 0 }, { @@ -2732,19 +2726,19 @@ { "ruleKey": "S6809", "hasTruePositives": false, - "falseNegatives": 94, + "falseNegatives": 96, "falsePositives": 0 }, { "ruleKey": "S6810", "hasTruePositives": false, - "falseNegatives": 6, + "falseNegatives": 5, "falsePositives": 0 }, { "ruleKey": "S6813", "hasTruePositives": true, - "falseNegatives": 33, + "falseNegatives": 66, "falsePositives": 0 }, { @@ -2753,6 +2747,12 @@ "falseNegatives": 5, "falsePositives": 0 }, + { + "ruleKey": "S6816", + "hasTruePositives": false, + "falseNegatives": 12, + "falsePositives": 0 + }, { "ruleKey": "S6817", "hasTruePositives": false, @@ -2762,7 +2762,7 @@ { "ruleKey": "S6818", "hasTruePositives": false, - "falseNegatives": 4, + "falseNegatives": 7, "falsePositives": 0 }, { @@ -2771,22 +2771,52 @@ "falseNegatives": 5, "falsePositives": 0 }, + { + "ruleKey": "S6830", + "hasTruePositives": false, + "falseNegatives": 19, + "falsePositives": 0 + }, { "ruleKey": "S6831", "hasTruePositives": false, "falseNegatives": 6, "falsePositives": 0 }, + { + "ruleKey": "S6832", + "hasTruePositives": false, + "falseNegatives": 41, + "falsePositives": 0 + }, + { + "ruleKey": "S6833", + "hasTruePositives": false, + "falseNegatives": 5, + "falsePositives": 0 + }, { "ruleKey": "S6837", "hasTruePositives": false, "falseNegatives": 2, "falsePositives": 0 }, + { + "ruleKey": "S6838", + "hasTruePositives": false, + "falseNegatives": 3, + "falsePositives": 0 + }, + { + "ruleKey": "S6856", + "hasTruePositives": false, + "falseNegatives": 61, + "falsePositives": 0 + }, { "ruleKey": "S6857", "hasTruePositives": false, - "falseNegatives": 57, + "falseNegatives": 64, "falsePositives": 0 }, { @@ -2798,7 +2828,25 @@ { "ruleKey": "S6863", "hasTruePositives": false, - "falseNegatives": 6, + "falseNegatives": 8, + "falsePositives": 0 + }, + { + "ruleKey": "S6876", + "hasTruePositives": true, + "falseNegatives": 0, + "falsePositives": 0 + }, + { + "ruleKey": "S6877", + "hasTruePositives": true, + "falseNegatives": 0, + "falsePositives": 0 + }, + { + "ruleKey": "S6878", + "hasTruePositives": true, + "falseNegatives": 0, "falsePositives": 0 }, { @@ -2807,21 +2855,63 @@ "falseNegatives": 0, "falsePositives": 0 }, + { + "ruleKey": "S6881", + "hasTruePositives": true, + "falseNegatives": 0, + "falsePositives": 0 + }, { "ruleKey": "S6885", "hasTruePositives": true, "falseNegatives": 0, "falsePositives": 0 }, + { + "ruleKey": "S6889", + "hasTruePositives": true, + "falseNegatives": 0, + "falsePositives": 0 + }, { "ruleKey": "S6901", + "hasTruePositives": true, + "falseNegatives": 0, + "falsePositives": 0 + }, + { + "ruleKey": "S6905", + "hasTruePositives": true, + "falseNegatives": 0, + "falsePositives": 0 + }, + { + "ruleKey": "S6906", "hasTruePositives": false, "falseNegatives": 0, "falsePositives": 0 }, + { + "ruleKey": "S6909", + "hasTruePositives": true, + "falseNegatives": 0, + "falsePositives": 0 + }, + { + "ruleKey": "S6912", + "hasTruePositives": true, + "falseNegatives": 0, + "falsePositives": 0 + }, + { + "ruleKey": "S6913", + "hasTruePositives": true, + "falseNegatives": 0, + "falsePositives": 0 + }, { "ruleKey": "S6915", - "hasTruePositives": false, + "hasTruePositives": true, "falseNegatives": 0, "falsePositives": 0 }, @@ -2832,43 +2922,187 @@ "falsePositives": 0 }, { - "ruleKey": "7477", + "ruleKey": "S7158", + "hasTruePositives": true, + "falseNegatives": 0, + "falsePositives": 0 + }, + { + "ruleKey": "S7177", "hasTruePositives": false, "falseNegatives": 0, "falsePositives": 0 }, { - "ruleKey": "7478", + "ruleKey": "S7178", + "hasTruePositives": false, + "falseNegatives": 12, + "falsePositives": 0 + }, + { + "ruleKey": "S7179", + "hasTruePositives": false, + "falseNegatives": 6, + "falsePositives": 0 + }, + { + "ruleKey": "S7180", + "hasTruePositives": false, + "falseNegatives": 9, + "falsePositives": 0 + }, + { + "ruleKey": "S7183", + "hasTruePositives": false, + "falseNegatives": 2, + "falsePositives": 0 + }, + { + "ruleKey": "S7184", + "hasTruePositives": false, + "falseNegatives": 5, + "falsePositives": 0 + }, + { + "ruleKey": "S7185", + "hasTruePositives": false, + "falseNegatives": 2, + "falsePositives": 0 + }, + { + "ruleKey": "S7186", + "hasTruePositives": false, + "falseNegatives": 3, + "falsePositives": 0 + }, + { + "ruleKey": "S7190", "hasTruePositives": false, "falseNegatives": 0, "falsePositives": 0 }, { - "ruleKey": "7479", + "ruleKey": "S7409", + "hasTruePositives": true, + "falseNegatives": 0, + "falsePositives": 0 + }, + { + "ruleKey": "S7435", + "hasTruePositives": true, + "falseNegatives": 0, + "falsePositives": 0 + }, + { + "ruleKey": "S7466", + "hasTruePositives": true, + "falseNegatives": 0, + "falsePositives": 0 + }, + { + "ruleKey": "S7467", + "hasTruePositives": true, + "falseNegatives": 0, + "falsePositives": 0 + }, + { + "ruleKey": "S7474", + "hasTruePositives": true, + "falseNegatives": 0, + "falsePositives": 0 + }, + { + "ruleKey": "S7475", + "hasTruePositives": true, + "falseNegatives": 0, + "falsePositives": 0 + }, + { + "ruleKey": "S7476", + "hasTruePositives": true, + "falseNegatives": 0, + "falsePositives": 0 + }, + { + "ruleKey": "S7477", "hasTruePositives": false, "falseNegatives": 0, "falsePositives": 0 }, { - "ruleKey": "7629", + "ruleKey": "S7478", "hasTruePositives": false, "falseNegatives": 0, "falsePositives": 0 }, { - "ruleKey": "8432", + "ruleKey": "S7479", "hasTruePositives": false, "falseNegatives": 0, "falsePositives": 0 }, { - "ruleKey": "8446", + "ruleKey": "S7481", + "hasTruePositives": false, + "falseNegatives": 0, + "falsePositives": 0 + }, + { + "ruleKey": "S7482", + "hasTruePositives": false, + "falseNegatives": 0, + "falsePositives": 0 + }, + { + "ruleKey": "S7629", + "hasTruePositives": false, + "falseNegatives": 0, + "falsePositives": 0 + }, + { + "ruleKey": "S8220", + "hasTruePositives": true, + "falseNegatives": 0, + "falsePositives": 0 + }, + { + "ruleKey": "S8346", + "hasTruePositives": true, + "falseNegatives": 0, + "falsePositives": 0 + }, + { + "ruleKey": "S8432", + "hasTruePositives": false, + "falseNegatives": 0, + "falsePositives": 0 + }, + { + "ruleKey": "S8433", + "hasTruePositives": false, + "falseNegatives": 0, + "falsePositives": 0 + }, + { + "ruleKey": "S8444", + "hasTruePositives": false, + "falseNegatives": 0, + "falsePositives": 0 + }, + { + "ruleKey": "S8445", + "hasTruePositives": true, + "falseNegatives": 0, + "falsePositives": 0 + }, + { + "ruleKey": "S8446", "hasTruePositives": true, "falseNegatives": 0, "falsePositives": 0 }, { - "ruleKey": "8447", + "ruleKey": "S8447", "hasTruePositives": false, "falseNegatives": 0, "falsePositives": 0 @@ -2890,5 +3124,71 @@ "hasTruePositives": false, "falseNegatives": 0, "falsePositives": 0 + }, + { + "ruleKey": "S8491", + "hasTruePositives": true, + "falseNegatives": 0, + "falsePositives": 0 + }, + { + "ruleKey": "S8688", + "hasTruePositives": true, + "falseNegatives": 0, + "falsePositives": 0 + }, + { + "ruleKey": "S8694", + "hasTruePositives": true, + "falseNegatives": 0, + "falsePositives": 0 + }, + { + "ruleKey": "S8695", + "hasTruePositives": true, + "falseNegatives": 0, + "falsePositives": 0 + }, + { + "ruleKey": "S8696", + "hasTruePositives": true, + "falseNegatives": 0, + "falsePositives": 0 + }, + { + "ruleKey": "S8700", + "hasTruePositives": true, + "falseNegatives": 0, + "falsePositives": 0 + }, + { + "ruleKey": "S8714", + "hasTruePositives": false, + "falseNegatives": 47, + "falsePositives": 0 + }, + { + "ruleKey": "S8715", + "hasTruePositives": false, + "falseNegatives": 172, + "falsePositives": 0 + }, + { + "ruleKey": "S8745", + "hasTruePositives": true, + "falseNegatives": 2, + "falsePositives": 0 + }, + { + "ruleKey": "S8786", + "hasTruePositives": true, + "falseNegatives": 5, + "falsePositives": 0 + }, + { + "ruleKey": "S8911", + "hasTruePositives": true, + "falseNegatives": 1, + "falsePositives": 0 } ] diff --git a/its/autoscan/src/test/resources/autoscan/diffs/diff_S6813.json b/its/autoscan/src/test/resources/autoscan/diffs/diff_S6813.json index d50149014fc..a9b3acaf13a 100644 --- a/its/autoscan/src/test/resources/autoscan/diffs/diff_S6813.json +++ b/its/autoscan/src/test/resources/autoscan/diffs/diff_S6813.json @@ -1,6 +1,6 @@ { "ruleKey": "S6813", "hasTruePositives": true, - "falseNegatives": 65, + "falseNegatives": 66, "falsePositives": 0 -} +} \ No newline at end of file diff --git a/its/autoscan/src/test/resources/autoscan/diffs/diff_S8911.json b/its/autoscan/src/test/resources/autoscan/diffs/diff_S8911.json new file mode 100644 index 00000000000..e88322b7386 --- /dev/null +++ b/its/autoscan/src/test/resources/autoscan/diffs/diff_S8911.json @@ -0,0 +1,6 @@ +{ + "ruleKey": "S8911", + "hasTruePositives": true, + "falseNegatives": 1, + "falsePositives": 0 +} \ No newline at end of file diff --git a/java-checks-test-sources/default/src/main/java/checks/StartupAnnotationCheckSample.java b/java-checks-test-sources/default/src/main/java/checks/StartupAnnotationCheckSample.java new file mode 100644 index 00000000000..9426241f9e0 --- /dev/null +++ b/java-checks-test-sources/default/src/main/java/checks/StartupAnnotationCheckSample.java @@ -0,0 +1,92 @@ +package checks; + +import io.quarkus.runtime.Startup; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.enterprise.inject.Produces; +import jakarta.inject.Inject; + +@ApplicationScoped +public class StartupAnnotationCheckSample { + + @Startup +// ^^^^^^^ > + static void staticMethod() { // Noncompliant {{"@Startup" annotation should not be applied to static methods}} +// ^^^^^^^^^^^^ + } + + @Startup +// ^^^^^^^ > + void withParameters(String config) { // Noncompliant {{"@Startup" annotation should only be applied to no-arg methods}} +// ^^^^^^^^^^^^^^ + } + + @Startup +// ^^^^^^^ > + @Produces + String producer() { // Noncompliant {{"@Startup" annotation should not be applied to producer methods}} +// ^^^^^^^^ + return "config"; + } + + @Startup +// ^^^^^^^ > + static void staticWithParams(String arg) { // Noncompliant {{"@Startup" annotation should not be applied to static methods}} +// ^^^^^^^^^^^^^^^^ + } + + @Startup +// ^^^^^^^ > + @Produces + static String staticProducer() { // Noncompliant {{"@Startup" annotation should not be applied to static methods}} +// ^^^^^^^^^^^^^^ + return "value"; + } + + @Startup +// ^^^^^^^ > + @Produces + Integer producerWithParams(String input) { // Noncompliant {{"@Startup" annotation should not be applied to producer methods}} +// ^^^^^^^^^^^^^^^^^^ + return 42; + } + + @Startup +// ^^^^^^^ > + @Produces + static Double allViolations(String arg1, int arg2) { // Noncompliant {{"@Startup" annotation should not be applied to static methods}} +// ^^^^^^^^^^^^^ + return 3.14; + } + + @Startup + void initialize() { + } + + @Inject + DatabaseService db; + + @Startup + void onStart() { + db.connect(); + } + + static void staticHelper() { + } + + void setupWithParams(String config, int port) { + } + + @Produces + String createConfig() { + return "config"; + } + + @Startup + private void privateInit() { + } + + static class DatabaseService { + void connect() { + } + } +} diff --git a/java-checks-test-sources/default/src/main/java/io/quarkus/runtime/Startup.java b/java-checks-test-sources/default/src/main/java/io/quarkus/runtime/Startup.java new file mode 100644 index 00000000000..53357d9de40 --- /dev/null +++ b/java-checks-test-sources/default/src/main/java/io/quarkus/runtime/Startup.java @@ -0,0 +1,11 @@ +package io.quarkus.runtime; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.TYPE, ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface Startup { +} diff --git a/java-checks/src/main/java/org/sonar/java/checks/StartupAnnotationCheck.java b/java-checks/src/main/java/org/sonar/java/checks/StartupAnnotationCheck.java new file mode 100644 index 00000000000..88b8e4a7464 --- /dev/null +++ b/java-checks/src/main/java/org/sonar/java/checks/StartupAnnotationCheck.java @@ -0,0 +1,94 @@ +/* + * SonarQube Java + * Copyright (C) SonarSource Sàrl + * mailto:info AT sonarsource DOT com + * + * You can redistribute and/or modify this program under the terms of + * the Sonar Source-Available License Version 1, as published by SonarSource Sàrl. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Sonar Source-Available License for more details. + * + * You should have received a copy of the Sonar Source-Available License + * along with this program; if not, see https://sonarsource.com/license/ssal/ + */ +package org.sonar.java.checks; + +import java.util.List; +import org.sonar.check.Rule; +import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; +import org.sonar.plugins.java.api.JavaFileScannerContext; +import org.sonar.plugins.java.api.tree.AnnotationTree; +import org.sonar.plugins.java.api.tree.MethodTree; +import org.sonar.plugins.java.api.tree.Tree; + +@Rule(key = "S8911") +public class StartupAnnotationCheck extends IssuableSubscriptionVisitor { + private static final String STARTUP_FQN = "io.quarkus.runtime.Startup"; + private static final String PRODUCES_FQN = "jakarta.enterprise.inject.Produces"; + + @Override + public List nodesToVisit() { + return List.of(Tree.Kind.METHOD); + } + + @Override + public void visitNode(Tree tree) { + MethodTree methodTree = (MethodTree) tree; + var startupAnnotations = getStartupAnnotations(methodTree); + + if (startupAnnotations.isEmpty()) { + return; + } + + var secondaryLocations = startupAnnotations.stream() + .map(annotation -> + new JavaFileScannerContext.Location("Triggered by this annotation", annotation.annotationType()) + ) + .toList(); + + // Only report one issue per method, prioritizing: static > producer > parameters + if (methodTree.symbol().isStatic()) { + reportIssue( + methodTree.simpleName(), + "\"@Startup\" annotation should not be applied to static methods", + secondaryLocations, + null); + return; + } + + var producesAnnotations = getProducesAnnotations(methodTree); + if (!producesAnnotations.isEmpty()) { + reportIssue( + methodTree.simpleName(), + "\"@Startup\" annotation should not be applied to producer methods", + secondaryLocations, + null + ); + return; + } + + if (!methodTree.parameters().isEmpty()) { + reportIssue( + methodTree.simpleName(), + "\"@Startup\" annotation should only be applied to no-arg methods", + secondaryLocations, + null + ); + } + } + + private static List getStartupAnnotations(MethodTree methodTree) { + return methodTree.modifiers().annotations().stream() + .filter(annotation -> annotation.annotationType().symbolType().is(STARTUP_FQN)) + .toList(); + } + + private static List getProducesAnnotations(MethodTree methodTree) { + return methodTree.modifiers().annotations().stream() + .filter(annotation -> annotation.annotationType().symbolType().is(PRODUCES_FQN)) + .toList(); + } +} diff --git a/java-checks/src/test/java/org/sonar/java/checks/StartupAnnotationCheckTest.java b/java-checks/src/test/java/org/sonar/java/checks/StartupAnnotationCheckTest.java new file mode 100644 index 00000000000..3b67c712d37 --- /dev/null +++ b/java-checks/src/test/java/org/sonar/java/checks/StartupAnnotationCheckTest.java @@ -0,0 +1,44 @@ +/* + * SonarQube Java + * Copyright (C) SonarSource Sàrl + * mailto:info AT sonarsource DOT com + * + * You can redistribute and/or modify this program under the terms of + * the Sonar Source-Available License Version 1, as published by SonarSource Sàrl. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Sonar Source-Available License for more details. + * + * You should have received a copy of the Sonar Source-Available License + * along with this program; if not, see https://sonarsource.com/license/ssal/ + */ +package org.sonar.java.checks; + +import org.junit.jupiter.api.Test; +import org.sonar.java.checks.verifier.CheckVerifier; + +import static org.sonar.java.checks.verifier.TestUtils.mainCodeSourcesPath; + +class StartupAnnotationCheckTest { + private static final String SAMPLE_FILE = mainCodeSourcesPath("checks/StartupAnnotationCheckSample.java"); + private static final StartupAnnotationCheck CHECK = new StartupAnnotationCheck(); + + @Test + void test() { + CheckVerifier.newVerifier() + .onFile(SAMPLE_FILE) + .withCheck(CHECK) + .verifyIssues(); + } + + @Test + void testWithoutSemantic() { + CheckVerifier.newVerifier() + .onFile(SAMPLE_FILE) + .withCheck(CHECK) + .withoutSemantic() + .verifyNoIssues(); + } +} diff --git a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S8911.html b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S8911.html new file mode 100644 index 00000000000..de5ff6359f3 --- /dev/null +++ b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S8911.html @@ -0,0 +1,61 @@ +

This is an issue when a method designated for automatic invocation at application startup is declared as a class-level method rather than an +instance method, is configured to produce managed objects, or requires input arguments. Such methods will not be properly invoked during application +startup.

+

In Java, this specifically refers to methods annotated with @Startup.

+

Why is this an issue?

+

Annotations or attributes that mark methods for execution during application startup in dependency injection frameworks have specific requirements +for how these initialization methods must be declared.

+

When you mark a method for startup execution, the dependency injection framework generates initialization hooks that trigger the method when the +application starts. For this mechanism to work correctly, the method must meet three requirements:

+
    +
  • Non-static: The method must be an instance method. Dependency injection frameworks work by creating managed component + instances and invoking methods on those instances. A static method belongs to the class itself, not to an instance, so the framework cannot properly + manage its lifecycle or invoke it as part of component initialization.
  • +
  • Non-producer: The method cannot be a producer method (one that creates and provides instances for other components to + consume). Producer methods are designed to create and provide component instances, not to perform initialization logic. Combining startup execution + markers with producer functionality creates a conflict in the intended purpose of the method.
  • +
  • No arguments: The method must not accept any parameters. The framework invokes these methods automatically at startup and has + no mechanism to provide argument values. If a method requires parameters, the framework cannot call it.
  • +
+

What is the potential impact?

+

When methods designated for startup execution don’t follow the required signature, the initialization logic will not execute at application +startup. This can lead to:

+
    +
  • Missing configuration or setup steps that are essential for the application to function correctly
  • +
  • Uninitialized resources or connections that other parts of the application depend on
  • +
  • Runtime errors when the application tries to use components that were supposed to be initialized at startup
  • +
  • Silent failures where the method is simply not called, making the problem difficult to diagnose
  • +
+

How to fix it

+

Remove the static modifier from the method to make it an instance method. Ensure the method has no parameters and is not annotated +with @Produces.

+

Code examples

+

Noncompliant code example

+
+@ApplicationScoped
+public class EagerAppBean {
+    @Startup
+    static void init() {  // Noncompliant: static method
+        doSomeCoolInit();
+    }
+}
+
+

Compliant solution

+
+@ApplicationScoped
+public class EagerAppBean {
+    @Startup
+    void init() {  // Compliant: non-static, no arguments
+        doSomeCoolInit();
+    }
+}
+
+

Resources

+

Documentation

+ + diff --git a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S8911.json b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S8911.json new file mode 100644 index 00000000000..fbfcb6238df --- /dev/null +++ b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S8911.json @@ -0,0 +1,25 @@ +{ + "title": "Methods annotated with \"@Startup\" should be non-static, non-producer, and parameter-free", + "type": "BUG", + "status": "ready", + "remediation": { + "func": "Constant\/Issue", + "constantCost": "5min" + }, + "tags": [ + "injection", + "lifecycle", + "quarkus" + ], + "defaultSeverity": "Critical", + "ruleSpecification": "RSPEC-8911", + "sqKey": "S8911", + "scope": "Main", + "quickfix": "unknown", + "code": { + "impacts": { + "RELIABILITY": "HIGH" + }, + "attribute": "LOGICAL" + } +} diff --git a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/Sonar_way_profile.json b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/Sonar_way_profile.json index 519e0c1058b..c0332390194 100644 --- a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/Sonar_way_profile.json +++ b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/Sonar_way_profile.json @@ -532,6 +532,7 @@ "S8715", "S8745", "S8786", + "S8911", "S8924" ] }