scanoss 0.2.26 → 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/.gitignore +5 -0
- package/.idea/codeStyles/Project.xml +61 -0
- package/.idea/codeStyles/codeStyleConfig.xml +5 -0
- package/.idea/inspectionProfiles/Project_Default.xml +6 -0
- package/.idea/modules.xml +8 -0
- package/.idea/scanoss.js.iml +12 -0
- package/.idea/vcs.xml +6 -0
- package/.idea/workspace.xml +366 -0
- 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 +5 -3
- package/build/main/commands/dep.js +1 -2
- package/build/main/commands/fingerprint.js +20 -12
- package/build/main/commands/helpers.js +1 -2
- package/build/main/commands/scan.js +7 -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 +130 -15
- 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.d.ts +14 -5
- package/build/main/lib/scanner/Dispatcher/DispatchableItem.js +30 -10
- package/build/main/lib/scanner/Dispatcher/Dispatcher.d.ts +2 -2
- package/build/main/lib/scanner/Dispatcher/Dispatcher.js +10 -15
- 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 +13 -9
- package/build/main/lib/scanner/ScannerCfg.js +2 -3
- package/build/main/lib/scanner/ScannerQueue.d.ts +3 -0
- package/build/main/lib/scanner/ScannerQueue.js +8 -0
- package/build/main/lib/scanner/ScannerTypes.d.ts +9 -2
- package/build/main/lib/scanner/ScannerTypes.js +8 -3
- package/build/main/lib/scanner/WfpProvider/FingerprintPackage.d.ts +9 -0
- package/build/main/lib/scanner/WfpProvider/FingerprintPackage.js +31 -0
- package/build/main/lib/scanner/WfpProvider/WfpCalculator/WfpCalculator.js +178 -21
- 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.d.ts +2 -2
- package/build/main/lib/scanner/WfpProvider/WfpProvider.js +6 -7
- 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 +5 -2
- package/build/module/commands/fingerprint.js +25 -16
- package/build/module/commands/scan.js +8 -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/mavenParser.js +130 -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/Dispatcher/DispatchableItem.d.ts +14 -5
- package/build/module/lib/scanner/Dispatcher/DispatchableItem.js +32 -10
- package/build/module/lib/scanner/Dispatcher/Dispatcher.d.ts +2 -2
- package/build/module/lib/scanner/Dispatcher/Dispatcher.js +10 -14
- package/build/module/lib/scanner/Scanner.js +12 -8
- package/build/module/lib/scanner/ScannerCfg.js +2 -2
- package/build/module/lib/scanner/ScannerQueue.d.ts +3 -0
- package/build/module/lib/scanner/ScannerQueue.js +4 -0
- package/build/module/lib/scanner/ScannerTypes.d.ts +9 -2
- package/build/module/lib/scanner/ScannerTypes.js +7 -1
- package/build/module/lib/scanner/WfpProvider/FingerprintPackage.d.ts +9 -0
- package/build/module/lib/scanner/WfpProvider/FingerprintPackage.js +30 -0
- package/build/module/lib/scanner/WfpProvider/WfpCalculator/WfpCalculator.js +178 -20
- 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/module/lib/scanner/WfpProvider/WfpProvider.d.ts +2 -2
- package/build/module/lib/scanner/WfpProvider/WfpProvider.js +6 -6
- package/build/tsconfig.module.tsbuildinfo +1 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -17
- package/src/bin/cli-bin.ts +4 -1
- package/src/commands/fingerprint.ts +26 -17
- package/src/commands/scan.ts +16 -3
- package/src/lib/dependencies/DependencyScanner.ts +20 -13
- 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/mavenParser.ts +143 -16
- package/src/lib/dependencies/LocalDependency/parsers/npmParser.ts +182 -7
- package/src/lib/scanner/Dispatcher/DispatchableItem.ts +45 -11
- package/src/lib/scanner/Dispatcher/Dispatcher.ts +11 -14
- package/src/lib/scanner/Scanner.ts +17 -13
- package/src/lib/scanner/ScannerCfg.ts +2 -1
- package/src/lib/scanner/ScannerTypes.ts +10 -2
- package/src/lib/scanner/WfpProvider/{FingerprintPacket.ts → FingerprintPackage.ts} +4 -14
- package/src/lib/scanner/WfpProvider/WfpCalculator/WfpCalculator.ts +177 -20
- package/src/lib/scanner/WfpProvider/WfpProvider.ts +5 -5
- package/tests/WfpCalculator.spec.ts +103 -0
- package/tests/data/dependencies/Gemfile/1/Gemfile +6 -0
- package/tests/data/dependencies/Gemfile/1/Gemfile~ +0 -0
- package/tests/data/dependencies/Gemfile/2/Gemfile +3 -0
- package/tests/data/dependencies/Gemfile/2/Gemfile~ +6 -0
- package/tests/data/dependencies/Gemfile/3/Gemfile +7 -0
- package/tests/data/dependencies/Gemfile/3/Gemfile~ +6 -0
- package/tests/data/dependencies/Gemfile/4/Gemfile +31 -0
- package/tests/data/dependencies/Gemfile/4/Gemfile~ +7 -0
- package/tests/data/dependencies/Gemfile.lock/1/Gemfile.lock +180 -0
- package/tests/data/dependencies/Gemfile.lock/2/Gemfile.lock +60 -0
- package/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/tests/data/dependencies/pom.xml/1/pom.xml +162 -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,23 +18,28 @@ 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);
|
|
29
37
|
bar1.start(filesToFingerprint.length, 0);
|
|
30
38
|
|
|
31
39
|
let fingerprints = '';
|
|
32
|
-
wfpCalculator.on(ScannerEvents.WINNOWING_NEW_CONTENT, (
|
|
33
|
-
bar1.increment(
|
|
34
|
-
fingerprints = fingerprints.concat(
|
|
40
|
+
wfpCalculator.on(ScannerEvents.WINNOWING_NEW_CONTENT, (fingerprintPackage: FingerprintPackage) => {
|
|
41
|
+
bar1.increment(fingerprintPackage.getNumberFilesFingerprinted());
|
|
42
|
+
fingerprints = fingerprints.concat( fingerprintPackage.getContent() );
|
|
35
43
|
});
|
|
36
44
|
|
|
37
45
|
if (options.verbose)
|
|
@@ -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
|
|
|
@@ -13,7 +20,6 @@ import { isFolder } from './helpers';
|
|
|
13
20
|
import fs from 'fs';
|
|
14
21
|
|
|
15
22
|
|
|
16
|
-
|
|
17
23
|
export async function scanHandler(rootPath: string, options: any): Promise<void> {
|
|
18
24
|
|
|
19
25
|
let scannerInput: ScannerInput = {fileList: []};
|
|
@@ -81,6 +87,13 @@ export async function scanHandler(rootPath: string, options: any): Promise<void>
|
|
|
81
87
|
});
|
|
82
88
|
|
|
83
89
|
if (options.wfp) scannerInput.wfpPath = rootPath;
|
|
90
|
+
if (options.hpsm) scannerInput.winnowingMode = WinnowingMode.FULL_WINNOWING_HPSM
|
|
91
|
+
|
|
92
|
+
if (options.ignore) {
|
|
93
|
+
scannerInput.sbom = fs.readFileSync(options.ignore, 'utf-8');
|
|
94
|
+
scannerInput.sbomMode = SbomMode.SBOM_IGNORE
|
|
95
|
+
}
|
|
96
|
+
|
|
84
97
|
await scanner.scan([scannerInput]);
|
|
85
98
|
|
|
86
99
|
}
|
|
@@ -22,14 +22,14 @@ export class DependencyScanner {
|
|
|
22
22
|
let localDependencies = await this.localDependency.search(files);
|
|
23
23
|
if (localDependencies.files.length === 0) return {filesList: []};
|
|
24
24
|
localDependencies = this.purlAdapter(localDependencies);
|
|
25
|
-
|
|
26
25
|
const request = this.buildRequest(localDependencies);
|
|
27
26
|
const grpcResponse = await this.grpcDependencyService.get(request);
|
|
28
27
|
const response = grpcResponse.toObject();
|
|
29
28
|
|
|
30
|
-
|
|
31
29
|
// Extract scope from localDependencies and add it to response
|
|
32
|
-
|
|
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);
|
|
33
33
|
return response;
|
|
34
34
|
}
|
|
35
35
|
|
|
@@ -72,27 +72,34 @@ export class DependencyScanner {
|
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
private
|
|
76
|
-
): IDependencyResponse {
|
|
77
|
-
|
|
78
|
-
const scopeHashMap = {};
|
|
75
|
+
private repairOutput(localdependency: ILocalDependencies, serverResponse: DependencyResponse.AsObject) {
|
|
79
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 = {};
|
|
80
82
|
for (const file of localdependency.files) {
|
|
81
83
|
const filename = file.file
|
|
82
|
-
for (const
|
|
83
|
-
|
|
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;
|
|
84
89
|
}
|
|
85
90
|
}
|
|
86
91
|
|
|
87
92
|
for (const file of serverResponse.filesList) {
|
|
88
93
|
const filename = file.file
|
|
89
94
|
for (const dependency of file.dependenciesList) {
|
|
90
|
-
const
|
|
91
|
-
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
|
+
}
|
|
92
100
|
}
|
|
93
101
|
}
|
|
94
|
-
|
|
95
|
-
return serverResponse;
|
|
96
102
|
}
|
|
97
103
|
|
|
104
|
+
|
|
98
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
|
+
|
|
@@ -4,8 +4,6 @@ import { ILocalDependency } from "../DependencyTypes";
|
|
|
4
4
|
|
|
5
5
|
const PURL_TYPE = 'maven';
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
7
|
// Parse a pom.txt file from maven manifest file
|
|
10
8
|
// See reference on: https://maven.apache.org/guides/introduction/introduction-to-the-pom.html
|
|
11
9
|
// and https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
|
|
@@ -31,17 +29,9 @@ export function pomParser(fileContent: string, filePath: string): ILocalDependen
|
|
|
31
29
|
const name = artifactId ? artifactId[1] : '';
|
|
32
30
|
|
|
33
31
|
const versionReg = dependency.match(/<version>([^<]*)<\/version>/);
|
|
34
|
-
let version =
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
if(ver && ver.length >= 1) {
|
|
38
|
-
if(ver[1] === 'project.version') { // TODO: Add support for project.version
|
|
39
|
-
version = undefined;
|
|
40
|
-
} else {
|
|
41
|
-
const res = fileContent.match(new RegExp(`<${ver[1]}>([^<]*)<\/${ver[1]}>`));
|
|
42
|
-
version = res.length >= 1 ? res[1] : '';
|
|
43
|
-
}
|
|
44
|
-
}
|
|
32
|
+
let version = null;
|
|
33
|
+
if(versionReg && versionReg.length>0) version = resolve_version(versionReg[1], fileContent);
|
|
34
|
+
|
|
45
35
|
|
|
46
36
|
let purlQualifiers;
|
|
47
37
|
const type = dependency.match(/<type>([^<]*)<\/type>/);
|
|
@@ -52,11 +42,148 @@ export function pomParser(fileContent: string, filePath: string): ILocalDependen
|
|
|
52
42
|
|
|
53
43
|
// Extract scope.
|
|
54
44
|
const scopeRes = dependency.match(/<scope>([^<]*)<\/scope>/);
|
|
55
|
-
const scope = scopeRes ? scopeRes[1] :
|
|
56
|
-
|
|
45
|
+
const scope = scopeRes ? scopeRes[1] : null;
|
|
57
46
|
const purlString = new PackageURL(PURL_TYPE, namespace, name, version, purlQualifiers, undefined).toString();
|
|
58
|
-
results.purls.push({purl: purlString, scope
|
|
47
|
+
results.purls.push({purl: purlString, scope});
|
|
59
48
|
});
|
|
60
49
|
}
|
|
61
50
|
return results;
|
|
62
51
|
}
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
function resolve_version(dependency_version: string, file_content: string): string {
|
|
55
|
+
// See properties: https://maven.apache.org/pom.html#properties
|
|
56
|
+
let version = '';
|
|
57
|
+
if(dependency_version) {
|
|
58
|
+
if(/\${project.version}/.test(dependency_version)) {
|
|
59
|
+
version = extract_content_from_tag(file_content, ['project', 'version']);
|
|
60
|
+
} else if(/\${.*?}/.test(dependency_version)) {
|
|
61
|
+
const property = dependency_version.match(/\${(.*?)}/)[1];
|
|
62
|
+
const result = file_content.match(new RegExp(`<${property}>([^<]*)<\/${property}>`));
|
|
63
|
+
if (result && result.length>0) version = result[1];
|
|
64
|
+
} else {
|
|
65
|
+
version = dependency_version.toString();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return version;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
function get_start_tag_name(line: string): string {
|
|
73
|
+
const result = line.match(/\<([\w\-\.]+).*?>/);
|
|
74
|
+
if (result) return result[1].trim();
|
|
75
|
+
return '';
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function get_end_tag_name(line: string): string {
|
|
79
|
+
const result = line.match(/\<\/([\w\-\.]+) ?>/);
|
|
80
|
+
if (result) return result[1].trim();
|
|
81
|
+
return '';
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function get_end_tag(line: string): string {
|
|
85
|
+
const result = get_end_tag_name(line);
|
|
86
|
+
if (result !== '') return `</${result}>`
|
|
87
|
+
return '';
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function get_start_tag(line: string): string {
|
|
91
|
+
const result = get_start_tag_name(line);
|
|
92
|
+
if (result !== '') return `<${result}>`
|
|
93
|
+
return '';
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function element_match(openTag: string, closeTag:string): boolean {
|
|
97
|
+
return get_start_tag_name(openTag) === get_end_tag_name(closeTag);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function is_element_complete(line: string) {
|
|
101
|
+
return get_start_tag_name(line) === get_end_tag_name(line);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
function get_offset_until_end_of_tag(lines: Array<string>, end_tag_name: string) {
|
|
106
|
+
let i = 0;
|
|
107
|
+
for (const line of lines) {
|
|
108
|
+
if ( get_end_tag_name(line) === end_tag_name) break;
|
|
109
|
+
i += 1;
|
|
110
|
+
}
|
|
111
|
+
return i;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function remove_comments(lines: Array<string>): Array<string> {
|
|
115
|
+
for (let i=0; i<lines.length; i+=1) {
|
|
116
|
+
let openCommentFlag = /<!--/.test(lines[i]);
|
|
117
|
+
let endCommentFlag = /-->/.test(lines[i]);
|
|
118
|
+
|
|
119
|
+
if(openCommentFlag && endCommentFlag)
|
|
120
|
+
lines[i] = lines[i].replace(/<!--.*-->/, '');
|
|
121
|
+
else if (openCommentFlag){
|
|
122
|
+
while(!/-->/.test(lines[i]) && i<lines.length) {
|
|
123
|
+
lines[i] = '';
|
|
124
|
+
i += 1;
|
|
125
|
+
}
|
|
126
|
+
lines[i] = lines[i].replace(/.*-->/, '');
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
}
|
|
130
|
+
return lines;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
function extract_content_from_tag(file_content: string, selector: Array<string>): string {
|
|
135
|
+
let lines = file_content.split('\n');
|
|
136
|
+
const stack: Array<string> = [];
|
|
137
|
+
|
|
138
|
+
let selectorIndex = 0;
|
|
139
|
+
let startTagName = '';
|
|
140
|
+
let endTagName = '';
|
|
141
|
+
let content = '';
|
|
142
|
+
|
|
143
|
+
// Sanitize xml: Removes comments
|
|
144
|
+
lines = remove_comments(lines);
|
|
145
|
+
|
|
146
|
+
for (let i=0; i<lines.length; i+=1) {
|
|
147
|
+
let line = lines[i].trim();
|
|
148
|
+
if(line === '') continue;
|
|
149
|
+
|
|
150
|
+
startTagName = get_start_tag_name(line);
|
|
151
|
+
endTagName = get_end_tag_name(line);
|
|
152
|
+
|
|
153
|
+
// Element complete in the same line and different than my selector
|
|
154
|
+
if(selector[selectorIndex] !== startTagName && is_element_complete(line)) continue;
|
|
155
|
+
|
|
156
|
+
// Element spans multiline and is different than my selector
|
|
157
|
+
// Loop until find corresponding end tag
|
|
158
|
+
if (selector[selectorIndex] !== startTagName) {
|
|
159
|
+
i += 1;
|
|
160
|
+
while (i<lines.length && !element_match(line, lines[i])) i+=1;
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// lines[i] points to the opening tag of the current selector[selectorIndex]
|
|
165
|
+
selectorIndex += 1;
|
|
166
|
+
stack.push(startTagName);
|
|
167
|
+
|
|
168
|
+
// Target reached
|
|
169
|
+
if(selector.length === stack.length) {
|
|
170
|
+
// Target has only one line
|
|
171
|
+
if (is_element_complete(line)) {
|
|
172
|
+
line = line.replace(get_end_tag(line), '');
|
|
173
|
+
line = line.replace(get_start_tag(line), '');
|
|
174
|
+
return line;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Extracts everything beetwen opening and closing tag and return.
|
|
178
|
+
i += 1;
|
|
179
|
+
while (i<lines.length && !element_match(line, lines[i]) ) {
|
|
180
|
+
content += lines[i].trim();
|
|
181
|
+
i += 1;
|
|
182
|
+
}
|
|
183
|
+
return content;
|
|
184
|
+
}
|
|
185
|
+
startTagName='';
|
|
186
|
+
endTagName='';
|
|
187
|
+
}
|
|
188
|
+
return '';
|
|
189
|
+
}
|