如何在不使用eval()的情况下使用回调更新包装函数的条件?

时间:2019-04-17 10:15:22

标签: javascript security while-loop eval

我想定义一个函数,该函数将充当while语句(带有一些插件,但出于简单起见,在此我将展示一个基本包装器)。因此,将条件作为第一个参数,并将在每个循环处执行的回调作为第二个参数。

我最初是使用这个版本的:

const wrappedWhile = (conditions, callback) => {
  let avoidInfinite = 0;

  while (conditions) {
    callback();
    
    if (avoidInfinite >= 10) {
      console.log('breaking while statement for avoiding infinite loop');
      break;
    }
    
    avoidInfinite++;
  }
};

let i = 0;

wrappedWhile(i < 5, () => {
  console.log('log from callback: i =', i);
  
  if (i >= 5) {
    console.log('the loop continues whereas it should stop');
  }
  
  i++;
});

从逻辑上讲,应该在i >= 5时停止。但是conditions参数在wrappedWhile函数中是一个简单的布尔值,因此它总是true,因为在调用时i小于5

然后,我想出了另一个版本,其中conditions在循环的每次迭代中都被评估:

const wrappedWhile = (conditions, callback) => {
  while (Function('return ' + conditions + ';')()) {
    callback();
  }
};

let i = 0;

wrappedWhile('i < 5', () => {
  console.log('log from callback: i =', i);
  i++;
});

但是,如果我没记错的话,Function就是在使用eval()才能正常工作,而且我们所有人都曾经听说过eval()的使用对于代码注入不是很安全

现在我的问题很简单:是否有更安全的替代方法可以完成我想实现的目标?

经过一些研究,我发现了link,它展示了在沙盒环境中进行评估的方法,但是我不知道这是不是一种好方法。

1 个答案:

答案 0 :(得分:1)

您应该传递一个函数作为条件,并在while循环中调用它

const wrappedWhile = (conditions, callback) => {
  let i = 0;

  while (conditions(i)) {
    callback(i);
    
    if (i >= 10) {
      console.log('breaking while statement for avoiding infinite loop');
      break;
    }
    
    i++;
  }
};

wrappedWhile((i) => (i < 5), (iteration) => {
  console.log('log from callback: i =', iteration);
});