Eval() function alternative - javascript

I have a json file where i am rendering the template and have an object like
"templateLabelEval":"return $row->['document_code'];"
I am rendering the label by using
eval(templateLabelEval);
Is there any other alternative way where i could avoid using eval as it is considered to be a bad practice

Given that the code string has a return statement, eval alone wouldn't work anyway, but you could use Function().
var result = Function(data.templateLabelEval)();
This has nearly all the same security concerns, but not so much the performance issues that eval has (or had). So of course, you should only execute code that is secure.
To explain the code, passing the string to the Function constructor creates a new function object with that strings as its body. (I assume the function needs no parameters defined for now.) So the trailing () invokes the function immediately and the result is stored in result.
You could store the function itself if you want, and then invoke it later as many times as you'd like.

Related

How to parse a string into javascript object?

I have a javascript object defined inside a string variable:
const str = "{a:1}";
I wonder what is the best way to convert it to a javascript object. I have searched a lot but all I found is to use JSON.parse or JSON.stringify to convert the string. But the tricky part in this string is that it is not a JSON object. The a is not quoted. I have tried below approach but it doesn't parse it to a object:
JSON.parse(JSON.stringify(str))
I know I can parse the string manually but I am looking for a more generic solution which support parsing all possible javascript object string.
var obj = eval(str);
Just be aware that using eval can have performance and security impacts.
If you don't control the content of str, i.e. it is a user input or it comes from a server you don't trust, the are risks.
Also, the JavaScript runtimes optimizes your code at runtime, but often disable many optimizations when engineering an eval.
Try to wrap the evaluation statement in a self invoked function that receive the variable passed to theeval:
(function(s) {
return eval(s);
}(str));
It ensures the creation of a closure to isolate the eval, mitigating it's potential impacts.
And last, don't take anything I've just said as an absolute truth: benchmark your code with and without the eval, just to be sure.

Is this bad practice: getMyObject().method()

Suppose I have a function which returns an object :
getMyObject(){
//do stuff here
return object;
}
Is it bad practice to call a method (that doesn't return anything) on the function name itself:
getMyObject().method();
instead of assigning a variable to the return object and then calling the method on that variable :
var returnedObject = getMyObject();
returnedObject.method();
I am working with an html page that has many nested frames, and I have access to a function that returns one of these frames. The frame might be used several times within other functions in my script, and I was wondering if it would be ok for me to access the frame in the way asked above, or if it would be better to declare a global variable.
*EDIT: * Ahh I haven't gotten a chance to use jQuery. Good to know!
Yes, this is perfectly OK. jQuery for example uses this as well. It returns objects on which you can call methods immediatley. This is called chaining.
In your example, method chaining is the better practice IMHO. If a function returns an object, upon which you want to call a method, but you do not need to reference that object after calling that method, don't assign it to a variable.
Also, jQuery code does this all the time(1):
$('#foo').on('click',function(){});
/\ \\
|| \\
|| \\
function call returns jQ object <============|
\\ ||
\\call method "on" upon _||
(1)To clarify: I do not claim that all jQ methods return an object .attr() or .prop() don't. What I mean by "all the time" is actually that the scenario the OP describes is very common in jQ code (function call, invoke method on returned object):
var someString = $($('.foo').get(0)).attr('id');//tricky little bugger, this :)
var aBool = $('#foo').prop('checked');
Usually, no. Chaining method calls like that is usually simpler, more elegant, and easier to read. However, there are a few cases when it's better to use a variable.
If you use a method (or chain of methods) a lot of times, you can use a variable if it makes the code cleaner.
If the method takes a long time to process, it's better to cache the result. For example, if you have some method called calculateResults(), and it pulls data from a database, that takes some time. If the data doesn't change, you'll be incurring that cost for each call to the method. Better to store it in a variable and reuse it.
If the method has side effects, you should be careful about calling it more than once. Those side-effects will be inflicted each time you call it. Again, as an example, if you have a function like nextItem() that advances to the next item and returns it (a la Java iterators), then calling it more than intended will actually change the result. In this case, you have no choice but store the result, since calling it more than once will produce incorrect behavior.
Otherwise, chain away!

How do I convert a string into an executable line of code in Javascript?

I have the following bit of code
console.log("I am");
var x = "console.log('Alive!')";
Now I only want to use x to execute the code-string that is assigned to it - I may not even know the value of x for example but simply want to execute it whatever it maybe - is this possible?
eval() This will convert string to javascript code.
eval("console.log('Alive! Woo!')");
eval and new Function let you parse and execute JavaScript code from strings.
In general, avoid executing code from strings. And never execute code from strings where the strings are untrusted input (for instance, if you take input from user A, never use these to evaluate it in a session with user B).
I see answers here pointing you at eval. eval grants access to your local variables and such to the code, making it really powerful and really dangerous if you use it with untrusted input.
Where possible, avoid eval. You can easily avoid it in your case:
For instance:
console.log("I am");
var x = "console.log('Alive!')";
new Function(x)();
That code creates a function whose body is the text from x, then immediately executes the function.
What you are looking for is eval(). By passing a string to this function you will evaluate the string as JavaScript code and it will return whatever return-value the code in the string returns.
Be aware when using this function though. You do not want to evaluate any code you do not know is safe to execute. For example, running user-generated code could mess up whatever you are making. While using this in JavaScript on a website this will probably only cause issues on the client-side and hence probably won't be much of a security threat, you would want to be VERY careful when evaluating code on for example a server side.
As have been hinted to in other posts here you probably want to make a function instead of an evaluated string if you are in control of the source code that is to be run.
What you are looking for is called a function:
function x() {
console.log('Alive!');
}
If x is already a string containing the code you could use eval(x) to execute it. eval is evil though.
var x = "console.log('Alive!')";
eval(x)

Javascript security question / Using eval()

I'm seeing code in the following form - is such use of eval() safe?
function genericTakeAction(frm_name,id,pagenum,action)
{
var rset=eval("document."+frm_name);
var x=eval("document."+frm_name+".edit_key");
var y=eval("document."+frm_name+".cAction")
if(x)
x.value=id;
if(y)
y.value=action;
page_list(pagenum);
}
Its used as:
<a href="javaScript:;" onClick="genericTakeAction('frmSearch',
'<?php echo $rec_id;?>','<?php echo $pagenum?>','makeOpen')"
class='link6'>Make Open</a>
Whether it's right or wrong, it's needlessly complicated.
function genericTakeAction(frm_name,id,pagenum,action)
{
var rset = document[frm_name];
var x = rset.edit_key;
var y = rset.cAction;
if(x)
x.value=id;
if(y)
y.value=action;
page_list(pagenum);
}
This works because in JavaScript, you can access an object's properties in one of two ways: Either using dotted syntax and a literal identifier, e.g. x = obj.foo;, or using bracket syntax and a string identifier, e.g. x = obj["foo"];. (Note how foo was not in quotes in the first one, but was in quotes for the second; but both do exactly the same thing. Also note that since the property name is a string in the second case, you can use any expression that results in a string, so y = "f"; x = obj[y + "oo"]; also works.)
P.S. It's wrong
eval() is generally frowned upon because, as you are already aware, it is considered unsafe.
In the browser environment, however, it is less of an issue, because in fact, any user could eval() any code they wanted to, using tools like Firebug, etc.
There is still an issue, in that the eval() embedded in the code can be run without the user knowing that he was triggering an eval(), but it's still much less of an issue than in a server-side environment like PHP.
eval() is actually typically used as you've shown to run JSON code being returned from a server-side request. Newer browsers can import JSON more safely using a dedicated JSON parse() function, but older browsers do not have this function and are forced to use eval() for this. Most JSON libraries have eval() in their code somewhere for this reason, but will generally do some sanitisation of the input before running it through eval().
Even if it might look a little bit convoluted, as others have already mentioned, from a pure security perspective, you have to make sure that the 'frm_name' parameter of the genericTakeAction() function can never contain user-supplied data.
In your example, the 'frm_name' parameter contains the hard-coded literal 'frmSearch'. So it is ok as long as this genericTakeAction() function does not get called somewhere else with user-supplied data for the 'frm_name' parameter.
See http://en.wikipedia.org/wiki/Cross-site_scripting#Traditional_versus_DOM-based_vulnerabilities

Why is dynamically modifying a JavaScript function's code mid-execution a bad thing?

A few days ago, I asked a question regarding dynamically modifying a function's code midway through the outerlying script's execution and I was told to completely forget ever coming upon the notion. I'm not sure I understand why that is. Let me give an example:
<script>
var display = function(msg)
{
alert(msg);
}
// Now, at the moment, the display() function
// is receiving a single parameter and alerting
// it to the user. I'm now going to use eval()
// to modify the display() function.
eval('display = ' + display.toString().replace('alert(', 'document.write('));
// Now, the display() function writes its parameter
// to the document as opposed to alerting it.
</script>
I realize this is a rather trivial example, but there must surely be some use that can be derived from being able to dynamically modify a function, something so useful by itself.
Although this may do what you need it to do, 6 months from now you (or the person maintaining your code) will be going "WTF?!"
If your use case is to alert or write based on some condition, why don't you write two different functions? Or have your function take another parameter that decides the output mode. Or pass in a function as a parameter that performs the actual output. Something, you know, a little more on the sane side. ;-)
There are cases where it could be useful to change a function's behavior, but there are better ways to do it. In your example, you could create new instances of the function that handle the output differently, by passing a function as an argument (similar to the strategy pattern):
function makeDisplay(displayStrategy) {
return function(msg) {
// I'm assuming you would do some additional processing here...
displayStrategy(msg);
}
}
var display = makeDisplay(alert);
// now modify display to use document.write
display = makeDisplay(function(msg) { document.write(msg); });
Well, using eval might be a security concern but modifying a function in real-time is ok. How else you can make memoization anyway?
Although, come to think of it, changing method signature isn't a great idea, other people won't know how to call this function after this, since it would depend on execution order and it's not easy to track usually.
I have found myself needing to do this in situations where I don't have the source code for a particular piece of vendor javascript; so that could be a legitimate use case. I agree that if you have another option, it's better to do it in a more organised way, editing the original function to be more flexible.

Categories