【问题标题】:How to convert a string into an operator in javascript?如何将字符串转换为javascript中的运算符?
【发布时间】:2021-05-03 16:31:43
【问题描述】:

如何在不使用eval()的情况下将字符串转换为javascript中的运算符?

我尝试过这样的事情:

        const num1 = parseInt(args[0])
        const num2 = parseInt(args[2])
        const operation = (args[1])
        const answer = eval(num1 + operation + num2)
        message.channel.send(answer)

但我认为 discord.js 不接受 eval(),因为机器人没有回复

【问题讨论】:

标签: javascript discord.js


【解决方案1】:

您可以使用Function 构造函数,但不应该这样做,因为它会尝试运行字符串中包含的任意代码。更安全的选择是使用 switch 语句和 whitelist 支持的操作 -

function applyOperator(op, a, b)
{ switch (op)
  { case "+": return a + b
    case "-": return a - b
    case "*": return a * b
    case "/": return a / b
    case "%": return a % b
    case "^": return Math.pow(a, b)
    default: throw Error(`unsupported operator: ${op}`)
  }
}

console.log(applyOperator("*", 3, 5))
console.log(applyOperator("-", 3, 5))
console.log(applyOperator("+", 3, 5))
console.log(applyOperator("!", 3, 5))
15
-2
8
Error: unsupported operator: !

另一个安全的选择是定义一组supportedOperations。调用applyOperation时,检查op是否支持并调用,否则抛出错误-

const supportedOperations =
  { "+": (a, b) => a + b
  , "-": (a, b) => a - b
  , "*": (a, b) => a * b
  , "/": (a, b) => a / b
  , "%": (a, b) => a % b
  , "^": (a, b) => Math.pow(a, b)
  }

function applyOperator(op, a, b)
{ if (op in supportedOperations)
    return supportedOperations[op](a, b)
  else
    throw Error(`unsupported operator: ${op}`)
}

console.log(applyOperator("*", 3, 5))
console.log(applyOperator("-", 3, 5))
console.log(applyOperator("+", 3, 5))
console.log(applyOperator("!", 3, 5))
15
-2
8
Error: unsupported operator: !

【讨论】:

  • 谢谢,但是如何将运算符和数字更改为用户输入?
  • @zai-tm 你不能把你的用户输入传递给applyOperator吗?
【解决方案2】:

您也可以使用Function 构造函数:

const num1 = 7
const num2 = 8
const operation = '*'
const allowedOperations = ['*', '+', '/'];

// Mitigate the critical code injection vulnerability
if (!allowedOperations.includes(operation))
  throw 'The operator is not part of the allowed ones';

const applyOperator = new Function('a', 'b', `return a ${operation} b;`);
const answer = applyOperator(num1, num2);

console.log(answer);

【讨论】:

  • evalFunction 执行任意代码。我强烈推荐我的回答中提出的更安全的替代方案。由于此代码是机器人的一部分,因此防止恶意用户输入至关重要。
  • 我添加了防止代码注入的防护措施,这大大降低(消除?)风险
  • 我正在尝试使用用户输入来完成它,因为它是一个不和谐的机器人。我试图将 consts 更改为 args 但它不起作用
  • 这可能是因为它在沙盒环境中运行,evalnew Function 已禁用,您应该考虑其他答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-03-24
  • 2012-10-16
  • 2019-04-04
  • 2011-07-04
  • 2019-02-04
相关资源
最近更新 更多