Skip to content

Commit 3ab7599

Browse files
committed
fix(go): handle replace directives in go list -m all parsing
The stream filter in getFinalPackagesVersionsForModule() only accepted 2-part lines from `go list -m all`, silently dropping replace directive lines (5-part format: name v1 => replacement v2). This caused replaced modules to be absent from the MVS version map, resulting in incorrect SBOM versions. Extract parseModuleVersions() to handle both standard and replace directive lines, mirroring the JS client fix (PR #505). Implements TC-4359 Assisted-by: Claude Code
1 parent 74fa2d9 commit 3ab7599

3 files changed

Lines changed: 25 additions & 10 deletions

File tree

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

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -347,12 +347,7 @@ private Map<String, List<String>> getFinalPackagesVersionsForModule(
347347
Operations.runProcessGetOutput(manifestPath.getParent(), goExecutable, "mod", "download");
348348
String finalVersionsForAllModules =
349349
Operations.runProcessGetOutput(manifestPath.getParent(), goExecutable, "list", "-m", "all");
350-
Map<String, String> finalModulesVersions =
351-
Arrays.stream(finalVersionsForAllModules.split(Operations.GENERIC_LINE_SEPARATOR))
352-
.filter(string -> string.trim().split(" ").length == 2)
353-
.collect(
354-
Collectors.toMap(
355-
t -> t.split(" ")[0], t -> t.split(" ")[1], (first, second) -> second));
350+
Map<String, String> finalModulesVersions = parseModuleVersions(finalVersionsForAllModules);
356351
Map<String, List<String>> listWithModifiedVersions = new HashMap<>();
357352
// Process all entries, including those without versions (like the root module)
358353
edges.forEach(
@@ -387,6 +382,24 @@ private Map<String, List<String>> getFinalPackagesVersionsForModule(
387382
return listWithModifiedVersions;
388383
}
389384

385+
/**
386+
* Parses {@code go list -m all} output into a map of module names to their final resolved
387+
* versions. Handles both standard lines ({@code name version}) and replace directive lines
388+
* ({@code name v1 => replacement v2}).
389+
*/
390+
static Map<String, String> parseModuleVersions(String goListOutput) {
391+
return Arrays.stream(goListOutput.split(Operations.GENERIC_LINE_SEPARATOR))
392+
.map(String::trim)
393+
.map(line -> line.split(" "))
394+
.filter(parts -> parts.length == 2 || (parts.length >= 4 && parts[2].equals("=>")))
395+
.collect(
396+
Collectors.toMap(
397+
parts -> parts[0],
398+
parts ->
399+
parts.length >= 4 && parts[2].equals("=>") ? parts[parts.length - 1] : parts[1],
400+
(first, second) -> second));
401+
}
402+
390403
private List<String> getListOfPackagesWithFinalVersions(
391404
Map<String, String> finalModulesVersions, List<String> packages) {
392405
return packages.stream()

src/test/resources/tst_manifests/golang/go_mod_light_no_ignore/expected_sbom_stack_analysis.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -263,11 +263,11 @@
263263
},
264264
{
265265
"type": "library",
266-
"bom-ref": "pkg:golang/gopkg.in/yaml.v3@v3.0.1",
266+
"bom-ref": "pkg:golang/gopkg.in/yaml.v3@v3.0.0",
267267
"group": "gopkg.in",
268268
"name": "yaml.v3",
269-
"version": "v3.0.1",
270-
"purl": "pkg:golang/gopkg.in/yaml.v3@v3.0.1"
269+
"version": "v3.0.0",
270+
"purl": "pkg:golang/gopkg.in/yaml.v3@v3.0.0"
271271
},
272272
{
273273
"type": "library",
@@ -497,7 +497,7 @@
497497
"dependsOn": []
498498
},
499499
{
500-
"ref": "pkg:golang/gopkg.in/yaml.v3@v3.0.1",
500+
"ref": "pkg:golang/gopkg.in/yaml.v3@v3.0.0",
501501
"dependsOn": [
502502
"pkg:golang/gopkg.in/check.v1@v0.0.0-20161208181325-20d25e280405"
503503
]

src/test/resources/tst_manifests/golang/go_mod_light_no_ignore/go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,5 @@ require golang.org/x/tools v0.0.0-20210112183307-1e6ecd4bf1b0
66
require github.com/spf13/cobra v0.0.5
77

88
require gopkg.in/yaml.v3 v3.0.1 // indirect
9+
10+
replace gopkg.in/yaml.v3 v3.0.1 => gopkg.in/yaml.v3 v3.0.0

0 commit comments

Comments
 (0)