Ошибка ссылки при попытке вернуть строку Nodejs VM - PullRequest
0 голосов
/ 15 февраля 2019

Я использую модуль npm, называемый safe-eval, для оценки кода JavaScript, который я отправляю бэкэнду.Код обычно является функцией, которая будет выполняться внутри safe-eval с параметрами, которые я предоставлю.Проблема в том, что при возврате определенного значения, в данном случае строки, он этого не делает, а вместо этого выдает ошибку Reference и интерпретирует строковое значение как переменную.

router.post('/test/:nombre', function(req, res, next){  
    let nombEjer = req.params.nombre;
    let code = "";
    let error = {etype : ""}

    try{
        //Evalua el codigo de manera segura
        code = safeEval(req.body.code, {},{timeout: 5, displayErrors : true});
    }catch(e){
        error.linea = e.stack.split('evalmachine.<anonymous>:')[1].substring(1, 2);
        error.etype = e.toString();

        //Devulve error en caso de que mala sintaxis
        return res.status(400).send(error); 
    }

    //Si es una funcion, trae los valores y soluciones de la base de datos
    if(typeof code === "function"){ 
        let resultados = [];

        Ejercicios.findOne({titulo: nombEjer}, 'parametros', (err, doc)=>{
            if(err) return res.status(500).send({error : "No se ha podido encontrar el ejercicio"});

            //Ejecutar el codigo con cada lista de parametros y almacenar los resultados
            doc.parametros.forEach(function(elem, indx) {
                try{
                    resultados[indx] = safeEval(code(...elem));
                }catch(e){
                    error.etype = e.toString();
                }
            });

            if(error.etype != "") return res.status(400).send(error);
            return res.status(200).send({results : resultados});
        });
    }else{
        return res.status(400).send({etype: "El codigo es invalido"});
    }
});

Проблемапроисходит в одной из итераций forEach.

Да, я знаю, что forEach не следует использовать в качестве управляющего оператора для цикла, но в этом случае я сделал это так, чтобы перехватить любую ошибкукоторые могут возникнуть во время выполнения со списком параметров, которые я передаю.

Тем не менее, проблема возникает, когда я передаю список параметров с помощью этой функции (эта функция должна возвращать строку nраз):

//Function I'm passing
function cadenaVeces(str, n) {
  return str.repeat(n);
}

//Parameter I'm passing
doc.parametros = [ [ "Ho", 2 ], [ "Ho", 3 ], [ "Ho", 1 ], [ "Ho", 0 ], [ "Ho", 5 ], [ "Vaya chico!", 2 ], [ "x", 4 ], [ "", 4 ], [ "codigo", 2 ], [ "codigo", 3 ] ]

Это ответ, который я получил.

{"etype": "ReferenceError: codigocodigocodigo не определено"}

1 Ответ

0 голосов
/ 15 февраля 2019

Такое поведение кажется действительным: safeEval принимает строку кода, оценивает ее и возвращает некоторое значение: примитив или объект (включая функцию).Когда вы вызываете safeEval(req.body.code), возвращается функция code().Когда вы звоните safeEval(code(...elem));, например safeEval(code(...[ "codigo", 3 ]));, вот что происходит:

  1. code(...[ "codigo", 3 ]) возвращает 'codigocodigocodigo';
  2. safeEval('codigocodigocodigo') пытается оценить codigocodigocodigo каккод, а не строка, и возникает ошибка ссылки, так как codigocodigocodigo не объявлен.

Если вам нужна только строка, вы можете просто позвонить code(...elem).Если вам нужно, чтобы результат функции оценивался как строка (хотя это может показаться странным), вызовите safeEval(`'${code(...elem)}'`);, чтобы заключить результат в кавычки.

...