Skip to content

Commit b45867e

Browse files
committed
🚧 Number Lines Once
1 parent ee5eba1 commit b45867e

File tree

2 files changed

+33
-19
lines changed

2 files changed

+33
-19
lines changed

‎core-codemods/src/main/java/io/codemodder/codemods/SensitiveDataLoggingCodemod.java‎

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@
2323
import java.util.Objects;
2424
import java.util.Optional;
2525
import java.util.concurrent.atomic.AtomicInteger;
26-
import java.util.stream.Collectors;
27-
import java.util.stream.Stream;
2826
import javax.inject.Inject;
2927

3028
/** A codemod that removes any sensitive data being logged. */
@@ -51,6 +49,12 @@ public SensitiveDataLoggingCodemod(
5149
public CodemodFileScanningResult visit(
5250
final CodemodInvocationContext context, final CompilationUnit cu) {
5351
final var source = context.path();
52+
final List<String> numberedLines;
53+
try {
54+
numberedLines = readNumberedLines(source);
55+
} catch (IOException e) {
56+
throw new UncheckedIOException("Couldn't read source file", e);
57+
}
5458
final List<Result> results = sarif.getResultsByLocationPath(source);
5559
final List<CodemodChange> changes = new ArrayList<>();
5660
for (final Result result : results) {
@@ -63,7 +67,7 @@ public CodemodFileScanningResult visit(
6367

6468
SensitivityAndFixAnalysis analysis;
6569
try {
66-
analysis = performSensitivityAnalysis(source, startLine);
70+
analysis = performSensitivityAnalysis(numberedLines, startLine);
6771
} catch (IOException e) {
6872
throw new UncheckedIOException("Couldn't perform sensitivity analysis", e);
6973
}
@@ -83,8 +87,8 @@ public CodemodFileScanningResult visit(
8387
}
8488

8589
private SensitivityAndFixAnalysis performSensitivityAnalysis(
86-
final Path source, final Integer startLine) throws IOException {
87-
String codeSnippet = numberedContextWithExtraLines(source, startLine);
90+
final List<String> source, final Integer startLine) throws IOException {
91+
String codeSnippet = snippet(source, startLine);
8892
String prompt =
8993
"""
9094
A tool has cited line %d of the code for possibly logging sensitive data:
@@ -145,6 +149,7 @@ private interface SensitivityAndFixAnalysis {
145149
}
146150

147151
private static class SensitivityAndFixAnalysisDTO implements SensitivityAndFixAnalysis {
152+
148153
@JsonProperty("sensitive_analysis_text")
149154
private String sensitiveAnalysisText;
150155

@@ -173,25 +178,34 @@ public String newStatement() {
173178
}
174179
}
175180

176-
private static String numberedContextWithExtraLines(final Path path, final int line)
177-
throws IOException {
178-
int startLine = Math.max(0, line - CONTEXT);
179-
try (final Stream<String> lines = Files.lines(path)) {
180-
final AtomicInteger counter = new AtomicInteger(startLine);
181-
return lines
182-
.skip(startLine)
183-
.limit(1L + CONTEXT)
184-
.map(s -> counter.incrementAndGet() + ": " + s)
185-
.collect(Collectors.joining("\n"));
186-
}
187-
}
188-
189181
@Override
190182
public boolean shouldRun() {
191183
List<Run> runs = sarif.rawDocument().getRuns();
192184
return runs != null && !runs.isEmpty() && !runs.get(0).getResults().isEmpty();
193185
}
194186

187+
/** Reads the source code from the given file and numbers each line. */
188+
private List<String> readNumberedLines(final Path source) throws IOException {
189+
final var counter = new AtomicInteger();
190+
try (final var lines = Files.lines(source)) {
191+
return lines.map(line -> counter.incrementAndGet() + ": " + line).toList();
192+
}
193+
}
194+
195+
/**
196+
* Returns a snippet of code surrounding the given line number.
197+
*
198+
* @param lines numbered source code lines
199+
* @param line the line number to center the snippet around
200+
* @return a snippet of code surrounding the given line number
201+
*/
202+
private static String snippet(final List<String> lines, final int line) {
203+
final int start = Math.max(0, line - CONTEXT);
204+
final int end = Math.min(lines.size(), line + CONTEXT + 1);
205+
final var snippet = lines.subList(start, end);
206+
return String.join("\n", snippet);
207+
}
208+
195209
/**
196210
* Number of lines of leading and trailing context surrounding each Semgrep finding to include in
197211
* the code snippet sent to OpenAI.

‎core-codemods/src/test/java/io/codemodder/codemods/SensitiveDataLoggingCodemodTest.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@
1010
testResourceDir = "sensitive-data-logging",
1111
dependencies = {})
1212
@OpenAIIntegrationTest
13-
@Disabled("more work needed before this codemod is reliable enough to include in the test suite")
1413
final class SensitiveDataLoggingCodemodTest implements LLMVerifyingCodemodTestMixin {
1514

1615
@Override
1716
public String getRequirementsPrompt() {
1817
return """
1918
- The code no longer logs sensitive data (or it does so at DEBUG or below level).
19+
- A username alone is not considered sensitive data.
2020
""";
2121
}
2222
}

0 commit comments

Comments
 (0)