Sometimes rule squid:S2259 is false positive with method in whitelist

SonarQube7.7, Scanner4.0.0.1744, Plugin sonar-java 5.13.1(build 18282)



org.springframework.util.CollectionUtils#isEmpty
org.springframework.util.Assert#notNull

As I see, the above methods are already in the “whitelist”, sometimes strange to me.

Below log maybe help. FYI

13:30:38.126 DEBUG: Could not complete symbolic execution: 
org.sonar.java.se.ExplodedGraphWalker$MaximumStepsReachedException: reached limit of 16000 steps for method buildQueryExample#467 in class ContractService
        at org.sonar.java.se.ExplodedGraphWalker.throwMaxSteps(ExplodedGraphWalker.java:306)
        at org.sonar.java.se.ExplodedGraphWalker.execute(ExplodedGraphWalker.java:245)
        at org.sonar.java.se.ExplodedGraphWalker.visitMethod(ExplodedGraphWalker.java:218)
        at org.sonar.java.se.SymbolicExecutionVisitor.execute(SymbolicExecutionVisitor.java:74)
        at org.sonar.java.se.SymbolicExecutionVisitor.visitNode(SymbolicExecutionVisitor.java:64)
        at org.sonar.java.ast.visitors.SubscriptionVisitor.visit(SubscriptionVisitor.java:103)
        at org.sonar.java.ast.visitors.SubscriptionVisitor.visitChildren(SubscriptionVisitor.java:128)
        at org.sonar.java.ast.visitors.SubscriptionVisitor.visit(SubscriptionVisitor.java:105)
        at org.sonar.java.ast.visitors.SubscriptionVisitor.visitChildren(SubscriptionVisitor.java:128)
        at org.sonar.java.ast.visitors.SubscriptionVisitor.visit(SubscriptionVisitor.java:105)
        at org.sonar.java.ast.visitors.SubscriptionVisitor.scanTree(SubscriptionVisitor.java:86)
        at org.sonar.java.ast.visitors.SubscriptionVisitor.scanFile(SubscriptionVisitor.java:72)
        at org.sonar.java.se.SymbolicExecutionVisitor.scanFile(SymbolicExecutionVisitor.java:54)
        at org.sonar.java.model.VisitorsBridge.runScanner(VisitorsBridge.java:149)
        at org.sonar.java.model.VisitorsBridge.visitFile(VisitorsBridge.java:137)
        at org.sonar.java.ast.JavaAstScanner.simpleScan(JavaAstScanner.java:90)
        at org.sonar.java.ast.JavaAstScanner.scan(JavaAstScanner.java:67)
        at org.sonar.java.JavaSquid.scanSources(JavaSquid.java:115)
        at org.sonar.java.JavaSquid.scan(JavaSquid.java:109)
        at org.sonar.plugins.java.JavaSquidSensor.execute(JavaSquidSensor.java:88)
        at org.sonar.scanner.sensor.AbstractSensorWrapper.analyse(AbstractSensorWrapper.java:48)
        at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:85)
        at org.sonar.scanner.sensor.ModuleSensorsExecutor.lambda$execute$1(ModuleSensorsExecutor.java:59)
        at org.sonar.scanner.sensor.ModuleSensorsExecutor.withModuleStrategy(ModuleSensorsExecutor.java:77)
        at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:59)
        at org.sonar.scanner.scan.ModuleScanContainer.doAfterStart(ModuleScanContainer.java:82)
        at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:136)
        at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:122)
        at org.sonar.scanner.scan.ProjectScanContainer.scan(ProjectScanContainer.java:359)
        at org.sonar.scanner.scan.ProjectScanContainer.scanRecursively(ProjectScanContainer.java:354)
        at org.sonar.scanner.scan.ProjectScanContainer.doAfterStart(ProjectScanContainer.java:317)
        at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:136)
        at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:122)
        at org.sonar.scanner.bootstrap.GlobalContainer.doAfterStart(GlobalContainer.java:128)
        at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:136)
        at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:122)
        at org.sonar.batch.bootstrapper.Batch.doExecute(Batch.java:73)
        at org.sonar.batch.bootstrapper.Batch.execute(Batch.java:67)
        at org.sonarsource.scanner.api.internal.batch.BatchIsolatedLauncher.execute(BatchIsolatedLauncher.java:46)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.base/java.lang.reflect.Method.invoke(Unknown Source)
        at org.sonarsource.scanner.api.internal.IsolatedLauncherProxy.invoke(IsolatedLauncherProxy.java:60)
        at com.sun.proxy.$Proxy0.execute(Unknown Source)
        at org.sonarsource.scanner.api.EmbeddedScanner.doExecute(EmbeddedScanner.java:185)
        at org.sonarsource.scanner.api.EmbeddedScanner.execute(EmbeddedScanner.java:137)
        at org.sonarsource.scanner.cli.Main.execute(Main.java:112)
        at org.sonarsource.scanner.cli.Main.execute(Main.java:75)
        at org.sonarsource.scanner.cli.Main.main(Main.java:61)

Hello,

Thanks for the feedback.

This is not easy to see with the information you provided if there is a FP or not. Ideally, if you could provide a reproducer that we can build and scan locally that would be better.

Anyway, I would like to suggest to test the latest SonarQube 8.2 which includes the Java analyzer 6.1 and see if you still have trouble because in all cases, if we do some changes, they will be done on top of the Java analyzer 6.1 and not on sonar-java 5.13.1

Alex

private void convertEntityToContractVoWithTaskElement(
            Map<Long, ContractDefContextEntity> defCttEntityMap) {
        if (defCttEntityMap == null) {

        }
        //获取流程定义中的extra内容
        if (!CollectionUtils.isEmpty(defCttEntityMap)) {
            defCttEntityMap.get("123");
        }
    }

The complete method is like this. I found that when remove the line “defCttEntityMap == null”, this NPE disappear. Hmm …

@neufeng, like already mentionned by Alexandre, your are using quite old version of SonarJava.

You are also using SonarQube 7.7, while the latest LTS version is 7.9. Your version is not maintained anymore and we can not guarantee support. Please update to latest SQ 7.9. If the problem persists, try with latest version of SonarJava, especially the 6.x serie, introduced in January 2020.

Thanks,
Michael

@Michael
I managed to reproduce the problem with SQ 8.2 + SonarJava 6.1 or 6.2 using MapUtils from Apache Commons Collections:


When I remove the first if statement checking if the Map is null, the NPE issue is not raised.

Reproducer: https://github.com/agigleux/analyzers-playground/blob/master/src/main/java/S2259/Community20880.java#L12

@neufeng
In your case you have the NPE with CollectionUtils. Can you share from where this class is coming from? In Commons Collections, I did not find a method isEmpty taking a Map as a parameter.

Thanks

@neufeng Please forget my question, I read again your post and you are talking about Spring’s CollectionUtils. With SonarJava 6.2, I no longer have the FP so I suggest that you upgrade to SonarJava 6.2 and confirm if you still have the problem.

Alex