Compare commits

..

5 Commits

Author SHA1 Message Date
copilot-swe-agent[bot] 88d212f82b Update test to match new error message format
Co-authored-by: bdehamer <398027+bdehamer@users.noreply.github.com>
2026-02-17 16:04:17 +00:00
copilot-swe-agent[bot] b0f0516e10 Improve error message clarity for subject count limit
Co-authored-by: bdehamer <398027+bdehamer@users.noreply.github.com>
2026-02-17 16:03:23 +00:00
copilot-swe-agent[bot] 14aaaaa7de Fix boundary condition for MAX_SUBJECT_COUNT check
Co-authored-by: bdehamer <398027+bdehamer@users.noreply.github.com>
2026-02-17 16:01:54 +00:00
copilot-swe-agent[bot] 6cf5fbc523 Optimize getSubjectFromPath to avoid concurrent stat calls
Co-authored-by: bdehamer <398027+bdehamer@users.noreply.github.com>
2026-02-17 16:00:46 +00:00
copilot-swe-agent[bot] f00e913aa0 Initial plan 2026-02-17 15:57:37 +00:00
6 changed files with 19 additions and 43 deletions
+1 -1
View File
@@ -484,7 +484,7 @@ describe('action', () => {
expect(setFailedMock).toHaveBeenCalledWith(
new Error(
'Too many subjects specified (1025). The maximum number of subjects is 1024.'
'Too many subjects specified (>1024). The maximum number of subjects is 1024.'
)
)
})
+1 -1
View File
@@ -17,7 +17,7 @@ describe('parseSBOMFromPath', () => {
describe('when file does not exist', () => {
it('throws an error', async () => {
await expect(parseSBOMFromPath('/nonexistent/file.json')).rejects.toThrow(
/SBOM file not found/
/ENOENT/
)
})
})
Generated Vendored
+3 -12
View File
@@ -120950,6 +120950,7 @@ const predicateFromInputs = async (inputs) => {
catch {
throw new Error(`predicate file not found: ${predicatePath}`);
}
/* istanbul ignore next */
const stat = await promises_default().stat(predicatePath);
/* istanbul ignore next */
if (stat.size > MAX_PREDICATE_SIZE_BYTES) {
@@ -120977,21 +120978,11 @@ const generateProvenancePredicate = async () => {
// SBOMs cannot exceed 16MB.
const MAX_SBOM_SIZE_BYTES = 16 * 1024 * 1024;
const parseSBOMFromPath = async (filePath) => {
let stats;
try {
stats = await promises_default().stat(filePath);
}
catch (error) {
const err = error;
if (err.code === 'ENOENT') {
throw new Error('SBOM file not found');
}
throw error;
}
const fileContent = await promises_default().readFile(filePath, 'utf8');
const stats = await promises_default().stat(filePath);
if (stats.size > MAX_SBOM_SIZE_BYTES) {
throw new Error(`SBOM file exceeds maximum allowed size: ${MAX_SBOM_SIZE_BYTES} bytes`);
}
const fileContent = await promises_default().readFile(filePath, 'utf8');
const sbom = JSON.parse(fileContent);
if (checkIsSPDX(sbom)) {
return { type: 'spdx', object: sbom };
-10
View File
@@ -175,7 +175,6 @@
"integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/code-frame": "^7.29.0",
"@babel/generator": "^7.29.0",
@@ -1498,7 +1497,6 @@
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-7.0.6.tgz",
"integrity": "sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q==",
"license": "MIT",
"peer": true,
"dependencies": {
"@octokit/auth-token": "^6.0.0",
"@octokit/graphql": "^9.0.3",
@@ -2367,7 +2365,6 @@
"integrity": "sha512-1y/MVSz0NglV1ijHC8OT49mPJ4qhPYjiK08YUQVbIOyu+5k862LKUHFkpKHWu//zmr7hDR2rhwUm6gnCGNmGBQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@eslint-community/regexpp": "^4.12.2",
"@typescript-eslint/scope-manager": "8.55.0",
@@ -2407,7 +2404,6 @@
"integrity": "sha512-4z2nCSBfVIMnbuu8uinj+f0o4qOeggYJLbjpPHka3KH1om7e+H9yLKTYgksTaHcGco+NClhhY2vyO3HsMH1RGw==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "8.55.0",
"@typescript-eslint/types": "8.55.0",
@@ -2924,7 +2920,6 @@
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"dev": true,
"license": "MIT",
"peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -3372,7 +3367,6 @@
}
],
"license": "MIT",
"peer": true,
"dependencies": {
"baseline-browser-mapping": "^2.9.0",
"caniuse-lite": "^1.0.30001759",
@@ -4401,7 +4395,6 @@
"integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.8.0",
"@eslint-community/regexpp": "^4.12.1",
@@ -6097,7 +6090,6 @@
"integrity": "sha512-F26gjC0yWN8uAA5m5Ss8ZQf5nDHWGlN/xWZIh8S5SRbsEKBovwZhxGd6LJlbZYxBgCYOtreSUyb8hpXyGC5O4A==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@jest/core": "30.2.0",
"@jest/types": "30.2.0",
@@ -9496,7 +9488,6 @@
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">=12"
},
@@ -9808,7 +9799,6 @@
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"dev": true,
"license": "Apache-2.0",
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
+2 -11
View File
@@ -11,24 +11,15 @@ export type SBOM = {
const MAX_SBOM_SIZE_BYTES = 16 * 1024 * 1024
export const parseSBOMFromPath = async (filePath: string): Promise<SBOM> => {
let stats
try {
stats = await fs.stat(filePath)
} catch (error) {
const err = error as NodeJS.ErrnoException
if (err.code === 'ENOENT') {
throw new Error('SBOM file not found')
}
throw error
}
const fileContent = await fs.readFile(filePath, 'utf8')
const stats = await fs.stat(filePath)
if (stats.size > MAX_SBOM_SIZE_BYTES) {
throw new Error(
`SBOM file exceeds maximum allowed size: ${MAX_SBOM_SIZE_BYTES} bytes`
)
}
const fileContent = await fs.readFile(filePath, 'utf8')
const sbom = JSON.parse(fileContent) as object
if (checkIsSPDX(sbom)) {
+12 -8
View File
@@ -94,14 +94,18 @@ const getSubjectFromPath = async (
// Expand the globbed paths to a list of actual paths
const paths = await glob.create(subjectPaths).then(async g => g.glob())
// Filter path list to just the files (not directories)
const stats = await Promise.all(paths.map(async p => fs.stat(p)))
const files = paths.filter((_, i) => stats[i].isFile())
if (files.length > MAX_SUBJECT_COUNT) {
throw new Error(
`Too many subjects specified (${files.length}). The maximum number of subjects is ${MAX_SUBJECT_COUNT}.`
)
// Filter path list to just the files (not directories), enforcing the maximum
const files: string[] = []
for (const p of paths) {
const stat = await fs.stat(p)
if (stat.isFile()) {
if (files.length >= MAX_SUBJECT_COUNT) {
throw new Error(
`Too many subjects specified (>${MAX_SUBJECT_COUNT}). The maximum number of subjects is ${MAX_SUBJECT_COUNT}.`
)
}
files.push(p)
}
}
for (const file of files) {