diff --git a/pkg/fanal/analyzer/language/nodejs/npm/npm.go b/pkg/fanal/analyzer/language/nodejs/npm/npm.go index b827a37f83ff..8f70bd5c25a4 100644 --- a/pkg/fanal/analyzer/language/nodejs/npm/npm.go +++ b/pkg/fanal/analyzer/language/nodejs/npm/npm.go @@ -8,7 +8,6 @@ import ( "os" "path" "path/filepath" - "strings" "golang.org/x/xerrors" @@ -87,13 +86,14 @@ func (a npmLibraryAnalyzer) PostAnalyze(_ context.Context, input analyzer.PostAn func (a npmLibraryAnalyzer) Required(filePath string, _ os.FileInfo) bool { fileName := filepath.Base(filePath) + // Don't save package-lock.json from the `node_modules` directory to avoid duplication and mistakes. if fileName == types.NpmPkgLock && !xpath.Contains(filePath, "node_modules") { return true } - // The file path to package.json - */node_modules//package.json - // The path is slashed in analyzers. - dirs := strings.Split(path.Dir(filePath), "/") - if len(dirs) > 1 && dirs[len(dirs)-2] == "node_modules" && fileName == types.NpmPkg { + + // Save package.json files only from the `node_modules` directory. + // Required to search for licenses. + if fileName == types.NpmPkg && xpath.Contains(filePath, "node_modules") { return true } return false diff --git a/pkg/fanal/analyzer/language/nodejs/npm/npm_test.go b/pkg/fanal/analyzer/language/nodejs/npm/npm_test.go index ec03e751778f..7635e0266729 100644 --- a/pkg/fanal/analyzer/language/nodejs/npm/npm_test.go +++ b/pkg/fanal/analyzer/language/nodejs/npm/npm_test.go @@ -34,6 +34,19 @@ func Test_npmLibraryAnalyzer_Analyze(t *testing.T) { Type: types.Npm, FilePath: "package-lock.json", Libraries: types.Packages{ + { + ID: "@babel/parser@7.23.6", + Name: "@babel/parser", + Version: "7.23.6", + Indirect: true, + Licenses: []string{"MIT"}, + Locations: []types.Location{ + { + StartLine: 6, + EndLine: 10, + }, + }, + }, { ID: "ansi-colors@3.2.3", Name: "ansi-colors", @@ -42,8 +55,8 @@ func Test_npmLibraryAnalyzer_Analyze(t *testing.T) { Indirect: true, Locations: []types.Location{ { - StartLine: 6, - EndLine: 11, + StartLine: 11, + EndLine: 16, }, }, }, @@ -54,8 +67,8 @@ func Test_npmLibraryAnalyzer_Analyze(t *testing.T) { Indirect: true, Locations: []types.Location{ { - StartLine: 12, - EndLine: 16, + StartLine: 17, + EndLine: 21, }, }, }, @@ -68,8 +81,8 @@ func Test_npmLibraryAnalyzer_Analyze(t *testing.T) { Licenses: []string{"MIT"}, Locations: []types.Location{ { - StartLine: 17, - EndLine: 39, + StartLine: 22, + EndLine: 44, }, }, }, @@ -82,12 +95,12 @@ func Test_npmLibraryAnalyzer_Analyze(t *testing.T) { Licenses: []string{"MIT"}, Locations: []types.Location{ { - StartLine: 25, - EndLine: 32, + StartLine: 30, + EndLine: 37, }, { - StartLine: 48, - EndLine: 55, + StartLine: 53, + EndLine: 60, }, }, }, @@ -100,8 +113,8 @@ func Test_npmLibraryAnalyzer_Analyze(t *testing.T) { Licenses: []string{"MIT"}, Locations: []types.Location{ { - StartLine: 40, - EndLine: 62, + StartLine: 45, + EndLine: 67, }, }, }, @@ -113,12 +126,12 @@ func Test_npmLibraryAnalyzer_Analyze(t *testing.T) { Licenses: []string{"MIT"}, Locations: []types.Location{ { - StartLine: 33, - EndLine: 37, + StartLine: 38, + EndLine: 42, }, { - StartLine: 56, - EndLine: 60, + StartLine: 61, + EndLine: 65, }, }, }, @@ -130,8 +143,8 @@ func Test_npmLibraryAnalyzer_Analyze(t *testing.T) { Licenses: []string{"MIT"}, Locations: []types.Location{ { - StartLine: 63, - EndLine: 67, + StartLine: 68, + EndLine: 72, }, }, }, @@ -206,9 +219,14 @@ func Test_nodePkgLibraryAnalyzer_Required(t *testing.T) { filePath: "npm/node_modules/ms/package.json", want: true, }, + { + name: "package.json with `/` in name", + filePath: "npm/node_modules/@babel/parser/package.json", + want: true, + }, { name: "sad path", - filePath: "npm/node_modules/package.json", + filePath: "npm/package.json", want: false, }, { diff --git a/pkg/fanal/analyzer/language/nodejs/npm/testdata/happy/node_modules/@babel/parser/package.json b/pkg/fanal/analyzer/language/nodejs/npm/testdata/happy/node_modules/@babel/parser/package.json new file mode 100644 index 000000000000..5dc69d812815 --- /dev/null +++ b/pkg/fanal/analyzer/language/nodejs/npm/testdata/happy/node_modules/@babel/parser/package.json @@ -0,0 +1,46 @@ +{ + "name": "@babel/parser", + "version": "7.23.6", + "description": "A JavaScript parser", + "author": "The Babel Team (https://babel.dev/team)", + "homepage": "https://babel.dev/docs/en/next/babel-parser", + "bugs": "https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen", + "license": "MIT", + "publishConfig": { + "access": "public" + }, + "keywords": [ + "babel", + "javascript", + "parser", + "tc39", + "ecmascript", + "@babel/parser" + ], + "repository": { + "type": "git", + "url": "https://github.com/babel/babel.git", + "directory": "packages/babel-parser" + }, + "main": "./lib/index.js", + "types": "./typings/babel-parser.d.ts", + "files": [ + "bin", + "lib", + "typings/babel-parser.d.ts", + "index.cjs" + ], + "engines": { + "node": ">=6.0.0" + }, + "devDependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/helper-check-duplicate-nodes": "^7.22.5", + "@babel/helper-fixtures": "^7.23.4", + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", + "charcodes": "^0.2.0" + }, + "bin": "./bin/babel-parser.js", + "type": "commonjs" +} \ No newline at end of file diff --git a/pkg/fanal/analyzer/language/nodejs/npm/testdata/happy/package-lock.json b/pkg/fanal/analyzer/language/nodejs/npm/testdata/happy/package-lock.json index 6d43d12c7888..60c78b708d60 100644 --- a/pkg/fanal/analyzer/language/nodejs/npm/testdata/happy/package-lock.json +++ b/pkg/fanal/analyzer/language/nodejs/npm/testdata/happy/package-lock.json @@ -3,6 +3,11 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@babel/parser": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", + "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==" + }, "ansi-colors": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz",