Browse Source

SONAR-22009 Fix NPE on SARIF import when Extensions don't have Rules

tags/10.5.0.89998
antoine.vinot 1 month ago
parent
commit
118a1b07a7

+ 2
- 0
sonar-core/src/main/java/org/sonar/core/sarif/Extension.java View File



import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import java.util.Set; import java.util.Set;
import javax.annotation.CheckForNull;


public class Extension { public class Extension {
@SerializedName("rules") @SerializedName("rules")
// http://stackoverflow.com/a/18645370/229031 // http://stackoverflow.com/a/18645370/229031
} }


@CheckForNull
public Set<Rule> getRules() { public Set<Rule> getRules() {
return rules; return rules;
} }

+ 6
- 1
sonar-scanner-engine/src/main/java/org/sonar/scanner/externalissue/sarif/RunMapper.java View File

import org.sonar.api.batch.sensor.rule.NewAdHocRule; import org.sonar.api.batch.sensor.rule.NewAdHocRule;
import org.sonar.api.scanner.ScannerSide; import org.sonar.api.scanner.ScannerSide;
import org.sonar.core.sarif.Driver; import org.sonar.core.sarif.Driver;
import org.sonar.core.sarif.Extension;
import org.sonar.core.sarif.Result; import org.sonar.core.sarif.Result;
import org.sonar.core.sarif.Rule; import org.sonar.core.sarif.Rule;
import org.sonar.core.sarif.Run; import org.sonar.core.sarif.Run;
private List<NewAdHocRule> toNewAdHocRules(Run run, String driverName, Map<String, String> ruleSeveritiesByRuleId, Map<String, String> ruleSeveritiesByRuleIdForNewCCT) { private List<NewAdHocRule> toNewAdHocRules(Run run, String driverName, Map<String, String> ruleSeveritiesByRuleId, Map<String, String> ruleSeveritiesByRuleIdForNewCCT) {
Set<Rule> driverRules = run.getTool().getDriver().getRules(); Set<Rule> driverRules = run.getTool().getDriver().getRules();
Set<Rule> extensionRules = hasExtensions(run.getTool()) Set<Rule> extensionRules = hasExtensions(run.getTool())
? run.getTool().getExtensions().stream().flatMap(extension -> extension.getRules().stream()).collect(toSet())
? run.getTool().getExtensions().stream().filter(RunMapper::hasRules).flatMap(extension -> extension.getRules().stream()).collect(toSet())
: Set.of(); : Set.of();
return Stream.concat(driverRules.stream(), extensionRules.stream()) return Stream.concat(driverRules.stream(), extensionRules.stream())
.distinct() .distinct()
return tool.getExtensions() != null && !tool.getExtensions().isEmpty(); return tool.getExtensions() != null && !tool.getExtensions().isEmpty();
} }


private static boolean hasRules(Extension extension) {
return extension.getRules() != null && !extension.getRules().isEmpty();
}

private List<NewExternalIssue> toNewExternalIssues(Run run, String driverName, Map<String, String> ruleSeveritiesByRuleId, Map<String, String> ruleSeveritiesByRuleIdForNewCCT) { private List<NewExternalIssue> toNewExternalIssues(Run run, String driverName, Map<String, String> ruleSeveritiesByRuleId, Map<String, String> ruleSeveritiesByRuleIdForNewCCT) {
return run.getResults() return run.getResults()
.stream() .stream()

+ 31
- 0
sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/sarif/RunMapperTest.java View File

import static java.util.Collections.emptySet; import static java.util.Collections.emptySet;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.assertj.core.api.Assertions.assertThatNoException;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mockStatic; import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
} }
} }


@Test
public void mapRun_shouldNotFail_whenExtensionsDontHaveRules() {
when(run.getTool().getDriver().getRules()).thenReturn(Set.of(rule));
Extension extension = mock(Extension.class);
when(extension.getRules()).thenReturn(null);
when(run.getTool().getExtensions()).thenReturn(Set.of(extension));

try (MockedStatic<RulesSeverityDetector> detector = mockStatic(RulesSeverityDetector.class)) {
detector.when(() -> RulesSeverityDetector.detectRulesSeverities(run, TEST_DRIVER)).thenReturn(Map.of(RULE_ID, WARNING));
detector.when(() -> RulesSeverityDetector.detectRulesSeveritiesForNewTaxonomy(run, TEST_DRIVER)).thenReturn(Map.of(RULE_ID, WARNING));

assertThatNoException().isThrownBy(() -> runMapper.mapRun(run));
}
}

@Test
public void mapRun_shouldNotFail_whenExtensionsHaveEmptyRules() {
when(run.getTool().getDriver().getRules()).thenReturn(Set.of(rule));
Extension extension = mock(Extension.class);
when(extension.getRules()).thenReturn(Set.of());
when(run.getTool().getExtensions()).thenReturn(Set.of(extension));

try (MockedStatic<RulesSeverityDetector> detector = mockStatic(RulesSeverityDetector.class)) {
detector.when(() -> RulesSeverityDetector.detectRulesSeverities(run, TEST_DRIVER)).thenReturn(Map.of(RULE_ID, WARNING));
detector.when(() -> RulesSeverityDetector.detectRulesSeveritiesForNewTaxonomy(run, TEST_DRIVER)).thenReturn(Map.of(RULE_ID, WARNING));

assertThatNoException().isThrownBy(() -> runMapper.mapRun(run));
}
}

@Test @Test
public void mapRun_ifRunIsEmpty_returnsEmptyList() { public void mapRun_ifRunIsEmpty_returnsEmptyList() {
when(run.getResults()).thenReturn(emptySet()); when(run.getResults()).thenReturn(emptySet());

Loading…
Cancel
Save