Skip to content

Commit

Permalink
meet new spec
Browse files Browse the repository at this point in the history
  • Loading branch information
nahsra committed Apr 5, 2024
1 parent 9e9f983 commit fde90bc
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 105 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ To deserialize a CodeTF file using these objects, simply deserialize with Jackso

## Gradle
```kotlin
implementation("io.codemodder:codetf-java:3.2.1")
implementation("io.codemodder:codetf-java:3.3.1")
```

## Maven
```xml
<dependency>
<groupId>io.codemodder</groupId>
<artifactId>codetf-java</artifactId>
<version>3.2.1</version>
<version>3.3.1</version>
</dependency>
```

Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<groupId>io.codemodder</groupId>
<artifactId>codetf-java</artifactId>
<version>3.2.1</version>
<version>3.3.1</version>


<name>codetf-java</name>
Expand Down
12 changes: 10 additions & 2 deletions src/main/java/io/codemodder/codetf/CodeTFResult.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public final class CodeTFResult {
private final List<CodeTFReference> references;
private final Map<String, String> properties;
private final List<CodeTFChangesetEntry> changeset;
private final List<UnfixedFinding> unfixedFindings;

@JsonCreator
public CodeTFResult(
Expand All @@ -25,7 +26,8 @@ public CodeTFResult(
@JsonProperty(value = "failedFiles", index = 5) final Set<String> failedFiles,
@JsonProperty(value = "references", index = 6) final List<CodeTFReference> references,
@JsonProperty(value = "properties", index = 7) final Map<String, String> properties,
@JsonProperty(value = "changeset", index = 8) final List<CodeTFChangesetEntry> changeset) {
@JsonProperty(value = "changeset", index = 8) final List<CodeTFChangesetEntry> changeset,
@JsonProperty(value = "unfixed", index = 9) final List<UnfixedFinding> unfixedFindings) {
this.codemod = CodeTFValidator.requireNonBlank(codemod);
this.summary = CodeTFValidator.requireNonBlank(summary);
this.description = CodeTFValidator.requireNonBlank(description);
Expand All @@ -34,6 +36,7 @@ public CodeTFResult(
this.references = CodeTFValidator.toImmutableCopyOrEmptyOnNull(references);
this.properties = CodeTFValidator.toImmutableCopyOrEmptyOnNull(properties);
this.changeset = Objects.requireNonNull(changeset);
this.unfixedFindings = CodeTFValidator.toImmutableCopyOrEmptyOnNull(unfixedFindings);
}

public String getCodemod() {
Expand Down Expand Up @@ -68,6 +71,10 @@ public List<CodeTFChangesetEntry> getChangeset() {
return changeset;
}

public List<UnfixedFinding> getUnfixedFindings() {
return unfixedFindings;
}

/** Create a new CodeTFResult builder based on an existing instance. */
public static Builder basedOn(final CodeTFResult result) {
return new Builder(result);
Expand Down Expand Up @@ -117,7 +124,8 @@ public CodeTFResult build() {
originalResult.getFailedFiles(),
updatedReferences != null ? updatedReferences : originalResult.getReferences(),
originalResult.getProperties(),
originalResult.getChangeset());
originalResult.getChangeset(),
originalResult.unfixedFindings);
}
}
}
24 changes: 11 additions & 13 deletions src/main/java/io/codemodder/codetf/DetectionTool.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,32 @@

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
import java.util.Objects;

/** Metadata about the external tool that generated results consumed by this codemod */
public final class DetectionTool {

private final String name;
private final DetectorRule rule;
private final List<DetectorFinding> findings;

@JsonCreator
public DetectionTool(
@JsonProperty(value = "name", index = 1) String name,
@JsonProperty(value = "rule", index = 2) DetectorRule rule,
@JsonProperty(value = "findings", index = 3) List<DetectorFinding> findings) {
public DetectionTool(@JsonProperty(value = "name", index = 1) String name) {
this.name = Objects.requireNonNull(name);
this.rule = Objects.requireNonNull(rule);
this.findings = CodeTFValidator.toImmutableCopyOrEmptyOnNull(findings);
}

public String getName() {
return name;
}

public DetectorRule getRule() {
return rule;
@Override
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
DetectionTool that = (DetectionTool) o;
return Objects.equals(name, that.name);
}

public List<DetectorFinding> getFindings() {
return findings;
@Override
public int hashCode() {
return Objects.hash(name);
}
}
38 changes: 0 additions & 38 deletions src/main/java/io/codemodder/codetf/DetectorFinding.java

This file was deleted.

28 changes: 28 additions & 0 deletions src/main/java/io/codemodder/codetf/FixedFinding.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package io.codemodder.codetf;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Objects;

/** Describes a fixed finding. */
public final class FixedFinding {

private final String id;
private final DetectorRule rule;

@JsonCreator
public FixedFinding(
@JsonProperty(value = "id", index = 1) final String id,
@JsonProperty(value = "rule", index = 2) final DetectorRule rule) {
this.id = CodeTFValidator.requireNonBlank(id);
this.rule = Objects.requireNonNull(rule);
}

public String getId() {
return id;
}

public DetectorRule getRule() {
return rule;
}
}
49 changes: 49 additions & 0 deletions src/main/java/io/codemodder/codetf/UnfixedFinding.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package io.codemodder.codetf;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Objects;

/** Describes an unfixed finding. */
public final class UnfixedFinding {

private final String id;
private final DetectorRule rule;
private final String path;
private final Integer line;
private final String reason;

@JsonCreator
public UnfixedFinding(
@JsonProperty(value = "id", index = 1) final String id,
@JsonProperty(value = "rule", index = 2) final DetectorRule rule,
@JsonProperty(value = "path", index = 3) final String path,
@JsonProperty(value = "line", index = 4) final Integer line,
@JsonProperty(value = "reason", index = 5) final String reason) {
this.id = CodeTFValidator.requireNonBlank(id);
this.rule = Objects.requireNonNull(rule);
this.path = CodeTFValidator.requireNonBlank(path);
this.line = line;
this.reason = CodeTFValidator.requireNonBlank(reason);
}

public String getId() {
return id;
}

public String getPath() {
return path;
}

public String getReason() {
return reason;
}

public DetectorRule getRule() {
return rule;
}

public Integer getLine() {
return line;
}
}
86 changes: 37 additions & 49 deletions src/test/java/io/codemodder/codetf/CodeTFResultTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ void it_creates_result() {
"pom.xml",
"... udiff text...",
List.of(
new CodeTFChange(1, null, "whatever", CodeTFDiffSide.RIGHT, null, null)))));
new CodeTFChange(1, null, "whatever", CodeTFDiffSide.RIGHT, null, null)))),
List.of());
assertNotNull(result);
assertEquals("codemodder:java/deserialization", result.getCodemod());
assertEquals("Hardened object deserialization calls against attack", result.getSummary());
Expand All @@ -46,12 +47,18 @@ void it_creates_result() {

@Test
void it_creates_result_with_detection_tool() {

DetectionTool tool = new DetectionTool("acme-scanner");
DetectorRule rule = new DetectorRule("rule", "Here's a rule", null);
UnfixedFinding unfixedFinding =
new UnfixedFinding("rule-id-23", rule, "/foo/bar.java", 42, "It's not fixed");

CodeTFResult result =
new CodeTFResult(
"codemodder:java/deserialization",
"Hardened object deserialization calls against attack",
"Lengthier description about deserialization risks, protections, etc...",
new DetectionTool("tool", new DetectorRule("rule", "Here's a rule", null), List.of()),
tool,
Set.of("/foo/failed.java"),
List.of(
new CodeTFReference(
Expand All @@ -68,7 +75,8 @@ void it_creates_result_with_detection_tool() {
"pom.xml",
"... udiff text...",
List.of(
new CodeTFChange(1, null, "whatever", CodeTFDiffSide.RIGHT, null, null)))));
new CodeTFChange(1, null, "whatever", CodeTFDiffSide.RIGHT, null, null)))),
List.of(unfixedFinding));
assertNotNull(result);
assertEquals("codemodder:java/deserialization", result.getCodemod());
assertEquals("Hardened object deserialization calls against attack", result.getSummary());
Expand All @@ -78,64 +86,44 @@ void it_creates_result_with_detection_tool() {
assertEquals(1, result.getReferences().size());
assertEquals(1, result.getFailedFiles().size());
assertEquals(2, result.getChangeset().size());
assertEquals(tool, result.getDetectionTool());
assertEquals(1, result.getUnfixedFindings().size());
assertNotNull(result.getDetectionTool());
}

@Test
void it_creates_detection_tool_with_empty_url() {
DetectionTool tool =
new DetectionTool(
"tool",
new DetectorRule("rule", "Here's a rule", null),
List.of(
new DetectorFinding("finding", true, null),
new DetectorFinding("finding", false, "It's fixed")));
assertNotNull(tool);
assertEquals("tool", tool.getName());
assertEquals("rule", tool.getRule().getId());
assertEquals("Here's a rule", tool.getRule().getName());
assertEquals(2, tool.getFindings().size());
assertNull(tool.getRule().getUrl());
}

@Test
void it_creates_detection_tool_with_url() {
DetectionTool tool =
new DetectionTool(
"tool",
new DetectorRule("rule", "Here's a rule", "https://example.com"),
List.of(
new DetectorFinding("finding", true, "It's fixed"),
new DetectorFinding("finding", false, "It's not fixed")));
assertNotNull(tool);
void it_creates_detection_tool() {
DetectorRule rule = new DetectorRule("rule", "Here's a rule", null);
DetectionTool tool = new DetectionTool("tool");
assertEquals("tool", tool.getName());
assertEquals("rule", tool.getRule().getId());
assertEquals("Here's a rule", tool.getRule().getName());
assertEquals(2, tool.getFindings().size());
assertNotNull(tool.getRule().getUrl());
assertEquals("https://example.com", tool.getRule().getUrl());
assertEquals("rule", rule.getId());
assertEquals("Here's a rule", rule.getName());
}

@Test
void it_creates_finding() {
DetectorFinding finding = new DetectorFinding("finding", true, "It's fixed");
assertNotNull(finding);
DetectorRule rule = new DetectorRule("foo", "bar", "");
FixedFinding finding = new FixedFinding("finding", rule);
assertEquals("finding", finding.getId());
assertTrue(finding.getFixed());
assertEquals("It's fixed", finding.getReason().get());
}

@Test
void it_raises_iae_on_fixed_finding_with_null_reason() {
assertThrows(IllegalArgumentException.class, () -> new DetectorFinding("finding", false, null));
assertThrows(NullPointerException.class, () -> new FixedFinding("finding", null));
assertThrows(IllegalArgumentException.class, () -> new FixedFinding("", rule));
assertThrows(IllegalArgumentException.class, () -> new FixedFinding(null, rule));
}

@Test
void it_creates_finding_with_null_reason() {
DetectorFinding finding = new DetectorFinding("finding", true, null);
assertNotNull(finding);
assertEquals("finding", finding.getId());
assertTrue(finding.getFixed());
assertTrue(finding.getReason().isEmpty());
void it_creates_unfixed_findings() {
DetectorRule rule = new DetectorRule("foo", "bar", "");
assertThrows(
IllegalArgumentException.class,
() -> new UnfixedFinding("finding", rule, "src/foo", 15, null));
assertThrows(
IllegalArgumentException.class,
() -> new UnfixedFinding("finding", rule, "src/foo", 15, ""));
assertThrows(
IllegalArgumentException.class,
() -> new UnfixedFinding("finding", rule, "", 15, "reason here"));
assertThrows(
IllegalArgumentException.class,
() -> new UnfixedFinding("finding", rule, null, 15, "reason here"));
}
}

0 comments on commit fde90bc

Please sign in to comment.