UNPKG

open-loop-killer

Version:

Inject timeout protection into JavaScript loops to prevent infinite loops. Supports while, for, do-while, for-in, and for-of loops with customizable timeout and error messages.

56 lines (43 loc) 1.72 kB
'use strict'; const randomIdGenerator = require('../util/idGenerator.js'); const insertionCode = require('./insertionBlock'); const injectionProcess = (ast, options = {}) => { // If this isn't actual body, recurse with the body if (!Array.isArray(ast)) { injectionProcess(ast.body, options); return; } // Traverse the body for (let i = ast.length; i--;) { const currentElement = ast[i]; const loopDetected = (currentElement && currentElement.type === 'ForStatement') || currentElement.type === 'WhileStatement' || currentElement.type === 'DoWhileStatement' || currentElement.type === 'ForInStatement' || currentElement.type === 'ForOfStatement'; if (loopDetected){ const insertionBlocks = insertionCode(options); const randomVariableName = randomIdGenerator(); //@ts-ignore insertionBlocks.before.declarations[0].id.name = insertionBlocks.inside.test.left.right.name = randomVariableName; // Insert time variable assignment as first child in the body array. ast.splice(i, 0, insertionBlocks.before); // If the loop's body is a single statement, then convert it into a block statement // so that we can insert our conditional break inside it. if (!Array.isArray(currentElement.body)) { currentElement.body = { body: [currentElement.body], type: 'BlockStatement', }; } // Insert the `If` Statement check currentElement.body.body.unshift(insertionBlocks.inside); } // Recurse on inner body if (currentElement.body) { injectionProcess(currentElement.body, options); } } }; module.exports = injectionProcess;