├── infinitest.args ├── infinitest.filters ├── test-resources ├── findbugs-exclude.xml ├── classes │ ├── Hello.class │ └── Hello$1.class └── src │ └── Hello.java ├── src ├── test │ ├── resources │ │ ├── projects │ │ │ ├── findbugs │ │ │ │ ├── .gitignore │ │ │ │ ├── src │ │ │ │ │ └── main │ │ │ │ │ │ └── java │ │ │ │ │ │ ├── Findbugs3.java │ │ │ │ │ │ ├── Findbugs2.java │ │ │ │ │ │ ├── Findbugs4.java │ │ │ │ │ │ └── Findbugs1.java │ │ │ │ └── pom.xml │ │ │ ├── multi-module │ │ │ │ ├── multi-module-groovy │ │ │ │ │ ├── .gitignore │ │ │ │ │ ├── src │ │ │ │ │ │ └── main │ │ │ │ │ │ │ ├── java │ │ │ │ │ │ │ └── org │ │ │ │ │ │ │ │ └── simple │ │ │ │ │ │ │ │ └── project │ │ │ │ │ │ │ │ └── Sample.java │ │ │ │ │ │ │ └── groovy │ │ │ │ │ │ │ └── GroovySample.groovy │ │ │ │ │ ├── build.gradle │ │ │ │ │ └── pom.xml │ │ │ │ ├── multi-module-kotlin │ │ │ │ │ ├── .gitignore │ │ │ │ │ ├── src │ │ │ │ │ │ └── main │ │ │ │ │ │ │ ├── java │ │ │ │ │ │ │ └── com │ │ │ │ │ │ │ │ └── bugs │ │ │ │ │ │ │ │ └── JavaKotlinSample.java │ │ │ │ │ │ │ └── kotlin │ │ │ │ │ │ │ └── com │ │ │ │ │ │ │ └── bugs │ │ │ │ │ │ │ └── KotlinSample.kt │ │ │ │ │ └── build.gradle │ │ │ │ ├── multi-module-clojure │ │ │ │ │ ├── .gitignore │ │ │ │ │ ├── src │ │ │ │ │ │ └── main │ │ │ │ │ │ │ └── clojure │ │ │ │ │ │ │ ├── clojuresample.clj │ │ │ │ │ │ │ └── com │ │ │ │ │ │ │ └── bugs │ │ │ │ │ │ │ └── ClojureSample.clj │ │ │ │ │ ├── build.gradle │ │ │ │ │ └── pom.xml │ │ │ │ ├── .gitignore │ │ │ │ ├── multi-module-app │ │ │ │ │ ├── .gitignore │ │ │ │ │ ├── build.gradle │ │ │ │ │ ├── src │ │ │ │ │ │ └── main │ │ │ │ │ │ │ └── java │ │ │ │ │ │ │ └── multimodule │ │ │ │ │ │ │ └── app │ │ │ │ │ │ │ └── SampleApp.java │ │ │ │ │ └── pom.xml │ │ │ │ ├── multi-module-fx │ │ │ │ │ ├── .gitignore │ │ │ │ │ ├── build.gradle │ │ │ │ │ ├── src │ │ │ │ │ │ └── main │ │ │ │ │ │ │ └── java │ │ │ │ │ │ │ └── multimodule │ │ │ │ │ │ │ └── fx │ │ │ │ │ │ │ └── SampleFx.java │ │ │ │ │ └── pom.xml │ │ │ │ ├── multi-module-core │ │ │ │ │ ├── .gitignore │ │ │ │ │ ├── build.gradle │ │ │ │ │ ├── src │ │ │ │ │ │ ├── main │ │ │ │ │ │ │ └── java │ │ │ │ │ │ │ │ └── multimodule │ │ │ │ │ │ │ │ └── core │ │ │ │ │ │ │ │ ├── InnerClassSample.java │ │ │ │ │ │ │ │ └── SampleCore.java │ │ │ │ │ │ └── test │ │ │ │ │ │ │ └── java │ │ │ │ │ │ │ └── multimodule │ │ │ │ │ │ │ └── core │ │ │ │ │ │ │ └── SampleCoreTest.java │ │ │ │ │ └── pom.xml │ │ │ │ ├── multi-module-scala │ │ │ │ │ ├── .gitignore │ │ │ │ │ ├── build.gradle │ │ │ │ │ ├── src │ │ │ │ │ │ └── main │ │ │ │ │ │ │ └── scala │ │ │ │ │ │ │ └── Hello.scala │ │ │ │ │ └── pom.xml │ │ │ │ ├── multi-module-jsp-uncompiled │ │ │ │ │ ├── .gitignore │ │ │ │ │ ├── src │ │ │ │ │ │ └── main │ │ │ │ │ │ │ └── webapp │ │ │ │ │ │ │ ├── WEB-INF │ │ │ │ │ │ │ ├── jsp │ │ │ │ │ │ │ │ └── pages │ │ │ │ │ │ │ │ │ └── page1.jsp │ │ │ │ │ │ │ └── web.xml │ │ │ │ │ │ │ └── index.jsp │ │ │ │ │ ├── build.gradle │ │ │ │ │ └── pom.xml │ │ │ │ ├── gradle.properties │ │ │ │ ├── gradle │ │ │ │ │ └── wrapper │ │ │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ │ │ └── gradle-wrapper.properties │ │ │ │ ├── settings.gradle │ │ │ │ ├── pom.xml │ │ │ │ ├── build.gradle │ │ │ │ └── gradlew.bat │ │ │ ├── multiple-directories-with-classes │ │ │ │ ├── .gitignore │ │ │ │ ├── dir1 │ │ │ │ │ ├── src │ │ │ │ │ │ └── File1.java │ │ │ │ │ └── pom.xml │ │ │ │ ├── dir2 │ │ │ │ │ ├── src │ │ │ │ │ │ └── File2.java │ │ │ │ │ └── pom.xml │ │ │ │ └── pom.xml │ │ │ ├── kotlin │ │ │ │ └── src │ │ │ │ │ └── main │ │ │ │ │ └── java │ │ │ │ │ └── com │ │ │ │ │ └── bugs │ │ │ │ │ └── JavaKotlinSample.java │ │ │ ├── jspc-jetty │ │ │ │ ├── src │ │ │ │ │ └── main │ │ │ │ │ │ └── webapp │ │ │ │ │ │ └── WEB-INF │ │ │ │ │ │ ├── jsp │ │ │ │ │ │ └── pages │ │ │ │ │ │ │ ├── page1 │ │ │ │ │ │ │ └── page1.jsp │ │ │ │ │ │ │ └── page2 │ │ │ │ │ │ │ └── page2.jsp │ │ │ │ │ │ └── web.xml │ │ │ │ └── pom.xml │ │ │ ├── jspc-sling │ │ │ │ ├── src │ │ │ │ │ └── main │ │ │ │ │ │ ├── webapp │ │ │ │ │ │ └── WEB-INF │ │ │ │ │ │ │ └── web.xml │ │ │ │ │ │ └── scripts │ │ │ │ │ │ └── index.jsp │ │ │ │ └── pom.xml │ │ │ ├── simple │ │ │ │ ├── src │ │ │ │ │ └── Simple.java │ │ │ │ └── pom.xml │ │ │ └── scala │ │ │ │ ├── src │ │ │ │ └── main │ │ │ │ │ └── scala │ │ │ │ │ └── HelloWorld.scala │ │ │ │ └── pom.xml │ │ ├── kt_classes │ │ │ ├── RtpPacket.clazz │ │ │ ├── TlsClientImpl.clazz │ │ │ ├── TxtOutputReport.clazz │ │ │ └── ByteArrayExtensionsKt.clazz │ │ ├── jsp_classes │ │ │ ├── weblogic │ │ │ │ ├── __test.clazz │ │ │ │ └── smap.txt │ │ │ └── jetty936 │ │ │ │ ├── test_jsp.clazz │ │ │ │ └── smap.txt │ │ ├── org │ │ │ └── sonar │ │ │ │ └── plugins │ │ │ │ └── findbugs │ │ │ │ ├── test_header.xml │ │ │ │ ├── shouldImportCodes.xml │ │ │ │ ├── findbugsXmlWithUnknownCode.xml │ │ │ │ ├── invalidPriority.xml │ │ │ │ ├── shouldImportCategories.xml │ │ │ │ ├── findbugsXmlWithUnknownCategory.xml │ │ │ │ ├── findbugsXmlWithUnknownRule.xml │ │ │ │ ├── test_module_tree.xml │ │ │ │ ├── shouldImportPatterns.xml │ │ │ │ ├── test_xml_complete.xml │ │ │ │ ├── uncorrectFindbugsXml.xml │ │ │ │ ├── findbugs-class-without-package.xml │ │ │ │ ├── FindbugsMavenInitializerTest │ │ │ │ └── pom.xml │ │ │ │ ├── findbugs-include.xml │ │ │ │ ├── shouldImportPatternsWithMultiplePriorities.xml │ │ │ │ ├── findbugsReportWithUnknownRule.xml │ │ │ │ └── findbugsReport.xml │ │ └── it │ │ │ └── profiles │ │ │ ├── empty-backup.xml │ │ │ ├── fbcontrib-backup.xml │ │ │ └── findbugs-backup.xml │ └── java │ │ └── org │ │ └── sonar │ │ └── plugins │ │ └── findbugs │ │ ├── it │ │ ├── IntegrationTest.java │ │ ├── IssueQuery.java │ │ ├── FindSecBugsIT.java │ │ ├── ScalaIT.java │ │ └── FBContribIT.java │ │ ├── util │ │ └── TestUtils.java │ │ ├── FindbugsVersionTest.java │ │ ├── FindbugsCategoryTest.java │ │ ├── profiles │ │ ├── FindbugsContribProfileTest.java │ │ ├── FindbugsScalaProfileTest.java │ │ ├── FindbugsSecurityAuditProfileTest.java │ │ └── FindbugsSecurityMinimalProfileTest.java │ │ ├── FindbugsPluginTest.java │ │ ├── configuration │ │ └── SimpleConfiguration.java │ │ ├── resource │ │ └── JspUtils.java │ │ ├── rule │ │ ├── SimpleActiveRule.java │ │ └── FakeActiveRules.java │ │ ├── FbContribRulesDefinitionTest.java │ │ ├── FindSecurityBugsRulesDefinitionTest.java │ │ ├── FindbugsTests.java │ │ ├── FindbugsRulesDefinitionTest.java │ │ └── FindbugsXmlReportParserTest.java ├── main │ ├── resources │ │ └── org │ │ │ └── sonar │ │ │ └── plugins │ │ │ └── findbugs │ │ │ ├── findbugs-plugin.properties │ │ │ ├── profile-findbugs-security-jsp.xml │ │ │ └── profile-findbugs-security-scala.xml │ └── java │ │ └── org │ │ └── sonar │ │ └── plugins │ │ └── findbugs │ │ ├── language │ │ ├── scala │ │ │ └── Scala.java │ │ ├── package-info.java │ │ └── Jsp.java │ │ ├── resource │ │ ├── ClassMetadataLoadingException.java │ │ ├── JasperUtils.java │ │ └── DebugExtensionExtractor.java │ │ ├── package-info.java │ │ ├── xml │ │ ├── package-info.java │ │ ├── ClassFilter.java │ │ ├── LocalFilter.java │ │ ├── Priority.java │ │ ├── PackageFilter.java │ │ ├── FieldFilter.java │ │ ├── Bug.java │ │ ├── MethodFilter.java │ │ ├── OrFilter.java │ │ └── Match.java │ │ ├── rules │ │ ├── FindSecurityBugsScalaRulesDefinition.java │ │ ├── FindSecurityBugsRulesDefinition.java │ │ ├── FbContribRulesDefinition.java │ │ ├── FindbugsRulesDefinition.java │ │ └── FindSecurityBugsJspRulesDefinition.java │ │ ├── profiles │ │ ├── FindbugsContribProfile.java │ │ ├── FindbugsProfile.java │ │ ├── FindbugsSecurityJspProfile.java │ │ ├── FindbugsSecurityScalaProfile.java │ │ ├── FindbugsSecurityAuditProfile.java │ │ └── FindbugsSecurityMinimalProfile.java │ │ ├── classpath │ │ ├── ClasspathLocator.java │ │ └── DefaultClasspathLocator.java │ │ ├── FindbugsLevelUtils.java │ │ ├── FindbugsCategory.java │ │ ├── AnalysisResult.java │ │ ├── FindbugsVersion.java │ │ ├── FindbugsConstants.java │ │ ├── ReportedBug.java │ │ └── FindbugsProfileExporter.java └── smoke-test │ ├── sonarqube-client │ ├── sonarqube-lts │ ├── sonarqube-latest │ ├── run.sh │ ├── docker-compose.yml │ └── smoke-test.sh ├── .dockerignore ├── generate_profiles ├── deprecated_rules │ └── sb-contrib │ │ ├── SPP_USELESS_TERNARY.json │ │ ├── FII_USE_METHOD_REFERENCE.json │ │ ├── SPP_TOSTRING_ON_STRING.json │ │ ├── SPP_USE_BIGDECIMAL_STRING_CTOR.json │ │ ├── AFBR_ABNORMAL_FINALLY_BLOCK_RETURN.json │ │ ├── AIOB_ARRAY_STORE_TO_NULL_REFERENCE.json │ │ └── USBR_UNNECESSARY_STORE_BEFORE_RETURN.json └── README.md ├── .mvn ├── maven.config ├── extensions.xml └── wrapper │ └── maven-wrapper.properties ├── renovate.json ├── .gitignore ├── .github ├── issue_template.md └── workflows │ ├── sonarqube.yml │ └── build.yml └── RELEASE_PROCEDURE.md /infinitest.args: -------------------------------------------------------------------------------- 1 | -Djava.awt.headless=true 2 | -------------------------------------------------------------------------------- /infinitest.filters: -------------------------------------------------------------------------------- 1 | excludeGroups=IntegrationTest 2 | -------------------------------------------------------------------------------- /test-resources/findbugs-exclude.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/test/resources/projects/findbugs/.gitignore: -------------------------------------------------------------------------------- 1 | /.scannerwork/ 2 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | * 2 | !target/sonar-findbugs-plugin.jar 3 | !src/smoke-test 4 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/multi-module-groovy/.gitignore: -------------------------------------------------------------------------------- 1 | /build/ 2 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/multi-module-kotlin/.gitignore: -------------------------------------------------------------------------------- 1 | /build/ 2 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/multi-module-clojure/.gitignore: -------------------------------------------------------------------------------- 1 | /build/ 2 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/.gitignore: -------------------------------------------------------------------------------- 1 | /.gradle/ 2 | /build/ 3 | /target/ 4 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/multi-module-app/.gitignore: -------------------------------------------------------------------------------- 1 | /build/ 2 | /target/ 3 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/multi-module-fx/.gitignore: -------------------------------------------------------------------------------- 1 | /build/ 2 | /target/ 3 | -------------------------------------------------------------------------------- /src/test/resources/projects/multiple-directories-with-classes/.gitignore: -------------------------------------------------------------------------------- 1 | /.scannerwork/ 2 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/multi-module-core/.gitignore: -------------------------------------------------------------------------------- 1 | /build/ 2 | /target/ 3 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/multi-module-scala/.gitignore: -------------------------------------------------------------------------------- 1 | /build/ 2 | /target/ 3 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/multi-module-jsp-uncompiled/.gitignore: -------------------------------------------------------------------------------- 1 | /build/ 2 | /target/ 3 | -------------------------------------------------------------------------------- /generate_profiles/deprecated_rules/sb-contrib/SPP_USELESS_TERNARY.json: -------------------------------------------------------------------------------- 1 | { 2 | "replacement": "java:S1125" 3 | } 4 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx2048M -XX:MaxMetaspaceSize=512m 2 | -------------------------------------------------------------------------------- /.mvn/maven.config: -------------------------------------------------------------------------------- 1 | -Daether.checksums.algorithms=SHA-512,SHA-256,SHA-1,MD5 2 | -Daether.connector.smartChecksums=false 3 | -------------------------------------------------------------------------------- /generate_profiles/deprecated_rules/sb-contrib/FII_USE_METHOD_REFERENCE.json: -------------------------------------------------------------------------------- 1 | { 2 | "replacement": "java:S1612" 3 | } 4 | -------------------------------------------------------------------------------- /generate_profiles/deprecated_rules/sb-contrib/SPP_TOSTRING_ON_STRING.json: -------------------------------------------------------------------------------- 1 | { 2 | "replacement": "java:S1858" 3 | } 4 | -------------------------------------------------------------------------------- /generate_profiles/deprecated_rules/sb-contrib/SPP_USE_BIGDECIMAL_STRING_CTOR.json: -------------------------------------------------------------------------------- 1 | { 2 | "replacement": "java:S2111" 3 | } 4 | -------------------------------------------------------------------------------- /test-resources/classes/Hello.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spotbugs/sonar-findbugs/HEAD/test-resources/classes/Hello.class -------------------------------------------------------------------------------- /generate_profiles/deprecated_rules/sb-contrib/AFBR_ABNORMAL_FINALLY_BLOCK_RETURN.json: -------------------------------------------------------------------------------- 1 | { 2 | "replacement": "java:S1143" 3 | } 4 | -------------------------------------------------------------------------------- /generate_profiles/deprecated_rules/sb-contrib/AIOB_ARRAY_STORE_TO_NULL_REFERENCE.json: -------------------------------------------------------------------------------- 1 | { 2 | "replacement": "java:S2259" 3 | } 4 | -------------------------------------------------------------------------------- /test-resources/classes/Hello$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spotbugs/sonar-findbugs/HEAD/test-resources/classes/Hello$1.class -------------------------------------------------------------------------------- /generate_profiles/deprecated_rules/sb-contrib/USBR_UNNECESSARY_STORE_BEFORE_RETURN.json: -------------------------------------------------------------------------------- 1 | { 2 | "replacement": "java:S1488" 3 | } 4 | -------------------------------------------------------------------------------- /src/test/resources/projects/findbugs/src/main/java/Findbugs3.java: -------------------------------------------------------------------------------- 1 | public final class Findbugs3 { 2 | private void method() { 3 | } 4 | } 5 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:recommended" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /src/test/resources/kt_classes/RtpPacket.clazz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spotbugs/sonar-findbugs/HEAD/src/test/resources/kt_classes/RtpPacket.clazz -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/multi-module-fx/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation project(':multi-module-core') 3 | } 4 | -------------------------------------------------------------------------------- /src/test/resources/kt_classes/TlsClientImpl.clazz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spotbugs/sonar-findbugs/HEAD/src/test/resources/kt_classes/TlsClientImpl.clazz -------------------------------------------------------------------------------- /src/test/resources/jsp_classes/weblogic/__test.clazz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spotbugs/sonar-findbugs/HEAD/src/test/resources/jsp_classes/weblogic/__test.clazz -------------------------------------------------------------------------------- /src/test/resources/kt_classes/TxtOutputReport.clazz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spotbugs/sonar-findbugs/HEAD/src/test/resources/kt_classes/TxtOutputReport.clazz -------------------------------------------------------------------------------- /src/test/resources/projects/kotlin/src/main/java/com/bugs/JavaKotlinSample.java: -------------------------------------------------------------------------------- 1 | package com.bugs; 2 | 3 | public class JavaKotlinSample { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/test/resources/jsp_classes/jetty936/test_jsp.clazz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spotbugs/sonar-findbugs/HEAD/src/test/resources/jsp_classes/jetty936/test_jsp.clazz -------------------------------------------------------------------------------- /src/test/resources/kt_classes/ByteArrayExtensionsKt.clazz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spotbugs/sonar-findbugs/HEAD/src/test/resources/kt_classes/ByteArrayExtensionsKt.clazz -------------------------------------------------------------------------------- /src/main/resources/org/sonar/plugins/findbugs/findbugs-plugin.properties: -------------------------------------------------------------------------------- 1 | # findbugs.plugin.version will be populated by Maven 2 | findbugs.plugin.version=${project.version} 3 | -------------------------------------------------------------------------------- /src/test/resources/org/sonar/plugins/findbugs/test_header.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/multi-module-groovy/src/main/java/org/simple/project/Sample.java: -------------------------------------------------------------------------------- 1 | package org.simple.project; 2 | 3 | public class Sample { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/multi-module-clojure/src/main/clojure/clojuresample.clj: -------------------------------------------------------------------------------- 1 | (def message "hello world") 2 | 3 | (defn hello [name] 4 | (println "Hello," name)) 5 | -------------------------------------------------------------------------------- /src/test/resources/org/sonar/plugins/findbugs/shouldImportCodes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/multi-module-app/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation project(':multi-module-core') 3 | implementation project(':multi-module-fx') 4 | } 5 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spotbugs/sonar-findbugs/HEAD/src/test/resources/projects/multi-module/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /src/test/resources/org/sonar/plugins/findbugs/findbugsXmlWithUnknownCode.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/test/resources/it/profiles/empty-backup.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | empty 5 | java 6 | 7 | -------------------------------------------------------------------------------- /src/test/resources/org/sonar/plugins/findbugs/invalidPriority.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/test/resources/org/sonar/plugins/findbugs/shouldImportCategories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/multi-module-groovy/src/main/groovy/GroovySample.groovy: -------------------------------------------------------------------------------- 1 | print "Hello World!\n".toString(); 2 | "unused".toString() 3 | 4 | x = 1.9 5 | if (x == Double.NaN) { 6 | x*2 7 | } 8 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/multi-module-kotlin/src/main/java/com/bugs/JavaKotlinSample.java: -------------------------------------------------------------------------------- 1 | package com.bugs; 2 | 3 | public class JavaKotlinSample { 4 | 5 | public static final int TATLTUAE = 42; 6 | } 7 | -------------------------------------------------------------------------------- /src/test/resources/org/sonar/plugins/findbugs/findbugsXmlWithUnknownCategory.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/multi-module-clojure/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "org.jetbrains.kotlin.jvm" version "1.6.21" 3 | } 4 | 5 | dependencies { 6 | implementation 'com.google.code.findbugs:jsr305:3.0.2' 7 | } 8 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/multi-module-kotlin/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "org.jetbrains.kotlin.jvm" version "1.6.21" 3 | } 4 | 5 | dependencies { 6 | implementation 'com.google.code.findbugs:jsr305:3.0.2' 7 | } 8 | -------------------------------------------------------------------------------- /.mvn/extensions.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | fr.jcgay.maven 5 | maven-profiler 6 | 3.3 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/multi-module-groovy/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'groovy' 3 | } 4 | 5 | dependencies { 6 | implementation 'org.codehaus.groovy:groovy-all:2.4.15' 7 | implementation project(':multi-module-core') 8 | } 9 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/multi-module-scala/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'scala' 3 | } 4 | 5 | dependencies { 6 | implementation 'org.scala-lang:scala3-library_3:3.0.1' 7 | implementation project(':multi-module-core') 8 | } 9 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/settings.gradle: -------------------------------------------------------------------------------- 1 | include 'multi-module-app' 2 | include 'multi-module-core' 3 | include 'multi-module-fx' 4 | include 'multi-module-kotlin' 5 | include 'multi-module-scala' 6 | include 'multi-module-groovy' 7 | include 'multi-module-jsp-uncompiled' 8 | -------------------------------------------------------------------------------- /src/test/resources/org/sonar/plugins/findbugs/findbugsXmlWithUnknownRule.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/test/resources/org/sonar/plugins/findbugs/test_module_tree.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/smoke-test/sonarqube-client: -------------------------------------------------------------------------------- 1 | FROM maven:3.9.9-jdk-8 2 | 3 | RUN apt-get update && apt-get install -y --no-install-recommends \ 4 | bash \ 5 | git \ 6 | nodejs \ 7 | && rm -rf /var/lib/apt/lists/* 8 | 9 | COPY src/smoke-test/smoke-test.sh /tmp/smoke-test.sh 10 | ENTRYPOINT /tmp/smoke-test.sh 11 | -------------------------------------------------------------------------------- /src/test/resources/projects/multiple-directories-with-classes/dir1/src/File1.java: -------------------------------------------------------------------------------- 1 | import java.util.Date; 2 | 3 | public final class File1 { 4 | public Date getDate(int seconds) { 5 | return new Date(seconds * 1000); // FindBugs: "int value converted to long and used as absolute time" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/test/resources/projects/multiple-directories-with-classes/dir2/src/File2.java: -------------------------------------------------------------------------------- 1 | import java.util.Date; 2 | 3 | public final class File2 { 4 | public Date getDate(int seconds) { 5 | return new Date(seconds * 1000); // FindBugs: "int value converted to long and used as absolute time" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/plugins/findbugs/language/scala/Scala.java: -------------------------------------------------------------------------------- 1 | package org.sonar.plugins.findbugs.language.scala; 2 | 3 | public class Scala { 4 | 5 | public static final String KEY = "scala"; 6 | 7 | private Scala() { 8 | // This class is not meant to be instantiated 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | wrapperVersion=3.3.4 2 | distributionType=source 3 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.12/apache-maven-3.9.12-bin.zip 4 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.3.4/maven-wrapper-3.3.4.jar 5 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/multi-module-scala/src/main/scala/Hello.scala: -------------------------------------------------------------------------------- 1 | import scala.util.Random 2 | 3 | object Hello { 4 | def main(args: Array[String]) = { 5 | println("Hello, world".toString()) 6 | 7 | val result = Seq.fill(16)(Random.nextInt) 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/test/resources/projects/jspc-jetty/src/main/webapp/WEB-INF/jsp/pages/page1/page1.jsp: -------------------------------------------------------------------------------- 1 | <% 2 | String x = request.getParameter("x"); 3 | 4 | java.util.Comparator comparator = new java.util.Comparator() { 5 | public int compare(Object o1, Object o2) { 6 | return 0; 7 | } 8 | }; 9 | 10 | %> 11 |

<%=x%>

12 | -------------------------------------------------------------------------------- /src/test/resources/projects/jspc-jetty/src/main/webapp/WEB-INF/jsp/pages/page2/page2.jsp: -------------------------------------------------------------------------------- 1 | <% 2 | String x = request.getParameter("x"); 3 | 4 | java.util.Comparator comparator = new java.util.Comparator() { 5 | public int compare(Object o1, Object o2) { 6 | return 0; 7 | } 8 | }; 9 | 10 | %> 11 |

<%=x%>

12 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/multi-module-kotlin/src/main/kotlin/com/bugs/KotlinSample.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("KotlinSample") 2 | package com.bugs 3 | 4 | fun main() { 5 | println("Hello, World!".toString()).toString() 6 | } 7 | 8 | fun getBugs(): Int { 9 | var x = "42".toString() 10 | return x.length 11 | } 12 | -------------------------------------------------------------------------------- /src/test/resources/org/sonar/plugins/findbugs/shouldImportPatterns.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/multi-module-jsp-uncompiled/src/main/webapp/WEB-INF/jsp/pages/page1.jsp: -------------------------------------------------------------------------------- 1 | <% 2 | String x = request.getParameter("x"); 3 | 4 | java.util.Comparator comparator = new java.util.Comparator() { 5 | public int compare(Object o1, Object o2) { 6 | return 0; 7 | } 8 | }; 9 | 10 | %> 11 |

<%=x%>

12 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/plugins/findbugs/resource/ClassMetadataLoadingException.java: -------------------------------------------------------------------------------- 1 | package org.sonar.plugins.findbugs.resource; 2 | 3 | public class ClassMetadataLoadingException extends RuntimeException { 4 | 5 | public ClassMetadataLoadingException(Throwable cause) { 6 | super("ASM failed to load classfile metadata", cause); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/test/resources/projects/jspc-jetty/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/test/resources/projects/jspc-sling/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/smoke-test/sonarqube-lts: -------------------------------------------------------------------------------- 1 | FROM sonarqube:7.9-community 2 | ENV SONAR_JAVA_VERSION=5.13.1.18282 3 | 4 | RUN (cd $SONARQUBE_HOME/extensions/plugins/ && curl -O https://repo.maven.apache.org/maven2/org/sonarsource/java/sonar-java-plugin/$SONAR_JAVA_VERSION/sonar-java-plugin-$SONAR_JAVA_VERSION.jar) 5 | COPY target/sonar-findbugs-plugin.jar $SONARQUBE_HOME/extensions/plugins/ 6 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/multi-module-core/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation 'com.google.code.findbugs:jsr305:3.0.2' 3 | 4 | testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2' 5 | testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2' 6 | } 7 | 8 | test { 9 | useJUnitPlatform() 10 | } 11 | -------------------------------------------------------------------------------- /src/smoke-test/sonarqube-latest: -------------------------------------------------------------------------------- 1 | FROM sonarqube:9.9-community 2 | ENV SONAR_JAVA_VERSION=8.6.0.37351 3 | 4 | RUN (cd $SONARQUBE_HOME/extensions/plugins/ && curl -O https://repo.maven.apache.org/maven2/org/sonarsource/java/sonar-java-plugin/$SONAR_JAVA_VERSION/sonar-java-plugin-$SONAR_JAVA_VERSION.jar) 5 | COPY target/sonar-findbugs-plugin.jar $SONARQUBE_HOME/extensions/plugins/ 6 | -------------------------------------------------------------------------------- /src/test/resources/projects/findbugs/src/main/java/Findbugs2.java: -------------------------------------------------------------------------------- 1 | import java.util.Date; 2 | 3 | public final class Findbugs2 { 4 | 5 | public Date getDate(int seconds) { 6 | // violation of the rule "int value converted to long and used as absolute time" that 7 | // is introduced in Findbugs 2.0 8 | return new Date(seconds * 1000); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/multi-module-jsp-uncompiled/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'war' 3 | } 4 | 5 | dependencies { 6 | implementation project(':multi-module-core') 7 | } 8 | 9 | sonarqube { 10 | properties { 11 | property 'sonar.sources', 'src/main/webapp' 12 | property 'sonar.findbugs.allowuncompiledcode', 'true' 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/test/resources/jsp_classes/jetty936/smap.txt: -------------------------------------------------------------------------------- 1 | SMAP 2 | test_jsp.java 3 | JSP 4 | *S JSP 5 | *F 6 | + 0 test.jsp 7 | test.jsp 8 | + 1 index.jsp 9 | index.jsp 10 | *L 11 | 1,6:127,0 12 | 6:172,6 13 | 6,3:130,0 14 | 8:191,8 15 | 8,3:133,0 16 | 10:212,8 17 | 10,5:136,0 18 | 1#1,23:137,0 19 | 14#0,3:138,0 20 | 16:233,8 21 | 16,5:141,0 22 | 20:260,10 23 | 20:144,0 24 | 21:289,6 25 | *E 26 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/multi-module-fx/src/main/java/multimodule/fx/SampleFx.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package multimodule.fx; 5 | 6 | import multimodule.core.SampleCore; 7 | 8 | public class SampleFx { 9 | private SampleCore field; 10 | 11 | public int npe() { 12 | System.out.println("test".toString()); 13 | return field.npe(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/multi-module-jsp-uncompiled/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/multi-module-core/src/main/java/multimodule/core/InnerClassSample.java: -------------------------------------------------------------------------------- 1 | package multimodule.core; 2 | 3 | public class InnerClassSample { 4 | 5 | public static class InnerStaticClass { 6 | private String name = "name".toString(); 7 | } 8 | 9 | public class InnerClass { 10 | private String name = "name".toString(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/plugins/findbugs/language/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This package and subpackage is reusing the lexer from the plugin Sonar-Web plugin. 3 | * 4 | * It is license under the GNU Lesser General Public License, Version 3.0 5 | * https://github.com/SonarSource/sonar-web 6 | * For special uses, contact the original owner. (see sonar-web/pom.xml) 7 | */ 8 | package org.sonar.plugins.findbugs.language; 9 | -------------------------------------------------------------------------------- /src/test/resources/org/sonar/plugins/findbugs/test_xml_complete.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/test/resources/projects/findbugs/src/main/java/Findbugs4.java: -------------------------------------------------------------------------------- 1 | import java.util.Date; 2 | 3 | public final class Findbugs4 { 4 | 5 | @SuppressWarnings("findbugs:ICAST_INT_2_LONG_AS_INSTANT") 6 | public Date getDate(int seconds) { 7 | // violation of the rule "int value converted to long and used as absolute time" that 8 | // is introduced in Findbugs 2.0 9 | return new Date(seconds * 1000); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/test/resources/projects/simple/src/Simple.java: -------------------------------------------------------------------------------- 1 | import java.util.Properties; 2 | import java.util.Random; 3 | 4 | public class Simple { 5 | public void method() { 6 | Random r = new Random(); 7 | String token = Long.toHexString(r.nextLong()); // fb-contrib violation (find security bugs) 8 | new Properties().put("key", (Object) null); // fb-contrib violation 9 | "".toString(); // findbugs violation 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/test/resources/org/sonar/plugins/findbugs/uncorrectFindbugsXml.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | /Users/freddy/Documents/sonar_projects/sonar/sonar-commons/target/classes 4 | /Users/freddy/.m2/repository/org/apache/maven/reporting/maven-reporting-impl/2.0/maven-reporting-impl-2.0.jar 5 | 6 | -------------------------------------------------------------------------------- /src/test/resources/projects/jspc-sling/src/main/scripts/index.jsp: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Index 5 | 6 | 7 | <% 8 | String x = request.getParameter("x"); 9 | 10 | java.util.Comparator comparator = new java.util.Comparator() { 11 | public int compare(Object o1, Object o2) { 12 | return 0; 13 | } 14 | }; 15 | 16 | %> 17 | 18 |

Hello <%=x%>

19 | 20 | 21 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/multi-module-app/src/main/java/multimodule/app/SampleApp.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package multimodule.app; 5 | 6 | import multimodule.core.SampleCore; 7 | import multimodule.fx.SampleFx; 8 | 9 | public class SampleApp { 10 | private SampleCore core; 11 | private SampleFx fx; 12 | 13 | public int npe() { 14 | System.out.println("test".toString()); 15 | return core.npe() + fx.npe(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/multi-module-jsp-uncompiled/src/main/webapp/index.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> 2 | 3 | 4 | 5 | 6 | Hello World 7 | 8 | Hello World 9 | 10 | -------------------------------------------------------------------------------- /src/test/resources/projects/scala/src/main/scala/HelloWorld.scala: -------------------------------------------------------------------------------- 1 | import scala.util.Random 2 | 3 | object Hello { 4 | def main(args: Array[String]) = { 5 | var x = "Hello, world" 6 | x = null 7 | 8 | println(x.toString) 9 | 10 | val result = Seq.fill(16)(Random.nextInt) 11 | } 12 | 13 | def isNumberNaN(mappedValue: Double): Double = mappedValue match { 14 | case Double.NaN => 0 15 | case _ => 1 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # ---- Maven 2 | target/ 3 | 4 | # ---- SonarQube 5 | .sonar 6 | 7 | # ---- IntelliJ IDEA 8 | *.iws 9 | *.iml 10 | *.ipr 11 | .idea/ 12 | 13 | # ---- Eclipse 14 | .classpath 15 | .project 16 | .settings 17 | 18 | # ---- Mac OS X 19 | .DS_Store 20 | Icon? 21 | # Thumbnails 22 | ._* 23 | # Files that might appear on external disk 24 | .Spotlight-V100 25 | .Trashes 26 | 27 | # ---- Windows 28 | # Windows image file caches 29 | Thumbs.db 30 | # Folder config file 31 | Desktop.ini 32 | #jenv 33 | .java-version 34 | -------------------------------------------------------------------------------- /src/test/resources/projects/findbugs/src/main/java/Findbugs1.java: -------------------------------------------------------------------------------- 1 | import java.io.IOException; 2 | import java.io.LineNumberReader; 3 | import java.io.Reader; 4 | 5 | public final class Findbugs1 { 6 | private final LineNumberReader reader; 7 | 8 | public Findbugs1(Reader r) { 9 | this.reader = new LineNumberReader(r); 10 | } 11 | 12 | public String[] readTokens() throws IOException { 13 | return reader.readLine().split("\\|"); // Dodgy - Dereference of the result of readLine() without nullcheck 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/multi-module-core/src/main/java/multimodule/core/SampleCore.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package multimodule.core; 5 | 6 | import javax.annotation.Nonnegative; 7 | 8 | public class SampleCore { 9 | private String field; 10 | 11 | public int npe() { 12 | System.out.println("test".toString()); 13 | return field.hashCode(); 14 | } 15 | 16 | public @Nonnegative int nonnegative() { 17 | if (field == null) { 18 | return -5; 19 | } else { 20 | return 42; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /test-resources/src/Hello.java: -------------------------------------------------------------------------------- 1 | import java.util.Arrays; 2 | import java.util.Collections; 3 | import java.util.Comparator; 4 | 5 | class Hello { 6 | 7 | static String name; 8 | 9 | public void methodWithViolations(String n) { 10 | name = n; 11 | Collections.sort(Arrays.asList(new Integer[]{1, 2, 3}), new Comparator() { 12 | public int compare(Integer o1, Integer o2) { 13 | return o1 - o2; 14 | } 15 | }); 16 | } 17 | 18 | @Override 19 | public boolean equals(Object obj) { 20 | return false; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/test/java/org/sonar/plugins/findbugs/it/IntegrationTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.sonar.plugins.findbugs.it; 5 | 6 | import java.lang.annotation.ElementType; 7 | import java.lang.annotation.Retention; 8 | import java.lang.annotation.RetentionPolicy; 9 | import java.lang.annotation.Target; 10 | 11 | import org.junit.jupiter.api.Test; 12 | 13 | /** 14 | * @author gtoison 15 | * 16 | */ 17 | @Target(value = {ElementType.METHOD, ElementType.TYPE}) 18 | @Retention(RetentionPolicy.RUNTIME) 19 | @Test 20 | public @interface IntegrationTest { 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/resources/org/sonar/plugins/findbugs/profile-findbugs-security-jsp.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/test/resources/jsp_classes/weblogic/smap.txt: -------------------------------------------------------------------------------- 1 | SMAP 2 | __test.java 3 | JSP 4 | *S JSP 5 | *F 6 | 1 test.jsp 7 | + 2 index.jsp 8 | index.jsp 9 | *L 10 | 4#1:90 11 | 6#1:92,2 12 | 8#1:96,2 13 | 10#1:100,2 14 | 12#1:102 15 | 1#2:103 16 | 16#1:106,2 17 | 18#1:108 18 | 20#1:110,2 19 | 21#1:114,13 20 | 6#1:128,7 21 | 6#1:136,9 22 | 6#1:146,14 23 | 8#1:161,7 24 | 8#1:169,10 25 | 8#1:180,14 26 | 10#1:195,7 27 | 10#1:203,10 28 | 10#1:214,14 29 | 16#1:229,8 30 | 16#1:238,9 31 | 16#1:248,24 32 | 20#1:273,8 33 | 20#1:282,10 34 | 20#1:293,25 35 | 21#1:319,7 36 | 21#1:327,9 37 | 21#1:337,15 38 | *E 39 | -------------------------------------------------------------------------------- /src/test/resources/org/sonar/plugins/findbugs/findbugs-class-without-package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/multi-module-core/src/test/java/multimodule/core/SampleCoreTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package multimodule.core; 5 | 6 | import javax.annotation.Nonnegative; 7 | import org.junit.jupiter.api.Test; 8 | 9 | public class SampleCoreTest { 10 | private String field; 11 | 12 | @Test 13 | public int npe() { 14 | System.out.println("test".toString()); 15 | return field.hashCode(); 16 | } 17 | 18 | @Test 19 | public @Nonnegative int nonnegative() { 20 | if (field == null) { 21 | return -5; 22 | } else { 23 | return 42; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/test/resources/projects/multiple-directories-with-classes/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | com.sonarsource.it.samples 5 | multiple-directories-with-classes 6 | 1.0-SNAPSHOT 7 | pom 8 | 9 | 10 | dir1 11 | dir2 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/smoke-test/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copied from https://github.com/SonarSource/docker-sonarqube/tree/master/7.1 under LGPL 3 | 4 | set -e 5 | 6 | if [ "${1:0:1}" != '-' ]; then 7 | exec "$@" 8 | fi 9 | 10 | chown -R sonarqube:sonarqube $SONARQUBE_HOME 11 | exec gosu sonarqube \ 12 | java -jar lib/sonar-application-$SONAR_VERSION.jar \ 13 | -Dsonar.log.console=true \ 14 | -Dsonar.jdbc.username="$SONARQUBE_JDBC_USERNAME" \ 15 | -Dsonar.jdbc.password="$SONARQUBE_JDBC_PASSWORD" \ 16 | -Dsonar.jdbc.url="$SONARQUBE_JDBC_URL" \ 17 | -Dsonar.web.javaAdditionalOpts="$SONARQUBE_WEB_JVM_OPTS -Djava.security.egd=file:/dev/./urandom" \ 18 | "$@" 19 | -------------------------------------------------------------------------------- /src/test/resources/it/profiles/fbcontrib-backup.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | IT 4 | java 5 | 6 | 7 | findbugs 8 | DM_STRING_TOSTRING 9 | INFO 10 | 11 | 12 | fb-contrib 13 | IPU_IMPROPER_PROPERTIES_USE_SETPROPERTY 14 | INFO 15 | 16 | 17 | findsecbugs 18 | PREDICTABLE_RANDOM 19 | INFO 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/test/resources/it/profiles/findbugs-backup.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | findbugs-it 5 | java 6 | 7 | 8 | findbugs 9 | NP_DEREFERENCE_OF_READLINE_VALUE 10 | MAJOR 11 | 12 | 13 | findbugs 14 | ICAST_INT_2_LONG_AS_INSTANT 15 | MAJOR 16 | 17 | 18 | findbugs 19 | UPM_UNCALLED_PRIVATE_METHOD 20 | CRITICAL 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/test/resources/projects/findbugs/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.sonarsource.it.samples 6 | findbugs 7 | 1.0-SNAPSHOT 8 | 9 | 10 | 11 | 12 | org.apache.maven.plugins 13 | maven-compiler-plugin 14 | 3.8.1 15 | 16 | 7 17 | 7 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/main/resources/org/sonar/plugins/findbugs/profile-findbugs-security-scala.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | spotbugs 5 | multi-module 6 | 0.0.1-SNAPSHOT 7 | pom 8 | 9 | multi-module-core 10 | multi-module-fx 11 | multi-module-app 12 | multi-module-scala 13 | multi-module-kotlin 14 | multi-module-groovy 15 | multi-module-clojure 16 | multi-module-jsp-uncompiled 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/test/resources/org/sonar/plugins/findbugs/FindbugsMavenInitializerTest/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | fake.group 6 | fake.artifactId 7 | jar 8 | 1.0-SNAPSHOT 9 | 10 | 11 | 12 | 13 | org.codehaus.mojo 14 | findbugs-maven-plugin 15 | 16 | foo.xml 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "java-library" 3 | id "org.sonarqube" version "3.3" 4 | } 5 | 6 | allprojects { 7 | ext.baseVersion = "0.1" 8 | ext.snapshotVersion = true 9 | 10 | group = "org.sonarqube" 11 | version = "$baseVersion" + (snapshotVersion ? "-SNAPSHOT" : "") 12 | } 13 | 14 | sonarqube { 15 | properties { 16 | property "sonar.projectName", "Multimodule Gradle Project" 17 | property "sonar.projectKey", "org.sonarqube:gradle-multimodule" 18 | } 19 | } 20 | 21 | subprojects { 22 | apply plugin: 'java-library' 23 | apply plugin: 'org.sonarqube' 24 | sonarqube { 25 | properties { 26 | //property "sonar.java.libraries", 27 | } 28 | } 29 | } 30 | 31 | allprojects { 32 | repositories { 33 | mavenCentral() 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/test/resources/projects/multiple-directories-with-classes/dir2/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.sonarsource.it.samples 6 | multiple-directories-with-classes-dir2 7 | 1.0-SNAPSHOT 8 | 9 | 10 | src 11 | 12 | 13 | org.apache.maven.plugins 14 | maven-compiler-plugin 15 | 3.8.1 16 | 17 | 7 18 | 7 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/test/resources/projects/multiple-directories-with-classes/dir1/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.sonarsource.it.samples 6 | multiple-directories-with-classes-dir1 7 | 1.0-SNAPSHOT 8 | 9 | 10 | src 11 | 12 | 13 | org.apache.maven.plugins 14 | maven-compiler-plugin 15 | 3.8.1 16 | 17 | 7 18 | 7 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/smoke-test/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | sonarqube-lts: 4 | build: 5 | context: . 6 | dockerfile: src/smoke-test/sonarqube-lts 7 | expose: 8 | - 9000 9 | networks: 10 | lts: 11 | aliases: 12 | - sonarqube 13 | sonarqube-latest: 14 | build: 15 | context: . 16 | dockerfile: src/smoke-test/sonarqube-latest 17 | expose: 18 | - 9000 19 | networks: 20 | latest: 21 | aliases: 22 | - sonarqube 23 | test-lts: 24 | build: 25 | context: . 26 | dockerfile: src/smoke-test/sonarqube-client 27 | depends_on: 28 | - sonarqube-lts 29 | networks: 30 | lts: 31 | test-latest: 32 | build: 33 | context: . 34 | dockerfile: src/smoke-test/sonarqube-client 35 | depends_on: 36 | - sonarqube-latest 37 | networks: 38 | latest: 39 | 40 | networks: 41 | lts: 42 | latest: 43 | -------------------------------------------------------------------------------- /src/test/resources/projects/simple/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | org.sonar.tests 5 | fb-contrib 6 | 0.1-SNAPSHOT 7 | jar 8 | Sonar tests - fb-contrib 9 | 10 | src 11 | 12 | 13 | org.apache.maven.plugins 14 | maven-compiler-plugin 15 | 3.8.1 16 | 17 | 7 18 | 7 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /.github/issue_template.md: -------------------------------------------------------------------------------- 1 | 2 | ## Issue Description 3 | 4 | 5 | 6 | 7 | 8 | 9 | ## Environment 10 | 11 | 12 | 13 | | Component | Version | 14 | | ------------------ | ------- | 15 | | SonarQube | ????? | 16 | | Sonar-FindBugs | ????? | 17 | | Maven | ????? | 18 | | Gradle | ????? | 19 | | Java | ????? | 20 | 21 | ## Code (If needed) 22 | 23 | 24 | 25 | ```java 26 | public class BugSample1 { 27 | public static void hello(String message) { 28 | 29 | //Something 30 | Runnable r = () -> System.out.println(message); 31 | 32 | r.run(); 33 | } 34 | } 35 | ``` 36 | -------------------------------------------------------------------------------- /src/test/java/org/sonar/plugins/findbugs/it/IssueQuery.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.sonar.plugins.findbugs.it; 5 | 6 | import org.sonarqube.ws.client.issues.SearchRequest; 7 | 8 | import java.util.Arrays; 9 | 10 | /** 11 | * @author gtoison 12 | * 13 | */ 14 | public class IssueQuery { 15 | 16 | public static IssueQuery create() { 17 | return new IssueQuery(); 18 | } 19 | 20 | public SearchRequest components(String ... keys) { 21 | SearchRequest request = new SearchRequest(); 22 | request.setComponentKeys(Arrays.asList(keys)); 23 | 24 | return request; 25 | } 26 | 27 | public SearchRequest projects(String ... keys) { 28 | SearchRequest request = new SearchRequest(); 29 | request.setProjects(Arrays.asList(keys)); 30 | 31 | return request; 32 | } 33 | 34 | public SearchRequest rules(String ... keys) { 35 | SearchRequest request = new SearchRequest(); 36 | request.setRules(Arrays.asList(keys)); 37 | 38 | return request; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/plugins/findbugs/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * Copyright (C) 2012 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | @ParametersAreNonnullByDefault 21 | package org.sonar.plugins.findbugs; 22 | 23 | import javax.annotation.ParametersAreNonnullByDefault; 24 | 25 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/plugins/findbugs/xml/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * Copyright (C) 2012 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | @ParametersAreNonnullByDefault 21 | package org.sonar.plugins.findbugs.xml; 22 | 23 | import javax.annotation.ParametersAreNonnullByDefault; 24 | 25 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/plugins/findbugs/rules/FindSecurityBugsScalaRulesDefinition.java: -------------------------------------------------------------------------------- 1 | package org.sonar.plugins.findbugs.rules; 2 | 3 | import org.sonar.api.server.rule.RulesDefinition; 4 | import org.sonar.api.server.rule.RulesDefinitionXmlLoader; 5 | import org.sonar.plugins.findbugs.language.scala.Scala; 6 | 7 | public class FindSecurityBugsScalaRulesDefinition implements RulesDefinition { 8 | public static final String REPOSITORY_KEY = "findsecbugs-scala"; 9 | public static final String REPOSITORY_SCALA_NAME = "Find Security Bugs (Scala)"; 10 | public static final int RULE_COUNT = 9; 11 | 12 | @Override 13 | public void define(Context context) { 14 | NewRepository repositoryJsp = context 15 | .createRepository(REPOSITORY_KEY, Scala.KEY) 16 | .setName(REPOSITORY_SCALA_NAME); 17 | 18 | RulesDefinitionXmlLoader ruleLoaderJsp = new RulesDefinitionXmlLoader(); 19 | ruleLoaderJsp.load(repositoryJsp, FindSecurityBugsRulesDefinition.class.getResourceAsStream("/org/sonar/plugins/findbugs/rules-scala.xml"), "UTF-8"); 20 | repositoryJsp.done(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/test/resources/org/sonar/plugins/findbugs/findbugs-include.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/test/java/org/sonar/plugins/findbugs/util/TestUtils.java: -------------------------------------------------------------------------------- 1 | package org.sonar.plugins.findbugs.util; 2 | 3 | import javax.annotation.CheckForNull; 4 | import java.io.File; 5 | import java.net.URISyntaxException; 6 | import java.net.URL; 7 | 8 | public class TestUtils { 9 | 10 | private TestUtils() { 11 | // utility class 12 | } 13 | 14 | /** 15 | * Search for a test resource in the classpath. For example getResource("org/sonar/MyClass/foo.txt"); 16 | * 17 | * @param path the starting slash is optional 18 | * @return the resource. Null if resource not found 19 | */ 20 | @CheckForNull 21 | public static File getResource(String path) { 22 | String resourcePath = path; 23 | if (!resourcePath.startsWith("/")) { 24 | resourcePath = "/" + resourcePath; 25 | } 26 | URL url = TestUtils.class.getResource(resourcePath); 27 | if (url != null) { 28 | try { 29 | return new File(url.toURI()); 30 | } catch (URISyntaxException e) { 31 | return null; 32 | } 33 | } 34 | return null; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/plugins/findbugs/profiles/FindbugsContribProfile.java: -------------------------------------------------------------------------------- 1 | package org.sonar.plugins.findbugs.profiles; 2 | 3 | import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition; 4 | import org.sonar.plugins.findbugs.FindbugsProfileImporter; 5 | import org.sonar.plugins.java.Java; 6 | 7 | import java.io.InputStreamReader; 8 | import java.io.Reader; 9 | 10 | public class FindbugsContribProfile implements BuiltInQualityProfilesDefinition { 11 | 12 | public static final String FB_CONTRIB_PROFILE_NAME = "FindBugs + FB-Contrib"; 13 | private final FindbugsProfileImporter importer; 14 | 15 | public FindbugsContribProfile(FindbugsProfileImporter importer) { 16 | this.importer = importer; 17 | } 18 | 19 | @Override 20 | public void define(Context context) { 21 | Reader findbugsProfile = new InputStreamReader(this.getClass().getResourceAsStream( 22 | "/org/sonar/plugins/findbugs/profile-findbugs-and-fb-contrib.xml")); 23 | NewBuiltInQualityProfile profile = context.createBuiltInQualityProfile(FB_CONTRIB_PROFILE_NAME, Java.KEY); 24 | importer.importProfile(findbugsProfile, profile); 25 | 26 | profile.done(); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/test/resources/projects/scala/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | org.sonar.tests 4 | scala 5 | 1.0-SNAPSHOT 6 | 7 | 8 | UTF-8 9 | 2.13.10 10 | 11 | 12 | 13 | 14 | org.scala-lang 15 | scala-library 16 | ${scala.version} 17 | 18 | 19 | 20 | 21 | 22 | 23 | org.scala-tools 24 | maven-scala-plugin 25 | 2.15.2 26 | 27 | 28 | 29 | compile 30 | testCompile 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/test/java/org/sonar/plugins/findbugs/FindbugsVersionTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * Copyright (C) 2012 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | package org.sonar.plugins.findbugs; 21 | 22 | import static org.assertj.core.api.Assertions.assertThat; 23 | 24 | import org.junit.jupiter.api.Test; 25 | 26 | class FindbugsVersionTest { 27 | 28 | @Test 29 | void getFindbugsVersion() { 30 | assertThat(FindbugsVersion.getVersion().length()).isGreaterThan(1); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/smoke-test/smoke-test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -eu 4 | 5 | # 1st param... The git URL to clone 6 | # 2nd param... The tag name to check out 7 | function download_target_project() { 8 | DIR_NAME=$(mktemp -d) 9 | cd /$DIR_NAME 10 | git clone "$1" target_repo 11 | cd target_repo 12 | git checkout "$2" 13 | } 14 | 15 | function run_smoke_test() { 16 | echo -n waiting SonarQube 17 | until $(curl --output /dev/null -s --fail http://sonarqube:9000); do 18 | echo -n '.' 19 | sleep 5 20 | done 21 | echo SonarQube has been launched. 22 | 23 | count=0 24 | until mvn compile org.eclipse.jetty.ee8:jetty-ee8-jspc-maven-plugin:12.0.15:jspc org.sonarsource.scanner.maven:sonar-maven-plugin:4.0.0.41219:sonar -B -Dmaven.test.skip -Dsonar.profile="FindBugs + FB-Contrib" -Dsonar.host.url=http://sonarqube:9000 -Dsonar.login=admin -Dsonar.password=admin; do 25 | count=$[ $count + 1 ] 26 | if [ $count -ge 5 ]; then 27 | echo Sonar fails to scan 5 times! 28 | exit 1 29 | fi 30 | echo SonarQube is not ready to scan project, wait 5 sec 31 | sleep 5 32 | done 33 | } 34 | 35 | # Use the project that uses Maven and contains .jsp file 36 | download_target_project 'https://github.com/spring-projects/spring-petclinic.git' 'e9f5f7b54108e35e660a9c9311a682ddce0633bc' 37 | run_smoke_test 38 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/plugins/findbugs/classpath/ClasspathLocator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * Copyright (C) 2012 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | package org.sonar.plugins.findbugs.classpath; 21 | 22 | import java.io.File; 23 | import java.util.Collection; 24 | 25 | /** 26 | * @author gtoison 27 | * 28 | */ 29 | public interface ClasspathLocator { 30 | 31 | Collection binaryDirs(); 32 | 33 | Collection classpath(); 34 | 35 | Collection testBinaryDirs(); 36 | 37 | Collection testClasspath(); 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/plugins/findbugs/language/Jsp.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * Copyright (C) 2012 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | package org.sonar.plugins.findbugs.language; 21 | 22 | /** 23 | * This language cover JavaServer Pages (JSP). 24 | * 25 | * As sonar-html, which defines JSP lang is installed by default on sonarqube 7.6, JSP language will be always available. 26 | */ 27 | public class Jsp { 28 | private Jsp() { 29 | } 30 | 31 | /** 32 | * JSP key 33 | */ 34 | public static final String KEY = "jsp"; 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/test/java/org/sonar/plugins/findbugs/FindbugsCategoryTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * Copyright (C) 2012 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | package org.sonar.plugins.findbugs; 21 | 22 | import static org.assertj.core.api.Assertions.assertThat; 23 | 24 | import org.junit.jupiter.api.Test; 25 | 26 | class FindbugsCategoryTest { 27 | @Test 28 | void test_mapping_of_categories() { 29 | assertThat(FindbugsCategory.findbugsToSonar("EXPERIMENTAL")).isEqualTo("Experimental"); 30 | assertThat(FindbugsCategory.findbugsToSonar("UNKNOWN_XXX")).isNull(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/multi-module-app/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | spotbugs 5 | multi-module 6 | 0.0.1-SNAPSHOT 7 | 8 | multi-module-app 9 | jar 10 | 11 | 12 | UTF-8 13 | 14 | 15 | 16 | 17 | 18 | org.apache.maven.plugins 19 | maven-compiler-plugin 20 | 3.8.1 21 | 22 | 7 23 | 7 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | spotbugs 32 | multi-module-core 33 | 0.0.1-SNAPSHOT 34 | 35 | 36 | spotbugs 37 | multi-module-fx 38 | 0.0.1-SNAPSHOT 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/multi-module-fx/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | spotbugs 5 | multi-module 6 | 0.0.1-SNAPSHOT 7 | 8 | multi-module-fx 9 | jar 10 | 11 | 12 | UTF-8 13 | 14 | 15 | 16 | 17 | 18 | org.apache.maven.plugins 19 | maven-compiler-plugin 20 | 3.8.1 21 | 22 | 7 23 | 7 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | spotbugs 32 | multi-module-core 33 | 0.0.1-SNAPSHOT 34 | 35 | 36 | 37 | junit 38 | junit 39 | test 40 | 4.13.1 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/multi-module-core/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | spotbugs 5 | multi-module 6 | 0.0.1-SNAPSHOT 7 | 8 | multi-module-core 9 | jar 10 | 11 | 12 | UTF-8 13 | 14 | 15 | 16 | 17 | 18 | org.apache.maven.plugins 19 | maven-compiler-plugin 20 | 3.8.1 21 | 22 | 7 23 | 7 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | com.google.code.findbugs 32 | jsr305 33 | 3.0.2 34 | 35 | 36 | 37 | org.junit.jupiter 38 | junit-jupiter 39 | 5.8.2 40 | test 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /src/test/resources/org/sonar/plugins/findbugs/shouldImportPatternsWithMultiplePriorities.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/plugins/findbugs/FindbugsLevelUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * Copyright (C) 2012 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | package org.sonar.plugins.findbugs; 21 | 22 | import org.sonar.api.rule.Severity; 23 | 24 | public class FindbugsLevelUtils { 25 | 26 | public String from(String priority) { 27 | if ("1".equals(priority)) { 28 | return Severity.BLOCKER; 29 | } 30 | if ("2".equals(priority)) { 31 | return Severity.MAJOR; 32 | } 33 | if ("3".equals(priority)) { 34 | return Severity.INFO; 35 | } 36 | throw new IllegalArgumentException("Priority not supported: " + priority); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /RELEASE_PROCEDURE.md: -------------------------------------------------------------------------------- 1 | # Release procedure 2 | 3 | When you release fixed version of SonarQube SpotBugs Plugin, please follow these procedures. 4 | 5 | * create topic branch from `master` branch 6 | 7 | ``` 8 | git checkout -b master-release 9 | ``` 10 | 11 | * Make sure profile XMLs are updated. See [`generate_profiles/README.md`](generate_profiles/README.md) for detail. 12 | 13 | * change version number in `pom.xml` to stable version (e.g. `1.2.3`), then commit changes 14 | 15 | ``` 16 | mvn versions:set -DnewVersion=1.2.3 17 | ``` 18 | 19 | * change version number in `pom.xml` to next development SNAPSHOT version (e.g. `1.2.4-SNAPSHOT`), then commit changes 20 | 21 | ``` 22 | mvn versions:set -DnewVersion=1.2.4-SNAPSHOT 23 | ``` 24 | 25 | * push your topic branch and propose a pull request 26 | * after merging your pull request, create a GitHub Release with the commit which has stable version in `pom.xml`. The name of tag should have no prefix nor suffix, e.g. `4.0.0` 27 | 28 | ## Release to Maven Central 29 | 30 | When we push the new tag, the Github Actions release build will be deploy to [Sonatype Nexus](https://oss.sonatype.org/). 31 | Check [Sonatype official page](http://central.sonatype.org/pages/apache-maven.html) for details. 32 | 33 | ## Release to SonarQube Marketplace 34 | 35 | To release to https://github.com/SonarSource/sonar-update-center-properties/, either use the forked copy in spotbugs and manually apply updates and send a pull request 36 | or manually fork a copy to your personal account and do the same. 37 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/plugins/findbugs/xml/ClassFilter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * Copyright (C) 2012 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | package org.sonar.plugins.findbugs.xml; 21 | 22 | import com.thoughtworks.xstream.annotations.XStreamAlias; 23 | import com.thoughtworks.xstream.annotations.XStreamAsAttribute; 24 | 25 | @XStreamAlias("Class") 26 | public class ClassFilter { 27 | 28 | @XStreamAsAttribute 29 | private String name; 30 | 31 | public ClassFilter() { 32 | // Empty constructor required by XStream converters 33 | } 34 | 35 | public ClassFilter(String name) { 36 | this.name = name; 37 | } 38 | 39 | public String getName() { 40 | return name; 41 | } 42 | 43 | public void setName(String name) { 44 | this.name = name; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/plugins/findbugs/xml/LocalFilter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * Copyright (C) 2012 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | package org.sonar.plugins.findbugs.xml; 21 | 22 | import com.thoughtworks.xstream.annotations.XStreamAlias; 23 | import com.thoughtworks.xstream.annotations.XStreamAsAttribute; 24 | 25 | @XStreamAlias("Local") 26 | public class LocalFilter { 27 | 28 | @XStreamAsAttribute 29 | private String name; 30 | 31 | public LocalFilter() { 32 | // Empty constructor required by XStream converters 33 | } 34 | 35 | public LocalFilter(String name) { 36 | this.name = name; 37 | } 38 | 39 | public String getName() { 40 | return name; 41 | } 42 | 43 | public void setName(String name) { 44 | this.name = name; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/plugins/findbugs/xml/Priority.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * Copyright (C) 2012 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | package org.sonar.plugins.findbugs.xml; 21 | 22 | import com.thoughtworks.xstream.annotations.XStreamAlias; 23 | import com.thoughtworks.xstream.annotations.XStreamAsAttribute; 24 | 25 | @XStreamAlias("Priority") 26 | public class Priority { 27 | 28 | @XStreamAsAttribute 29 | private String value; 30 | 31 | public Priority() { 32 | // Empty constructor required by XStream converters 33 | } 34 | 35 | public Priority(String value) { 36 | this.value = value; 37 | } 38 | 39 | public String getValue() { 40 | return value; 41 | } 42 | 43 | public void setValue(String value) { 44 | this.value = value; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/plugins/findbugs/xml/PackageFilter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * Copyright (C) 2012 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | package org.sonar.plugins.findbugs.xml; 21 | 22 | import com.thoughtworks.xstream.annotations.XStreamAlias; 23 | import com.thoughtworks.xstream.annotations.XStreamAsAttribute; 24 | 25 | @XStreamAlias("Package") 26 | public class PackageFilter { 27 | 28 | @XStreamAsAttribute 29 | private String name; 30 | 31 | public PackageFilter() { 32 | // Empty constructor required by XStream converters 33 | } 34 | 35 | public PackageFilter(String name) { 36 | this.name = name; 37 | } 38 | 39 | public String getName() { 40 | return name; 41 | } 42 | 43 | public void setName(String name) { 44 | this.name = name; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/multi-module-jsp-uncompiled/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | spotbugs 5 | multi-module 6 | 0.0.1-SNAPSHOT 7 | 8 | multi-module-jsp-uncompiled 9 | war 10 | 11 | 12 | UTF-8 13 | true 14 | 15 | 16 | 17 | 18 | 19 | org.apache.maven.plugins 20 | maven-compiler-plugin 21 | 3.8.1 22 | 23 | 7 24 | 7 25 | 26 | 27 | 28 | 29 | org.apache.maven.plugins 30 | maven-war-plugin 31 | 3.3.2 32 | 33 | 34 | 35 | 36 | 37 | 38 | spotbugs 39 | multi-module-core 40 | 0.0.1-SNAPSHOT 41 | 42 | 43 | 44 | junit 45 | junit 46 | test 47 | 4.13.1 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/multi-module-scala/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | spotbugs 5 | multi-module 6 | 0.0.1-SNAPSHOT 7 | 8 | multi-module-scala 9 | jar 10 | 11 | 12 | UTF-8 13 | src/main/scala 14 | 15 | 16 | 17 | 18 | 19 | net.alchim31.maven 20 | scala-maven-plugin 21 | 4.6.1 22 | 23 | 24 | 25 | compile 26 | testCompile 27 | 28 | 29 | 30 | 31 | scala-sources 32 | 33 | add-source 34 | 35 | process-sources 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | spotbugs 45 | multi-module-core 46 | 0.0.1-SNAPSHOT 47 | 48 | 49 | 50 | org.scala-lang 51 | scala3-library_3 52 | 3.1.2 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/plugins/findbugs/xml/FieldFilter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * Copyright (C) 2012 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | package org.sonar.plugins.findbugs.xml; 21 | 22 | import com.thoughtworks.xstream.annotations.XStreamAlias; 23 | import com.thoughtworks.xstream.annotations.XStreamAsAttribute; 24 | 25 | @XStreamAlias("Field") 26 | public class FieldFilter { 27 | 28 | @XStreamAsAttribute 29 | private String name; 30 | 31 | @XStreamAsAttribute 32 | private String type; 33 | 34 | public FieldFilter() { 35 | // Empty constructor required by XStream converters 36 | } 37 | 38 | public FieldFilter(String name) { 39 | this.name = name; 40 | } 41 | 42 | public String getName() { 43 | return name; 44 | } 45 | 46 | public void setName(String name) { 47 | this.name = name; 48 | } 49 | 50 | public String getType() { 51 | return type; 52 | } 53 | 54 | public void setType(String type) { 55 | this.type = type; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/plugins/findbugs/rules/FindSecurityBugsRulesDefinition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * Copyright (C) 2012 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | package org.sonar.plugins.findbugs.rules; 21 | 22 | import org.sonar.api.server.rule.RulesDefinition; 23 | import org.sonar.api.server.rule.RulesDefinitionXmlLoader; 24 | import org.sonar.plugins.java.Java; 25 | 26 | public final class FindSecurityBugsRulesDefinition implements RulesDefinition { 27 | 28 | public static final String REPOSITORY_KEY = "findsecbugs"; 29 | public static final String REPOSITORY_NAME = "Find Security Bugs"; 30 | public static final int RULE_COUNT = 129; 31 | 32 | @Override 33 | public void define(Context context) { 34 | NewRepository repository = context 35 | .createRepository(REPOSITORY_KEY, Java.KEY) 36 | .setName(REPOSITORY_NAME); 37 | 38 | RulesDefinitionXmlLoader ruleLoader = new RulesDefinitionXmlLoader(); 39 | ruleLoader.load(repository, FindSecurityBugsRulesDefinition.class.getResourceAsStream("/org/sonar/plugins/findbugs/rules-findsecbugs.xml"), "UTF-8"); 40 | repository.done(); 41 | 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/test/java/org/sonar/plugins/findbugs/profiles/FindbugsContribProfileTest.java: -------------------------------------------------------------------------------- 1 | package org.sonar.plugins.findbugs.profiles; 2 | 3 | import static org.assertj.core.api.Assertions.assertThat; 4 | 5 | import org.junit.jupiter.api.Test; 6 | import org.junit.jupiter.api.extension.RegisterExtension; 7 | import org.slf4j.event.Level; 8 | import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition.BuiltInQualityProfile; 9 | import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition.Context; 10 | import org.sonar.api.testfixtures.log.LogTesterJUnit5; 11 | import org.sonar.plugins.findbugs.FindbugsProfileImporter; 12 | import org.sonar.plugins.findbugs.rule.FakeRuleFinder; 13 | import org.sonar.plugins.findbugs.rules.FbContribRulesDefinition; 14 | import org.sonar.plugins.findbugs.rules.FindbugsRulesDefinition; 15 | import org.sonar.plugins.java.Java; 16 | 17 | class FindbugsContribProfileTest { 18 | 19 | @RegisterExtension 20 | public LogTesterJUnit5 logTester = new LogTesterJUnit5(); 21 | 22 | @Test 23 | void shouldCreateProfile() { 24 | FindbugsProfileImporter importer = new FindbugsProfileImporter(FakeRuleFinder.createWithAllRules()); 25 | FindbugsContribProfile findbugsProfile = new FindbugsContribProfile(importer); 26 | Context context = new Context(); 27 | findbugsProfile.define(context); 28 | 29 | BuiltInQualityProfile profile = context.profile(Java.KEY, FindbugsContribProfile.FB_CONTRIB_PROFILE_NAME); 30 | assertThat(profile.rules().stream().filter(r -> r.repoKey().equals(FindbugsRulesDefinition.REPOSITORY_KEY)).count()).isEqualTo(FindbugsRulesDefinition.RULE_COUNT); 31 | assertThat(profile.rules().stream().filter(r -> r.repoKey().equals(FbContribRulesDefinition.REPOSITORY_KEY)).count()).isEqualTo(FbContribRulesDefinition.RULE_COUNT); 32 | assertThat(logTester.getLogs(Level.ERROR)).isEmpty(); 33 | 34 | FindbugsProfileTest.assertHasOnlyRulesForLanguage(profile.rules(), Java.KEY); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/plugins/findbugs/rules/FbContribRulesDefinition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * Copyright (C) 2012 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | package org.sonar.plugins.findbugs.rules; 21 | 22 | import org.sonar.api.server.rule.RulesDefinition; 23 | import org.sonar.api.server.rule.RulesDefinitionXmlLoader; 24 | import org.sonar.plugins.java.Java; 25 | 26 | public class FbContribRulesDefinition implements RulesDefinition { 27 | 28 | public static final String REPOSITORY_KEY = "fb-contrib"; 29 | public static final String REPOSITORY_NAME = "FindBugs Contrib"; 30 | public static final int RULE_COUNT = 332; 31 | public static final int DEACTIVED_RULE_COUNT = 0; 32 | 33 | @Override 34 | public void define(Context context) { 35 | NewRepository repository = context 36 | .createRepository(REPOSITORY_KEY, Java.KEY) 37 | .setName(REPOSITORY_NAME); 38 | 39 | RulesDefinitionXmlLoader ruleLoader = new RulesDefinitionXmlLoader(); 40 | ruleLoader.load(repository, FbContribRulesDefinition.class.getResourceAsStream("/org/sonar/plugins/findbugs/rules-fbcontrib.xml"), "UTF-8"); 41 | repository.done(); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/plugins/findbugs/FindbugsCategory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * Copyright (C) 2012 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | package org.sonar.plugins.findbugs; 21 | 22 | import java.util.Collections; 23 | import java.util.HashMap; 24 | import java.util.Map; 25 | 26 | public final class FindbugsCategory { 27 | private static final Map FINDBUGS_TO_SONAR; 28 | 29 | static { 30 | Map map = new HashMap<>(); 31 | 32 | map.put("BAD_PRACTICE", "Bad practice"); 33 | map.put("CORRECTNESS", "Correctness"); 34 | map.put("MT_CORRECTNESS", "Multithreaded correctness"); 35 | map.put("I18N", "Internationalization"); 36 | map.put("EXPERIMENTAL", "Experimental"); 37 | map.put("MALICIOUS_CODE", "Malicious code"); 38 | map.put("PERFORMANCE", "Performance"); 39 | map.put("SECURITY", "Security"); 40 | map.put("STYLE", "Style"); 41 | 42 | FINDBUGS_TO_SONAR = Collections.unmodifiableMap(map); 43 | } 44 | 45 | public static String findbugsToSonar(String findbugsCategKey) { 46 | return FINDBUGS_TO_SONAR.get(findbugsCategKey); 47 | } 48 | 49 | private FindbugsCategory() { 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/plugins/findbugs/AnalysisResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 17 | */ 18 | package org.sonar.plugins.findbugs; 19 | 20 | import java.util.ArrayList; 21 | import java.util.Arrays; 22 | import java.util.Collection; 23 | 24 | import edu.umd.cs.findbugs.AnalysisError; 25 | import edu.umd.cs.findbugs.BugInstance; 26 | 27 | /** 28 | * @author gtoison 29 | * 30 | */ 31 | public class AnalysisResult { 32 | private Collection reportedBugs; 33 | private Collection analysisErrors; 34 | 35 | public AnalysisResult() { 36 | this(new ArrayList<>(), new ArrayList<>()); 37 | } 38 | 39 | public AnalysisResult(BugInstance bugInstance) { 40 | this(Arrays.asList(new ReportedBug(bugInstance)), new ArrayList<>()); 41 | } 42 | 43 | public AnalysisResult(Collection reportedBugs, Collection errors) { 44 | this.reportedBugs = reportedBugs; 45 | this.analysisErrors = new ArrayList<>(errors); 46 | } 47 | 48 | public Collection getReportedBugs() { 49 | return reportedBugs; 50 | } 51 | 52 | public Collection getAnalysisErrors() { 53 | return analysisErrors; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/plugins/findbugs/FindbugsVersion.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * Copyright (C) 2012 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | package org.sonar.plugins.findbugs; 21 | 22 | import java.io.IOException; 23 | import java.io.InputStream; 24 | import java.util.Properties; 25 | 26 | import org.slf4j.LoggerFactory; 27 | 28 | public enum FindbugsVersion { 29 | INSTANCE; 30 | 31 | private static final String PROPERTIES_PATH = "/org/sonar/plugins/findbugs/findbugs-plugin.properties"; 32 | private String version; 33 | 34 | public static String getVersion() { 35 | return INSTANCE.version; 36 | } 37 | 38 | private FindbugsVersion() { 39 | try (InputStream input = getClass().getResourceAsStream(PROPERTIES_PATH)) { 40 | Properties properties = new Properties(); 41 | properties.load(input); 42 | this.version = properties.getProperty("findbugs.plugin.version"); 43 | } catch (IOException e) { 44 | LoggerFactory.getLogger(getClass()).warn("Can not load the Findbugs version from the file " + PROPERTIES_PATH); 45 | LoggerFactory.getLogger(getClass()).debug("Error while loading propoerties", e); 46 | this.version = ""; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /.github/workflows/sonarqube.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - master 5 | - sq-10 6 | release: 7 | types: 8 | - created 9 | 10 | # set necessary permissions for SQ's GitHub integration 11 | # https://docs.sonarqube.org/latest/analysis/github-integration/#header-2 12 | permissions: 13 | checks: write 14 | contents: read 15 | pull-requests: write 16 | statuses: read 17 | 18 | jobs: 19 | build: 20 | if: github.repository_owner == 'spotbugs' 21 | runs-on: ubuntu-latest 22 | steps: 23 | - uses: actions/checkout@v6 24 | with: 25 | fetch-depth: 0 26 | - name: Set up JDK 17 27 | uses: actions/setup-java@v5 28 | with: 29 | java-version: 17 30 | distribution: temurin 31 | cache: 'maven' 32 | - name: Cache SonarCloud packages 33 | uses: actions/cache@v5 34 | with: 35 | path: | 36 | ~/.sonar/cache 37 | key: ${{ runner.os }}-sonar 38 | restore-keys: ${{ runner.os }}-sonar 39 | - name: Build 40 | run: | 41 | ./mvnw org.jacoco:jacoco-maven-plugin:prepare-agent verify sonar:sonar -B -e -V -DskipITs \ 42 | -Dsonar.server.version=${{ env.SONAR_SERVER_VERSION }} \ 43 | -Dsonar-plugin-api.version=${{ env.SONAR_PLUGIN_API_VERSION }} \ 44 | -Dsonar.projectKey=com.github.spotbugs:sonar-findbugs-plugin \ 45 | -Dsonar.organization=spotbugs \ 46 | -Dsonar.host.url=https://sonarcloud.io \ 47 | -Dsonar.token=$SONAR_TOKEN \ 48 | ${PR_NUMBER:+ -Dsonar.pullrequest.key=$PR_NUMBER -Dsonar.pullrequest.branch=$PR_BRANCH } 49 | env: 50 | # previous LTS version 51 | SONAR_SERVER_VERSION: 9.9.7.96285 52 | SONAR_PLUGIN_API_VERSION: 9.14.0.375 53 | SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} 54 | PR_NUMBER: ${{ github.event.pull_request.number }} 55 | PR_BRANCH: ${{ github.event.pull_request.head.ref }} 56 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/plugins/findbugs/profiles/FindbugsProfile.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * Copyright (C) 2012 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | package org.sonar.plugins.findbugs.profiles; 21 | 22 | import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition; 23 | import org.sonar.plugins.findbugs.FindbugsProfileImporter; 24 | import org.sonar.plugins.java.Java; 25 | 26 | import java.io.InputStreamReader; 27 | import java.io.Reader; 28 | 29 | public class FindbugsProfile implements BuiltInQualityProfilesDefinition { 30 | 31 | public static final String FINDBUGS_PROFILE_NAME = "FindBugs"; 32 | private final FindbugsProfileImporter importer; 33 | 34 | public FindbugsProfile(FindbugsProfileImporter importer) { 35 | this.importer = importer; 36 | } 37 | 38 | @Override 39 | public void define(Context context) { 40 | Reader findbugsProfile = new InputStreamReader(this.getClass().getResourceAsStream( 41 | "/org/sonar/plugins/findbugs/profile-findbugs-only.xml")); 42 | NewBuiltInQualityProfile profile = context.createBuiltInQualityProfile(FINDBUGS_PROFILE_NAME, Java.KEY); 43 | importer.importProfile(findbugsProfile, profile); 44 | 45 | profile.done(); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/plugins/findbugs/xml/Bug.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * Copyright (C) 2012 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | package org.sonar.plugins.findbugs.xml; 21 | 22 | import com.thoughtworks.xstream.annotations.XStreamAlias; 23 | import com.thoughtworks.xstream.annotations.XStreamAsAttribute; 24 | 25 | @XStreamAlias("Bug") 26 | public class Bug { 27 | 28 | @XStreamAsAttribute 29 | private String code; 30 | 31 | @XStreamAsAttribute 32 | private String category; 33 | 34 | @XStreamAsAttribute 35 | private String pattern; 36 | 37 | public Bug() { 38 | // Empty constructor required by XStream converters 39 | } 40 | 41 | public Bug(String pattern) { 42 | this.pattern = pattern; 43 | } 44 | 45 | public String getPattern() { 46 | return pattern; 47 | } 48 | 49 | public void setPattern(String pattern) { 50 | this.pattern = pattern; 51 | } 52 | 53 | public String getCode() { 54 | return code; 55 | } 56 | 57 | public void setCode(String code) { 58 | this.code = code; 59 | } 60 | 61 | public String getCategory() { 62 | return category; 63 | } 64 | 65 | public void setCategory(String category) { 66 | this.category = category; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/plugins/findbugs/xml/MethodFilter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * Copyright (C) 2012 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | package org.sonar.plugins.findbugs.xml; 21 | 22 | import com.thoughtworks.xstream.annotations.XStreamAlias; 23 | import com.thoughtworks.xstream.annotations.XStreamAsAttribute; 24 | 25 | @XStreamAlias("Method") 26 | public class MethodFilter { 27 | 28 | @XStreamAsAttribute 29 | private String name; 30 | 31 | @XStreamAsAttribute 32 | private String params; 33 | 34 | @XStreamAsAttribute 35 | private String returns; 36 | 37 | public MethodFilter() { 38 | // Empty constructor required by XStream converters 39 | } 40 | 41 | public MethodFilter(String name) { 42 | this.name = name; 43 | } 44 | 45 | public String getName() { 46 | return name; 47 | } 48 | 49 | public void setName(String name) { 50 | this.name = name; 51 | } 52 | 53 | public String getParams() { 54 | return params; 55 | } 56 | 57 | public void setParams(String params) { 58 | this.params = params; 59 | } 60 | 61 | public String getReturns() { 62 | return returns; 63 | } 64 | 65 | public void setReturns(String returns) { 66 | this.returns = returns; 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/test/java/org/sonar/plugins/findbugs/FindbugsPluginTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * Copyright (C) 2012 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | package org.sonar.plugins.findbugs; 21 | 22 | import static org.junit.jupiter.api.Assertions.assertEquals; 23 | import static org.mockito.Mockito.mock; 24 | import static org.mockito.Mockito.when; 25 | 26 | import org.junit.jupiter.params.ParameterizedTest; 27 | import org.junit.jupiter.params.provider.CsvSource; 28 | import org.sonar.api.Plugin; 29 | import org.sonar.api.SonarRuntime; 30 | import org.sonar.api.utils.Version; 31 | 32 | class FindbugsPluginTest { 33 | 34 | @ParameterizedTest 35 | @CsvSource({ 36 | "11.3,26", 37 | // We disable the profile exporter when the plugin API version is >= 11.4 (since 2025.3 commercial editions) 38 | "11.4,25" 39 | }) 40 | void testGetExtensions(String version, int expectedExtensionsCount) { 41 | SonarRuntime runtime = mock(SonarRuntime.class); 42 | when(runtime.getApiVersion()).thenReturn(Version.parse(version)); 43 | Plugin.Context ctx = new Plugin.Context(runtime); 44 | 45 | FindbugsPlugin plugin = new FindbugsPlugin(); 46 | plugin.define(ctx); 47 | 48 | assertEquals(expectedExtensionsCount, ctx.getExtensions().size(), "extensions count"); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/plugins/findbugs/profiles/FindbugsSecurityJspProfile.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * Copyright (C) 2012 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | package org.sonar.plugins.findbugs.profiles; 21 | 22 | import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition; 23 | import org.sonar.plugins.findbugs.FindbugsProfileImporter; 24 | import org.sonar.plugins.findbugs.language.Jsp; 25 | 26 | import java.io.InputStreamReader; 27 | import java.io.Reader; 28 | 29 | public class FindbugsSecurityJspProfile implements BuiltInQualityProfilesDefinition { 30 | 31 | public static final String FINDBUGS_SECURITY_JSP_PROFILE_NAME = "FindBugs Security JSP"; 32 | private final FindbugsProfileImporter importer; 33 | 34 | public FindbugsSecurityJspProfile(FindbugsProfileImporter importer) { 35 | this.importer = importer; 36 | } 37 | 38 | @Override 39 | public void define(Context context) { 40 | Reader findbugsProfile = new InputStreamReader(this.getClass().getResourceAsStream( 41 | "/org/sonar/plugins/findbugs/profile-findbugs-security-jsp.xml")); 42 | NewBuiltInQualityProfile profile = context.createBuiltInQualityProfile(FINDBUGS_SECURITY_JSP_PROFILE_NAME, Jsp.KEY); 43 | importer.importProfile(findbugsProfile, profile); 44 | 45 | profile.done(); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/plugins/findbugs/resource/JasperUtils.java: -------------------------------------------------------------------------------- 1 | package org.sonar.plugins.findbugs.resource; 2 | 3 | import java.awt.event.KeyEvent; 4 | 5 | public class JasperUtils { 6 | 7 | /** 8 | * Transform a class name from a precompiled JSP and return the file name of the source file (*.jsp). 9 | * @param className Class name of the JSP class 10 | * @return JSP file name 11 | */ 12 | public static String decodeJspClassName(String className) { 13 | className = className.replace(".", "/"); 14 | 15 | for(char ch = Character.MIN_VALUE; ch < 128 ; ch++) { 16 | //Condition minimize the number of replace operations 17 | if((isPrintableChar(ch) && !Character.isJavaIdentifierPart(ch)) || ch == '_') { 18 | 19 | //The replaceAll operation is highly ineffective for large string 20 | //In was implemented this way because it is simpler to maintain. 21 | className = className.replace(mangleChar(ch), Character.toString(ch)); 22 | } 23 | } 24 | return className.replace("_jsp", ".jsp"); 25 | } 26 | 27 | /** 28 | * Encode special char to make sure it will be compliant to the class name restriction. 29 | * @param ch Special character 30 | * @return Encoded format (_XXXX) 31 | */ 32 | public static final String mangleChar(char ch) 33 | { 34 | char[] result = new char[5]; 35 | result[0] = '_'; 36 | result[1] = Character.forDigit(ch >> '\f' & 0xF, 16); 37 | result[2] = Character.forDigit(ch >> '\b' & 0xF, 16); 38 | result[3] = Character.forDigit(ch >> '\004' & 0xF, 16); 39 | result[4] = Character.forDigit(ch & 0xF, 16); 40 | return new String(result); 41 | } 42 | 43 | /** 44 | * Detect if the character is printable 45 | * @param c Character to test 46 | * @return boolean true if its a printable char otherwise false 47 | */ 48 | public static boolean isPrintableChar( char c ) { 49 | Character.UnicodeBlock block = Character.UnicodeBlock.of( c ); 50 | return (!Character.isISOControl(c)) && 51 | c != KeyEvent.CHAR_UNDEFINED && 52 | block != null && 53 | block != Character.UnicodeBlock.SPECIALS; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/plugins/findbugs/profiles/FindbugsSecurityScalaProfile.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * Copyright (C) 2012 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | package org.sonar.plugins.findbugs.profiles; 21 | 22 | import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition; 23 | import org.sonar.plugins.findbugs.FindbugsProfileImporter; 24 | import org.sonar.plugins.findbugs.language.scala.Scala; 25 | 26 | import java.io.InputStreamReader; 27 | import java.io.Reader; 28 | 29 | public class FindbugsSecurityScalaProfile implements BuiltInQualityProfilesDefinition { 30 | 31 | public static final String FINDBUGS_SECURITY_SCALA_PROFILE_NAME = "FindBugs Security Scala"; 32 | private final FindbugsProfileImporter importer; 33 | 34 | public FindbugsSecurityScalaProfile(FindbugsProfileImporter importer) { 35 | this.importer = importer; 36 | } 37 | 38 | @Override 39 | public void define(Context context) { 40 | Reader findbugsProfile = new InputStreamReader(this.getClass().getResourceAsStream( 41 | "/org/sonar/plugins/findbugs/profile-findbugs-security-scala.xml")); 42 | 43 | NewBuiltInQualityProfile profile = context.createBuiltInQualityProfile(FINDBUGS_SECURITY_SCALA_PROFILE_NAME, Scala.KEY); 44 | importer.importProfile(findbugsProfile, profile); 45 | 46 | profile.done(); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/multi-module-clojure/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | spotbugs 5 | multi-module 6 | 0.0.1-SNAPSHOT 7 | 8 | multi-module-clojure 9 | jar 10 | 11 | 12 | UTF-8 13 | 11 14 | 15 | 16 | 17 | 18 | 19 | com.theoryinpractise 20 | clojure-maven-plugin 21 | 1.8.4 22 | true 23 | 24 | 25 | clojure-compile 26 | compile 27 | 28 | compile 29 | 30 | 31 | 32 | clojure-test 33 | test 34 | 35 | test 36 | 37 | 38 | 39 | 40 | 41 | src/main/clojure 42 | 43 | 44 | 45 | 46 | maven-compiler-plugin 47 | 3.5.1 48 | 49 | 1.8 50 | 1.8 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | spotbugs 59 | multi-module-core 60 | 0.0.1-SNAPSHOT 61 | 62 | 63 | 64 | org.clojure 65 | clojure 66 | 1.11.2 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/plugins/findbugs/FindbugsConstants.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * Copyright (C) 2012 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | package org.sonar.plugins.findbugs; 21 | 22 | public final class FindbugsConstants { 23 | 24 | public static final String PLUGIN_NAME = "FindBugs"; 25 | 26 | public static final String EFFORT_PROPERTY = "sonar.findbugs.effort"; 27 | public static final String EFFORT_DEFAULT_VALUE = "Default"; 28 | 29 | public static final String CONFIDENCE_LEVEL_PROPERTY = "sonar.findbugs.confidenceLevel"; 30 | public static final String CONFIDENCE_LEVEL_DEFAULT_VALUE = "medium"; 31 | 32 | public static final String TIMEOUT_PROPERTY = "sonar.findbugs.timeout"; 33 | public static final long TIMEOUT_DEFAULT_VALUE = 600000L; 34 | 35 | public static final String ALLOW_UNCOMPILED_CODE = "sonar.findbugs.allowuncompiledcode"; 36 | public static final boolean ALLOW_UNCOMPILED_CODE_VALUE = false; 37 | 38 | public static final String REPORT_PATHS = "sonar.findbugs.reportpaths"; 39 | 40 | 41 | public static final String EXCLUDES_FILTERS_PROPERTY = "sonar.findbugs.excludesFilters"; 42 | 43 | public static final String ONLY_ANALYZE_PROPERTY = "sonar.findbugs.onlyAnalyze"; 44 | 45 | public static final String ANALYZE_TESTS = "sonar.findbugs.analyzeTests"; 46 | public static final boolean ANALYZE_TESTS_VALUE = true; 47 | 48 | private FindbugsConstants() { 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/plugins/findbugs/profiles/FindbugsSecurityAuditProfile.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * Copyright (C) 2012 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | package org.sonar.plugins.findbugs.profiles; 21 | 22 | import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition; 23 | import org.sonar.plugins.findbugs.FindbugsProfileImporter; 24 | import org.sonar.plugins.java.Java; 25 | 26 | import java.io.InputStreamReader; 27 | import java.io.Reader; 28 | 29 | /** 30 | * Security rules including informational rules. This profile is intend for in depth security code review. 31 | */ 32 | public class FindbugsSecurityAuditProfile implements BuiltInQualityProfilesDefinition { 33 | 34 | public static final String FINDBUGS_SECURITY_AUDIT_PROFILE_NAME = "FindBugs Security Audit"; 35 | private final FindbugsProfileImporter importer; 36 | 37 | public FindbugsSecurityAuditProfile(FindbugsProfileImporter importer) { 38 | this.importer = importer; 39 | } 40 | 41 | @Override 42 | public void define(Context context) { 43 | Reader findbugsProfile = new InputStreamReader(this.getClass().getResourceAsStream( 44 | "/org/sonar/plugins/findbugs/profile-findbugs-security-audit.xml")); 45 | NewBuiltInQualityProfile profile = context.createBuiltInQualityProfile(FINDBUGS_SECURITY_AUDIT_PROFILE_NAME, Java.KEY); 46 | importer.importProfile(findbugsProfile, profile); 47 | 48 | profile.done(); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/test/resources/projects/jspc-sling/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | org.sonar.tests 4 | jspc-sling 5 | 0.1-SNAPSHOT 6 | war 7 | Sonar tests - JSPC Sling sample 8 | 9 | 10 | UTF-8 11 | 12 | 13 | 14 | src 15 | 16 | 17 | org.apache.maven.plugins 18 | maven-compiler-plugin 19 | 3.8.1 20 | 21 | 7 22 | 7 23 | 24 | 25 | 26 | 27 | org.apache.sling 28 | jspc-maven-plugin 29 | 2.3.0 30 | 31 | 32 | compile-jsp 33 | 34 | jspc 35 | 36 | 37 | 38 | 39 | 40 | 41 | org.apache.maven.plugins 42 | maven-war-plugin 43 | 3.3.2 44 | 45 | 46 | 47 | 48 | 49 | 50 | javax.servlet 51 | javax.servlet-api 52 | 4.0.1 53 | provided 54 | 55 | 56 | javax.servlet.jsp 57 | javax.servlet.jsp-api 58 | 2.3.3 59 | provided 60 | 61 | 62 | org.apache.sling 63 | org.apache.sling.scripting.jsp 64 | 2.5.4 65 | provided 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /src/test/java/org/sonar/plugins/findbugs/it/FindSecBugsIT.java: -------------------------------------------------------------------------------- 1 | package org.sonar.plugins.findbugs.it; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertFalse; 4 | 5 | import java.io.File; 6 | 7 | import org.junit.jupiter.api.AfterEach; 8 | import org.junit.jupiter.api.BeforeEach; 9 | import org.junit.jupiter.api.Test; 10 | import org.sonarqube.ws.client.qualityprofiles.AddProjectRequest; 11 | 12 | import com.sonar.orchestrator.build.MavenBuild; 13 | import com.sonar.orchestrator.junit5.OrchestratorExtension; 14 | 15 | /** 16 | * @author gtoison 17 | * 18 | */ 19 | @IntegrationTest 20 | class FindSecBugsIT { 21 | 22 | private static final String PROJECT_KEY = "com.sonarsource.it.samples:findbugs"; 23 | public static OrchestratorExtension orchestrator = FindbugsTestSuite.ORCHESTRATOR; 24 | 25 | @BeforeEach 26 | public void setupProfile() { 27 | FindbugsTestSuite.setupProjectAndProfile(PROJECT_KEY, "Find Sec Bugs Integration Tests", "IT", "java"); 28 | } 29 | 30 | @AfterEach 31 | public void deleteProject() { 32 | FindbugsTestSuite.deleteProject(PROJECT_KEY); 33 | } 34 | 35 | @Test 36 | void noAnalysisWhenProfileDoesNotHaveSpotBugsRules() throws Exception { 37 | // Set an empty Java quality profile for the project 38 | AddProjectRequest addProjectRequest = new AddProjectRequest(); 39 | addProjectRequest.setLanguage("java"); 40 | addProjectRequest.setProject(PROJECT_KEY); 41 | addProjectRequest.setQualityProfile("empty"); 42 | FindbugsTestSuite.qualityProfileClient().addProject(addProjectRequest); 43 | 44 | MavenBuild build = MavenBuild.create() 45 | .setPom(FindbugsTestSuite.projectPom("findbugs")) 46 | .setProperty("sonar.dynamicAnalysis", "false") 47 | .setProperty("sonar.findbugs.confidenceLevel", "low") 48 | .setCleanPackageSonarGoals(); 49 | orchestrator.executeBuild(build); 50 | 51 | File projectDir = FindbugsTestSuite.projectPom("findbugs").getParentFile(); 52 | File resultFile = new File(projectDir, "target/sonar/findbugs-result.xml"); 53 | 54 | String message = "The analysis must not run because the findbugs sample project does not contain JSP files and there are no spotbugs rules in the profile"; 55 | assertFalse(resultFile.exists(), message); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/test/java/org/sonar/plugins/findbugs/configuration/SimpleConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube SpotBugs Plugin 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 17 | */ 18 | package org.sonar.plugins.findbugs.configuration; 19 | 20 | import org.apache.commons.lang3.ArrayUtils; 21 | import org.sonar.api.config.Configuration; 22 | 23 | import java.util.ArrayList; 24 | import java.util.HashMap; 25 | import java.util.List; 26 | import java.util.Map; 27 | import java.util.Optional; 28 | 29 | public class SimpleConfiguration implements Configuration { 30 | private Map values = new HashMap<>(); 31 | 32 | @Override 33 | public Optional get(String key) { 34 | return Optional.ofNullable(values.get(key)); 35 | } 36 | 37 | @Override 38 | public boolean hasKey(String key) { 39 | return values.containsKey(key); 40 | } 41 | 42 | @Override 43 | public String[] getStringArray(String key) { 44 | String value = values.get(key); 45 | if (value == null) { 46 | return ArrayUtils.EMPTY_STRING_ARRAY; 47 | } 48 | 49 | List values = new ArrayList<>(); 50 | for (String v : value.split(",")) { 51 | values.add(v.replace("%2C", ",")); 52 | } 53 | return values.toArray(new String[values.size()]); 54 | } 55 | 56 | public void setProperty(String key, int i) { 57 | values.put(key, Integer.toString(i)); 58 | } 59 | 60 | public void setProperty(String key, String ... v) { 61 | values.put(key, String.join(",", v)); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/plugins/findbugs/profiles/FindbugsSecurityMinimalProfile.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * Copyright (C) 2012 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | package org.sonar.plugins.findbugs.profiles; 21 | 22 | import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition; 23 | import org.sonar.plugins.findbugs.FindbugsProfileImporter; 24 | import org.sonar.plugins.java.Java; 25 | 26 | import java.io.InputStreamReader; 27 | import java.io.Reader; 28 | 29 | /** 30 | * Security rules with only the issue that require immediate analysis. It is intend for periodic scan that will trigger 31 | * a moderate number of false positive. 32 | */ 33 | public class FindbugsSecurityMinimalProfile implements BuiltInQualityProfilesDefinition { 34 | 35 | public static final String FINDBUGS_SECURITY_AUDIT_PROFILE_NAME = "FindBugs Security Minimal"; 36 | private final FindbugsProfileImporter importer; 37 | 38 | public FindbugsSecurityMinimalProfile(FindbugsProfileImporter importer) { 39 | this.importer = importer; 40 | } 41 | 42 | @Override 43 | public void define(Context context) { 44 | Reader findbugsProfile = new InputStreamReader(this.getClass().getResourceAsStream( 45 | "/org/sonar/plugins/findbugs/profile-findbugs-security-minimal.xml")); 46 | NewBuiltInQualityProfile profile = context.createBuiltInQualityProfile(FINDBUGS_SECURITY_AUDIT_PROFILE_NAME, Java.KEY); 47 | importer.importProfile(findbugsProfile, profile); 48 | 49 | profile.done(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/test/java/org/sonar/plugins/findbugs/resource/JspUtils.java: -------------------------------------------------------------------------------- 1 | package org.sonar.plugins.findbugs.resource; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | 6 | public class JspUtils { 7 | private static final List javaKeywords = Arrays.asList("abstract", "assert", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "default", "do", "double", "else", "enum", "extends", "final", "finally", "float", "for", "goto", "if", "implements", "import", "instanceof", "int", "interface", "long", "native", "new", "package", "private", "protected", "public", "return", "short", "static", "strictfp", "super", "switch", "synchronized", "this", "throw", "throws", "transient", "try", "void", "volatile", "while"); 8 | 9 | public static final String makeJavaPackage(String path) 10 | { 11 | String[] classNameComponents = path.split("/"); 12 | StringBuilder legalClassNames = new StringBuilder(); 13 | for (int i = 0; i < classNameComponents.length; i++) 14 | { 15 | legalClassNames.append(makeJavaIdentifier(classNameComponents[i])); 16 | if (i < classNameComponents.length - 1) { 17 | legalClassNames.append('.'); 18 | } 19 | } 20 | return legalClassNames.toString(); 21 | } 22 | 23 | private static final String makeJavaIdentifier(String identifier) 24 | { 25 | boolean periodToUnderscore = true; 26 | StringBuilder modifiedIdentifier = new StringBuilder(identifier.length()); 27 | if (!Character.isJavaIdentifierStart(identifier.charAt(0))) { 28 | modifiedIdentifier.append('_'); 29 | } 30 | for (int i = 0; i < identifier.length(); i++) 31 | { 32 | char ch = identifier.charAt(i); 33 | if ((Character.isJavaIdentifierPart(ch)) && ((ch != '_') || (!periodToUnderscore))) { 34 | modifiedIdentifier.append(ch); 35 | } else if ((ch == '.') && (periodToUnderscore)) { 36 | modifiedIdentifier.append('_'); 37 | } else { 38 | modifiedIdentifier.append(JasperUtils.mangleChar(ch)); 39 | } 40 | } 41 | if (isJavaKeyword(modifiedIdentifier.toString())) { 42 | modifiedIdentifier.append('_'); 43 | } 44 | return modifiedIdentifier.toString(); 45 | } 46 | 47 | 48 | public static boolean isJavaKeyword(String key) 49 | { 50 | return javaKeywords.contains(key); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/plugins/findbugs/classpath/DefaultClasspathLocator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * Copyright (C) 2012 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | package org.sonar.plugins.findbugs.classpath; 21 | 22 | import java.io.File; 23 | import java.util.Collection; 24 | 25 | import org.sonar.api.batch.ScannerSide; 26 | import org.sonar.api.batch.fs.FileSystem; 27 | import org.sonar.api.config.Configuration; 28 | import org.sonar.java.classpath.ClasspathForMain; 29 | import org.sonar.java.classpath.ClasspathForTest; 30 | 31 | /** 32 | * @author gtoison 33 | * 34 | */ 35 | @ScannerSide 36 | public class DefaultClasspathLocator implements ClasspathLocator { 37 | private final ClasspathForMain classpathForMain; 38 | private final ClasspathForTest classpathForTest; 39 | 40 | public DefaultClasspathLocator(Configuration configuration, FileSystem fileSystem) { 41 | classpathForMain = new ClasspathForMain(configuration, fileSystem); 42 | classpathForTest = new ClasspathForTest(configuration, fileSystem); 43 | } 44 | 45 | @Override 46 | public Collection binaryDirs() { 47 | return classpathForMain.getBinaryDirs(); 48 | } 49 | 50 | @Override 51 | public Collection classpath() { 52 | return classpathForMain.getElements(); 53 | } 54 | 55 | @Override 56 | public Collection testBinaryDirs() { 57 | return classpathForTest.getBinaryDirs(); 58 | } 59 | 60 | @Override 61 | public Collection testClasspath() { 62 | return classpathForTest.getElements(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/test/java/org/sonar/plugins/findbugs/rule/SimpleActiveRule.java: -------------------------------------------------------------------------------- 1 | package org.sonar.plugins.findbugs.rule; 2 | 3 | import org.sonar.api.batch.rule.ActiveRule; 4 | import org.sonar.api.rule.RuleKey; 5 | import org.sonar.api.rule.Severity; 6 | import org.sonar.api.rules.Rule; 7 | import org.sonar.api.rules.RuleParam; 8 | 9 | import java.util.HashMap; 10 | import java.util.Map; 11 | 12 | /** 13 | * Use for testing purpose only. It wrap a {@link Rule} instance and expose the {@link ActiveRule} interface. 14 | */ 15 | public class SimpleActiveRule implements ActiveRule { 16 | 17 | private final RuleKey ruleKey; 18 | private final String severity; 19 | private final String internalKey; 20 | private final String language; 21 | private final String templateRuleKey; 22 | private final Map params = new HashMap<>(); 23 | 24 | public SimpleActiveRule(Rule rule) { 25 | 26 | this.severity = rule.getSeverity() != null ? rule.getSeverity().name() : Severity.INFO; 27 | this.internalKey = rule.getRepositoryKey(); 28 | this.templateRuleKey = rule.getTemplate() != null ? rule.getTemplate().getKey() : ""; 29 | this.ruleKey = RuleKey.of(rule.getRepositoryKey(), rule.getKey()); 30 | this.language = rule.getLanguage(); 31 | if (rule.getParams() != null) { 32 | for (RuleParam param : rule.getParams()) { 33 | params.put(param.getKey(), param.getDescription()); 34 | } 35 | } 36 | } 37 | 38 | @Override 39 | public RuleKey ruleKey() { 40 | return ruleKey; 41 | } 42 | 43 | @Override 44 | public String severity() { 45 | return severity; 46 | } 47 | 48 | @Override 49 | public String language() { 50 | return language; 51 | } 52 | 53 | @Override 54 | public String param(String key) { 55 | return key; 56 | } 57 | 58 | @Override 59 | public Map params() { 60 | return params; 61 | } 62 | 63 | @Override 64 | public String internalKey() { 65 | return internalKey; 66 | } 67 | 68 | @Override 69 | public String templateRuleKey() { 70 | return templateRuleKey; 71 | } 72 | 73 | /** 74 | * Key of the quality profile the rule belongs to. To compile with SonarQube 7.4 and older, we do not annotate this method with {@code @Override} for now. 75 | */ 76 | public String qpKey() { 77 | return "quality-profile-key"; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/test/java/org/sonar/plugins/findbugs/FbContribRulesDefinitionTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * Copyright (C) 2012 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | package org.sonar.plugins.findbugs; 21 | 22 | import org.junit.jupiter.api.Test; 23 | import org.sonar.api.server.rule.RulesDefinition; 24 | import org.sonar.api.server.rule.RulesDefinition.Rule; 25 | import org.sonar.plugins.findbugs.rules.FbContribRulesDefinition; 26 | import org.sonar.plugins.java.Java; 27 | 28 | import java.util.List; 29 | 30 | import static org.assertj.core.api.Assertions.assertThat; 31 | 32 | class FbContribRulesDefinitionTest { 33 | 34 | @Test 35 | void test() { 36 | FbContribRulesDefinition definition = new FbContribRulesDefinition(); 37 | RulesDefinition.Context context = new RulesDefinition.Context(); 38 | definition.define(context); 39 | RulesDefinition.Repository repository = context.repository(FbContribRulesDefinition.REPOSITORY_KEY); 40 | 41 | assertThat(repository.name()).isEqualTo(FbContribRulesDefinition.REPOSITORY_NAME); 42 | assertThat(repository.language()).isEqualTo(Java.KEY); 43 | 44 | List rules = repository.rules(); 45 | assertThat(rules).hasSize(FbContribRulesDefinition.RULE_COUNT + FbContribRulesDefinition.DEACTIVED_RULE_COUNT); 46 | 47 | for (Rule rule : rules) { 48 | assertThat(rule.key()).isNotNull(); 49 | assertThat(rule.internalKey()).isEqualTo(rule.key()); 50 | assertThat(rule.name()).isNotNull(); 51 | assertThat(rule.htmlDescription()).isNotNull(); 52 | } 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/test/java/org/sonar/plugins/findbugs/FindSecurityBugsRulesDefinitionTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * Copyright (C) 2012 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | package org.sonar.plugins.findbugs; 21 | 22 | import org.junit.jupiter.api.Test; 23 | import org.sonar.api.server.rule.RulesDefinition; 24 | import org.sonar.api.server.rule.RulesDefinition.Rule; 25 | import org.sonar.plugins.findbugs.rules.FindSecurityBugsRulesDefinition; 26 | import org.sonar.plugins.java.Java; 27 | 28 | import java.util.List; 29 | 30 | import static org.assertj.core.api.Assertions.assertThat; 31 | 32 | class FindSecurityBugsRulesDefinitionTest { 33 | 34 | @Test 35 | void testLoadRepositoryFromXml() { 36 | FindSecurityBugsRulesDefinition definition = new FindSecurityBugsRulesDefinition(); 37 | RulesDefinition.Context context = new RulesDefinition.Context(); 38 | definition.define(context); 39 | RulesDefinition.Repository repository = context.repository(FindSecurityBugsRulesDefinition.REPOSITORY_KEY); 40 | 41 | assertThat(repository.name()).isEqualTo(FindSecurityBugsRulesDefinition.REPOSITORY_NAME); 42 | assertThat(repository.language()).isEqualTo(Java.KEY); 43 | 44 | List rules = repository.rules(); 45 | assertThat(rules).hasSize(FindSecurityBugsRulesDefinition.RULE_COUNT); 46 | 47 | for (Rule rule : rules) { 48 | assertThat(rule.key()).isNotNull(); 49 | assertThat(rule.internalKey()).isEqualTo(rule.key()); 50 | assertThat(rule.name()).isNotNull(); 51 | assertThat(rule.htmlDescription()).isNotNull(); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/plugins/findbugs/rules/FindbugsRulesDefinition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * Copyright (C) 2012 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | package org.sonar.plugins.findbugs.rules; 21 | 22 | import org.sonar.api.server.rule.RulesDefinition; 23 | import org.sonar.api.server.rule.RulesDefinitionXmlLoader; 24 | import org.sonar.plugins.java.Java; 25 | 26 | public final class FindbugsRulesDefinition implements RulesDefinition { 27 | 28 | public static final String REPOSITORY_KEY = "findbugs"; 29 | public static final String REPOSITORY_NAME = "FindBugs"; 30 | public static final int RULE_COUNT = 492; 31 | public static final int DEACTIVED_RULE_COUNT = 5; 32 | 33 | @Override 34 | public void define(Context context) { 35 | NewRepository repository = context 36 | .createRepository(REPOSITORY_KEY, Java.KEY) 37 | .setName(REPOSITORY_NAME); 38 | 39 | 40 | RulesDefinitionXmlLoader ruleLoaderJsp = new RulesDefinitionXmlLoader(); 41 | ruleLoaderJsp.load(repository, FindSecurityBugsRulesDefinition.class.getResourceAsStream("/org/sonar/plugins/findbugs/rules-findbugs.xml"), "UTF-8"); 42 | repository.done(); 43 | 44 | // RulesDefinitionXmlLoader ruleLoader = new RulesDefinitionXmlLoader(); 45 | // ruleLoader.load(repository, FindbugsRulesDefinition.class.getResourceAsStream("/org/sonar/plugins/findbugs/rules.xml"), "UTF-8"); 46 | // ExternalDescriptionLoader.loadHtmlDescriptions(repository, "/org/sonar/l10n/findbugs/rules/findbugs"); 47 | // SqaleXmlLoader.load(repository, "/com/sonar/sqale/findbugs-model.xml"); 48 | // repository.done(); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/multi-module-groovy/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | spotbugs 5 | multi-module 6 | 0.0.1-SNAPSHOT 7 | 8 | multi-module-groovy 9 | jar 10 | 11 | 12 | UTF-8 13 | 2.5.16 14 | 15 | 16 | 17 | 18 | 19 | 20 | maven-compiler-plugin 21 | 3.5.1 22 | 23 | 1.8 24 | 1.8 25 | 26 | 27 | 28 | 29 | org.codehaus.gmavenplus 30 | gmavenplus-plugin 31 | 1.13.1 32 | 33 | 34 | 35 | execute 36 | addSources 37 | addTestSources 38 | generateStubs 39 | compile 40 | generateTestStubs 41 | compileTests 42 | removeStubs 43 | removeTestStubs 44 | 45 | 46 | 47 | 48 | 49 | org.codehaus.groovy 50 | groovy-all 51 | ${groovy.version} 52 | runtime 53 | pom 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | spotbugs 63 | multi-module-core 64 | 0.0.1-SNAPSHOT 65 | 66 | 67 | 68 | org.codehaus.groovy 69 | groovy-all 70 | ${groovy.version} 71 | pom 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/plugins/findbugs/resource/DebugExtensionExtractor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * Copyright (C) 2012 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | package org.sonar.plugins.findbugs.resource; 21 | 22 | import edu.umd.cs.findbugs.classfile.engine.asm.FindBugsASM; 23 | 24 | import org.objectweb.asm.ClassReader; 25 | import org.objectweb.asm.ClassVisitor; 26 | 27 | import javax.annotation.Nullable; 28 | import java.io.IOException; 29 | import java.io.InputStream; 30 | 31 | /** 32 | * Load SourceDebugExtension section from class file. 33 | * 34 | * SourceDebugExtension is use to store optionally the line of code mapping. 35 | * The code content if not empty is must likely format according to JSR45 (SMAP). 36 | */ 37 | public class DebugExtensionExtractor { 38 | 39 | @Nullable 40 | public String getDebugExtFromClass(InputStream classIn) throws IOException { 41 | 42 | AbstractClassVisitor visitor = new AbstractClassVisitor(); 43 | try { 44 | ClassReader classReader = new ClassReader(classIn); 45 | classReader.accept(visitor, 0); 46 | 47 | return visitor.debug; 48 | } 49 | catch (Exception e) { 50 | throw new ClassMetadataLoadingException(e); 51 | } 52 | } 53 | 54 | private static class AbstractClassVisitor extends ClassVisitor { 55 | protected String debug; 56 | 57 | public AbstractClassVisitor() { 58 | super(FindBugsASM.ASM_VERSION); 59 | } 60 | 61 | @Override 62 | public void visitSource(String source, String debug) { 63 | super.visitSource(source, debug); 64 | 65 | this.debug = debug; 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/test/resources/projects/jspc-jetty/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | org.sonar.tests 4 | jspc-jetty 5 | 0.1-SNAPSHOT 6 | war 7 | Sonar tests - JSPC Jetty sample 8 | 9 | 10 | UTF-8 11 | 12 | 13 | 14 | src 15 | 16 | 17 | org.apache.maven.plugins 18 | maven-compiler-plugin 19 | 3.8.1 20 | 21 | 7 22 | 7 23 | 24 | 25 | 26 | 27 | org.eclipse.jetty 28 | jetty-jspc-maven-plugin 29 | 9.4.44.v20210927 30 | 31 | 32 | 33 | jspc 34 | 35 | 36 | 37 | 38 | 1.8 39 | 1.8 40 | true 41 | 42 | false 43 | true 44 | 45 | 46 | 47 | 48 | 49 | org.apache.maven.plugins 50 | maven-war-plugin 51 | 3.3.2 52 | 53 | 54 | 55 | 56 | 57 | 58 | javax.servlet 59 | javax.servlet-api 60 | 4.0.1 61 | provided 62 | 63 | 64 | javax.servlet.jsp 65 | javax.servlet.jsp-api 66 | 2.3.3 67 | provided 68 | 69 | 70 | org.apache.sling 71 | org.apache.sling.scripting.jsp 72 | 2.5.4 73 | provided 74 | 75 | 76 | 77 | javax.servlet 78 | jstl 79 | 1.2 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /src/test/java/org/sonar/plugins/findbugs/profiles/FindbugsScalaProfileTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube SpotBugs Plugin 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 17 | */ 18 | package org.sonar.plugins.findbugs.profiles; 19 | 20 | import static org.assertj.core.api.Assertions.assertThat; 21 | 22 | import org.junit.jupiter.api.Test; 23 | import org.junit.jupiter.api.extension.RegisterExtension; 24 | import org.slf4j.event.Level; 25 | import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition.BuiltInQualityProfile; 26 | import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition.Context; 27 | import org.sonar.api.testfixtures.log.LogTesterJUnit5; 28 | import org.sonar.plugins.findbugs.FindbugsProfileImporter; 29 | import org.sonar.plugins.findbugs.language.scala.Scala; 30 | import org.sonar.plugins.findbugs.rule.FakeRuleFinder; 31 | import org.sonar.plugins.findbugs.rules.FindSecurityBugsScalaRulesDefinition; 32 | 33 | class FindbugsScalaProfileTest { 34 | 35 | @RegisterExtension 36 | public LogTesterJUnit5 logTester = new LogTesterJUnit5(); 37 | 38 | @Test 39 | void shouldCreateProfile() { 40 | FindbugsProfileImporter importer = new FindbugsProfileImporter(FakeRuleFinder.createWithAllRules()); 41 | FindbugsSecurityScalaProfile findbugsProfile = new FindbugsSecurityScalaProfile(importer); 42 | Context context = new Context(); 43 | findbugsProfile.define(context); 44 | 45 | BuiltInQualityProfile profile = context.profile(Scala.KEY, FindbugsSecurityScalaProfile.FINDBUGS_SECURITY_SCALA_PROFILE_NAME); 46 | assertThat(profile.rules()).hasSize(FindSecurityBugsScalaRulesDefinition.RULE_COUNT); 47 | assertThat(profile.rules().stream().filter(r -> r.repoKey().equals(FindSecurityBugsScalaRulesDefinition.REPOSITORY_KEY)).count()).isEqualTo(FindSecurityBugsScalaRulesDefinition.RULE_COUNT); 48 | assertThat(logTester.getLogs(Level.ERROR)).isEmpty(); 49 | 50 | FindbugsProfileTest.assertHasOnlyRulesForLanguage(profile.rules(), Scala.KEY); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /generate_profiles/README.md: -------------------------------------------------------------------------------- 1 | # XML files generation 2 | 3 | This set of Groovy scripts generate all the XML files for the descriptions and the profiles. 4 | All the descriptions are already present in the `messages.xml`/`findbugs.xml` of each respective plugins. This script convert the description to SonarQube file formats. 5 | 6 | 7 | ## Running the script 8 | 9 | ``` 10 | $ groovy BuildXmlFiles.groovy 11 | 12 | Building ruleset findbugs (C:\Code\workspace-java\sonar-findbugs\generate_profiles\out_sonar\rules-findbugs.xml) 13 | Building ruleset findsecbugs (C:\Code\workspace-java\sonar-findbugs\generate_profiles\out_sonar\rules-findsecbugs.xml) 14 | Building ruleset jsp (C:\Code\workspace-java\sonar-findbugs\generate_profiles\out_sonar\rules-jsp.xml) 15 | Building ruleset fbcontrib (C:\Code\workspace-java\sonar-findbugs\generate_profiles\out_sonar\rules-fbcontrib.xml) 16 | Building profile findbugs-only (C:\Code\workspace-java\sonar-findbugs\generate_profiles\out_sonar\profile-findbugs-only.xml) 17 | Building profile findbugs-and-fb-contrib (C:\Code\workspace-java\sonar-findbugs\generate_profiles\out_sonar\profile-findbugs-and-fb-contrib.xml) 18 | Building profile findbugs-security-audit (C:\Code\workspace-java\sonar-findbugs\generate_profiles\out_sonar\profile-findbugs-security-audit.xml) 19 | Building profile findbugs-security-minimal (C:\Code\workspace-java\sonar-findbugs\generate_profiles\out_sonar\profile-findbugs-security-minimal.xml) 20 | Building profile findbugs-security-jsp (C:\Code\workspace-java\sonar-findbugs\generate_profiles\out_sonar\profile-findbugs-security-jsp.xml) 21 | Total bugs patterns 820 22 | ``` 23 | 24 | The generated XML files will be place in `src/main/resources/org/sonar/plugins/findbugs` automatically. 25 | Prior committing the new rules, please review with a diff of the changes. 26 | - Make sure you are not removing rules by mistake. 27 | - Make sure you are not changing the indent of the entire files, new line to carriage return, etc. 28 | 29 | ## Update the plugin 30 | 31 | To update the description of a specific plugin, you must edit the script at two places before running it. 32 | 33 | ```groovy 34 | @Grapes([ 35 | @Grab(group='com.github.spotbugs', module='spotbugs', version='3.1.0'), 36 | @Grab(group='com.mebigfatguy.fb-contrib', module='fb-contrib', version='7.0.0'), 37 | @Grab(group='com.h3xstream.findsecbugs' , module='findsecbugs-plugin', version='1.6.0')] 38 | ) 39 | [...] 40 | FB = new Plugin(groupId: 'com.github.spotbugs', artifactId: 'spotbugs', version: '3.1.0') 41 | CONTRIB = new Plugin(groupId: 'com.mebigfatguy.fb-contrib', artifactId: 'fb-contrib', version: '7.0.0') 42 | FSB = new Plugin(groupId: 'com.h3xstream.findsecbugs', artifactId: 'findsecbugs-plugin', version: '1.6.0') 43 | 44 | ``` 45 | -------------------------------------------------------------------------------- /src/test/java/org/sonar/plugins/findbugs/FindbugsTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * Copyright (C) 2012 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | package org.sonar.plugins.findbugs; 21 | 22 | import java.io.File; 23 | import java.io.FileReader; 24 | import java.io.IOException; 25 | import java.io.Reader; 26 | import java.util.ArrayList; 27 | import java.util.List; 28 | import org.apache.commons.lang3.CharUtils; 29 | import org.custommonkey.xmlunit.Diff; 30 | import org.custommonkey.xmlunit.XMLUnit; 31 | import org.junit.jupiter.api.Assertions; 32 | import org.sonar.api.rules.Rule; 33 | import org.sonar.plugins.findbugs.rules.FindbugsRulesDefinition; 34 | import org.sonar.plugins.findbugs.util.TestUtils; 35 | import org.xml.sax.SAXException; 36 | 37 | public abstract class FindbugsTests { 38 | 39 | protected void assertXmlAreSimilar(String actualContent, String expectedFileName) throws SAXException, IOException { 40 | File expectedContent = TestUtils.getResource("/org/sonar/plugins/findbugs/" + expectedFileName); 41 | assertSimilarXml(expectedContent, actualContent); 42 | } 43 | 44 | protected List buildRulesFixture() { 45 | List rules = new ArrayList(); 46 | 47 | Rule rule1 = Rule.create(FindbugsRulesDefinition.REPOSITORY_KEY, "DLS_DEAD_LOCAL_STORE", "DLS: Dead store to local variable"); 48 | Rule rule2 = Rule.create(FindbugsRulesDefinition.REPOSITORY_KEY, "URF_UNREAD_FIELD", "UrF: Unread field"); 49 | 50 | rules.add(rule1); 51 | rules.add(rule2); 52 | 53 | return rules; 54 | } 55 | 56 | private void assertSimilarXml(File expectedFile, String xml) throws SAXException, IOException { 57 | XMLUnit.setIgnoreWhitespace(true); 58 | Reader reader = new FileReader(expectedFile); 59 | Diff diff = XMLUnit.compareXML(reader, xml); 60 | String message = "Diff: " + diff.toString() + CharUtils.LF + "XML: " + xml; 61 | Assertions.assertTrue(diff.similar(), message); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/plugins/findbugs/rules/FindSecurityBugsJspRulesDefinition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * Copyright (C) 2012 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | package org.sonar.plugins.findbugs.rules; 21 | 22 | import org.sonar.api.server.rule.RulesDefinition; 23 | import org.sonar.api.server.rule.RulesDefinitionXmlLoader; 24 | import org.sonar.plugins.findbugs.language.Jsp; 25 | 26 | /** 27 | * This RulesDefinition build a separate repository from the FindSecurityBugsRulesDefinition to allow a separate ruleset 28 | * for JSP language. 29 | * @see FindSecurityBugsRulesDefinition 30 | */ 31 | public class FindSecurityBugsJspRulesDefinition implements RulesDefinition { 32 | 33 | public static final String REPOSITORY_KEY = "findsecbugs-jsp"; 34 | public static final String REPOSITORY_JSP_NAME = "Find Security Bugs (JSP)"; 35 | 36 | @Override 37 | public void define(Context context) { 38 | NewRepository repositoryJsp = context 39 | .createRepository(REPOSITORY_KEY, Jsp.KEY) 40 | .setName(REPOSITORY_JSP_NAME); 41 | 42 | RulesDefinitionXmlLoader ruleLoaderJsp = new RulesDefinitionXmlLoader(); 43 | ruleLoaderJsp.load(repositoryJsp, FindSecurityBugsRulesDefinition.class.getResourceAsStream("/org/sonar/plugins/findbugs/rules-jsp.xml"), "UTF-8"); 44 | 45 | addDeprecatedRuleKeys(repositoryJsp); 46 | 47 | repositoryJsp.done(); 48 | } 49 | 50 | public void addDeprecatedRuleKeys(NewRepository repositoryJsp) { 51 | String[] rulesMovedFromFindSecurityBugs = new String[] { 52 | "XSS_JSP_PRINT", 53 | "XSS_REQUEST_PARAMETER_TO_JSP_WRITER" 54 | }; 55 | 56 | for (String key : rulesMovedFromFindSecurityBugs) { 57 | NewRule rule = repositoryJsp.rule(key); 58 | if (rule != null) { 59 | rule.addDeprecatedRuleKey(FindSecurityBugsRulesDefinition.REPOSITORY_KEY, key); 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/multi-module-clojure/src/main/clojure/com/bugs/ClojureSample.clj: -------------------------------------------------------------------------------- 1 | (ns com.bugs.ClojureSample 2 | (:import (java.awt Color Container Graphics Canvas Dimension) 3 | (javax.swing JPanel JFrame) 4 | (java.awt.image BufferedImage BufferStrategy)) 5 | (:gen-class)) 6 | 7 | (set! *warn-on-reflection* true) 8 | 9 | (def width (float 640)) 10 | (def height (float 640)) 11 | (def max-steps (float 64)) 12 | (def color-scale (float (quot 255 max-steps))) 13 | (def height-factor (/ 2.5 height)) 14 | (def width-factor (/ 2.5 width)) 15 | (def bailout (float 4.0)) 16 | 17 | (defn on-thread [^Runnable f] (.start (new Thread f))) 18 | 19 | (defn check-bounds [cr ci] 20 | (loop [i (int 1) 21 | zi (float 0.0) 22 | zr (float 0.0)] 23 | 24 | (let [zr2 (float (* zr zr)) 25 | zi2 (float (* zi zi)) 26 | temp (float (* zr zi))] 27 | (cond 28 | (> (float (+ zi2 zr2)) bailout) i 29 | 30 | (> i max-steps) 0 31 | 32 | :default (recur (inc i) 33 | (float (+ (+ temp temp) ci)) 34 | (float (+ (- zr2 zi2) cr))))))) 35 | 36 | (defn draw-line [^Graphics g y] 37 | (let [dy (float (- 1.25 (* y height-factor)))] 38 | (doseq [x (range 0 width)] 39 | (let [dx (float (- (* x width-factor) (float 2.0)))] 40 | 41 | (let [value (check-bounds dx dy) 42 | scaled (Math/round (float (* value color-scale))) 43 | xscaled (Math/round (float (* x (/ 255 width))))] 44 | 45 | (if (> value 0) 46 | (.setColor g (new Color 255 (- 255 scaled) scaled)) 47 | (.setColor g (new Color xscaled (- 255 xscaled) xscaled))) 48 | 49 | (.drawRect g x y 0 0)))))) 50 | 51 | (defn draw-lines 52 | ([buffer g] (draw-lines buffer g height)) 53 | ([^BufferStrategy buffer g y] 54 | (doseq [y (range y)] 55 | (on-thread (draw-line g y)) 56 | (.show buffer)))) 57 | 58 | (defn draw [^Canvas canvas] 59 | (let [buffer (.getBufferStrategy canvas) 60 | g (.getDrawGraphics buffer)] 61 | (draw-lines buffer g))) 62 | 63 | (defn -main [] 64 | (let [panel (new JPanel) 65 | canvas (new Canvas) 66 | frame (new JFrame "Mandelbrot")] 67 | 68 | (doto panel 69 | (.setPreferredSize (new Dimension width height)) 70 | (.setLayout nil) 71 | (.add canvas)) 72 | 73 | (doto frame 74 | (.setDefaultCloseOperation JFrame/EXIT_ON_CLOSE) 75 | (.setBounds 0 0 width height) 76 | (.setResizable false) 77 | (.add panel) 78 | (.setVisible true)) 79 | 80 | (doto canvas 81 | (.setBounds 0 0 width height) 82 | (.setBackground (Color/BLACK)) 83 | (.createBufferStrategy 2) 84 | (.requestFocus)) 85 | 86 | (draw canvas))) 87 | 88 | 89 | -------------------------------------------------------------------------------- /src/test/java/org/sonar/plugins/findbugs/it/ScalaIT.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube SpotBugs Plugin 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 17 | */ 18 | package org.sonar.plugins.findbugs.it; 19 | 20 | import static org.assertj.core.api.Assertions.assertThat; 21 | 22 | import java.util.List; 23 | 24 | import org.junit.jupiter.api.AfterEach; 25 | import org.junit.jupiter.api.BeforeEach; 26 | import org.junit.jupiter.api.Test; 27 | import org.sonar.plugins.findbugs.profiles.FindbugsSecurityScalaProfile; 28 | import org.sonarqube.ws.Issues.Issue; 29 | import org.sonarqube.ws.client.issues.IssuesService; 30 | 31 | import com.sonar.orchestrator.build.MavenBuild; 32 | import com.sonar.orchestrator.junit5.OrchestratorExtension; 33 | 34 | @IntegrationTest 35 | class ScalaIT { 36 | 37 | private static final String PROJECT_KEY = "org.sonar.tests:scala"; 38 | public static OrchestratorExtension orchestrator = FindbugsTestSuite.ORCHESTRATOR; 39 | 40 | @BeforeEach 41 | public void setupProfile() { 42 | FindbugsTestSuite.setupProjectAndProfile(PROJECT_KEY, "Scala Integration Tests", "IT", "java"); 43 | FindbugsTestSuite.setupProfile(PROJECT_KEY, FindbugsSecurityScalaProfile.FINDBUGS_SECURITY_SCALA_PROFILE_NAME, "scala"); 44 | } 45 | 46 | @AfterEach 47 | public void deleteProject() { 48 | FindbugsTestSuite.deleteProject(PROJECT_KEY); 49 | } 50 | 51 | @Test 52 | void test() throws Exception { 53 | MavenBuild build = MavenBuild.create() 54 | .setPom(FindbugsTestSuite.projectPom("scala")) 55 | .setProperty("sonar.dynamicAnalysis", "false") 56 | .setProperty("sonar.findbugs.confidenceLevel", "low") 57 | //.setProperty("sonar.sources", "src/main/scala") 58 | //.setProperty("sonar.java.binaries", "target/classes") 59 | .setGoals("clean package sonar:sonar"); 60 | orchestrator.executeBuild(build); 61 | 62 | IssuesService issueClient = FindbugsTestSuite.issueClient(); 63 | List issues = issueClient.search(IssueQuery.create().projects(PROJECT_KEY)).getIssuesList(); 64 | assertThat(issues).hasSize(2); 65 | assertThat(issues.get(0).getMessage()).isEqualTo("Hello$.main(String[]) invokes toString() method on a String"); 66 | assertThat(issues.get(1).getMessage()).isEqualTo("This Scala random generator (scala.util.Random.nextInt()) is predictable"); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/test/java/org/sonar/plugins/findbugs/rule/FakeActiveRules.java: -------------------------------------------------------------------------------- 1 | package org.sonar.plugins.findbugs.rule; 2 | 3 | import org.sonar.api.batch.rule.ActiveRule; 4 | import org.sonar.api.batch.rule.ActiveRules; 5 | import org.sonar.api.rule.RuleKey; 6 | import org.sonar.api.rules.Rule; 7 | import org.sonar.api.rules.RuleFinder; 8 | import org.sonar.api.rules.RuleQuery; 9 | 10 | import java.util.ArrayList; 11 | import java.util.Collection; 12 | import java.util.List; 13 | 14 | /** 15 | * {@link ActiveRules} is the future API for doing lookup to find rules. It has similar operations as {@link RuleFinder}. 16 | * As long as {@link RuleFinder}, we can wrap the same mock {@link FakeRuleFinder} to create the behavior of a basic 17 | * repository. 18 | */ 19 | public class FakeActiveRules { 20 | 21 | public static ActiveRules createWithOnlyFindbugsRules() { 22 | return new ActiveRulesMock(FakeRuleFinder.createWithOnlyFindbugsRules()); 23 | } 24 | 25 | public static ActiveRules createWithOnlyFbContribRules() { 26 | return new ActiveRulesMock(FakeRuleFinder.createWithOnlyFbContribRules()); 27 | } 28 | 29 | public static ActiveRules createWithOnlyFindSecBugsRules() { 30 | return new ActiveRulesMock(FakeRuleFinder.createWithOnlyFindSecBugsRules()); 31 | } 32 | 33 | public static ActiveRules createWithOnlyFindSecBugsJspRules() { 34 | return new ActiveRulesMock(FakeRuleFinder.createWithOnlyFindSecBugsJspRules()); 35 | } 36 | 37 | public static ActiveRules createWithNoRules() { 38 | return new ActiveRulesMock(FakeRuleFinder.createWithNoRules()); 39 | } 40 | 41 | public static class ActiveRulesMock implements ActiveRules { 42 | private RuleFinder ruleFinder; 43 | 44 | public ActiveRulesMock(RuleFinder ruleFinder) { 45 | this.ruleFinder = ruleFinder; 46 | } 47 | 48 | @Override 49 | public ActiveRule find(RuleKey ruleKey) { 50 | Rule r = ruleFinder.findByKey(ruleKey); 51 | if (r == null) return null; 52 | return new SimpleActiveRule(r); 53 | } 54 | 55 | @Override 56 | public Collection findAll() { 57 | return transformRules(ruleFinder.findAll(RuleQuery.create())); 58 | } 59 | 60 | @Override 61 | public Collection findByRepository(String repository) { 62 | return transformRules(ruleFinder.findAll(RuleQuery.create().withRepositoryKey(repository))); 63 | } 64 | 65 | @Override 66 | public Collection findByLanguage(String language) { 67 | return transformRules(ruleFinder.findAll(RuleQuery.create())); 68 | } 69 | 70 | @Override 71 | public ActiveRule findByInternalKey(String repository, String internalKey) { 72 | Rule r = ruleFinder.findByKey(repository, internalKey); 73 | if (r == null) return null; 74 | return new SimpleActiveRule(r); 75 | } 76 | 77 | public Collection transformRules(Collection all) { 78 | List newList = new ArrayList<>(); 79 | for (Rule r : all) { 80 | newList.add(new SimpleActiveRule(r)); 81 | } 82 | return newList; 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/plugins/findbugs/ReportedBug.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * Copyright (C) 2012 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | package org.sonar.plugins.findbugs; 21 | 22 | import edu.umd.cs.findbugs.BugInstance; 23 | 24 | import java.util.regex.Matcher; 25 | import java.util.regex.Pattern; 26 | 27 | public class ReportedBug { 28 | 29 | private final String type; 30 | private final String message; 31 | private final String className; 32 | private final int startLine; 33 | private final String sourceFile; 34 | private final String classFile; 35 | 36 | private static final Pattern SOURCE_FILE_PATTERN = createSourceFilePattern(); 37 | 38 | public ReportedBug(BugInstance bugInstance) { 39 | this.type = bugInstance.getType(); 40 | this.message = bugInstance.getMessageWithoutPrefix(); 41 | this.className = bugInstance.getPrimarySourceLineAnnotation().getClassName(); 42 | this.startLine = bugInstance.getPrimarySourceLineAnnotation().getStartLine(); 43 | this.sourceFile = bugInstance.getPrimarySourceLineAnnotation().getSourcePath(); 44 | Matcher m = SOURCE_FILE_PATTERN.matcher(sourceFile); 45 | if (m.find()) { 46 | this.classFile = m.group(1).replace("/","."); 47 | } 48 | else { 49 | this.classFile = className; 50 | } 51 | } 52 | 53 | public String getType() { 54 | return type; 55 | } 56 | 57 | public String getMessage() { 58 | return message; 59 | } 60 | 61 | public String getClassName() { 62 | return className; 63 | } 64 | 65 | public int getStartLine() { 66 | return startLine; 67 | } 68 | 69 | public String getSourceFile() { return sourceFile; } 70 | 71 | public String getClassFile() { return classFile; } 72 | 73 | private static Pattern createSourceFilePattern() { 74 | StringBuffer extensions = new StringBuffer(); 75 | 76 | for (int i = 0; i < FindbugsPlugin.SUPPORTED_JVM_LANGUAGES_EXTENSIONS.length; i++) { 77 | String extension = FindbugsPlugin.SUPPORTED_JVM_LANGUAGES_EXTENSIONS[i]; 78 | extensions.append(extension); 79 | if(i< FindbugsPlugin.SUPPORTED_JVM_LANGUAGES_EXTENSIONS.length - 1 ) { 80 | extensions.append("|"); 81 | } 82 | } 83 | 84 | String pattern = "^(.*)\\.(" + extensions + ")$"; 85 | return Pattern.compile(pattern); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/test/resources/projects/multi-module/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /src/test/java/org/sonar/plugins/findbugs/profiles/FindbugsSecurityAuditProfileTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * Copyright (C) 2012 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | package org.sonar.plugins.findbugs.profiles; 21 | 22 | import org.junit.jupiter.api.Test; 23 | import org.junit.jupiter.api.extension.RegisterExtension; 24 | import org.slf4j.event.Level; 25 | import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition.BuiltInQualityProfile; 26 | import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition.Context; 27 | import org.sonar.api.testfixtures.log.LogTesterJUnit5; 28 | import org.sonar.plugins.findbugs.FindbugsProfileImporter; 29 | import org.sonar.plugins.findbugs.rule.FakeRuleFinder; 30 | import org.sonar.plugins.findbugs.rules.FindSecurityBugsRulesDefinition; 31 | import org.sonar.plugins.findbugs.rules.FindbugsRulesDefinition; 32 | import org.sonar.plugins.java.Java; 33 | 34 | import static org.assertj.core.api.Assertions.assertThat; 35 | 36 | class FindbugsSecurityAuditProfileTest { 37 | 38 | @RegisterExtension 39 | public LogTesterJUnit5 logTester = new LogTesterJUnit5(); 40 | 41 | @Test 42 | void shouldCreateProfile() { 43 | FindbugsProfileImporter importer = new FindbugsProfileImporter(FakeRuleFinder.createWithAllRules()); 44 | FindbugsSecurityAuditProfile findbugsProfile = new FindbugsSecurityAuditProfile(importer); 45 | Context context = new Context(); 46 | findbugsProfile.define(context); 47 | 48 | // The standard FindBugs include only 9. Fb-Contrib and FindSecurityBugs include other rules 49 | BuiltInQualityProfile profile = context.profile(Java.KEY, FindbugsSecurityAuditProfile.FINDBUGS_SECURITY_AUDIT_PROFILE_NAME); 50 | assertThat(logTester.getLogs(Level.ERROR)).isEmpty(); 51 | // FSB rules must be added to FsbClassifier.groovy otherwise new rules metadata are not added in rules-findsecbugs.xml 52 | assertThat(logTester.getLogs(Level.WARN)).isEmpty(); 53 | assertThat(profile.rules().stream().filter(r -> r.repoKey().equals(FindbugsRulesDefinition.REPOSITORY_KEY)).count()).isEqualTo(8); 54 | assertThat(profile.rules().stream().filter(r -> r.repoKey().equals(FindSecurityBugsRulesDefinition.REPOSITORY_KEY)).count()) 55 | .isEqualTo(FindSecurityBugsRulesDefinition.RULE_COUNT); 56 | 57 | FindbugsProfileTest.assertHasOnlyRulesForLanguage(profile.rules(), Java.KEY); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/test/java/org/sonar/plugins/findbugs/profiles/FindbugsSecurityMinimalProfileTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * Copyright (C) 2012 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | package org.sonar.plugins.findbugs.profiles; 21 | 22 | import org.junit.jupiter.api.Test; 23 | import org.junit.jupiter.api.extension.RegisterExtension; 24 | import org.slf4j.event.Level; 25 | import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition.BuiltInQualityProfile; 26 | import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition.Context; 27 | import org.sonar.api.testfixtures.log.LogTesterJUnit5; 28 | import org.sonar.plugins.findbugs.FindbugsProfileImporter; 29 | import org.sonar.plugins.findbugs.rule.FakeRuleFinder; 30 | import org.sonar.plugins.findbugs.rules.FindSecurityBugsRulesDefinition; 31 | import org.sonar.plugins.findbugs.rules.FindbugsRulesDefinition; 32 | import org.sonar.plugins.java.Java; 33 | 34 | import static org.assertj.core.api.Assertions.assertThat; 35 | 36 | class FindbugsSecurityMinimalProfileTest { 37 | 38 | @RegisterExtension 39 | public LogTesterJUnit5 logTester = new LogTesterJUnit5(); 40 | 41 | @Test 42 | void shouldCreateProfile() { 43 | FindbugsProfileImporter importer = new FindbugsProfileImporter(FakeRuleFinder.createWithAllRules()); 44 | FindbugsSecurityMinimalProfile findbugsProfile = new FindbugsSecurityMinimalProfile(importer); 45 | Context context = new Context(); 46 | findbugsProfile.define(context); 47 | 48 | BuiltInQualityProfile profile = context.profile(Java.KEY, FindbugsSecurityMinimalProfile.FINDBUGS_SECURITY_AUDIT_PROFILE_NAME); 49 | assertThat(logTester.getLogs(Level.ERROR)).isEmpty(); 50 | // FSB rules must be added to FsbClassifier.groovy otherwise new rules metadata are not added in rules-findsecbugs.xml 51 | assertThat(logTester.getLogs(Level.WARN)).isEmpty(); 52 | // The standard FindBugs include only 9. Fb-Contrib and FindSecurityBugs include other rules 53 | assertThat(profile.rules().stream().filter(r -> r.repoKey().equals(FindbugsRulesDefinition.REPOSITORY_KEY)).count()).isEqualTo(8); 54 | // 94 rules total - 8 fb = 86 55 | assertThat(profile.rules().stream().filter(r -> r.repoKey().equals(FindSecurityBugsRulesDefinition.REPOSITORY_KEY)).count()).isEqualTo(99); 56 | 57 | FindbugsProfileTest.assertHasOnlyRulesForLanguage(profile.rules(), Java.KEY); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/test/resources/org/sonar/plugins/findbugs/findbugsReportWithUnknownRule.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Method may fail to clean up stream or resource 7 | Method com.exedio.csvtools.DBTool.executeUpdate(String) may fail to clean up java.sql.Statement 8 | 9 | 10 | At DBTool.java:[lines 55-338] 11 | 12 | In class com.exedio.csvtools.DBTool 13 | 14 | 15 | 16 | In method com.exedio.csvtools.DBTool.executeUpdate(String) 17 | 18 | 19 | 20 | In Statement.java 21 | 22 | Reference type java.sql.Statement 23 | 24 | 25 | 1 instances of obligation remaining 26 | 27 | 28 | Obligation to clean up resource created at DBTool.java:[line 302] is not discharged 29 | 30 | 31 | Path continues at DBTool.java:[line 303] 32 | 33 | 34 | Path continues at DBTool.java:[line 313] 35 | 36 | 37 | Remaining obligations: {Statement x 1} 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/test/java/org/sonar/plugins/findbugs/it/FBContribIT.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Findbugs :: IT :: Plugin 3 | * Copyright (C) 2014 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | package org.sonar.plugins.findbugs.it; 21 | 22 | import static org.assertj.core.api.Assertions.assertThat; 23 | 24 | import org.junit.jupiter.api.AfterEach; 25 | import org.junit.jupiter.api.BeforeEach; 26 | import org.junit.jupiter.api.Test; 27 | import org.sonarqube.ws.Issues.Issue; 28 | import org.sonarqube.ws.client.issues.IssuesService; 29 | 30 | import java.util.List; 31 | 32 | import com.sonar.orchestrator.build.MavenBuild; 33 | import com.sonar.orchestrator.junit5.OrchestratorExtension; 34 | 35 | @IntegrationTest 36 | class FBContribIT { 37 | 38 | private static final String PROJECT_KEY = "org.sonar.tests:fb-contrib"; 39 | public static OrchestratorExtension orchestrator = FindbugsTestSuite.ORCHESTRATOR; 40 | 41 | @BeforeEach 42 | public void setupProfile() { 43 | FindbugsTestSuite.setupProjectAndProfile(PROJECT_KEY, "Findbugs Contrib Integration Tests", "IT", "java"); 44 | } 45 | 46 | @AfterEach 47 | public void deleteProject() { 48 | FindbugsTestSuite.deleteProject(PROJECT_KEY); 49 | } 50 | 51 | @Test 52 | void test() throws Exception { 53 | MavenBuild build = MavenBuild.create() 54 | .setPom(FindbugsTestSuite.projectPom("simple")) 55 | .setProperty("sonar.dynamicAnalysis", "false") 56 | .setProperty("sonar.findbugs.confidenceLevel", "low") 57 | .setCleanPackageSonarGoals(); 58 | orchestrator.executeBuild(build); 59 | 60 | IssuesService issueClient = FindbugsTestSuite.issueClient(); 61 | List issues = issueClient.search(IssueQuery.create().projects(PROJECT_KEY)).getIssuesList(); 62 | assertThat(issues).hasSize(3); 63 | 64 | issues = issueClient.search(IssueQuery.create().rules("fb-contrib:IPU_IMPROPER_PROPERTIES_USE_SETPROPERTY")).getIssuesList(); 65 | // SONARJAVA-216: 66 | assertThat(issues).hasSize(1); 67 | assertThat(issues.get(0).getMessage()).isEqualTo("Method Simple.method() uses Properties.put instead of Properties.setProperty"); 68 | 69 | issues = issueClient.search(IssueQuery.create().rules("findsecbugs:PREDICTABLE_RANDOM")).getIssuesList(); 70 | assertThat(issues).hasSize(1); 71 | assertThat(issues.get(0).getMessage()).isEqualTo("This random generator (java.util.Random) is predictable"); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/test/java/org/sonar/plugins/findbugs/FindbugsRulesDefinitionTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * Copyright (C) 2012 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | package org.sonar.plugins.findbugs; 21 | 22 | import org.junit.jupiter.api.BeforeEach; 23 | import org.junit.jupiter.api.Disabled; 24 | import org.junit.jupiter.api.Test; 25 | import org.sonar.api.rule.RuleStatus; 26 | import org.sonar.api.server.rule.RulesDefinition; 27 | import org.sonar.api.server.rule.RulesDefinition.Rule; 28 | import org.sonar.plugins.findbugs.rules.FindbugsRulesDefinition; 29 | import org.sonar.plugins.java.Java; 30 | 31 | import java.util.List; 32 | 33 | import static org.assertj.core.api.Assertions.assertThat; 34 | 35 | class FindbugsRulesDefinitionTest { 36 | /** 37 | * The SpotBugs rules repository 38 | */ 39 | private RulesDefinition.Repository repository; 40 | 41 | @BeforeEach 42 | public void setupRepository() { 43 | FindbugsRulesDefinition definition = new FindbugsRulesDefinition(); 44 | RulesDefinition.Context context = new RulesDefinition.Context(); 45 | definition.define(context); 46 | 47 | repository = context.repository(FindbugsRulesDefinition.REPOSITORY_KEY); 48 | } 49 | 50 | @Test 51 | void testRepositoryRulesCount() { 52 | assertThat(repository.name()).isEqualTo(FindbugsRulesDefinition.REPOSITORY_NAME); 53 | assertThat(repository.language()).isEqualTo(Java.KEY); 54 | 55 | List rules = repository.rules(); 56 | assertThat(rules).hasSize(FindbugsRulesDefinition.RULE_COUNT + FindbugsRulesDefinition.DEACTIVED_RULE_COUNT); 57 | 58 | for (Rule rule : rules) { 59 | assertThat(rule.key()).isNotNull(); 60 | assertThat(rule.internalKey()).isEqualTo(rule.key()); 61 | assertThat(rule.name()).isNotNull(); 62 | assertThat(rule.htmlDescription()).isNotNull(); 63 | } 64 | } 65 | 66 | /** 67 | * Rule TLW_TWO_LOCK_NOTIFY was marked deprecated in Spotbugs so we're testing that the SonarQube rule status is updated accordingly 68 | * 69 | * In case that rule is removed in a future release, this unit test will need to be updated to test against another deprecated rule 70 | */ 71 | @Test 72 | @Disabled("No deprecated rule as of SpotBugs 4.9.2") 73 | void testDeprecatedRules() { 74 | Rule rule = repository.rule("TLW_TWO_LOCK_NOTIFY"); 75 | 76 | assertThat(rule).isNotNull(); 77 | assertThat(rule.status()).isEqualTo(RuleStatus.DEPRECATED); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/plugins/findbugs/xml/OrFilter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * Copyright (C) 2012 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | package org.sonar.plugins.findbugs.xml; 21 | 22 | import com.thoughtworks.xstream.annotations.XStreamAlias; 23 | import com.thoughtworks.xstream.annotations.XStreamImplicit; 24 | 25 | import java.util.ArrayList; 26 | import java.util.List; 27 | 28 | @XStreamAlias("Or") 29 | public class OrFilter { 30 | 31 | @XStreamImplicit(itemFieldName = "Bug") 32 | private List bugs; 33 | 34 | @XStreamImplicit(itemFieldName = "Package") 35 | private List packages; 36 | 37 | @XStreamImplicit(itemFieldName = "Class") 38 | private List classes; 39 | 40 | @XStreamImplicit(itemFieldName = "Method") 41 | private List methods; 42 | 43 | @XStreamImplicit(itemFieldName = "Field") 44 | private List fields; 45 | 46 | @XStreamImplicit(itemFieldName = "Local") 47 | private List locals; 48 | 49 | public OrFilter() { 50 | bugs = new ArrayList(); 51 | packages = new ArrayList(); 52 | classes = new ArrayList(); 53 | methods = new ArrayList(); 54 | fields = new ArrayList(); 55 | locals = new ArrayList(); 56 | } 57 | 58 | public List getBugs() { 59 | return bugs; 60 | } 61 | 62 | public void setBugs(List bugs) { 63 | this.bugs = bugs; 64 | } 65 | 66 | public List getPackages() { 67 | return packages; 68 | } 69 | 70 | public void setPackages(List packages) { 71 | this.packages = packages; 72 | } 73 | 74 | public List getClasses() { 75 | return classes; 76 | } 77 | 78 | public void setClasses(List classes) { 79 | this.classes = classes; 80 | } 81 | 82 | public List getMethods() { 83 | return methods; 84 | } 85 | 86 | public void setMethods(List methods) { 87 | this.methods = methods; 88 | } 89 | 90 | public List getFields() { 91 | return fields; 92 | } 93 | 94 | public void setFields(List fields) { 95 | this.fields = fields; 96 | } 97 | 98 | public List getLocals() { 99 | return locals; 100 | } 101 | 102 | public void setLocals(List locals) { 103 | this.locals = locals; 104 | } 105 | 106 | } 107 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - master 5 | - sq-10 6 | pull_request: 7 | branches: 8 | - master 9 | release: 10 | types: 11 | - published 12 | 13 | jobs: 14 | build: 15 | runs-on: ubuntu-latest 16 | strategy: 17 | fail-fast: false 18 | matrix: 19 | include: 20 | # 9.9 LTS 21 | - SONAR_SERVER_VERSION: 9.9.9.104369 22 | SONAR_SERVER_JAVA_VERSION: 17 23 | # 10.x 24 | - SONAR_SERVER_VERSION: 10.7.0.96327 25 | SONAR_SERVER_JAVA_VERSION: 17 26 | # 25.x 27 | - SONAR_SERVER_VERSION: 25.10.0.114319 28 | SONAR_SERVER_JAVA_VERSION: 17 29 | # https://mvnrepository.com/artifact/org.sonarsource.sonarqube/sonar-core 30 | steps: 31 | - uses: actions/checkout@v6 32 | with: 33 | fetch-depth: 0 34 | - name: Set up JDK 35 | uses: actions/setup-java@v5 36 | with: 37 | java-version: ${{ matrix.SONAR_SERVER_JAVA_VERSION }} 38 | distribution: temurin 39 | cache: 'maven' 40 | - name: Cache SonarCloud packages 41 | uses: actions/cache@v5 42 | with: 43 | path: | 44 | ~/.sonar/cache 45 | ~/.sonar/orchestrator/cache 46 | key: ${{ runner.os }}-sonar-${{ matrix.SONAR_SERVER_VERSION }} 47 | restore-keys: ${{ runner.os }}-sonar-${{ matrix.SONAR_SERVER_VERSION }} 48 | - name: Build 49 | run: | 50 | ./mvnw verify -B -e -V \ 51 | -Dsonar.server.version=${{ matrix.SONAR_SERVER_VERSION }} \ 52 | deploy: 53 | runs-on: ubuntu-latest 54 | needs: build 55 | # Forked repos do not have the secrets to deploy so this would fail 56 | if: ( github.event_name == 'release' || ( github.event_name == 'push' && github.ref == 'refs/heads/master' )) && github.repository == 'spotbugs/sonar-findbugs' 57 | steps: 58 | - uses: actions/checkout@v6 59 | with: 60 | fetch-depth: 0 61 | - name: Set up JDK 17 62 | uses: actions/setup-java@v5 63 | with: 64 | java-version: 17 65 | distribution: temurin 66 | cache: 'maven' 67 | server-id: central 68 | server-username: SONATYPE_USERNAME 69 | server-password: SONATYPE_TOKEN 70 | gpg-private-key: ${{ secrets.SIGNING_KEY }} 71 | gpg-passphrase: GPG_PASSPHRASE 72 | - name: Deploy artifacts to Maven Central 73 | run: | 74 | ./mvnw clean deploy -B -e -P deploy -DskipTests 75 | env: 76 | SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} 77 | SONATYPE_TOKEN: ${{ secrets.SONATYPE_TOKEN }} 78 | GPG_PASSPHRASE: ${{ secrets.SIGNING_PASSWORD }} 79 | CI: true 80 | - name: Get release URL 81 | if: github.event_name == 'release' 82 | id: get_release 83 | uses: bruceadams/get-release@v1.3.2 84 | env: 85 | GITHUB_TOKEN: ${{ github.token }} 86 | - name: Upload .jar file to GitHub Release 87 | if: github.event_name == 'release' 88 | uses: actions/upload-release-asset@v1 89 | env: 90 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 91 | with: 92 | upload_url: ${{ steps.get_release.outputs.upload_url }} 93 | asset_path: ./target/sonar-findbugs-plugin.jar 94 | asset_name: sonar-findbugs-plugin-${{ github.event.release.tag_name }}.jar 95 | asset_content_type: application/zip 96 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/plugins/findbugs/FindbugsProfileExporter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * Copyright (C) 2012 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | package org.sonar.plugins.findbugs; 21 | 22 | import com.thoughtworks.xstream.XStream; 23 | import java.io.IOException; 24 | import java.io.Writer; 25 | import java.util.stream.Collectors; 26 | import org.sonar.api.profiles.ProfileExporter; 27 | import org.sonar.api.profiles.RulesProfile; 28 | import org.sonar.api.rules.ActiveRule; 29 | import org.sonar.api.utils.SonarException; 30 | import org.sonar.plugins.findbugs.rules.FbContribRulesDefinition; 31 | import org.sonar.plugins.findbugs.rules.FindSecurityBugsRulesDefinition; 32 | import org.sonar.plugins.findbugs.rules.FindbugsRulesDefinition; 33 | import org.sonar.plugins.findbugs.xml.Bug; 34 | import org.sonar.plugins.findbugs.xml.FindBugsFilter; 35 | import org.sonar.plugins.findbugs.xml.Match; 36 | 37 | public class FindbugsProfileExporter extends ProfileExporter { 38 | 39 | public FindbugsProfileExporter() { 40 | super(/* (Godin): actually exporter key: */FindbugsRulesDefinition.REPOSITORY_KEY, FindbugsConstants.PLUGIN_NAME); 41 | setSupportedLanguages(FindbugsPlugin.SUPPORTED_JVM_LANGUAGES); 42 | setMimeType("application/xml"); 43 | } 44 | 45 | @Override 46 | public void exportProfile(RulesProfile profile, Writer writer) { 47 | try { 48 | FindBugsFilter filter = buildFindbugsFilter( 49 | profile.getActiveRules().stream().filter(activeRule -> 50 | activeRule.getRepositoryKey().contains(FindbugsRulesDefinition.REPOSITORY_KEY) || 51 | activeRule.getRepositoryKey().contains(FindSecurityBugsRulesDefinition.REPOSITORY_KEY) || 52 | activeRule.getRepositoryKey().contains(FbContribRulesDefinition.REPOSITORY_KEY)) 53 | .collect(Collectors.toList()) 54 | ); 55 | XStream xstream = FindBugsFilter.createXStream(); 56 | writer.append(xstream.toXML(filter)); 57 | } catch (IOException e) { 58 | throw new SonarException("Fail to export the Findbugs profile : " + profile, e); 59 | } 60 | } 61 | 62 | public static FindBugsFilter buildFindbugsFilter(Iterable activeRules) { 63 | FindBugsFilter root = new FindBugsFilter(); 64 | for (ActiveRule activeRule : activeRules) { 65 | String repoKey = activeRule.getRepositoryKey(); 66 | 67 | if (repoKey.contains(FindSecurityBugsRulesDefinition.REPOSITORY_KEY) || repoKey.contains(FindbugsRulesDefinition.REPOSITORY_KEY) || repoKey.contains(FbContribRulesDefinition.REPOSITORY_KEY)) { 68 | Match child = new Match(); 69 | child.setBug(new Bug(activeRule.getConfigKey())); 70 | root.addMatch(child); 71 | } 72 | } 73 | return root; 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /src/test/java/org/sonar/plugins/findbugs/FindbugsXmlReportParserTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * Copyright (C) 2012 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | package org.sonar.plugins.findbugs; 21 | 22 | import static org.junit.jupiter.api.Assertions.assertEquals; 23 | import static org.junit.jupiter.api.Assertions.assertThrows; 24 | 25 | import org.junit.jupiter.api.BeforeEach; 26 | import org.junit.jupiter.api.Test; 27 | 28 | import java.io.File; 29 | import java.net.URISyntaxException; 30 | import java.util.List; 31 | 32 | import static org.assertj.core.api.Assertions.assertThat; 33 | 34 | class FindbugsXmlReportParserTest { 35 | 36 | private List violations; 37 | 38 | @BeforeEach 39 | public void init() { 40 | File findbugsXmlReport = getFile("/org/sonar/plugins/findbugs/findbugsReport.xml"); 41 | FindbugsXmlReportParser xmlParser = new FindbugsXmlReportParser(findbugsXmlReport); 42 | violations = xmlParser.getBugInstances(); 43 | } 44 | 45 | @Test 46 | void createFindbugsXmlReportParserWithUnexistedReportFile() { 47 | File xmlReport = new File("doesntExist.xml"); 48 | 49 | Throwable thrown = assertThrows(IllegalStateException.class, () -> { 50 | new FindbugsXmlReportParser(xmlReport); 51 | }); 52 | 53 | assertEquals("The findbugs XML report can't be found at '" + xmlReport.getAbsolutePath() + "'", thrown.getMessage()); 54 | } 55 | 56 | @Test 57 | void testGetViolations() { 58 | assertThat(violations).hasSize(2); 59 | 60 | FindbugsXmlReportParser.XmlBugInstance fbViolation = violations.get(0); 61 | assertThat(fbViolation.getType()).isEqualTo("AM_CREATES_EMPTY_ZIP_FILE_ENTRY"); 62 | assertThat(fbViolation.getLongMessage()).isEqualTo("Empty zip file entry created in org.sonar.commons.ZipUtils._zip(String, File, ZipOutputStream)"); 63 | 64 | FindbugsXmlReportParser.XmlSourceLineAnnotation sourceLine = fbViolation.getPrimarySourceLine(); 65 | assertThat(sourceLine.getStart()).isEqualTo(107); 66 | assertThat(sourceLine.getEnd()).isEqualTo(107); 67 | assertThat(sourceLine.getClassName()).isEqualTo("org.sonar.commons.ZipUtils"); 68 | } 69 | 70 | @Test 71 | void testGetSonarJavaFileKey() { 72 | FindbugsXmlReportParser.XmlSourceLineAnnotation sourceLine = new FindbugsXmlReportParser.XmlSourceLineAnnotation(); 73 | sourceLine.className = "org.sonar.batch.Sensor"; 74 | assertThat(sourceLine.getSonarJavaFileKey()).isEqualTo("org.sonar.batch.Sensor"); 75 | sourceLine.className = "Sensor"; 76 | assertThat(sourceLine.getSonarJavaFileKey()).isEqualTo("Sensor"); 77 | sourceLine.className = "org.sonar.batch.Sensor$1"; 78 | assertThat(sourceLine.getSonarJavaFileKey()).isEqualTo("org.sonar.batch.Sensor"); 79 | } 80 | 81 | private final File getFile(String filename) { 82 | try { 83 | return new File(getClass().getResource(filename).toURI()); 84 | } catch (URISyntaxException e) { 85 | throw new IllegalStateException("Unable to open file " + filename, e); 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/plugins/findbugs/xml/Match.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Findbugs Plugin 3 | * Copyright (C) 2012 SonarSource 4 | * sonarqube@googlegroups.com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 19 | */ 20 | package org.sonar.plugins.findbugs.xml; 21 | 22 | import com.thoughtworks.xstream.annotations.XStreamAlias; 23 | import com.thoughtworks.xstream.annotations.XStreamImplicit; 24 | 25 | import java.util.List; 26 | 27 | @XStreamAlias("Match") 28 | public class Match { 29 | 30 | @XStreamAlias("Bug") 31 | private Bug bug; 32 | 33 | @XStreamAlias("Priority") 34 | private Priority priority; 35 | 36 | @XStreamAlias("Package") 37 | private PackageFilter particularPackage; 38 | 39 | @XStreamAlias("Class") 40 | private ClassFilter particularClass; 41 | 42 | @XStreamAlias("Method") 43 | private MethodFilter particularMethod; 44 | 45 | @XStreamAlias("Field") 46 | private FieldFilter particularField; 47 | 48 | @XStreamAlias("Local") 49 | private LocalFilter particularLocal; 50 | 51 | @XStreamImplicit(itemFieldName = "Or") 52 | private List ors; 53 | 54 | public Match() { 55 | // Empty constructor required by XStream converters 56 | } 57 | 58 | public Match(Bug bug, Priority priority) { 59 | this.bug = bug; 60 | this.priority = priority; 61 | } 62 | 63 | public Match(Bug bug) { 64 | this.bug = bug; 65 | } 66 | 67 | public Match(ClassFilter particularClass) { 68 | this.particularClass = particularClass; 69 | } 70 | 71 | public Bug getBug() { 72 | return bug; 73 | } 74 | 75 | public void setBug(Bug bug) { 76 | this.bug = bug; 77 | } 78 | 79 | public Priority getPriority() { 80 | return priority; 81 | } 82 | 83 | public void setPriority(Priority priority) { 84 | this.priority = priority; 85 | } 86 | 87 | public PackageFilter getParticularPackage() { 88 | return particularPackage; 89 | } 90 | 91 | public void setParticularPackage(PackageFilter particularPackage) { 92 | this.particularPackage = particularPackage; 93 | } 94 | 95 | public ClassFilter getParticularClass() { 96 | return particularClass; 97 | } 98 | 99 | public void setParticularClass(ClassFilter particularClass) { 100 | this.particularClass = particularClass; 101 | } 102 | 103 | public MethodFilter getParticularMethod() { 104 | return particularMethod; 105 | } 106 | 107 | public void setParticularMethod(MethodFilter particularMethod) { 108 | this.particularMethod = particularMethod; 109 | } 110 | 111 | public FieldFilter getParticularField() { 112 | return particularField; 113 | } 114 | 115 | public void setParticularField(FieldFilter particularField) { 116 | this.particularField = particularField; 117 | } 118 | 119 | public LocalFilter getParticularLocal() { 120 | return particularLocal; 121 | } 122 | 123 | public void setParticularLocal(LocalFilter particularLocal) { 124 | this.particularLocal = particularLocal; 125 | } 126 | 127 | public List getOrs() { 128 | return ors; 129 | } 130 | 131 | public void setOrs(List ors) { 132 | this.ors = ors; 133 | } 134 | 135 | public void addDisjunctCombine(OrFilter child) { 136 | ors.add(child); 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /src/test/resources/org/sonar/plugins/findbugs/findbugsReport.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | /Users/freddy/Documents/sonar_projects/sonar/sonar-commons/target/classes 4 | /Users/freddy/.m2/repository/org/apache/maven/reporting/maven-reporting-impl/2.0/maven-reporting-impl-2.0.jar 5 | /Users/freddy/Documents/sonar_projects/sonar/sonar-commons/src/main/java 6 | /Users/freddy/Documents/sonar_projects/sonar/sonar-commons/target 7 | 8 | 9 | Creates an empty zip file entry 10 | Empty zip file entry created in org.sonar.commons.ZipUtils._zip(String, File, ZipOutputStream) 11 | 12 | 13 | At ZipUtils.java:[lines 33-139] 14 | 15 | In class org.sonar.commons.ZipUtils 16 | 17 | 18 | 19 | In method org.sonar.commons.ZipUtils._zip(String, File, ZipOutputStream) 20 | 21 | 22 | At ZipUtils.java:[line 107] 23 | 24 | 25 | At ZipUtils.java:[line 107] 26 | 27 | 28 | 29 | Could be refactored into a named static inner class 30 | The class org.sonar.commons.resources.MeasuresDao$1 could be refactored into a named _static_ inner class 31 | 32 | 33 | At MeasuresDao.java:[lines 56-57] 34 | 35 | In class org.sonar.commons.resources.MeasuresDao$1 36 | 37 | 38 | At MeasuresDao.java:[lines 56-57] 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | --------------------------------------------------------------------------------