Skip to content
This repository was archived by the owner on Jul 18, 2025. It is now read-only.

Commit 40d5544

Browse files
committed
Read version from binary
Signed-off-by: Christian Dupuis <[email protected]>
1 parent 942f25e commit 40d5544

File tree

1 file changed

+70
-2
lines changed

1 file changed

+70
-2
lines changed

sbom/detect/node.go

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,24 @@
1717
package detect
1818

1919
import (
20+
"bufio"
2021
"fmt"
22+
"io"
23+
"strconv"
2124
"strings"
2225

2326
"github.com/anchore/syft/syft/source"
2427
"github.com/docker/index-cli-plugin/types"
2528
)
2629

27-
func nodePackageDetector(_ []types.Package, image source.Source, lm types.LayerMapping) []types.Package {
30+
func nodePackageDetector(pkgs []types.Package, image source.Source, lm types.LayerMapping) []types.Package {
31+
// Already found nodejs via package manager
32+
for _, p := range pkgs {
33+
if purl, err := types.ToPackageUrl(p.Purl); err == nil && purl.Name == "nodejs" {
34+
return []types.Package{}
35+
}
36+
}
37+
2838
var path []string
2939
var nodeVersion string
3040

@@ -40,12 +50,25 @@ func nodePackageDetector(_ []types.Package, image source.Source, lm types.LayerM
4050
}
4151
}
4252

43-
if nodeVersion != "" && len(path) > 0 {
53+
if len(path) > 0 {
4454
res, _ := image.FileResolver(source.SquashedScope)
4555
for _, p := range path {
4656
fp := fmt.Sprintf("%s/node", p)
4757
if locations, err := res.FilesByPath(fp); err == nil && len(locations) > 0 {
4858
loc := locations[0]
59+
60+
if nodeVersion == "" {
61+
f, _ := res.FileContentsByLocation(loc)
62+
values := readStrings(f, "node.js/v")
63+
if len(values) == 1 {
64+
nodeVersion = values[0][9:]
65+
}
66+
}
67+
68+
if nodeVersion == "" {
69+
continue
70+
}
71+
4972
return []types.Package{{
5073
Type: "github",
5174
Namespace: "nodejs",
@@ -68,3 +91,48 @@ func nodePackageDetector(_ []types.Package, image source.Source, lm types.LayerM
6891

6992
return []types.Package{}
7093
}
94+
95+
var (
96+
min = 6
97+
max = 256
98+
ascii = true
99+
)
100+
101+
func readStrings(file io.ReadCloser, prefix string) []string {
102+
detected := make([]string, 0)
103+
in := bufio.NewReader(file)
104+
str := make([]rune, 0, max)
105+
filePos := int64(0)
106+
print := func() {
107+
if len(str) >= min {
108+
s := string(str)
109+
if strings.HasPrefix(s, prefix) {
110+
detected = append(detected, s)
111+
}
112+
}
113+
str = str[0:0]
114+
}
115+
for {
116+
var (
117+
r rune
118+
wid int
119+
err error
120+
)
121+
for ; ; filePos += int64(wid) {
122+
r, wid, err = in.ReadRune()
123+
if err != nil {
124+
return detected
125+
}
126+
if !strconv.IsPrint(r) || ascii && r >= 0xFF {
127+
print()
128+
continue
129+
}
130+
// It's printable. Keep it.
131+
if len(str) >= max {
132+
print()
133+
}
134+
str = append(str, r)
135+
}
136+
}
137+
return detected
138+
}

0 commit comments

Comments
 (0)