Replace Eval function

1

I have to replace in a JEE application (I did not create it myself) all occurrences of the eval() function. The reason is given after carrying out an analysis of the code through a solution for measuring the quality and security of the software (Kiuwan), which indicates as one of the solutions to improve the metrics, eliminate the occurrences of said function.

According to this, several cases arise in which I do not know very well how to perform the replacement. I would like to know if the changes I have made are correct and in the case where I do not know how to do it, you can guide me (the lines with eval are commented):

CASE 1

edicionGrid = function(formid,nombregrid) {
    $("#Act_Buttons td:first").remove();
    //var gruposLocal = eval("grupos_" + nombregrid);
    var gruposLocal = (new Function('return ' + 'grupos_' + nombregrid))();
    ...

Error :

VM1089:1 Uncaught ReferenceError: grupos_evaluacion is not defined
...

CASE 2

myelemSelect = function(value, options) {
//Crea el elemento DOM para el tipo de campo MODCAMPO_SELECT
    var nombreCampo = options["name"]; 
    var select;
    var id = jQuery(idGridParaCombos).getGridParam('selrow');
    var valorSeleccionado;
    var rowData;
    if (id) {
        var rowData = jQuery(idGridParaCombos).getRowData(id);
        //valorSeleccionado = eval("rowData." + nombreCampo);
        valorSeleccionado = (new Function('return rowData.' + nombreCampo))();
    } else {        
        rowData = jQuery(idGridParaCombos).getRowData();
        if(rowData != '') {
            valorSeleccionado = value;
            //valorSeleccionado = eval("rowData[0]." + nombreCampo);
            valorSeleccionado = (new Function('return rowData[0].' + nombreCampo))();
        } 
    }
    ...

Error :

VM1089:1 Uncaught ReferenceError: rowData is not defined
...

CASE 3

for(var i = 0; i < opciones["colModel"].length ; i++) {
    if(opciones["colModel"][i].editoptions != null) {
        if(opciones["colModel"][i].editoptions.custom_element != undefined) {
            var evalFunction = opciones["colModel"][i].editoptions.custom_element = eval(opciones["colModel"][i].editoptions.custom_element);
        }

        if(opciones["colModel"][i].editoptions.custom_value != undefined) {
            opciones["colModel"][i].editoptions.custom_value = eval(opciones["colModel"][i].editoptions.custom_value);
        }
    }
}

Note: In this case I do not know how to perform the replacement.

CASE 4

if (isDefined("gridLoadComplete")) {
    gridLoadCompleteSoloLectura();
    //eval("gridLoadComplete();"); //Ejecuto loadcomplete propio de la pagina
    gridLoadComplete();
}

Note: I call the function directly. I do not know if it's right.

CASE 5

//eval("$(\"#jqgh_" + nuevoString+ " .ui-icon-" + arOrden[i] + "\").removeClass(\"ui-state-disabled\");");
$("#jqgh_" + nuevoString + " .ui-icon-" + arOrden[i]).removeClass("ui-state-disabled");

Note: In this case, it seems to work correctly.

I have given an example of each of the cases in which the function eval() appears and I would like you to help me or tell me if it is well done or not.

In other appearances I made the replacement and in principle it seems that it does not give problems, as in cases 4 and 5.

Thank you.

    
asked by DevCodeG 12.07.2018 в 10:04
source

1 answer

1

Changing the eval function to use Function may cause the Kiuwan metrics to give better values, but you really do not gain almost anything, the ideal would be to modify the code so that it does not use that functionality.

I understand that being the legacy code you do not want to modify it much, but the logical thing would be to try to refactor the code to eliminate the need.

Options that occur to me:

CASE 1

edicionGrid = function(formid,nombregrid) {
    $("#Act_Buttons td:first").remove();
    var gruposLocal = eval("grupos_" + nombregrid); 
...

If the variables with the prefix grupos_ are global, that means you can access them through the global object window :

 var gruposLocal=window['grupos_${nombregrid}'];

If they are not global, create an object that includes them:

const global={};

global.grupos_loquesea= ...;

And you can access in the same way:

let gruposLocal=global['grupos_${nombregrid}'];

var unEjemplo='Hola';

console.log('Con eval()',eval('unEjemplo;'))

console.log('Con window:',window['unEjemplo']);


(function () {
  var unEjemplo2='Hola';

  console.log('Con eval()',eval('unEjemplo2;'))
  // Así no funciona, la variable es local a la función
  console.log('Con window:',window['unEjemplo2']);


})();

// Agupando las variables en una constante global
(function () {
  const global={};
  global.unEjemplo2='Prueba';
  
  console.log('Con global:',global['unEjemplo2']);


})()

CASE 2

This is even simpler, since

valorSeleccionado = eval("rowData." + nombreCampo);

is equivalent to

valorSeleccionado = rowData[nombreCampo];

CASE 3

This case is a bit more complex because it really is a horrible code in many ways: you are going to replace, as an attribute value, the name of a variable with the value of that variable:

    if(opciones["colModel"][i].editoptions.custom_element != undefined) {
        var evalFunction = opciones["colModel"][i].editoptions.custom_element = eval(opciones["colModel"][i].editoptions.custom_element);
    }

    if(opciones["colModel"][i].editoptions.custom_value != undefined) {
        opciones["colModel"][i].editoptions.custom_value = eval(opciones["colModel"][i].editoptions.custom_value);
    }

But it is reduced in the same way as case 1 :

    if(opciones["colModel"][i].editoptions.custom_element != undefined) {
        const nombreVariable =opciones["colModel"][i].editoptions.custom_element;
        var evalFunction = opciones["colModel"][i].editoptions.custom_element = window[nombreVariable];
    }

    if(opciones["colModel"][i].editoptions.custom_value != undefined) {
        const nombreVariable2=opciones["colModel"][i].editoptions.custom_value;
        opciones["colModel"][i].editoptions.custom_value = window[nombreVariable2];
    }

Cases 4 and 5 I think they work well just like you do.

    
answered by 12.07.2018 / 10:44
source