agentsqripts
Version:
Comprehensive static code analysis toolkit for identifying technical debt, security vulnerabilities, performance issues, and code quality problems
84 lines (73 loc) • 3.21 kB
JavaScript
/**
* @file Detect unbounded memory growth patterns
* @description Single responsibility: Detect patterns where memory grows without bounds
*/
const { iterateLines, isLoopPattern, isUnboundedLoop } = require('../../../utils/patternDetector');
/**
* Detect unbounded memory growth patterns
*/
function detectUnboundedGrowth(lines, filePath) {
const issues = [];
iterateLines(lines, (line, lineNumber, trimmed, i) => {
// Array growth in loops - only flag truly unbounded patterns
if (isLoopPattern(trimmed)) {
// Only check for array growth if loop appears unbounded
if (isUnboundedLoop(trimmed)) {
for (let j = i + 1; j < Math.min(i + 10, lines.length); j++) {
const innerLine = lines[j].trim();
if (/\.push\s*\(|\.concat\s*\(|\.unshift\s*\(/.test(innerLine) &&
!innerLine.includes('splice') && !innerLine.includes('slice')) {
// Check surrounding context for exit conditions
const contextStart = Math.max(0, i - 5);
const contextEnd = Math.min(lines.length, j + 5);
const context = lines.slice(contextStart, contextEnd).join('\n');
// Skip if there are exit conditions
if (/break|return|throw|process\.exit|maxIterations|\.length\s*>=/.test(context)) {
continue;
}
issues.push({
type: 'unbounded_growth',
severity: 'HIGH',
category: 'Memory',
location: `${filePath}:${lineNumber}`,
line: lineNumber,
code: trimmed,
description: 'Unbounded array growth in infinite/unbounded loop - memory leak risk',
summary: 'Array grows without bounds checking',
recommendation: 'Add size limits, use circular buffer, or implement cleanup logic',
effort: 2,
impact: 'Prevents memory exhaustion and OOM errors',
estimatedSavings: 'prevents memory bloat; unbounded growth fixed'
});
break;
}
}
}
}
// String concatenation in loops (memory inefficient)
if (/for\s*\(|while\s*\(|\.forEach\s*\(/.test(trimmed)) {
for (let j = i + 1; j < Math.min(i + 5, lines.length); j++) {
const innerLine = lines[j].trim();
if (/\w+\s*\+=\s*['"`]|\w+\s*=\s*\w+\s*\+\s*['"`]/.test(innerLine)) {
issues.push({
type: 'string_concat_loop',
severity: 'MEDIUM',
category: 'Memory',
location: `${filePath}:${j + 1}`,
line: j + 1,
code: innerLine,
description: 'String concatenation in loop creates multiple string objects',
summary: 'Inefficient string building pattern',
recommendation: 'Use array.join() or template literals for better memory efficiency',
effort: 1,
impact: '50-80% memory reduction for string building',
estimatedSavings: '50-80% memory reduction'
});
break;
}
}
}
});
return issues;
}
module.exports = detectUnboundedGrowth;