Skip to content

Commit 2559ac6

Browse files
committed
chore: merge main into fix/dockerfile-attribution
2 parents 0ff2b69 + f7906b7 commit 2559ac6

File tree

22 files changed

+7099
-3850
lines changed

22 files changed

+7099
-3850
lines changed

.circleci/config.yml

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -132,17 +132,30 @@ jobs:
132132
- attach_workspace:
133133
at: ~/snyk-docker-plugin
134134
- run: npm run lint
135-
test:
135+
test_unit:
136+
<<: *defaults
137+
resource_class: medium
138+
steps:
139+
- checkout
140+
- attach_workspace:
141+
at: ~/snyk-docker-plugin
142+
- run: npm run test:unit > test-unit-logs.txt 2>&1
143+
- store_artifacts:
144+
path: test-unit-logs.txt
145+
destination: test-unit-logs
146+
test_system:
136147
<<: *defaults
137148
steps:
138149
- checkout
139150
- setup_remote_docker
140151
- attach_workspace:
141152
at: ~/snyk-docker-plugin
142-
- run: npm run test-jest > test-logs.txt 2>&1
153+
- run:
154+
command: npm run test:system > test-system-logs.txt 2>&1
155+
no_output_timeout: 20m
143156
- store_artifacts:
144-
path: test-logs.txt
145-
destination: test-logs
157+
path: test-system-logs.txt
158+
destination: test-system-logs
146159
test_jest_windows_with_docker:
147160
<<: *windows_big
148161
steps:
@@ -252,8 +265,17 @@ workflows:
252265
context: infrasec_container
253266
post-steps:
254267
- *slack-fail-notify
255-
- test:
256-
name: Test
268+
- test_unit:
269+
name: Unit Test
270+
context:
271+
- nodejs-install
272+
- snyk-bot-slack
273+
requires:
274+
- Build
275+
post-steps:
276+
- *slack-fail-notify
277+
- test_system:
278+
name: System Test
257279
context:
258280
- nodejs-install
259281
- snyk-bot-slack
@@ -303,7 +325,8 @@ workflows:
303325
- Lint
304326
- Build
305327
- Security Scans
306-
- Test
328+
- Unit Test
329+
- System Test
307330
- Test Jest Windows with Docker
308331
- Test Jest Windows no Docker
309332
post-steps:

.snyk

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,8 @@
22
version: v1.25.0
33
# ignores vulnerabilities until expiry date; change duration by modifying expiry date
44
ignore:
5-
SNYK-JS-TAR-15307072:
6-
- 'snyk-nodejs-lockfile-parser > @yarnpkg/core > tar':
7-
reason: 'Indirect dependency from snyk-nodejs-lockfile-parser, waiting for upstream fix'
8-
expires: 2026-03-26T00:00:00.000Z
9-
SNYK-JS-TAR-15416075:
10-
- 'snyk-nodejs-lockfile-parser > @yarnpkg/core > tar':
11-
reason: 'Indirect dependency from snyk-nodejs-lockfile-parser, waiting for upstream fix'
12-
expires: 2026-03-26T00:00:00.000Z
13-
SNYK-JS-TAR-15456201:
14-
- 'snyk-nodejs-lockfile-parser > @yarnpkg/core > tar':
15-
reason: 'Indirect dependency from snyk-nodejs-lockfile-parser, waiting for upstream fix'
16-
expires: 2026-03-26T00:00:00.000Z
5+
SNYK-JS-LODASH-15869625:
6+
- '*':
7+
reason: 'Indirect dependency, waiting for upstream fix'
8+
expires: 2026-04-09T00:00:00.000Z
179
patch: {}

components/common.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ schemas:
1717
enum:
1818
- autoDetectedUserInstructions
1919
- binaries
20+
- baseRuntimes
2021
- depGraph
2122
- dockerfileAnalysis
2223
- dockerLayers
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { ExtractedLayers } from "../../extractor/types";
2+
import { BaseRuntime } from "../../facts";
3+
import { getJavaRuntimeReleaseContent } from "../../inputs/base-runtimes/static";
4+
import { parseJavaRuntimeRelease } from "./parser";
5+
6+
export function detectJavaRuntime(
7+
extractedLayers: ExtractedLayers,
8+
): BaseRuntime | null {
9+
const releaseContent = getJavaRuntimeReleaseContent(extractedLayers);
10+
return releaseContent ? parseJavaRuntimeRelease(releaseContent) : null;
11+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { BaseRuntime } from "../../facts";
2+
3+
const VALID_VERSION_PATTERN =
4+
/^(?!.*\.\.)[0-9]+(?:[._+a-zA-Z0-9-]*[a-zA-Z0-9])?$/;
5+
6+
const regex = /^\s*JAVA_VERSION\s*=\s*(?:(["'])(.*?)\1|([^#\r\n]+))/gm;
7+
8+
function isValidJavaVersion(version: string): boolean {
9+
if (!version || version.length === 0) {
10+
return false;
11+
}
12+
return VALID_VERSION_PATTERN.test(version);
13+
}
14+
15+
export function parseJavaRuntimeRelease(content: string): BaseRuntime | null {
16+
if (!content || content.trim().length === 0) {
17+
return null;
18+
}
19+
try {
20+
const matches = [...content.matchAll(regex)];
21+
22+
if (matches.length !== 1) {
23+
return null;
24+
}
25+
const version = (matches[0][2] || matches[0][3] || "").trim();
26+
27+
if (!isValidJavaVersion(version)) {
28+
return null;
29+
}
30+
return { type: "java", version };
31+
} catch (error) {
32+
return null;
33+
}
34+
}

lib/analyzer/static-analyzer.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
getDpkgFileContentAction,
1616
getExtFileContentAction,
1717
} from "../inputs/apt/static";
18+
import { getJavaRuntimeReleaseAction } from "../inputs/base-runtimes/static";
1819
import {
1920
getBinariesHashes,
2021
getNodeBinariesFileContentAction,
@@ -67,6 +68,7 @@ import { jarFilesToScannedResults } from "./applications/java";
6768
import { pipFilesToScannedProjects } from "./applications/python";
6869
import { getApplicationFiles } from "./applications/runtime-common";
6970
import { AppDepsScanResultWithoutTarget } from "./applications/types";
71+
import { detectJavaRuntime } from "./base-runtimes";
7072
import * as osReleaseDetector from "./os-release";
7173
import { analyze as apkAnalyze } from "./package-managers/apk";
7274
import {
@@ -105,6 +107,7 @@ export async function analyze(
105107
...getOsReleaseActions,
106108
getNodeBinariesFileContentAction,
107109
getOpenJDKBinariesFileContentAction,
110+
getJavaRuntimeReleaseAction,
108111
getDpkgPackageFileContentAction,
109112
getRedHatRepositoriesContentAction,
110113
];
@@ -233,6 +236,8 @@ export async function analyze(
233236
}
234237

235238
const binaries = getBinariesHashes(extractedLayers);
239+
const javaRuntime = detectJavaRuntime(extractedLayers);
240+
const baseRuntimes = javaRuntime ? [javaRuntime] : undefined;
236241

237242
const applicationDependenciesScanResults: AppDepsScanResultWithoutTarget[] =
238243
[];
@@ -309,6 +314,7 @@ export async function analyze(
309314
platform,
310315
results,
311316
binaries,
317+
baseRuntimes,
312318
imageLayers: manifestLayers,
313319
rootFsLayers,
314320
applicationDependenciesScanResults,

lib/analyzer/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { ImageName } from "../extractor/image";
2+
import { BaseRuntime } from "../facts";
23
import { AutoDetectedUserInstructions, ManifestFile } from "../types";
34
import {
45
AppDepsScanResultWithoutTarget,
@@ -75,6 +76,7 @@ export interface StaticAnalysis {
7576
osRelease: OSRelease;
7677
results: ImageAnalysis[];
7778
binaries: string[];
79+
baseRuntimes?: BaseRuntime[];
7880
imageLayers: string[];
7981
rootFsLayers?: string[];
8082
autoDetectedUserInstructions?: AutoDetectedUserInstructions;

lib/facts.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,3 +152,13 @@ export interface PluginWarningsFact {
152152
parameterChecks?: string[];
153153
};
154154
}
155+
156+
export interface BaseRuntime {
157+
type: string;
158+
version: string;
159+
}
160+
161+
export interface BaseRuntimesFact {
162+
type: "baseRuntimes";
163+
data: BaseRuntime[];
164+
}

lib/go-parser/go-binary.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -169,10 +169,7 @@ export class GoBinary {
169169
// result in the package name "github.com/my/pkg/a".
170170
const parts = pkgFile.split(modFullName);
171171
if (parts.length !== 2 || parts[0] !== "") {
172-
throw {
173-
fileName: pkgFile,
174-
moduleName: modFullName,
175-
} as GoFileNameError;
172+
throw new GoFileNameError(pkgFile, modFullName);
176173
}
177174

178175
// for files in the "root" of a module
@@ -194,9 +191,17 @@ export class GoBinary {
194191
}
195192
}
196193

197-
interface GoFileNameError extends Error {
198-
fileName: string;
199-
moduleName: string;
194+
export class GoFileNameError extends Error {
195+
public readonly fileName: string;
196+
public readonly moduleName: string;
197+
198+
constructor(fileName: string, moduleName: string) {
199+
super();
200+
this.name = "GoFileNameError";
201+
this.message = `Failed to match Go file "${fileName}" to module "${moduleName}"`;
202+
this.fileName = fileName;
203+
this.moduleName = moduleName;
204+
}
200205
}
201206

202207
/**

lib/inputs/base-runtimes/static.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { normalize as normalizePath } from "path";
2+
import { getContentAsString } from "../../extractor";
3+
import { ExtractAction, ExtractedLayers } from "../../extractor/types";
4+
import { streamToString } from "../../stream-utils";
5+
6+
export const getJavaRuntimeReleaseAction: ExtractAction = {
7+
actionName: "java-runtime-release",
8+
filePathMatches: (filePath) =>
9+
filePath === normalizePath("/opt/java/openjdk/release"),
10+
callback: streamToString,
11+
};
12+
13+
export function getJavaRuntimeReleaseContent(
14+
extractedLayers: ExtractedLayers,
15+
): string {
16+
const content = getContentAsString(
17+
extractedLayers,
18+
getJavaRuntimeReleaseAction,
19+
);
20+
return content || "";
21+
}

0 commit comments

Comments
 (0)