Skip to content

Commit a4a87fb

Browse files
committed
enhance package.json finder
Signed-off-by: Tristan Bastian <[email protected]>
1 parent 188598c commit a4a87fb

File tree

10 files changed

+2640
-10
lines changed

10 files changed

+2640
-10
lines changed

src/_helpers.ts

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,36 +18,56 @@ Copyright (c) OWASP Foundation. All Rights Reserved.
1818
*/
1919

2020
import { existsSync, readFileSync } from 'fs'
21-
import { dirname, isAbsolute, join } from 'path'
21+
import { dirname, isAbsolute, join, sep } from 'path'
2222

2323
export interface PackageDescription {
2424
path: string
2525
packageJson: any
2626
}
2727

2828
export function getPackageDescription (path: string): PackageDescription | undefined {
29+
const isSubDirOfNodeModules = isSubDirectoryOfNodeModulesFolder(path)
30+
2931
while (isAbsolute(path)) {
30-
const packageJson = join(path, 'package.json')
31-
if (existsSync(packageJson)) {
32+
const pathToPackageJson = join(path, 'package.json')
33+
if (existsSync(pathToPackageJson)) {
3234
try {
33-
return {
34-
path: packageJson,
35-
packageJson: loadJsonFile(packageJson) ?? {}
35+
const contentOfPackageJson = loadJsonFile(pathToPackageJson) ?? {}
36+
// only look for valid candidate if we are in a node_modules subdirectory
37+
if (!isSubDirOfNodeModules || isValidPackageJSON(contentOfPackageJson)) {
38+
return {
39+
path: pathToPackageJson,
40+
packageJson: loadJsonFile(pathToPackageJson) ?? {}
41+
}
3642
}
3743
} catch {
3844
return undefined
3945
}
4046
}
4147

4248
const nextPath = dirname(path)
43-
if (nextPath === path) {
49+
if (nextPath === path || isNodeModulesFolder(nextPath)) {
4450
return undefined
4551
}
4652
path = nextPath
4753
}
4854
return undefined
4955
}
5056

57+
function isNodeModulesFolder (path: string): boolean {
58+
return path.endsWith(`${sep}node_modules`)
59+
}
60+
61+
function isSubDirectoryOfNodeModulesFolder (path: string): boolean {
62+
return path.includes(`${sep}node_modules${sep}`)
63+
}
64+
65+
export function isValidPackageJSON (pkg: any): boolean {
66+
// checking for the existence of name and version properties
67+
// both are required for a valid package.json according to https://docs.npmjs.com/cli/v10/configuring-npm/package-json
68+
return typeof pkg.name === 'string' && typeof pkg.version === 'string'
69+
}
70+
5171
export function loadJsonFile (path: string): any {
5272
return JSON.parse(readFileSync(path, 'utf8'))
5373
// may be replaced by `require(f, { with: { type: "json" } })`
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
*
2+
!/.gitignore
3+
!/.gitattributes
4+
!/README.md
5+
!/package.json
6+
!/package-lock.json
7+
!/webpack.config.js
8+
!/src
9+
!/src/*
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Test: is copied file's package detected
2+
3+
This setup is intended to create reproducible results (SBoM).
4+
It might install outdated, unmaintained or vulnerable components, for showcasing purposes.
5+
6+
Importing `libphonenumber-js/max` should not result in `libphonenumber-js/max` being added to the SBoM without any version.
7+
Instead `libphonenumber-js` should be added with the correct version.
8+
9+
Importing `luxon` should result in `luxon` being added to the SBoM.

0 commit comments

Comments
 (0)