scanoss 0.2.28 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/reuse.yml +15 -0
- package/.github/workflows/scanoss.yml +24 -0
- package/.gitignore +0 -1
- package/.idea/workspace.xml +296 -6
- package/.nyc_output/a25d3ac4-ee71-4c5e-926e-3a17714555cd.json +1 -0
- package/.nyc_output/processinfo/a25d3ac4-ee71-4c5e-926e-3a17714555cd.json +1 -0
- package/.nyc_output/processinfo/index.json +1 -0
- package/.reuse/dep5 +16 -0
- package/LICENSES/CC0-1.0.txt +121 -0
- package/LICENSES/MIT.txt +9 -0
- package/README.md +9 -0
- package/build/main/bin/cli-bin.js +4 -3
- package/build/main/commands/dep.js +1 -2
- package/build/main/commands/fingerprint.js +17 -9
- package/build/main/commands/helpers.js +1 -2
- package/build/main/commands/scan.js +3 -2
- package/build/main/index.js +1 -2
- package/build/main/lib/dependencies/DependencyScanner.d.ts +1 -1
- package/build/main/lib/dependencies/DependencyScanner.js +23 -12
- package/build/main/lib/dependencies/DependencyScannerCfg.js +1 -2
- package/build/main/lib/dependencies/DependencyTypes.js +0 -1
- package/build/main/lib/dependencies/LocalDependency/DependencyTypes.js +0 -1
- package/build/main/lib/dependencies/LocalDependency/LocalDependency.js +3 -2
- package/build/main/lib/dependencies/LocalDependency/parsers/golangParser.d.ts +1 -0
- package/build/main/lib/dependencies/LocalDependency/parsers/golangParser.js +50 -16
- package/build/main/lib/dependencies/LocalDependency/parsers/mavenParser.js +1 -2
- package/build/main/lib/dependencies/LocalDependency/parsers/npmParser.d.ts +10 -0
- package/build/main/lib/dependencies/LocalDependency/parsers/npmParser.js +146 -10
- package/build/main/lib/dependencies/LocalDependency/parsers/pyParser.js +1 -2
- package/build/main/lib/dependencies/LocalDependency/parsers/rubyParser.js +1 -2
- package/build/main/lib/dependencies/LocalDependency/parsers/utils.js +1 -2
- package/build/main/lib/filters/defaultFilter.js +1 -2
- package/build/main/lib/filters/filtering.js +1 -2
- package/build/main/lib/grpc/GrpcDependencyService.js +1 -2
- package/build/main/lib/grpc/scanoss/api/components/v2/scanoss-components_grpc_pb.d.ts +62 -0
- package/build/main/lib/grpc/scanoss/api/components/v2/scanoss-components_grpc_pb.js +128 -0
- package/build/main/lib/grpc/scanoss/api/components/v2/scanoss-components_pb.d.ts +1 -0
- package/build/main/lib/grpc/scanoss/api/components/v2/scanoss-components_pb.js +1403 -0
- package/build/main/lib/scanner/Dispatcher/DispatchableItem.js +1 -2
- package/build/main/lib/scanner/Dispatcher/Dispatcher.js +1 -2
- package/build/main/lib/scanner/Dispatcher/DispatcherResponse.js +1 -2
- package/build/main/lib/scanner/Dispatcher/GlobalControllerAborter.js +1 -2
- package/build/main/lib/scanner/Scannable/ScannableItem.js +1 -2
- package/build/main/lib/scanner/Scanner.js +1 -2
- package/build/main/lib/scanner/ScannerCfg.js +2 -3
- package/build/main/lib/scanner/ScannerTypes.d.ts +1 -0
- package/build/main/lib/scanner/ScannerTypes.js +2 -2
- package/build/main/lib/scanner/WfpProvider/FingerprintPackage.js +1 -2
- package/build/main/lib/scanner/WfpProvider/WfpCalculator/WfpCalculator.js +175 -18
- package/build/main/lib/scanner/WfpProvider/WfpCalculator/Winnower.d.ts +3 -0
- package/build/main/lib/scanner/WfpProvider/WfpCalculator/Winnower.js +211 -0
- package/build/main/lib/scanner/WfpProvider/WfpProvider.js +1 -2
- package/build/main/lib/scanner/WfpProvider/WfpSplitter/WfpSplitter.js +1 -2
- package/build/main/lib/tree/File.js +1 -2
- package/build/main/lib/tree/Folder.js +1 -2
- package/build/main/lib/tree/Node.js +1 -2
- package/build/main/lib/tree/Tree.js +1 -2
- package/build/module/bin/cli-bin.js +4 -2
- package/build/module/commands/fingerprint.js +22 -13
- package/build/module/commands/scan.js +4 -2
- package/build/module/lib/dependencies/DependencyScanner.d.ts +1 -1
- package/build/module/lib/dependencies/DependencyScanner.js +23 -11
- package/build/module/lib/dependencies/LocalDependency/LocalDependency.js +5 -3
- package/build/module/lib/dependencies/LocalDependency/parsers/golangParser.d.ts +1 -0
- package/build/module/lib/dependencies/LocalDependency/parsers/golangParser.js +47 -14
- package/build/module/lib/dependencies/LocalDependency/parsers/npmParser.d.ts +10 -0
- package/build/module/lib/dependencies/LocalDependency/parsers/npmParser.js +140 -8
- package/build/module/lib/grpc/scanoss/api/components/v2/scanoss-components_grpc_pb.d.ts +62 -0
- package/build/module/lib/grpc/scanoss/api/components/v2/scanoss-components_grpc_pb.js +128 -0
- package/build/module/lib/grpc/scanoss/api/components/v2/scanoss-components_pb.d.ts +1 -0
- package/build/module/lib/grpc/scanoss/api/components/v2/scanoss-components_pb.js +1403 -0
- package/build/module/lib/scanner/ScannerCfg.js +2 -2
- package/build/module/lib/scanner/ScannerTypes.d.ts +1 -0
- package/build/module/lib/scanner/ScannerTypes.js +2 -1
- package/build/module/lib/scanner/WfpProvider/WfpCalculator/WfpCalculator.js +175 -17
- package/build/module/lib/scanner/WfpProvider/WfpCalculator/Winnower.d.ts +3 -0
- package/build/module/lib/scanner/WfpProvider/WfpCalculator/Winnower.js +211 -0
- package/build/tsconfig.module.tsbuildinfo +1 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -17
- package/src/bin/cli-bin.ts +3 -1
- package/src/commands/fingerprint.ts +23 -14
- package/src/commands/scan.ts +10 -2
- package/src/lib/dependencies/DependencyScanner.ts +20 -12
- package/src/lib/dependencies/LocalDependency/LocalDependency.ts +8 -2
- package/src/lib/dependencies/LocalDependency/parsers/golangParser.ts +67 -15
- package/src/lib/dependencies/LocalDependency/parsers/npmParser.ts +182 -7
- package/src/lib/scanner/ScannerCfg.ts +2 -1
- package/src/lib/scanner/ScannerTypes.ts +1 -0
- package/src/lib/scanner/WfpProvider/FingerprintPackage.ts +1 -1
- package/src/lib/scanner/WfpProvider/WfpCalculator/WfpCalculator.ts +174 -17
- package/tests/WfpCalculator.spec.ts +103 -0
- package/{test/dependencies/data → tests/data/dependencies}/Gemfile/1/Gemfile +0 -0
- package/{test/dependencies/data → tests/data/dependencies}/Gemfile/1/Gemfile~ +0 -0
- package/{test/dependencies/data → tests/data/dependencies}/Gemfile/2/Gemfile +0 -0
- package/{test/dependencies/data → tests/data/dependencies}/Gemfile/2/Gemfile~ +0 -0
- package/{test/dependencies/data → tests/data/dependencies}/Gemfile/3/Gemfile +0 -0
- package/{test/dependencies/data → tests/data/dependencies}/Gemfile/3/Gemfile~ +0 -0
- package/{test/dependencies/data → tests/data/dependencies}/Gemfile/4/Gemfile +0 -0
- package/{test/dependencies/data → tests/data/dependencies}/Gemfile/4/Gemfile~ +0 -0
- package/{test/dependencies/data → tests/data/dependencies}/Gemfile.lock/1/Gemfile.lock +0 -0
- package/{test/dependencies/data → tests/data/dependencies}/Gemfile.lock/2/Gemfile.lock +0 -0
- package/{test/dependencies/data → tests/data/dependencies}/Gemfile.lock/2/Gemfile.lock~ +0 -0
- package/tests/data/dependencies/go.sum/1/go.sum +119 -0
- package/tests/data/dependencies/go.sum/depJSON.sh +23 -0
- package/tests/data/dependencies/package-lock/1/package-lock.json +715 -0
- package/tests/data/dependencies/package-lock/2/package-lock.json +32069 -0
- package/tests/data/dependencies/package-lock/3/package-lock.json +9013 -0
- package/{test/dependencies/data → tests/data/dependencies}/pom.xml/1/pom.xml +0 -0
- package/tests/data/dependencies/yarn-lock/generate_expected_output.sh +4 -0
- package/tests/data/dependencies/yarn-lock/v1/yarn.lock +50 -0
- package/tests/data/dependencies/yarn-lock/v1/yarn.lock-expected +13 -0
- package/tests/data/dependencies/yarn-lock/v1-complex/yarn.lock +27 -0
- package/tests/data/dependencies/yarn-lock/v1-complex/yarn.lock-expected +8 -0
- package/tests/data/dependencies/yarn-lock/v1-complex2/yarn.lock +220 -0
- package/tests/data/dependencies/yarn-lock/v2/yarn.lock +31 -0
- package/tests/data/dependencies/yarn-lock/v2/yarn.lock-expected +57 -0
- package/tests/data/dependencies/yarn-lock/v2-local/yarn.lock +11 -0
- package/tests/data/dependencies/yarn-lock/v2-local/yarn.lock-expected +27204 -0
- package/tests/data/scanner/file1.c +41 -0
- package/tests/data/scanner/file2.go +87 -0
- package/tests/dependencies/golangParser.goModParser.specs.ts +146 -0
- package/tests/dependencies/npmParser.spec.ts +133 -0
- package/tsconfig.json +4 -3
- package/yarn.lock +4596 -5321
- package/examples/defaultFilter.json +0 -203
- package/package-lock.json +0 -18588
- package/src/lib/scanner/Winnower/WinnowerExtractor.ts +0 -37
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import { isFolder } from
|
|
2
|
-
import { ScannerEvents, WfpCalculator } from
|
|
3
|
-
import { Tree } from
|
|
4
|
-
import { FilterList } from
|
|
5
|
-
import {
|
|
1
|
+
import { isFolder } from './helpers';
|
|
2
|
+
import { ScannerEvents, WfpCalculator, WinnowingMode } from '..';
|
|
3
|
+
import { Tree } from '../lib/tree/Tree';
|
|
4
|
+
import { FilterList } from '../lib/filters/filtering';
|
|
5
|
+
import {
|
|
6
|
+
FingerprintPackage
|
|
7
|
+
} from '../lib/scanner/WfpProvider/FingerprintPackage';
|
|
6
8
|
import fs from 'fs';
|
|
7
|
-
import { defaultFilter } from
|
|
9
|
+
import { defaultFilter } from '../lib/filters/defaultFilter';
|
|
8
10
|
import cliProgress from 'cli-progress';
|
|
11
|
+
import { IWfpProviderInput } from '../lib/scanner/WfpProvider/WfpProvider';
|
|
9
12
|
|
|
10
13
|
|
|
11
14
|
export async function fingerprintHandler(rootPath: string, options: any): Promise<void> {
|
|
@@ -15,14 +18,19 @@ export async function fingerprintHandler(rootPath: string, options: any): Promis
|
|
|
15
18
|
const pathIsFolder = await isFolder(rootPath);
|
|
16
19
|
const wfpCalculator = new WfpCalculator();
|
|
17
20
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
let filesToFingerprint: string[] = [];
|
|
22
|
+
if (pathIsFolder) {
|
|
23
|
+
const tree = new Tree(rootPath);
|
|
24
|
+
const filter = new FilterList('');
|
|
25
|
+
filter.load(defaultFilter as FilterList);
|
|
21
26
|
|
|
22
|
-
|
|
23
|
-
|
|
27
|
+
tree.loadFilter(filter);
|
|
28
|
+
tree.buildTree();
|
|
29
|
+
filesToFingerprint = tree.getFileList();
|
|
30
|
+
} else {
|
|
31
|
+
filesToFingerprint.push(rootPath)
|
|
32
|
+
}
|
|
24
33
|
|
|
25
|
-
const filesToFingerprint = tree.getFileList();
|
|
26
34
|
|
|
27
35
|
const optBar1 = { format: 'Fingerprinting Progress: [{bar}] {percentage}% | Fingerprinted {value} files of {total}' };
|
|
28
36
|
const bar1 = new cliProgress.SingleBar(optBar1, cliProgress.Presets.shades_classic);
|
|
@@ -48,8 +56,9 @@ export async function fingerprintHandler(rootPath: string, options: any): Promis
|
|
|
48
56
|
}
|
|
49
57
|
});
|
|
50
58
|
|
|
51
|
-
|
|
52
|
-
|
|
59
|
+
const wfpInput: IWfpProviderInput = {fileList: filesToFingerprint, folderRoot: rootPath}
|
|
60
|
+
if(options.hpsm) wfpInput.winnowingMode = WinnowingMode.FULL_WINNOWING_HPSM;
|
|
61
|
+
wfpCalculator.start(wfpInput);
|
|
53
62
|
|
|
54
63
|
|
|
55
64
|
}
|
package/src/commands/scan.ts
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import { Scanner } from '../lib/scanner/Scanner';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
SbomMode,
|
|
4
|
+
ScannerEvents,
|
|
5
|
+
ScannerInput,
|
|
6
|
+
WinnowingMode
|
|
7
|
+
} from '../lib/scanner/ScannerTypes';
|
|
3
8
|
import { ScannerCfg } from '../lib/scanner/ScannerCfg';
|
|
4
9
|
import { Tree } from '../lib/tree/Tree';
|
|
5
10
|
|
|
6
11
|
import cliProgress from 'cli-progress';
|
|
7
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
DispatcherResponse
|
|
14
|
+
} from '../lib/scanner/Dispatcher/DispatcherResponse';
|
|
8
15
|
import { defaultFilter } from '../lib/filters/defaultFilter';
|
|
9
16
|
import { FilterList } from '../lib/filters/filtering';
|
|
10
17
|
|
|
@@ -80,6 +87,7 @@ export async function scanHandler(rootPath: string, options: any): Promise<void>
|
|
|
80
87
|
});
|
|
81
88
|
|
|
82
89
|
if (options.wfp) scannerInput.wfpPath = rootPath;
|
|
90
|
+
if (options.hpsm) scannerInput.winnowingMode = WinnowingMode.FULL_WINNOWING_HPSM
|
|
83
91
|
|
|
84
92
|
if (options.ignore) {
|
|
85
93
|
scannerInput.sbom = fs.readFileSync(options.ignore, 'utf-8');
|
|
@@ -26,9 +26,10 @@ export class DependencyScanner {
|
|
|
26
26
|
const grpcResponse = await this.grpcDependencyService.get(request);
|
|
27
27
|
const response = grpcResponse.toObject();
|
|
28
28
|
|
|
29
|
-
|
|
30
29
|
// Extract scope from localDependencies and add it to response
|
|
31
|
-
|
|
30
|
+
// Also adds the requirements field from localDependency to the response if the server didn't
|
|
31
|
+
// replay back a version
|
|
32
|
+
this.repairOutput(localDependencies, response);
|
|
32
33
|
return response;
|
|
33
34
|
}
|
|
34
35
|
|
|
@@ -71,27 +72,34 @@ export class DependencyScanner {
|
|
|
71
72
|
}
|
|
72
73
|
}
|
|
73
74
|
|
|
74
|
-
private
|
|
75
|
-
): IDependencyResponse {
|
|
76
|
-
|
|
77
|
-
const scopeHashMap = {};
|
|
75
|
+
private repairOutput(localdependency: ILocalDependencies, serverResponse: DependencyResponse.AsObject) {
|
|
78
76
|
|
|
77
|
+
// Create a map with key = [filename + purl] and the value is an object containing:
|
|
78
|
+
// * The scope of the local dependency
|
|
79
|
+
// * The requirement of the local dependency
|
|
80
|
+
// Later this map is used to add information in the server response
|
|
81
|
+
const localDependencyInfo = {};
|
|
79
82
|
for (const file of localdependency.files) {
|
|
80
83
|
const filename = file.file
|
|
81
|
-
for (const
|
|
82
|
-
|
|
84
|
+
for (const localDependency of file.purls) {
|
|
85
|
+
const localInfo = {}
|
|
86
|
+
if (localDependency?.scope) localInfo['scope'] = localDependency.scope
|
|
87
|
+
if(localDependency?.requirement) localInfo['requirement'] = localDependency.requirement
|
|
88
|
+
localDependencyInfo[filename + localDependency.purl] = localInfo;
|
|
83
89
|
}
|
|
84
90
|
}
|
|
85
91
|
|
|
86
92
|
for (const file of serverResponse.filesList) {
|
|
87
93
|
const filename = file.file
|
|
88
94
|
for (const dependency of file.dependenciesList) {
|
|
89
|
-
const
|
|
90
|
-
if (scope) dependency['scope'] = scope;
|
|
95
|
+
const localDependencyData = localDependencyInfo[filename + dependency.purl];
|
|
96
|
+
if (localDependencyData?.scope) dependency['scope'] = localDependencyData.scope;
|
|
97
|
+
if (localDependencyData?.requirement && dependency.version == "") {
|
|
98
|
+
dependency.version = localDependencyData.requirement;
|
|
99
|
+
}
|
|
91
100
|
}
|
|
92
101
|
}
|
|
93
|
-
|
|
94
|
-
return serverResponse;
|
|
95
102
|
}
|
|
96
103
|
|
|
104
|
+
|
|
97
105
|
}
|
|
@@ -3,9 +3,13 @@ import fs from 'fs';
|
|
|
3
3
|
import { ParserFuncType, ILocalDependencies } from "./DependencyTypes";
|
|
4
4
|
import { requirementsParser } from "./parsers/pyParser";
|
|
5
5
|
import { pomParser } from "./parsers/mavenParser";
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
packagelockParser,
|
|
8
|
+
packageParser,
|
|
9
|
+
yarnLockParser
|
|
10
|
+
} from './parsers/npmParser';
|
|
7
11
|
import { gemfilelockParser, gemfileParser } from "./parsers/rubyParser";
|
|
8
|
-
import { goModParser } from './parsers/golangParser';
|
|
12
|
+
import { goModParser, goSumParser } from './parsers/golangParser';
|
|
9
13
|
|
|
10
14
|
export class LocalDependencies {
|
|
11
15
|
|
|
@@ -24,6 +28,8 @@ export class LocalDependencies {
|
|
|
24
28
|
'Gemfile': gemfileParser,
|
|
25
29
|
'Gemfile.lock': gemfilelockParser,
|
|
26
30
|
'go.mod': goModParser,
|
|
31
|
+
'go.sum': goSumParser,
|
|
32
|
+
'yarn.lock': yarnLockParser
|
|
27
33
|
};
|
|
28
34
|
}
|
|
29
35
|
|
|
@@ -3,15 +3,6 @@ import { ILocalDependency } from "../DependencyTypes";
|
|
|
3
3
|
import { PackageURL } from "packageurl-js";
|
|
4
4
|
import path from "path";
|
|
5
5
|
|
|
6
|
-
function parseModule (str: string) {
|
|
7
|
-
const res = /(?<type>[^\s]+)(?:\s)+(?<ns_name>[^\s]+)\s?(?<version>(.*))/.exec(str);
|
|
8
|
-
return {
|
|
9
|
-
type: res.groups.type,
|
|
10
|
-
ns_name: res.groups.ns_name,
|
|
11
|
-
version: res.groups.version
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
|
|
15
6
|
function parseDepLink (str: string) {
|
|
16
7
|
const res = /.*?(?<ns_name>[^\s]+)\s+(?<version>(.*))/.exec(str);
|
|
17
8
|
return {
|
|
@@ -20,6 +11,16 @@ function parseDepLink (str: string) {
|
|
|
20
11
|
};
|
|
21
12
|
}
|
|
22
13
|
|
|
14
|
+
function getDepDataGoModFromLine(line: string) {
|
|
15
|
+
const {ns_name, version} = parseDepLink(line);
|
|
16
|
+
|
|
17
|
+
const index = ns_name.lastIndexOf('/');
|
|
18
|
+
const namespace = ns_name.substring(0, index);
|
|
19
|
+
const name = ns_name.substring(index + 1);
|
|
20
|
+
|
|
21
|
+
return {namespace, name, version}
|
|
22
|
+
}
|
|
23
|
+
|
|
23
24
|
// Removes comments and spaces
|
|
24
25
|
function preprocessLine(line: string) {
|
|
25
26
|
if (line.includes("//"))
|
|
@@ -45,7 +46,6 @@ export function goModParser(fileContent: string, filePath: string): ILocalDepend
|
|
|
45
46
|
const lines = fileContent.split('\n');
|
|
46
47
|
|
|
47
48
|
const require = [];
|
|
48
|
-
const exclude = [];
|
|
49
49
|
|
|
50
50
|
for (let num = 0 ; num < lines.length ; num+=1) {
|
|
51
51
|
|
|
@@ -57,11 +57,7 @@ export function goModParser(fileContent: string, filePath: string): ILocalDepend
|
|
|
57
57
|
line = preprocessLine(lines[num]);
|
|
58
58
|
while (num < lines.length && line!==')') {
|
|
59
59
|
|
|
60
|
-
const {
|
|
61
|
-
|
|
62
|
-
const index = ns_name.lastIndexOf('/');
|
|
63
|
-
const namespace = ns_name.substring(0, index);
|
|
64
|
-
const name = ns_name.substring(index + 1);
|
|
60
|
+
const {namespace, name, version} = getDepDataGoModFromLine(line)
|
|
65
61
|
|
|
66
62
|
const purlString = new PackageURL(PURL_TYPE, namespace, name, version, undefined, undefined).toString();
|
|
67
63
|
results.purls.push({purl: purlString});
|
|
@@ -76,3 +72,59 @@ export function goModParser(fileContent: string, filePath: string): ILocalDepend
|
|
|
76
72
|
|
|
77
73
|
return results;
|
|
78
74
|
}
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
function parseGoSumDepLink (str: string) {
|
|
81
|
+
const res = /.*?(?<ns_name>[^\s]+)\s+(?<version>(.*))\s+h1:(?<checksum>(.*))/.exec(str);
|
|
82
|
+
return {
|
|
83
|
+
ns_name: res?.groups?.ns_name,
|
|
84
|
+
version: res?.groups?.version,
|
|
85
|
+
checksum: res?.groups?.checksum
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function getDepDataGoSumFromLine(line: string) {
|
|
90
|
+
const {ns_name, version} = parseGoSumDepLink(line);
|
|
91
|
+
|
|
92
|
+
if (!ns_name) return {};
|
|
93
|
+
|
|
94
|
+
const index = ns_name.lastIndexOf('/');
|
|
95
|
+
const namespace = ns_name.substring(0, index);
|
|
96
|
+
const name = ns_name.substring(index + 1);
|
|
97
|
+
|
|
98
|
+
return {namespace, name, version}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// See reference on: https://go.dev/ref/mod#go-mod-file
|
|
102
|
+
export function goSumParser(fileContent: string, filePath: string): ILocalDependency {
|
|
103
|
+
|
|
104
|
+
// If the file is not a go.mod manifest file, return an empty results
|
|
105
|
+
const results: ILocalDependency = { file: filePath, purls: [] };
|
|
106
|
+
if (path.basename(filePath) != 'go.sum')
|
|
107
|
+
return results;
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
const lines = fileContent.split('\n');
|
|
111
|
+
for (let num = 0; num < lines.length; num += 1) {
|
|
112
|
+
|
|
113
|
+
let line = preprocessLine(lines[num]); //Deletes coments
|
|
114
|
+
if(!line) continue
|
|
115
|
+
|
|
116
|
+
line = line.replace('/go.mod', '')
|
|
117
|
+
const {namespace, name, version} = getDepDataGoSumFromLine(line)
|
|
118
|
+
|
|
119
|
+
if (!name) continue
|
|
120
|
+
|
|
121
|
+
//const purlString = new PackageURL(PURL_TYPE, namespace, name, undefined, undefined, undefined).toString();
|
|
122
|
+
const purlString = `pkg:${PURL_TYPE}/${namespace}/${name}`
|
|
123
|
+
results.purls.push({purl: purlString, requirement: version})
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return results;
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
}
|
|
130
|
+
|
|
@@ -16,7 +16,6 @@ export function packageParser(fileContent: string, filePath: string): ILocalDepe
|
|
|
16
16
|
const o = JSON.parse(fileContent);
|
|
17
17
|
let devDeps = Object.keys(o.devDependencies || {});
|
|
18
18
|
let deps = Object.keys(o.dependencies || {});
|
|
19
|
-
let listDeps = [...deps, ...devDeps];
|
|
20
19
|
|
|
21
20
|
for(const name of deps){
|
|
22
21
|
const purlString = new PackageURL(PURL_TYPE, undefined, name, undefined, undefined, undefined).toString();
|
|
@@ -34,18 +33,194 @@ export function packageParser(fileContent: string, filePath: string): ILocalDepe
|
|
|
34
33
|
|
|
35
34
|
// Parse a package-lock.json file from node projects
|
|
36
35
|
// See reference on: https://docs.npmjs.com/cli/v8/configuring-npm/package-json
|
|
37
|
-
const MANIFEST_FILE_1 = 'package-lock.json';
|
|
38
36
|
export function packagelockParser(fileContent: string, filePath: string): ILocalDependency {
|
|
39
37
|
|
|
40
38
|
const results: ILocalDependency = {file: filePath, purls: []};
|
|
41
|
-
|
|
39
|
+
|
|
40
|
+
if(path.basename(filePath) != 'package-lock.json')
|
|
42
41
|
return results;
|
|
43
42
|
|
|
44
|
-
const
|
|
45
|
-
|
|
43
|
+
const packages = JSON.parse(fileContent)?.packages;
|
|
44
|
+
|
|
45
|
+
if(!packages) return results;
|
|
46
|
+
|
|
47
|
+
for (const [key, value] of Object.entries(packages)) {
|
|
46
48
|
if(!key) continue;
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
|
|
50
|
+
const keySplit = key.split("/")
|
|
51
|
+
const depName = keySplit[keySplit.length-1]
|
|
52
|
+
|
|
53
|
+
let purl = new PackageURL(PURL_TYPE, undefined, depName,undefined, undefined, undefined).toString();
|
|
54
|
+
let req = value['version'];
|
|
55
|
+
results.purls.push({purl: purl, requirement: req});
|
|
49
56
|
}
|
|
57
|
+
|
|
58
|
+
return results;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
export function yarnLockParser(fileContent: string, filePath: string): ILocalDependency {
|
|
64
|
+
const results: ILocalDependency = {file: filePath, purls: []};
|
|
65
|
+
|
|
66
|
+
if(path.basename(filePath) != 'yarn.lock')
|
|
50
67
|
return results;
|
|
68
|
+
|
|
69
|
+
const yarnVersion = yarnLockRecognizeVersion(fileContent)
|
|
70
|
+
if (yarnVersion === YarnLockVersionEnum.V1) return yarnLockV1Parser(fileContent, filePath)
|
|
71
|
+
else if (yarnVersion === YarnLockVersionEnum.V2) return yarnLockV2Parser(fileContent, filePath)
|
|
72
|
+
|
|
73
|
+
return results;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
enum YarnLockVersionEnum {
|
|
77
|
+
"V1" ,
|
|
78
|
+
"V2",
|
|
79
|
+
UnknownYarnLockFormat
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/*
|
|
83
|
+
The start of v1 file has this:
|
|
84
|
+
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
|
85
|
+
# yarn lockfile v1
|
|
86
|
+
|
|
87
|
+
The start of v2 file has this:
|
|
88
|
+
# This file is generated by running "yarn install" inside your project.
|
|
89
|
+
# Manual changes might be lost - proceed with caution!
|
|
90
|
+
|
|
91
|
+
__metadata:
|
|
92
|
+
*/
|
|
93
|
+
export function yarnLockRecognizeVersion(fileContent: string): YarnLockVersionEnum {
|
|
94
|
+
|
|
95
|
+
const yarn = fileContent.split("\n", 10) //Check only the first 10 lines;
|
|
96
|
+
for (const line of yarn) {
|
|
97
|
+
if ( line.includes('__metadata:') ) return YarnLockVersionEnum.V2
|
|
98
|
+
if ( line.includes('yarn lockfile v1') ) return YarnLockVersionEnum.V1
|
|
99
|
+
}
|
|
100
|
+
return YarnLockVersionEnum.UnknownYarnLockFormat
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export function yarnLockV1Parser(fileContent: string, filePath: string): ILocalDependency {
|
|
104
|
+
|
|
105
|
+
const results: ILocalDependency = {file: filePath, purls: []};
|
|
106
|
+
|
|
107
|
+
//Yield an array with each element is a dependency
|
|
108
|
+
/*
|
|
109
|
+
"@babel/core@^7.1.0", "@babel/core@^7.3.4":
|
|
110
|
+
version "7.3.4"
|
|
111
|
+
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.3.4.tgz#921a5a13746c21e32445bf0798680e9d11a6530b"
|
|
112
|
+
integrity sha512-jRsuseXBo9pN197KnDwhhaaBzyZr2oIcLHHTt2oDdQrej5Qp57dCCJafWx5ivU8/alEYDpssYqv1MUqcxwQlrA==
|
|
113
|
+
dependencies:
|
|
114
|
+
"@babel/code-frame" "^7.0.0"
|
|
115
|
+
"@babel/generator" "^7.3.4"
|
|
116
|
+
*/
|
|
117
|
+
const yl_dependencies = fileContent.split("\n\n");
|
|
118
|
+
|
|
119
|
+
for (const yl_dependency of yl_dependencies) {
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
const dependencyData: Record<string, string> = {}
|
|
124
|
+
const topRequirements = [];
|
|
125
|
+
|
|
126
|
+
const dep_lines = yl_dependency.split("\n");
|
|
127
|
+
if (dep_lines.every((line) => line.trim().startsWith("#") == true)) continue //All lines are coments
|
|
128
|
+
if (dep_lines.every((line) => line.trim() == "")) continue //All lines are empty lines
|
|
129
|
+
|
|
130
|
+
for (const dep_line of dep_lines) {
|
|
131
|
+
|
|
132
|
+
// Clean comments and empty lines
|
|
133
|
+
const trimmed = dep_line.trim();
|
|
134
|
+
const comment = trimmed.startsWith('#');
|
|
135
|
+
if (!trimmed || comment) continue
|
|
136
|
+
|
|
137
|
+
// Do nothing with it's own dependencies
|
|
138
|
+
// "@babel/code-frame" "^7.0.0"
|
|
139
|
+
// "@babel/generator" "^7.3.4"
|
|
140
|
+
if (dep_line.startsWith(' '.repeat(4))) {}
|
|
141
|
+
|
|
142
|
+
// version "7.3.4"
|
|
143
|
+
// resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.3.4.tgz#921a5a13746c21e32445bf0798680e9d11a6530b"
|
|
144
|
+
// integrity sha512-jRsuseXBo9pN197KnDwhhaaBzyZr2oIcLHHTt2oDdQrej5Qp57dCCJafWx5ivU8/alEYDpssYqv1MUqcxwQlrA==
|
|
145
|
+
// dependencies:
|
|
146
|
+
else if (dep_line.startsWith(' '.repeat(2))) {
|
|
147
|
+
const dep = trimmed.split(" ")
|
|
148
|
+
const key = dep[0].trim();
|
|
149
|
+
if (key !== "dependencies:") {
|
|
150
|
+
dependencyData[key] = dep[1].replace(/"|'/g, "");
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// the first line of a dependency has the name and requirements
|
|
155
|
+
//"@babel/core@^7.1.0", "@babel/core@^7.3.4":
|
|
156
|
+
else if (!dep_line.startsWith(' ')){
|
|
157
|
+
const dep = dep_line.replace(/:/g, "").split(",");
|
|
158
|
+
const requirements = dep.map(line => line.trim().replace(/"|'/g, ""));
|
|
159
|
+
|
|
160
|
+
for (const req of requirements) {
|
|
161
|
+
|
|
162
|
+
const atIndex = req.lastIndexOf("@")
|
|
163
|
+
|
|
164
|
+
let constraint = req.slice(atIndex+1) // gets ^7.1.0
|
|
165
|
+
constraint = constraint.replace(/"|'/g, "");
|
|
166
|
+
|
|
167
|
+
const ns_name = req.slice(0, atIndex)
|
|
168
|
+
|
|
169
|
+
let ns = '';
|
|
170
|
+
let name = ns_name;
|
|
171
|
+
if (ns_name.includes("/")) {
|
|
172
|
+
const slashIndex = req.lastIndexOf("/")
|
|
173
|
+
ns = ns_name.slice(0,slashIndex);
|
|
174
|
+
name = ns_name.slice(slashIndex+1)
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
topRequirements.push({constraint: constraint, ns: ns, name: name });
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
//Make sure that name and namespace are equal for the same dependency
|
|
186
|
+
const isNsNameEqual = topRequirements.every((topRequirement) => {
|
|
187
|
+
return topRequirement.ns === topRequirements[0].ns && topRequirement.name === topRequirements[0].name
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
if (!isNsNameEqual) {
|
|
191
|
+
console.error("Different names for same dependency is not supported")
|
|
192
|
+
continue
|
|
193
|
+
}
|
|
194
|
+
const topRequirement = topRequirements[0];
|
|
195
|
+
const namespace = topRequirement.ns;
|
|
196
|
+
const name = topRequirement.name;
|
|
197
|
+
const version = dependencyData['version'];
|
|
198
|
+
const purl = new PackageURL(PURL_TYPE, namespace, name, version, undefined, undefined).toString()
|
|
199
|
+
|
|
200
|
+
let requirement = ''
|
|
201
|
+
for (const topRequirement of topRequirements) {
|
|
202
|
+
requirement += topRequirement.constraint + ", "
|
|
203
|
+
}
|
|
204
|
+
if (requirement.endsWith(", ")) {
|
|
205
|
+
requirement = requirement.slice(0, requirement.length-2)
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
results.purls.push({purl: purl, requirement: requirement})
|
|
209
|
+
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
return results;
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
export function yarnLockV2Parser(fileContent: string, filePath: string): ILocalDependency {
|
|
220
|
+
|
|
221
|
+
const results: ILocalDependency = {file: filePath, purls: []};
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
return results;
|
|
225
|
+
|
|
51
226
|
}
|
|
@@ -20,10 +20,11 @@ export class ScannerCfg {
|
|
|
20
20
|
|
|
21
21
|
ABORT_ON_MAX_RETRIES = true;
|
|
22
22
|
|
|
23
|
-
// Persist results after [ X ]
|
|
23
|
+
// Persist results after [ X ] server responses
|
|
24
24
|
MAX_RESPONSES_IN_BUFFER = 300;
|
|
25
25
|
|
|
26
26
|
DISPATCHER_QUEUE_SIZE_MAX_LIMIT = 300;
|
|
27
27
|
|
|
28
28
|
DISPATCHER_QUEUE_SIZE_MIN_LIMIT = 200;
|
|
29
|
+
|
|
29
30
|
};
|