UNPKG

ubon

Version:

Security scanner for AI-generated React/Next.js and Python apps. Catches hardcoded secrets, accessibility issues, and vulnerabilities that traditional linters miss.

114 lines (113 loc) 4.11 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.detectSuppressions = detectSuppressions; exports.applySuppressions = applySuppressions; exports.filterSuppressedResults = filterSuppressedResults; const fs_1 = require("fs"); /** * Detects inline suppression comments in a file * Supports formats: * - // ubon-disable-next-line RULEID * - // ubon-disable-next-line RULEID reason goes here * - comment: ubon-disable-next-line RULEID * - comment: ubon-disable-next-line RULEID reason goes here */ function detectSuppressions(filePath) { try { const content = (0, fs_1.readFileSync)(filePath, 'utf8'); const lines = content.split('\n'); const suppressions = []; for (let i = 0; i < lines.length; i++) { const line = lines[i]; const lineNumber = i + 1; // Match both // and /* */ style comments const patterns = [ // Single line: // ubon-disable-next-line RULEID optional reason /\/\/\s*ubon-disable-next-line\s+([A-Z0-9]+)(?:\s+(.+))?$/, // Multi line: /* ubon-disable-next-line RULEID optional reason */ /\/\*\s*ubon-disable-next-line\s+([A-Z0-9]+)(?:\s+([^*]+))?\s*\*\// ]; for (const pattern of patterns) { const match = line.match(pattern); if (match) { const ruleId = match[1]; const reason = match[2]?.trim(); suppressions.push({ ruleId, reason, line: lineNumber }); break; // Only one suppression per line } } } return suppressions; } catch (error) { // File doesn't exist or can't be read return []; } } /** * Applies suppressions to scan results */ function applySuppressions(results) { const suppressionCache = new Map(); return results.map(result => { if (!result.file || !result.line) { return result; } // Cache suppressions per file // Try both the relative and absolute path const filePath = result.file; let cacheKey = filePath; if (!suppressionCache.has(cacheKey)) { // Try to resolve the file path - could be relative or absolute let suppressions = []; try { suppressions = detectSuppressions(filePath); } catch (error) { // If direct path fails, try with current working directory try { const path = require('path'); const fullPath = path.resolve(filePath); suppressions = detectSuppressions(fullPath); } catch (error2) { suppressions = []; } } suppressionCache.set(cacheKey, suppressions); } const suppressions = suppressionCache.get(cacheKey); // Check if this result is suppressed // Look for suppression on the line before the issue const suppressionLine = result.line - 1; const suppression = suppressions.find(s => s.line === suppressionLine && (s.ruleId === result.ruleId || s.ruleId === 'ALL')); if (suppression) { return { ...result, suppressed: true, suppressionReason: suppression.reason }; } return result; }); } /** * Filters results based on suppression options */ function filterSuppressedResults(results, options) { if (options.ignoreSuppressed) { // Completely ignore suppressed results return results.filter(r => !r.suppressed); } if (options.showSuppressed) { // Show all results including suppressed ones return results; } // Default: hide suppressed results but include them in counts return results.filter(r => !r.suppressed); }