github.com/google/osv-scalibr@v0.4.1/extractor/filesystem/language/golang/gomod/gosum.go (about) 1 // Copyright 2025 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package gomod 16 17 import ( 18 "bufio" 19 "fmt" 20 "strings" 21 22 "github.com/google/osv-scalibr/extractor" 23 "github.com/google/osv-scalibr/extractor/filesystem" 24 "github.com/google/osv-scalibr/purl" 25 ) 26 27 // extractFromSum extracts dependencies from the go.sum file. 28 // 29 // Below 1.17 go.mod does not contain indirect dependencies 30 // but they might be in go.sum, thus we look into it as well. 31 // 32 // Note: This function may produce false positives, as the go.sum file might be outdated. 33 func extractFromSum(input *filesystem.ScanInput) (map[pkgKey]*extractor.Package, error) { 34 goSumPath := strings.TrimSuffix(input.Path, ".mod") + ".sum" 35 f, err := input.FS.Open(goSumPath) 36 if err != nil { 37 return nil, err 38 } 39 40 scanner := bufio.NewScanner(f) 41 packages := map[pkgKey]*extractor.Package{} 42 43 for lineNumber := 0; scanner.Scan(); lineNumber++ { 44 line := scanner.Text() 45 46 if line == "" { 47 continue 48 } 49 50 parts := strings.Fields(line) 51 if len(parts) != 3 { 52 return nil, fmt.Errorf("error reading line: %d", lineNumber) 53 } 54 55 name := parts[0] 56 version := strings.TrimPrefix(parts[1], "v") 57 58 // skip a line if the version contains "/go.mod" because lines 59 // containing "/go.mod" are duplicates used to verify the hash of the go.mod file 60 if strings.Contains(version, "/go.mod") { 61 continue 62 } 63 64 packages[pkgKey{name: name, version: version}] = &extractor.Package{ 65 Name: name, 66 Version: version, 67 PURLType: purl.TypeGolang, 68 Locations: []string{goSumPath}, 69 } 70 } 71 72 if err := scanner.Err(); err != nil { 73 return nil, err 74 } 75 76 return packages, nil 77 }