fix: make security fixtures fail closed
This commit is contained in:
@@ -107,13 +107,17 @@ async function defaultAssertReadable(target: string): Promise<void> {
|
||||
await handle.close();
|
||||
}
|
||||
|
||||
function normalizeRepositoryPath(value: string, label: string): string {
|
||||
export function normalizeRepositoryRelativePath(
|
||||
value: string,
|
||||
label = "repository path",
|
||||
): string {
|
||||
if (
|
||||
value.length === 0 ||
|
||||
path.posix.isAbsolute(value) ||
|
||||
path.win32.isAbsolute(value) ||
|
||||
value.includes("\\") ||
|
||||
value.includes("\0")
|
||||
value.includes("\0") ||
|
||||
value.endsWith("/")
|
||||
) {
|
||||
throw new TypeError(`${label} must be a repository-relative POSIX path`);
|
||||
}
|
||||
@@ -122,7 +126,7 @@ function normalizeRepositoryPath(value: string, label: string): string {
|
||||
normalized === "." ||
|
||||
normalized === ".." ||
|
||||
normalized.startsWith("../") ||
|
||||
normalized !== value.replace(/\/$/u, "")
|
||||
normalized !== value
|
||||
) {
|
||||
throw new TypeError(`${label} must be a repository-relative POSIX path`);
|
||||
}
|
||||
@@ -168,7 +172,7 @@ function parseGitFileList(result: GitFileListResult): string[] {
|
||||
throw new TypeError("git ls-files returned an empty NUL-delimited path");
|
||||
}
|
||||
const normalized = rows.map((row) =>
|
||||
normalizeRepositoryPath(row, "git ls-files path"),
|
||||
normalizeRepositoryRelativePath(row, "git ls-files path"),
|
||||
);
|
||||
if (new Set(normalized).size !== normalized.length) {
|
||||
throw new TypeError("git ls-files returned a duplicate path");
|
||||
@@ -193,14 +197,14 @@ export async function buildRepositoryFileInventory(
|
||||
const realpathPath = options.realpathPath ?? realpath;
|
||||
const assertReadable = options.assertReadable ?? defaultAssertReadable;
|
||||
const trackedRoots = options.trackedRoots.map((root) =>
|
||||
normalizeRepositoryPath(root, "tracked root"),
|
||||
normalizeRepositoryRelativePath(root, "tracked root"),
|
||||
);
|
||||
const generatedRoots = (options.generatedRoots ?? []).map((root) =>
|
||||
normalizeRepositoryPath(root, "generated root"),
|
||||
normalizeRepositoryRelativePath(root, "generated root"),
|
||||
);
|
||||
const optionalRoots = new Set(
|
||||
(options.optionalRoots ?? []).map((root) =>
|
||||
normalizeRepositoryPath(root, "optional root"),
|
||||
normalizeRepositoryRelativePath(root, "optional root"),
|
||||
),
|
||||
);
|
||||
for (const root of optionalRoots) {
|
||||
@@ -290,7 +294,7 @@ export async function buildRepositoryFileInventory(
|
||||
const entries = await readdir(absoluteTarget, { withFileTypes: true });
|
||||
for (const entry of entries.sort((left, right) => left.name.localeCompare(right.name))) {
|
||||
await collectGenerated(
|
||||
normalizeRepositoryPath(
|
||||
normalizeRepositoryRelativePath(
|
||||
`${relativeTarget}/${entry.name}`,
|
||||
"generated inventory path",
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user