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.
Files changed (158) hide show
  1. package/.github/workflows/reuse.yml +15 -0
  2. package/.github/workflows/scanoss.yml +24 -0
  3. package/.gitignore +0 -1
  4. package/.idea/.gitignore +5 -0
  5. package/.idea/codeStyles/Project.xml +61 -0
  6. package/.idea/codeStyles/codeStyleConfig.xml +5 -0
  7. package/.idea/inspectionProfiles/Project_Default.xml +6 -0
  8. package/.idea/modules.xml +8 -0
  9. package/.idea/scanoss.js.iml +12 -0
  10. package/.idea/vcs.xml +6 -0
  11. package/.idea/workspace.xml +366 -0
  12. package/.nyc_output/a25d3ac4-ee71-4c5e-926e-3a17714555cd.json +1 -0
  13. package/.nyc_output/processinfo/a25d3ac4-ee71-4c5e-926e-3a17714555cd.json +1 -0
  14. package/.nyc_output/processinfo/index.json +1 -0
  15. package/.reuse/dep5 +16 -0
  16. package/LICENSES/CC0-1.0.txt +121 -0
  17. package/LICENSES/MIT.txt +9 -0
  18. package/README.md +9 -0
  19. package/build/main/bin/cli-bin.js +5 -3
  20. package/build/main/commands/dep.js +1 -2
  21. package/build/main/commands/fingerprint.js +20 -12
  22. package/build/main/commands/helpers.js +1 -2
  23. package/build/main/commands/scan.js +7 -2
  24. package/build/main/index.js +1 -2
  25. package/build/main/lib/dependencies/DependencyScanner.d.ts +1 -1
  26. package/build/main/lib/dependencies/DependencyScanner.js +23 -12
  27. package/build/main/lib/dependencies/DependencyScannerCfg.js +1 -2
  28. package/build/main/lib/dependencies/DependencyTypes.js +0 -1
  29. package/build/main/lib/dependencies/LocalDependency/DependencyTypes.js +0 -1
  30. package/build/main/lib/dependencies/LocalDependency/LocalDependency.js +3 -2
  31. package/build/main/lib/dependencies/LocalDependency/parsers/golangParser.d.ts +1 -0
  32. package/build/main/lib/dependencies/LocalDependency/parsers/golangParser.js +50 -16
  33. package/build/main/lib/dependencies/LocalDependency/parsers/mavenParser.js +130 -15
  34. package/build/main/lib/dependencies/LocalDependency/parsers/npmParser.d.ts +10 -0
  35. package/build/main/lib/dependencies/LocalDependency/parsers/npmParser.js +146 -10
  36. package/build/main/lib/dependencies/LocalDependency/parsers/pyParser.js +1 -2
  37. package/build/main/lib/dependencies/LocalDependency/parsers/rubyParser.js +1 -2
  38. package/build/main/lib/dependencies/LocalDependency/parsers/utils.js +1 -2
  39. package/build/main/lib/filters/defaultFilter.js +1 -2
  40. package/build/main/lib/filters/filtering.js +1 -2
  41. package/build/main/lib/grpc/GrpcDependencyService.js +1 -2
  42. package/build/main/lib/grpc/scanoss/api/components/v2/scanoss-components_grpc_pb.d.ts +62 -0
  43. package/build/main/lib/grpc/scanoss/api/components/v2/scanoss-components_grpc_pb.js +128 -0
  44. package/build/main/lib/grpc/scanoss/api/components/v2/scanoss-components_pb.d.ts +1 -0
  45. package/build/main/lib/grpc/scanoss/api/components/v2/scanoss-components_pb.js +1403 -0
  46. package/build/main/lib/scanner/Dispatcher/DispatchableItem.d.ts +14 -5
  47. package/build/main/lib/scanner/Dispatcher/DispatchableItem.js +30 -10
  48. package/build/main/lib/scanner/Dispatcher/Dispatcher.d.ts +2 -2
  49. package/build/main/lib/scanner/Dispatcher/Dispatcher.js +10 -15
  50. package/build/main/lib/scanner/Dispatcher/DispatcherResponse.js +1 -2
  51. package/build/main/lib/scanner/Dispatcher/GlobalControllerAborter.js +1 -2
  52. package/build/main/lib/scanner/Scannable/ScannableItem.js +1 -2
  53. package/build/main/lib/scanner/Scanner.js +13 -9
  54. package/build/main/lib/scanner/ScannerCfg.js +2 -3
  55. package/build/main/lib/scanner/ScannerQueue.d.ts +3 -0
  56. package/build/main/lib/scanner/ScannerQueue.js +8 -0
  57. package/build/main/lib/scanner/ScannerTypes.d.ts +9 -2
  58. package/build/main/lib/scanner/ScannerTypes.js +8 -3
  59. package/build/main/lib/scanner/WfpProvider/FingerprintPackage.d.ts +9 -0
  60. package/build/main/lib/scanner/WfpProvider/FingerprintPackage.js +31 -0
  61. package/build/main/lib/scanner/WfpProvider/WfpCalculator/WfpCalculator.js +178 -21
  62. package/build/main/lib/scanner/WfpProvider/WfpCalculator/Winnower.d.ts +3 -0
  63. package/build/main/lib/scanner/WfpProvider/WfpCalculator/Winnower.js +211 -0
  64. package/build/main/lib/scanner/WfpProvider/WfpProvider.d.ts +2 -2
  65. package/build/main/lib/scanner/WfpProvider/WfpProvider.js +6 -7
  66. package/build/main/lib/scanner/WfpProvider/WfpSplitter/WfpSplitter.js +1 -2
  67. package/build/main/lib/tree/File.js +1 -2
  68. package/build/main/lib/tree/Folder.js +1 -2
  69. package/build/main/lib/tree/Node.js +1 -2
  70. package/build/main/lib/tree/Tree.js +1 -2
  71. package/build/module/bin/cli-bin.js +5 -2
  72. package/build/module/commands/fingerprint.js +25 -16
  73. package/build/module/commands/scan.js +8 -2
  74. package/build/module/lib/dependencies/DependencyScanner.d.ts +1 -1
  75. package/build/module/lib/dependencies/DependencyScanner.js +23 -11
  76. package/build/module/lib/dependencies/LocalDependency/LocalDependency.js +5 -3
  77. package/build/module/lib/dependencies/LocalDependency/parsers/golangParser.d.ts +1 -0
  78. package/build/module/lib/dependencies/LocalDependency/parsers/golangParser.js +47 -14
  79. package/build/module/lib/dependencies/LocalDependency/parsers/mavenParser.js +130 -14
  80. package/build/module/lib/dependencies/LocalDependency/parsers/npmParser.d.ts +10 -0
  81. package/build/module/lib/dependencies/LocalDependency/parsers/npmParser.js +140 -8
  82. package/build/module/lib/grpc/scanoss/api/components/v2/scanoss-components_grpc_pb.d.ts +62 -0
  83. package/build/module/lib/grpc/scanoss/api/components/v2/scanoss-components_grpc_pb.js +128 -0
  84. package/build/module/lib/grpc/scanoss/api/components/v2/scanoss-components_pb.d.ts +1 -0
  85. package/build/module/lib/grpc/scanoss/api/components/v2/scanoss-components_pb.js +1403 -0
  86. package/build/module/lib/scanner/Dispatcher/DispatchableItem.d.ts +14 -5
  87. package/build/module/lib/scanner/Dispatcher/DispatchableItem.js +32 -10
  88. package/build/module/lib/scanner/Dispatcher/Dispatcher.d.ts +2 -2
  89. package/build/module/lib/scanner/Dispatcher/Dispatcher.js +10 -14
  90. package/build/module/lib/scanner/Scanner.js +12 -8
  91. package/build/module/lib/scanner/ScannerCfg.js +2 -2
  92. package/build/module/lib/scanner/ScannerQueue.d.ts +3 -0
  93. package/build/module/lib/scanner/ScannerQueue.js +4 -0
  94. package/build/module/lib/scanner/ScannerTypes.d.ts +9 -2
  95. package/build/module/lib/scanner/ScannerTypes.js +7 -1
  96. package/build/module/lib/scanner/WfpProvider/FingerprintPackage.d.ts +9 -0
  97. package/build/module/lib/scanner/WfpProvider/FingerprintPackage.js +30 -0
  98. package/build/module/lib/scanner/WfpProvider/WfpCalculator/WfpCalculator.js +178 -20
  99. package/build/module/lib/scanner/WfpProvider/WfpCalculator/Winnower.d.ts +3 -0
  100. package/build/module/lib/scanner/WfpProvider/WfpCalculator/Winnower.js +211 -0
  101. package/build/module/lib/scanner/WfpProvider/WfpProvider.d.ts +2 -2
  102. package/build/module/lib/scanner/WfpProvider/WfpProvider.js +6 -6
  103. package/build/tsconfig.module.tsbuildinfo +1 -1
  104. package/build/tsconfig.tsbuildinfo +1 -1
  105. package/package.json +6 -17
  106. package/src/bin/cli-bin.ts +4 -1
  107. package/src/commands/fingerprint.ts +26 -17
  108. package/src/commands/scan.ts +16 -3
  109. package/src/lib/dependencies/DependencyScanner.ts +20 -13
  110. package/src/lib/dependencies/LocalDependency/LocalDependency.ts +8 -2
  111. package/src/lib/dependencies/LocalDependency/parsers/golangParser.ts +67 -15
  112. package/src/lib/dependencies/LocalDependency/parsers/mavenParser.ts +143 -16
  113. package/src/lib/dependencies/LocalDependency/parsers/npmParser.ts +182 -7
  114. package/src/lib/scanner/Dispatcher/DispatchableItem.ts +45 -11
  115. package/src/lib/scanner/Dispatcher/Dispatcher.ts +11 -14
  116. package/src/lib/scanner/Scanner.ts +17 -13
  117. package/src/lib/scanner/ScannerCfg.ts +2 -1
  118. package/src/lib/scanner/ScannerTypes.ts +10 -2
  119. package/src/lib/scanner/WfpProvider/{FingerprintPacket.ts → FingerprintPackage.ts} +4 -14
  120. package/src/lib/scanner/WfpProvider/WfpCalculator/WfpCalculator.ts +177 -20
  121. package/src/lib/scanner/WfpProvider/WfpProvider.ts +5 -5
  122. package/tests/WfpCalculator.spec.ts +103 -0
  123. package/tests/data/dependencies/Gemfile/1/Gemfile +6 -0
  124. package/tests/data/dependencies/Gemfile/1/Gemfile~ +0 -0
  125. package/tests/data/dependencies/Gemfile/2/Gemfile +3 -0
  126. package/tests/data/dependencies/Gemfile/2/Gemfile~ +6 -0
  127. package/tests/data/dependencies/Gemfile/3/Gemfile +7 -0
  128. package/tests/data/dependencies/Gemfile/3/Gemfile~ +6 -0
  129. package/tests/data/dependencies/Gemfile/4/Gemfile +31 -0
  130. package/tests/data/dependencies/Gemfile/4/Gemfile~ +7 -0
  131. package/tests/data/dependencies/Gemfile.lock/1/Gemfile.lock +180 -0
  132. package/tests/data/dependencies/Gemfile.lock/2/Gemfile.lock +60 -0
  133. package/tests/data/dependencies/Gemfile.lock/2/Gemfile.lock~ +0 -0
  134. package/tests/data/dependencies/go.sum/1/go.sum +119 -0
  135. package/tests/data/dependencies/go.sum/depJSON.sh +23 -0
  136. package/tests/data/dependencies/package-lock/1/package-lock.json +715 -0
  137. package/tests/data/dependencies/package-lock/2/package-lock.json +32069 -0
  138. package/tests/data/dependencies/package-lock/3/package-lock.json +9013 -0
  139. package/tests/data/dependencies/pom.xml/1/pom.xml +162 -0
  140. package/tests/data/dependencies/yarn-lock/generate_expected_output.sh +4 -0
  141. package/tests/data/dependencies/yarn-lock/v1/yarn.lock +50 -0
  142. package/tests/data/dependencies/yarn-lock/v1/yarn.lock-expected +13 -0
  143. package/tests/data/dependencies/yarn-lock/v1-complex/yarn.lock +27 -0
  144. package/tests/data/dependencies/yarn-lock/v1-complex/yarn.lock-expected +8 -0
  145. package/tests/data/dependencies/yarn-lock/v1-complex2/yarn.lock +220 -0
  146. package/tests/data/dependencies/yarn-lock/v2/yarn.lock +31 -0
  147. package/tests/data/dependencies/yarn-lock/v2/yarn.lock-expected +57 -0
  148. package/tests/data/dependencies/yarn-lock/v2-local/yarn.lock +11 -0
  149. package/tests/data/dependencies/yarn-lock/v2-local/yarn.lock-expected +27204 -0
  150. package/tests/data/scanner/file1.c +41 -0
  151. package/tests/data/scanner/file2.go +87 -0
  152. package/tests/dependencies/golangParser.goModParser.specs.ts +146 -0
  153. package/tests/dependencies/npmParser.spec.ts +133 -0
  154. package/tsconfig.json +4 -3
  155. package/yarn.lock +4596 -5321
  156. package/examples/defaultFilter.json +0 -203
  157. package/package-lock.json +0 -18588
  158. package/src/lib/scanner/Winnower/WinnowerExtractor.ts +0 -37
@@ -1,11 +1,14 @@
1
- import { isFolder } from "./helpers";
2
- import { ScannerEvents, WfpCalculator } from "..";
3
- import { Tree } from "../lib/tree/Tree";
4
- import { FilterList } from "../lib/filters/filtering";
5
- import { FingerprintPacket } from "../lib/scanner/WfpProvider/FingerprintPacket";
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 "../lib/filters/defaultFilter";
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
- const tree = new Tree(rootPath);
19
- const filter = new FilterList('');
20
- filter.load(defaultFilter as FilterList);
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
- tree.loadFilter(filter);
23
- tree.buildTree();
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, (fingerprintPacket: FingerprintPacket) => {
33
- bar1.increment(fingerprintPacket.getNumberFilesFingerprinted());
34
- fingerprints = fingerprints.concat( fingerprintPacket.getContent() );
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
- wfpCalculator.start({fileList: filesToFingerprint, folderRoot: rootPath});
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
  }
@@ -1,10 +1,17 @@
1
1
  import { Scanner } from '../lib/scanner/Scanner';
2
- import { ScannerEvents, ScannerInput } from '../lib/scanner/ScannerTypes';
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 { DispatcherResponse } from '../lib/scanner/Dispatcher/DispatcherResponse';
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
- this.mergeScopeField(localDependencies, response);
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 mergeScopeField(localdependency: ILocalDependencies, serverResponse: DependencyResponse.AsObject
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 dependency of file.purls) {
83
- if (dependency?.scope) scopeHashMap[filename + dependency.purl] = dependency.scope;
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 scope = scopeHashMap[filename + dependency.purl];
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 { packagelockParser, packageParser } from "./parsers/npmParser";
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 {ns_name, version} = parseDepLink(line);
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 = versionReg ? versionReg[1] : '';
35
-
36
- const ver = version.match(/\${(.*?)}/);
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] : undefined;
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: 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
+ }