Skip to content

Commit 7d20efe

Browse files
a-orenclaude
andauthored
fix(golang): reject // indirect //exhortignore as ignore marker (guacsec#538)
## Summary - Fix greedy regex in `IgnoredLine` that incorrectly treated `// indirect //exhortignore` as an ignored dependency (TC-4345) - Parse the first `//` comment and only accept standalone ignore markers (`// exhortignore`) or the semicolon-separated format (`// indirect; exhortignore`), matching the JavaScript client behavior - Add test cases for the `// indirect //exhortignore` format ## Test plan - [x] Existing `test_IgnoredLine_rejects_old_space_separated_indirect_format` passes with new assertions - [ ] CI passes - [ ] Verify with integration test `golang-go_mod_with_ignore[stack]` that Java and JS clients produce matching results 🤖 Generated with [Claude Code](https://claude.com/claude-code) ## Summary by Sourcery Update Go modules ignore-line detection to only treat standalone or semicolon-separated ignore markers as valid, and align behavior with the JavaScript client. Bug Fixes: - Prevent lines with the invalid "// indirect //exhortignore" or "// indirect //trustify-da-ignore" formats from being treated as ignored dependencies. Tests: - Extend IgnoredLine tests to cover double-slash indirect formats and confirm they are not recognized while the semicolon format remains supported. --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent cea1a4b commit 7d20efe

2 files changed

Lines changed: 40 additions & 26 deletions

File tree

src/main/java/io/github/guacsec/trustifyda/providers/GoModulesProvider.java

Lines changed: 33 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,14 @@ public final class GoModulesProvider extends Provider {
6262
"TRUSTIFY_DA_GO_MVS_LOGIC_ENABLED";
6363
private static final Logger log = LoggersFactory.getLogger(GoModulesProvider.class.getName());
6464
public static final String DEFAULT_MAIN_VERSION = "v0.0.0";
65+
66+
private static final Pattern STANDALONE_IGNORE_PATTERN =
67+
Pattern.compile("(exhortignore|trustify-da-ignore)");
68+
private static final Pattern INDIRECT_IGNORE_PATTERN =
69+
Pattern.compile("indirect\\s*;\\s*(//)?\\s*(exhortignore|trustify-da-ignore)");
70+
private static final Pattern DEPENDENCY_LINE_PATTERN =
71+
Pattern.compile("^[a-z.0-9/-]+\\s{1,2}[vV][0-9]\\.[0-9](\\.[0-9]){0,2}.*");
72+
6573
private final String goExecutable;
6674

6775
public String getMainModuleVersion() {
@@ -560,32 +568,31 @@ private String extractPackageName(String line) {
560568
public boolean IgnoredLine(String line) {
561569
boolean result = false;
562570
if (IgnorePatternDetector.containsIgnorePattern(line)) {
563-
// if exhortignore or trustify-da-ignore is alone in a comment or is in a comment together
564-
// with indirect or as a
565-
// comment inside a
566-
// comment ( e.g // indirect //exhort)
567-
// then this line is to be checked if it's a comment after a package name.
568-
if (Pattern.matches(".+//\\s*(exhortignore|trustify-da-ignore)", line)
569-
|| Pattern.matches(
570-
".+//\\s*indirect\\s*;\\s*(//)?\\s*(exhortignore|trustify-da-ignore)", line)) {
571-
String trimmedRow = line.trim();
572-
// filter out lines where exhortignore or trustify-da-ignore has no meaning
573-
if (!trimmedRow.startsWith("module ")
574-
&& !trimmedRow.startsWith("go ")
575-
&& !trimmedRow.startsWith("require (")
576-
&& !trimmedRow.startsWith("require(")
577-
&& !trimmedRow.startsWith("exclude ")
578-
&& !trimmedRow.startsWith("replace ")
579-
&& !trimmedRow.startsWith("retract ")
580-
&& !trimmedRow.startsWith("use ")
581-
&& !trimmedRow.contains(
582-
"=>")) { // only for lines that after trimming starts with "require " or starting
583-
// with
584-
// package name followd by one space, and then a semver version.
585-
if (trimmedRow.startsWith("require ")
586-
|| Pattern.matches(
587-
"^[a-z.0-9/-]+\\s{1,2}[vV][0-9]\\.[0-9](\\.[0-9]){0,2}.*", trimmedRow)) {
588-
result = true;
571+
String trimmedRow = line.trim();
572+
int firstComment = trimmedRow.indexOf("//");
573+
if (firstComment >= 0) {
574+
String comment = trimmedRow.substring(firstComment + 2).trim();
575+
// Match standalone ignore pattern (e.g. "// exhortignore") or
576+
// semicolon-separated with indirect (e.g. "// indirect; exhortignore",
577+
// "// indirect; // exhortignore").
578+
// Does NOT match "// indirect //exhortignore" (no semicolon) or
579+
// "// indirect exhortignore" (space-separated) — these are incorrect formats.
580+
if (STANDALONE_IGNORE_PATTERN.matcher(comment).matches()
581+
|| INDIRECT_IGNORE_PATTERN.matcher(comment).matches()) {
582+
// filter out lines where exhortignore or trustify-da-ignore has no meaning
583+
if (!trimmedRow.startsWith("module ")
584+
&& !trimmedRow.startsWith("go ")
585+
&& !trimmedRow.startsWith("require (")
586+
&& !trimmedRow.startsWith("require(")
587+
&& !trimmedRow.startsWith("exclude ")
588+
&& !trimmedRow.startsWith("replace ")
589+
&& !trimmedRow.startsWith("retract ")
590+
&& !trimmedRow.startsWith("use ")
591+
&& !trimmedRow.contains("=>")) {
592+
if (trimmedRow.startsWith("require ")
593+
|| DEPENDENCY_LINE_PATTERN.matcher(trimmedRow).matches()) {
594+
result = true;
595+
}
589596
}
590597
}
591598
}

src/test/java/io/github/guacsec/trustifyda/providers/Golang_Modules_Provider_Test.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,13 @@ void test_IgnoredLine_rejects_old_space_separated_indirect_format() {
239239
.isFalse();
240240
assertThat(provider.IgnoredLine(" github.com/foo/bar v1.0.0 // indirect exhortignore"))
241241
.isFalse();
242+
// Double-slash without semicolon should NOT be recognized (TC-4345)
243+
assertThat(
244+
provider.IgnoredLine(
245+
" github.com/foo/bar v1.0.0 // indirect //trustify-da-ignore"))
246+
.isFalse();
247+
assertThat(provider.IgnoredLine(" github.com/foo/bar v1.0.0 // indirect //exhortignore"))
248+
.isFalse();
242249
// New semicolon format should still be recognized
243250
assertThat(
244251
provider.IgnoredLine(

0 commit comments

Comments
 (0)