1export interface SecretValue {2 name: string;3 value: string;4}56export interface SecretLeak {7 name: string;8 path: string;9}1011function contains(haystack: Uint8Array, needle: Uint8Array): boolean {12 if (needle.length === 0 || haystack.length < needle.length) return false;13 outer:14 for (let offset = 0; offset <= haystack.length - needle.length; offset++) {15 for (let index = 0; index < needle.length; index++) {16 if (haystack[offset + index] !== needle[index]) continue outer;17 }18 return true;19 }20 return false;21}2223export function findSecretLeaks(24 files: ReadonlyArray<{ path: string; content: Uint8Array }>,25 secrets: readonly SecretValue[],26): SecretLeak[] {27 const encoder = new TextEncoder();28 return files.flatMap(({ path, content }) =>29 secrets30 .filter(({ value }) => contains(content, encoder.encode(value)))31 .map(({ name }) => ({ name, path }))32 );33}