import { readFileSync, statSync } from 'node:fs'; const MAX_SNIPPET_FILE_BYTES = 1024 * 1024 * 2; const SKIPPED_PATH_MARKERS = [ '.min.js', '.min.css', '.map', 'node_modules', '.next', 'dist/', 'build/', '__pycache__', ] as const; /** * Extracts a numbered code snippet around a 1-indexed vulnerable line. * * The returned snippet spans the range `[line-6, line+5]` in 0-indexed * coordinates, with the vulnerable line marked by `→` and all other lines * marked by two spaces. Returns `null` for unreadable/missing files, * oversized files (>2MB), known generated/minified paths, binary files, * or out-of-range line numbers. */ export function extractSnippet(filePath: string, line: number): string | null { if (!Number.isInteger(line) || line < 1) { return null; } if (shouldSkipSnippetPath(filePath)) { return null; } try { const stats = statSync(filePath); if (!stats.isFile() || stats.size > MAX_SNIPPET_FILE_BYTES) { return null; } const fileBuffer = readFileSync(filePath); if (fileBuffer.includes(0)) { return null; } const lines = fileBuffer.toString('utf8').split(/\r?\n/); if (line > lines.length) { return null; } const startIndex = Math.max(0, line - 6); const endExclusive = Math.min(lines.length, line + 5); const lineNumberWidth = String(endExclusive).length; const formatted = lines .slice(startIndex, endExclusive) .map((content, offset) => { const lineNumber = startIndex + offset + 1; const marker = lineNumber === line ? '→' : ' '; return `${marker} ${String(lineNumber).padStart(lineNumberWidth, ' ')} | ${content}`; }); return formatted.join('\n'); } catch { return null; } } function shouldSkipSnippetPath(filePath: string): boolean { const normalizedPath = filePath.replace(/\\/g, '/').toLowerCase(); return SKIPPED_PATH_MARKERS.some((marker) => normalizedPath.includes(marker)); }