Is there any way to inject JavaScript code stored in a string in AngularJS controllers dynamically?
var dynamicJS = "function DoSomething(value){var x = 1+1 return 2;}"
I have to dynamically inject the above function into my AngularJS controller and have it be called on selection change of drop-down, the values of which are bound to the AngularJS controller. The reason is the JavaScript function would vary based on my each row of data which I have based on my configuration at an application level. I am aware we can make use of $eval but would like to get some better approaches, if any exist.
Can anyone give me any idea on this?
Note: I am using AngularJS v1.4.5
I would believe the easier way will be to parse the String and then use the function constructor.
Something like this:
var DoSomething = new Function('value', 'var x = 1+1 return 2');
There are multiple ways to achieve this.
Function object
Create a Function, passing the one argument (i.e. value) and functionBody as parameters:
var dynamicJS = "var x = 1+1; return 2;"
var DoSomething = new Function("value", dynamicJS );
eval()
While arguably more dangerous1, eval() can be used.
var dynamicJS = "function DoSomething(value){var x = 1+1 return 2;}"\
eval(dynamicJS);
Because you mentioned in a comment
"it is intranet application and not going to outer world. no issues on this for this req."
this would likely be fine but please read the section below.
Caution
From the this section of the MDN documentation about eval():
Don't use eval needlessly!
eval() is a dangerous function, which executes the code it's passed with the privileges of the caller. If you run eval() with a string that could be affected by a malicious party, you may end up running malicious code on the user's machine with the permissions of your webpage / extension. More importantly, third party code can see the scope in which eval() was invoked, which can lead to possible attacks in ways to which the similar Function is not susceptible.
eval() is also generally slower than the alternatives, since it has to
invoke the JS interpreter, while many other constructs are optimized by modern JS engines.
There are safer (and faster!) alternatives to eval() for common use-cases.
2
See a demonstration of these techniques utilized below. Click on the buttons corresponding to each technique to see the output on the console.
var dynamicJS = "function DoSomething(value){var x = 1+1; return 2;}"
var functionBody = "var x = 1+1; return 2;";
document.addEventListener('DOMContentLoaded', function() {
document.getElementById('eval').addEventListener('click', function() {
eval(dynamicJS);
console.log('DoSomething(3) -> ',DoSomething(3));
});
document.getElementById('function').addEventListener('click', function() {
var dynamicFunction = new Function("value", functionBody);
console.log('dynamic function(3) ->',dynamicFunction(3));
});
});
<button id="eval">click to eval</button>
<button id="function">click to use Function</button>
1https://stackoverflow.com/a/4599946/1575353
2https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#Don't_use_eval_needlessly!
Perhaps try something like:
function myFunc(obj){
var param = obj.hasOwnProperty('param') ? obj.param : undefined;
console.log(param);
}
var funcString = "myFunc({ param: 'something' });",
Construct = new Function(funcString);
Construct();
Haven't tested it to be honest ... but this way you avoid eval().
more info on Function object
Related
How do you call fat arrow function like below (stored in string) without using eval?
"g => { alert(g); }"
With using eval, the below code is working fine, but I want to avoid using eval.
eval("g => { alert(g); }")('hello')
I hope I could do something like below using "new Function", but I have no luck so far.
new Function("g => { alert(g); }")('hello')
Thanks so much in advance.
from MDN
The Function constructor creates a new Function object. Calling the constructor directly can create functions dynamically, but suffers from security and performance issues similar to eval.
that said, you can easyly parse your string to use function constructor, for example:
const str = [g,body] = "g => { console.log(g); }".split(" => ");
var myFunc = new Function(g, body);
myFunc("hello");
const str2 = [args,body] = "(h,i) => {console.log(h,i);}".split(" => ");
const [h,i] = args.replace(/\(|\)/g,"").split(",");
var myFunc2 = new Function(h,i, body);
myFunc2("hello","buddy");
Anything you do, including your own JS interpreter, is going to be a functional equivalent to eval. Calling eval() function is not a security gap by itself. Executing unsanitized code is what is a security issue, and that's the thing you are trying to do here. Using eval or any equivalent creates an XSS vulnerability.
If you use real interpreter written in JS, you may be able to sandbox the code and mitigate the risk, but it's still a grey area.
OTOH, if you have valid reasons to consider the code in question to be sanitized, there's no good reason to not use eval.
Be aware that you can't reliably sanitize JS code. Anything can be done with very little JS syntax available, so either the code is from a trusted source or it should never be run.
All that said, perhaps the simplest way to get your function compiled with new Function is
(new Function('return ('+code+')'))()
This is almost exact equivalent to calling eval(code), just without any access to the local namespace. Using eval() directly should be slightly faster (omits creating unnecessary function object).
in theory, this works. Still seems like a bad idea.
var fatso = "g => { alert(g); }";
var s = document.createElement("script");
s.innerText = "function callMe(f) { var a = " + fatso + "; a(f) }"
document.head.appendChild(s);
callMe("hello");
This question already has answers here:
How to execute a JavaScript function when I have its name as a string
(36 answers)
Closed 6 years ago.
I have string logo.cr.Button and function
logo.cr.Button = function(){
//something
}
var strg = 'logo.cr.Button';
strg();
now somehow i have to make that string a function call
like strg(); but it is saying
strg is not a constructor
here
Generally when we write JavaScript functions the resulting function declaration looks like this:
function demo() {
// function stuff here
}
You’re probably more than aware that “In JavaScript Functions are first-class Objects”. It’s a phrase that is spouted everywhere, and for good reason. It’s a very powerful idea that has worked to elevate JavaScript to where it is. We’re not going into the details of first-class objects here. All we care about is the fact that, in JavaScript, functions are objects.
This means that the above function can also be declared by calling its Constructor:
var demo = new Function();
Now lets imagine we have a function with parameters and instructions:
function demo(name, age) {
console.log('my name is ' + name);
console.log('my age is ' + age);
}
and now to convert it to Constructor syntax:
var demo = new Function(
"name,age",
"console.log('my name is ' + name);" +
"console.log('my age is ' + age);"
);
This makes it pretty easy to see that these two functions are the same, they are just declared differently. The important difference is that one has easily accessible strings that we should be able to manipulate.
This applies to your function in a very similar way.
var strfunc = new Function ("", "logo.cr.Button()");
I can't seem to format this because I'm on mobile. But i will asap.
Use eval("logo.cr.Button")();
This will execute the function, of course if you have an object like:
var logo = {
cr: {
}
};
This won't work because JavaScript thinks you are using dot notation. When you write logo.cr.Button() JavaScript is looking for a function Button() within the object cr which is in the object logo.
I recommend changing the name to logoCrButton = function()...
You could use eval, but its not recommended.
Secury issues are just one reason, because an user might exploit eval to execute different code that is not supposed to be executed. Within this question it is explained fully.
var logo={cr:{}};
logo.cr.Button = function(){
console.log("something");
}
var string = "logo.cr.Button()";
eval(string);
If you can avoid eval then use a normal function call, an object or an array instead. For insteads Iterating through an array is much better and more stable compared to evaluating some parameters dynamically, as you can see here.
This second example does not use eval, but nevertheless you can call a certain function by using a string:
var obj={logo:{cr:{Button:function(){console.log("something");}}}};
var string = "logo.cr.Button";
function callFunctionByString(string,obj){
var parts = string.split('.');
parts.forEach(function(part){
obj = obj[part];
});
obj();
}
callFunctionByString(string,obj);
Hope this helps.
I would like to be able to store functions in ArangoDB documents. From what I have seen, this is actually possible, since user-defined AQL functions seem to be stored that way, as plain strings. My question goes in that direction: how are those strings converted to callable functions afterwards?
Right now I found a working solution which I don't really like (eval usage seems to be discouraged). I am looking for a better solution. I can store functions and use them afterwards in the following way:
var fnString = "['a','b', function(a,b) { return a + b }]";
var fn = Function.apply(null, eval(fnString));
var someValue = fn(1,2) //returns 3
Is there out a better way to achieve this?
At some point the function code must be converted from a string to something executable.
This can be achieved by (evil) eval, but its usage is discouraged as you say. Eval can execute arbitrary code, and normally that's not what one wants.
Another way is to use the Function constructor:
var fn = new Function('a', 'b', 'return a + b');
var someValue = fn(1, 2); // returns 3
Using the Function constructor limits the potential harm, because the code is not executed directly, but only when the function is called. When the function is called, the potential damage the code can cause is limited to the scope of the function itself.
So in summary using the Function constructors should be a lot better than using eval.
Still, JSLint will tell you that the Function constructor is eval. But if you need to create functions from strings dynamically, then there's nothing you can do about it except silencing it like this.
/*jslint evil: true */
var fn = new Function('a', 'b', 'return a + b');
/*jslint evil: false */
I have this function call passed as a string:
var dcall = "tumbsNav(1)";
Is it possible to execute this dynamically like exec in SQL??
exec(dcall)
eval is the equivalent, but you should NOT use it.
Instead, pass the function like this:
var dcall = function() {tumbsNav(1);};
Then call it with:
dcall();
To do this, you want eval(dcall).
eval can open terribly security holes and performance issues in your program. If you need to use it, that usually means you have designed your program poorly.
Instead, you might keep a reference to the function you want to call and hold an array of arguments and use apply, e.g., tumbsNav.apply(null, [1]);. I don't know your code, so that's most general solution I can offer.
Wherever you're storing
var dcall = "tumbsNav(1)";
You can instead store
var dcall = function() {
return tumbsNav(1);
};
Wherever you were calling it, instead of calling
eval(dcall);
You can instead call
dcall();
The only case this wouldn't work is if tumbsNav wasn't defined at the time var func = ... is called. Then you would have to store the string. If the string is completely under your control, then there's no security hole, but be aware of all the problems mentioned by #Porco
As Kolink mentioned, my example would not cause a problem if tumbsNav was not defined when assigning it with a wrapped anonymous function that calls tumbs. The comment above would only make sense if the example had been the following:
var dcall = tumbsNav, darg = 1;
// later in the code, you can call
dcall(darg) ;
Use eval(dcall).
As others have mentioned eval is considered bad practice. The main reasons for this are
1) Improper use can leave your code vulnerable to injection attacks.
2) Maintaining code becomes more difficult (no line numbers, can't use debugging tools)
3) Executes more slowly (browsers can't compile)
4) Scope becomes impossible to predict.
However, if you understand all these then eval can be very helpful.
What is the 'best practise' with regard to coding style.
Should I use _ for private members?
Should I use this._privateMember?
Please re-write my code in proper style if its wrong:
(function()){
var _blah = 1;
someFunction = function() {
alert(_blah);
};
someOtherFunction = function {
someFunction();
}
}();
I would read this and incorporate any part you agree with:
http://javascript.crockford.com/code.html
You do not have to agree with all of it
I don't think there is one. Use a prefix if you think it helps.
I use _ for private members because it distinguishes them which can be quite helpful in Javascript when you have variables coming from all over the place. But they do clutter the code a bit.
I don't use _ for variables that are declared using var. I do however, use _ to denote object members that shouldn't be access directly.
Some people (who are strange in my opinion :P), also prefix variables with a $ if it contains a jQuery object.
As long as you are consistent with what you do, there are no problems.
Aside from just the code you're showing now, you should use Capital Letters to distinguish constructor functions, and camelCase to name instances of objects.
function Foo (val) {
this.set(val);
};
Foo.prototype.get = function () {
return this._dontTouchMePlease;
};
Foo.prototype.set = function(val) {
this._dontTouchMePlease = parseInt(val, 10);
};
var aFoo = new Foo(6);
I think that its generally accepted that if a variable name starts with a _, you probably shouldn't touch it (accept in dire cirumcstances and even then, two keys and special codes should be provided).
If I'm remembering my Crockford correctly, you'll want to put var in front of the two inner functions, otherwise they will be implicit globals. If you want them to be globals, then that's moot. Either way, your second inner function declaration should probably end in a semicolon. This might be a misformating thing, but I think its generally accepted that the bodies of functions are indented one more level in. Also, I've never seen the (function()){/* stuff */}(); construction before, but that says pretty much nothing.
I'd write it these ways - one for if your just declaring a function and another for if your using an anonymous function and immediately applying it to get a result, because I don't which one you're trying to do (again, if you want the inner functions to be global, then this won't be what you intended):
//function declaration
var myFunction = function () {
var _blah = 1;
var someFunction () {
alert(_blah); //or console.log(_blah); for debugging purposes
};
var someOtherFunction () {
someFunction();
};
};
//using a one-of to assign a result
/* NOTE: if you are using this version, myResult will be undefined
(at least given the functions you provided), but like I said,
I don't recognize the construction you provided, and am therefore
assuming that you meant one of these two, which could be a perfectly
falacious assumption, and in that case, my apologies
*/
var myResult = function () {
var _blah = 1;
var someFunction () {
alert(_blah);
};
var someOtherFunction () {
someFunction();
};
}();
BTW, (and I don't want to overstep) Crockford's "JavaScript: The Good Parts" is a stellar reference for JavaScript syntax. He also has, on his website a JavaScript style guide of sorts (though I don't know how widely followed it is). Link is: http://javascript.crockford.com/code.html
I also use the "_" in c# for private/protected members. It is a fast way to see if the variable is a member-variable or not. And you can access it faster with code-completion because you don't get in mess with the public members (private: _blah , public property: Blah).
But are there any private members in javascript anyway? I think every variable defined as member is accessible from the outside.
So you don't have a public wrapper for the private member. And that means the "_" is a bit a overhead and the same can be achieved with "this.".
I prefer you to use the following stuffs which is preferably used around the world programmers.. see below
i = Int
f = Float
o = Object
r = Return
a = Array
e = Element
g = Global declaration
hook = a function which can be used for hooking with other functions
call = a function which can be used for making call from client to server system
sync = a function which can be used for SYNC
and so on.. you can prefix on your coding...