From 2fba57b7775ca8029ed2d2f83aaa6113cd0518a3 Mon Sep 17 00:00:00 2001 From: Adva Oren Date: Mon, 22 Jun 2026 20:53:28 +0300 Subject: [PATCH 1/2] fix(golang): reject // indirect //exhortignore as ignore marker (TC-4345) The greedy regex in IgnoredLine matched the last // in a line, causing "// indirect //exhortignore" to be incorrectly treated as ignored. Parse the first // comment instead and only accept standalone ignore markers or the semicolon-separated format (// indirect; exhortignore), matching the JavaScript client behavior. Co-Authored-By: Claude Opus 4.6 --- .../providers/GoModulesProvider.java | 52 +++++++++---------- .../Golang_Modules_Provider_Test.java | 7 +++ 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/src/main/java/io/github/guacsec/trustifyda/providers/GoModulesProvider.java b/src/main/java/io/github/guacsec/trustifyda/providers/GoModulesProvider.java index 90eeb8ce..e8e29610 100644 --- a/src/main/java/io/github/guacsec/trustifyda/providers/GoModulesProvider.java +++ b/src/main/java/io/github/guacsec/trustifyda/providers/GoModulesProvider.java @@ -560,32 +560,32 @@ private String extractPackageName(String line) { public boolean IgnoredLine(String line) { boolean result = false; if (IgnorePatternDetector.containsIgnorePattern(line)) { - // if exhortignore or trustify-da-ignore is alone in a comment or is in a comment together - // with indirect or as a - // comment inside a - // comment ( e.g // indirect //exhort) - // then this line is to be checked if it's a comment after a package name. - if (Pattern.matches(".+//\\s*(exhortignore|trustify-da-ignore)", line) - || Pattern.matches( - ".+//\\s*indirect\\s*;\\s*(//)?\\s*(exhortignore|trustify-da-ignore)", line)) { - String trimmedRow = line.trim(); - // filter out lines where exhortignore or trustify-da-ignore has no meaning - if (!trimmedRow.startsWith("module ") - && !trimmedRow.startsWith("go ") - && !trimmedRow.startsWith("require (") - && !trimmedRow.startsWith("require(") - && !trimmedRow.startsWith("exclude ") - && !trimmedRow.startsWith("replace ") - && !trimmedRow.startsWith("retract ") - && !trimmedRow.startsWith("use ") - && !trimmedRow.contains( - "=>")) { // only for lines that after trimming starts with "require " or starting - // with - // package name followd by one space, and then a semver version. - if (trimmedRow.startsWith("require ") - || Pattern.matches( - "^[a-z.0-9/-]+\\s{1,2}[vV][0-9]\\.[0-9](\\.[0-9]){0,2}.*", trimmedRow)) { - result = true; + String trimmedRow = line.trim(); + int firstComment = trimmedRow.indexOf("//"); + if (firstComment >= 0) { + String comment = trimmedRow.substring(firstComment + 2).trim(); + // Match standalone ignore pattern (e.g. "// exhortignore") or + // semicolon-separated with indirect (e.g. "// indirect; exhortignore", + // "// indirect; // exhortignore"). + // Does NOT match "// indirect //exhortignore" (no semicolon) or + // "// indirect exhortignore" (space-separated) — these are incorrect formats. + if (comment.matches("(exhortignore|trustify-da-ignore)") + || comment.matches("indirect\\s*;\\s*(//)?\\s*(exhortignore|trustify-da-ignore)")) { + // filter out lines where exhortignore or trustify-da-ignore has no meaning + if (!trimmedRow.startsWith("module ") + && !trimmedRow.startsWith("go ") + && !trimmedRow.startsWith("require (") + && !trimmedRow.startsWith("require(") + && !trimmedRow.startsWith("exclude ") + && !trimmedRow.startsWith("replace ") + && !trimmedRow.startsWith("retract ") + && !trimmedRow.startsWith("use ") + && !trimmedRow.contains("=>")) { + if (trimmedRow.startsWith("require ") + || Pattern.matches( + "^[a-z.0-9/-]+\\s{1,2}[vV][0-9]\\.[0-9](\\.[0-9]){0,2}.*", trimmedRow)) { + result = true; + } } } } diff --git a/src/test/java/io/github/guacsec/trustifyda/providers/Golang_Modules_Provider_Test.java b/src/test/java/io/github/guacsec/trustifyda/providers/Golang_Modules_Provider_Test.java index 1849d6f7..cdf9725f 100644 --- a/src/test/java/io/github/guacsec/trustifyda/providers/Golang_Modules_Provider_Test.java +++ b/src/test/java/io/github/guacsec/trustifyda/providers/Golang_Modules_Provider_Test.java @@ -239,6 +239,13 @@ void test_IgnoredLine_rejects_old_space_separated_indirect_format() { .isFalse(); assertThat(provider.IgnoredLine(" github.com/foo/bar v1.0.0 // indirect exhortignore")) .isFalse(); + // Double-slash without semicolon should NOT be recognized (TC-4345) + assertThat( + provider.IgnoredLine( + " github.com/foo/bar v1.0.0 // indirect //trustify-da-ignore")) + .isFalse(); + assertThat(provider.IgnoredLine(" github.com/foo/bar v1.0.0 // indirect //exhortignore")) + .isFalse(); // New semicolon format should still be recognized assertThat( provider.IgnoredLine( From 4dd9db8ae5eba21fcbf5f1cbd889a6bb35a94064 Mon Sep 17 00:00:00 2001 From: Adva Oren Date: Mon, 22 Jun 2026 21:13:06 +0300 Subject: [PATCH 2/2] refactor: extract ignore-format regexes into precompiled Pattern constants Avoids recompiling regexes on every IgnoredLine call. Co-Authored-By: Claude Opus 4.6 --- .../trustifyda/providers/GoModulesProvider.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/main/java/io/github/guacsec/trustifyda/providers/GoModulesProvider.java b/src/main/java/io/github/guacsec/trustifyda/providers/GoModulesProvider.java index e8e29610..56f38b9f 100644 --- a/src/main/java/io/github/guacsec/trustifyda/providers/GoModulesProvider.java +++ b/src/main/java/io/github/guacsec/trustifyda/providers/GoModulesProvider.java @@ -62,6 +62,14 @@ public final class GoModulesProvider extends Provider { "TRUSTIFY_DA_GO_MVS_LOGIC_ENABLED"; private static final Logger log = LoggersFactory.getLogger(GoModulesProvider.class.getName()); public static final String DEFAULT_MAIN_VERSION = "v0.0.0"; + + private static final Pattern STANDALONE_IGNORE_PATTERN = + Pattern.compile("(exhortignore|trustify-da-ignore)"); + private static final Pattern INDIRECT_IGNORE_PATTERN = + Pattern.compile("indirect\\s*;\\s*(//)?\\s*(exhortignore|trustify-da-ignore)"); + private static final Pattern DEPENDENCY_LINE_PATTERN = + Pattern.compile("^[a-z.0-9/-]+\\s{1,2}[vV][0-9]\\.[0-9](\\.[0-9]){0,2}.*"); + private final String goExecutable; public String getMainModuleVersion() { @@ -569,8 +577,8 @@ public boolean IgnoredLine(String line) { // "// indirect; // exhortignore"). // Does NOT match "// indirect //exhortignore" (no semicolon) or // "// indirect exhortignore" (space-separated) — these are incorrect formats. - if (comment.matches("(exhortignore|trustify-da-ignore)") - || comment.matches("indirect\\s*;\\s*(//)?\\s*(exhortignore|trustify-da-ignore)")) { + if (STANDALONE_IGNORE_PATTERN.matcher(comment).matches() + || INDIRECT_IGNORE_PATTERN.matcher(comment).matches()) { // filter out lines where exhortignore or trustify-da-ignore has no meaning if (!trimmedRow.startsWith("module ") && !trimmedRow.startsWith("go ") @@ -582,8 +590,7 @@ public boolean IgnoredLine(String line) { && !trimmedRow.startsWith("use ") && !trimmedRow.contains("=>")) { if (trimmedRow.startsWith("require ") - || Pattern.matches( - "^[a-z.0-9/-]+\\s{1,2}[vV][0-9]\\.[0-9](\\.[0-9]){0,2}.*", trimmedRow)) { + || DEPENDENCY_LINE_PATTERN.matcher(trimmedRow).matches()) { result = true; } }