JS Check if input string is valid code and run input - javascript

So I really couldn't find much on this. The idea is that I have a user input (text) and I want to check if its valid code in JS and then run it if it is.
I know that I can do if (typeof userInput === "function") { if the userInput was actually a function, but the user input is just a string input at this point, so I'm quite stuck, and it also contains any arguments or other code.
As an example, the input may be "alert('test')" and that would be valid, and I would like to run that, however something like "madeUpFunction(lol)" would be invalid.
I'm happy if I can just get functions working and not any JS code.

You can extract the string up until the first ( in order to get the function name, and then test that it exists using typeof eval(funcName). Then use the Function constructor to make sure that the syntax is valid for the rest of the arguments without actually executing the code.
You can then return the function which executes what the user entered, but note that there may be security issues if you decide to execute the function.
function parseFunctionCall(str) {
var funcName = str.slice(0, str.indexOf('('));
if (typeof eval(funcName) === 'function') {
return new Function(str);
} else {
throw new Error('Invalid function name');
}
}
console.log(parseFunctionCall("console.log('hi')"));

You can use eval("typeof "+ input) to achieve what you want. The argument of the eval() function is a string. If the string represents an expression, eval() evaluates the expression.
var myFunc = function(){};
var input = prompt('Enter input string');
if(eval("typeof "+input) === "function"){
document.getElementById('d1').innerHTML = "Yes it's a funtion";
}
else{
document.getElementById('d1').innerHTML = "Not a funtion";
}
<div id="d1">
</div>

Assuming this is in a browser and that that function you want to check is in the global scope:
if (typeof window[userInput] === "function" ) {
...
}

Related

How to run the logTruthiness function

This code given below is supposed to evaluate if a value coerces to true or false. How does this work? for example if I want to know if a string- "my string" will be coereced to true or false, how do I use the to determine that?
I have tried to replace val in the code below with "my string" everywhere val shows up
function logTruthiness (val) {
if (val) {
console.log("Truthy!");
} else {
console.log("Falsy.");
}
}
function logTruthiness ("my string") {
if ("my string") {
console.log("Truthy!");
} else {
console.log("Falsy.");
}
}
error
function logTruthiness ("my string") {
SyntaxError: Unexpected string
You could submit a value directly to it:
logTruthiness("my string");
You could also submit a variable:
let str = "my string";
logTruthiness(str);
But you don't want to change the function declaration itself (which is what you did by trying to modify the parameter to a pre-defined string)
Actually I figured out the answer after reading about functions.
So the function is kind of chain of commands that will be executed, one has to provide the value after declaring the function.
Thanks for the patience.

How do I check the Boolean value on eval() or if an arithmetic operation is false?

I am doing this for a calculator project, I want to check if the operation is valid or not, somehow I cannot check for the Boolean value of eval if it is false? on the console:
Boolean(eval('2+2(9.1-)9'));
Boolean(2+2(9.1-)9); // Both operations return unexpected token
unlike Boolean(2+2) <-- returns true. Help?
You actually don't need to evaluate the code in order to see if it's valid - just try creating a Function:
function checkIt() {
var fn
try {
var fn = new Function(document.getElementById("code").value)
alert("Great, that's a valid piece of code!")
} catch (e) {
alert("That's not a valid piece of code.")
}
}
<input id="code">
<button onclick="checkIt()">Check it</button>
For example, try "123", "valid", and "''not[valid!!!".
Though if you are going to be evaluating it right away, if it's valid, you should probably just check if the error is a syntax error, or otherwise.
function doIt() {
var fn
try {
var result = eval(document.getElementById("code").value)
alert("The result is: " + result)
} catch (e) {
if (e instanceof SyntaxError) {
alert("That's not a valid piece of code.")
} else {
alert(e.message)
}
}
}
<input id="code">
<button onclick="doIt()">Check it</button>
For example, try the same things you tried before and see how this behaves.
If I understood your question correctly, the only thing you want to know is "Is that a valid expression". One very simple way to check this is using eval() as you did here, and to enclose it in a try, and see if any error occurs. For example, you could write this :
try {
eval('2+2(9.1-)9');
valid = true;
} catch (e) {
valid = false;
}
Then, the variable valid contains true if the expression is valid, and false if it is not.
Warning with eval() though : Every valid code will pass this test, not only mathematical expressions : Plus, that code will be executed. Be careful what strings you give it.

Anyway to save a parameter inside a function until it is replaced by calling the same function with new parameter?

Say I have a function name myFunA, when the first time call the function and pass a parameter to it, the function actually stored the variable. Each time I call this function, it will return the same variable, until I call the function again and pass a parameter to replace the previous parameter.
function myFunA(input){
if(input exist){
storedVar = input //declare a variable and store the input
}
console.log(storedVar);
}
myFunA('First Input'); // output will be 'First Input'.
myFunA(); // output will still be 'First Input'.
myFunA('Second Input'); // output will be 'Second Input'.
myFunA(); // As the variable is replaced, the output will still be 'Second Input'.
Is this possible?
I know that there is a Garbage Collection feature in JavaScript to scrap the variable and release memory, but is there anyway to prevent?
Really appreciate if someone could let me know the way. If this is not possible to achieve, it is still good to confirm it.
Thank you so much.
Javascript functions are first class objects. Therefore, you can set a property of the function just like any other variable.
function myFunA(input) {
if (input) {
myFunA.storedVar = input;
}
console.log(myFunA.storedVar);
}
myFunA('First Input'); // First Input
myFunA(); // First Input
myFunA('Second Input'); // Second Input
myFunA(); // Second Input
The answer of #NinaScholz is fine, but allows you to change the stored value without calling the function. If you want to avoid it, here is another pattern :
var myFunA = (function() {
var storedVar = null;
return function(input) {
if(typeof(input) != "undefined") {
storedVar = input;
}
console.log(storedVar);
};
})();

javascript variable scope - how can i work around this?

I have an input field, where a user can enter an INPUTVALUE, this INPUTVALUE gets checked for correctness against a reg-ex, then sent off to a php file, which will do calculations with it, and return either 0 (meaning the INPUTVALUE was not valid) or a RETURNVALUE. This RETURNVALUE should be displayed in an element on the website with the id #VALUEINFO. Also I would like this RETURNVALUE returned by my function get_value_by_input(). In order to check what was returned, I am displaying an alert first.
(A practical application for this could be for example a coupon code on an order... put in your coupon code, we check it in the database, it returns the value of the coupon or 0 if it was not a valid coupon code.)
My problem is, I must be messing up something with the variable scope in Javascript, because eventhough my #VALUEINFO displays the correct RETURNVALUE, the alert will always say no returnvalue specified.
function get_value_by_input()
{
var returnvalue;
var valueinfo = $('#valueinfo');
valueinfo.text('');
var inputvalue = $("input[name='inputvalue']").val();
var correctinput = /^[a-zA-Z]*$/i;
if( inputvalue.length > 0 && correctinput.test(inputvalue))
{
$.post('ajax/valuecheck.php', {inputvalue_test: inputvalue}, function(is_valid){
if(is_valid == 0)
{
valueinfo.text('Sorry, this input is not working...');
returnvalue = 0;
}
if(is_valid != 0)
{
valueinfo.text('the returned value for your input is '+is_valid);
returnvalue = is_valid;
}
});
}
else
{
if(inputvalue)
{
valueinfo.text('Invalid input.');
returnvalue = 0;
}
}
if(returnvalue)
{
alert('the value for this input was was '+returnvalue);
return returnvalue;
}
else
{
alert('no returnvalue specified.');
return 0;
}
}
Again:
Why does this code ALWAYS alert 'no returnvalue specified' eventhough #VALUEINFO gives me the correct returnvalue?
I assume this has to do with the if block, I read that javascript will not ignore the setting of any variables within if blocks, even if the condition is not fulfilled... But how else could I pass the value to #valueinfo and return it at the same time?
Any help or suggestions would be greatly appreciated! :-)
EDIT:
Well, yes it has nothing to do with variable scope, but it's about Asynchronus-jax.
I ended up restructuring my code... get_value_by_input() is now more of a process_input() function. First the INPUTVALUE is checked for correctness, and only if there were no errors $.post(... is called. The value returned by the php file is then used immediately within the callback function, rather then to be returned and then used from another function... Unfortunately I couldn't get my brain wrapped around working with .done() or something similar, guess I've been working too long on this today already... -.- Maybe next time. It works for now :)
As mentioned in the comments, you need to handle the return value in a callback (since you're dealing with an asynchronous call).
This might give you a better understanding on how to solve the problem:
function getReturnValue(inputvalue, callback){
$.post('ajax/valuecheck.php', { 'inputvalue_test': inputvalue}, callback);
}
var inputvalue = $("input[name='inputvalue']").val();
getReturnValue(inputvalue, function(is_valid){
//handle is_valid here
//it's the data returned from the ajax call
});
There are a lot of similar threads.

Testing if value is a function

I need to test whether the value of a form's onsubmit is a function. The format is typically onsubmit="return valid();". Is there a way to tell if this is a function, and if it's callable? Using typeof just returns that it's a string, which doesn't help me much.
EDIT: Of course, I understand that "return valid();" is a string. I've replaced it down to "valid();", and even "valid()". I want to know if either of those is a function.
EDIT: Here's some code, which may help explain my problem:
$("a.button").parents("form").submit(function() {
var submit_function = $("a.button").parents("form").attr("onsubmit");
if ( submit_function && typeof( submit_function.replace(/return /,"") ) == 'function' ) {
return eval(submit_function.replace(/return /,""));
} else {
alert("onSubmit is not a function.\n\nIs the script included?"); return false;
}
} );
EDIT 2: Here's the new code. It seems that I still have to use an eval, because calling form.submit() doesn't fire existing onsubmits.
var formObj = $("a.button").parents("form");
formObj.submit(function() {
if ( formObj[0].onsubmit && typeof( formObj.onsubmit ) == 'function' ) {
return eval(formObj.attr("onsubmit").replace(/return /,""));
} else {
alert("onSubmit is not a function.\n\nIs the script included?");
return false;
}
} );
Suggestions on possibly how to do this better?
I'm replacing a submit button with an
anchor link. Since calling
form.submit() does not activate
onsubmit's, I'm finding it, and
eval()ing it myself. But I'd like to
check if the function exists before
just eval()ing what's there. – gms8994
<script type="text/javascript">
function onsubmitHandler() {
alert('running onsubmit handler');
return true;
}
function testOnsubmitAndSubmit(f) {
if (typeof f.onsubmit === 'function') {
// onsubmit is executable, test the return value
if (f.onsubmit()) {
// onsubmit returns true, submit the form
f.submit();
}
}
}
</script>
<form name="theForm" onsubmit="return onsubmitHandler();">
<a href="#" onclick="
testOnsubmitAndSubmit(document.forms['theForm']);
return false;
"></a>
</form>
EDIT : missing parameter f in function testOnsubmitAndSubmit
The above should work regardless of whether you assign the onsubmit HTML attribute or assign it in JavaScript:
document.forms['theForm'].onsubmit = onsubmitHandler;
Try
if (this.onsubmit instanceof Function) {
// do stuff;
}
You could simply use the typeof operator along with a ternary operator for short:
onsubmit="return typeof valid =='function' ? valid() : true;"
If it is a function we call it and return it's return value, otherwise just return true
Edit:
I'm not quite sure what you really want to do, but I'll try to explain what might be happening.
When you declare your onsubmit code within your html, it gets turned into a function and thus its callable from the JavaScript "world". That means that those two methods are equivalent:
HTML: <form onsubmit="return valid();" />
JavaScript: myForm.onsubmit = function() { return valid(); };
These two will be both functions and both will be callable. You can test any of those using the typeof operator which should yeld the same result: "function".
Now if you assign a string to the "onsubmit" property via JavaScript, it will remain a string, hence not callable. Notice that if you apply the typeof operator against it, you'll get "string" instead of "function".
I hope this might clarify a few things. Then again, if you want to know if such property (or any identifier for the matter) is a function and callable, the typeof operator should do the trick. Although I'm not sure if it works properly across multiple frames.
Cheers
What browser are you using?
alert(typeof document.getElementById('myform').onsubmit);
This gives me "function" in IE7 and FireFox.
using a string based variable as example and making use instanceof Function
You register the function..assign the variable...check the variable is the name of function...do pre-process... assign the function to new var...then call the function.
function callMe(){
alert('You rang?');
}
var value = 'callMe';
if (window[value] instanceof Function) {
// do pre-process stuff
// FYI the function has not actually been called yet
console.log('callable function');
//now call function
var fn = window[value];
fn();
}
Make sure you are calling typeof on the actual function, not a string literal:
function x() {
console.log("hi");
}
typeof "x"; // returns "string"
typeof x; // returns "function"
You can try modifying this technique to suit your needs:
function isFunction() {
var functionName = window.prompt('Function name: ');
var isDefined = eval('(typeof ' + functionName + '==\'function\');');
if (isDefined)
eval(functionName + '();');
else
alert('Function ' + functionName + ' does not exist');
}
function anotherFunction() {
alert('message from another function.');
}
form.onsubmit will always be a function when defined as an attribute of HTML the form element. It's some sort of anonymous function attached to an HTML element, which has the this pointer bound to that FORM element and also has a parameter named event which will contain data about the submit event.
Under these circumstances I don't understand how you got a string as a result of a typeof operation. You should give more details, better some code.
Edit (as a response to your second edit):
I believe the handler attached to the HTML attribute will execute regardless of the above code. Further more, you could try to stop it somehow, but, it appears that FF 3, IE 8, Chrome 2 and Opera 9 are executing the HTML attribute handler in the first place and then the one attached (I didn't tested with jQuery though, but with addEventListener and attachEvent). So... what are you trying to accomplish exactly?
By the way, your code isn't working because your regular expression will extract the string "valid();", which is definitely not a function.
If it's a string, you could assume / hope it's always of the form
return SomeFunction(arguments);
parse for the function name, and then see if that function is defined using
if (window[functionName]) {
// do stuff
}
Isn't typeof xxx === 'function' the best and the fastest?
I made an bench in wich you can try it out, compared to instanceof and _underscore
Its just seems to be faster than instanceof (using chrome)
It won't trow an error if the variable is not defined
Here a bench: https://jsbench.me/qnkf076cqb/1
Checking the call method on the value seems to be a good enough test. e.g., val.call && val()
> a = () => {}
[Function: a]
> function b() {}
undefined
> c = function(){}
[Function: c]
> d = 2
2
> e = []
[]
> f = {}
{}
> a.call
[Function: call]
> b.call
[Function: call]
> c.call
[Function: call]
> d.call
undefined
> e.call
undefined
> f.call
undefined
Note: Except when it's a class.
Well, "return valid();" is a string, so that's correct.
If you want to check if it has a function attached instead, you could try this:
formId.onsubmit = function (){ /* */ }
if(typeof formId.onsubmit == "function"){
alert("it's a function!");
}
You can always use one of the typeOf functions on JavaScript blogs such as Chris West's. Using a definition such as the following for the typeOf() function would work:
function typeOf(o){return {}.toString.call(o).slice(8,-1)}
This function (which is declared in the global namespace, can be used like this:
alert("onsubmit is a " + typeOf(elem.onsubmit));
If it is a function, "Function" will be returned. If it is a string, "String" will be returned. Other possible values are shown here.
I think the source of confusion is the distinction between a node's attribute and the corresponding property.
You're using:
$("a.button").parents("form").attr("onsubmit")
You're directly reading the onsubmit attribute's value (which must be a string). Instead, you should access the onsubmit property of the node:
$("a.button").parents("form").prop("onsubmit")
Here's a quick test:
<form id="form1" action="foo1.htm" onsubmit="return valid()"></form>
<script>
window.onload = function () {
var form1 = document.getElementById("form1");
function log(s) {
document.write("<div>" + s + "</div>");
}
function info(v) {
return "(" + typeof v + ") " + v;
}
log("form1 onsubmit property: " + info(form1.onsubmit));
log("form1 onsubmit attribute: " + info(form1.getAttribute("onsubmit")));
};
</script>
This yields:
form1 onsubmit property: (function) function onsubmit(event) { return valid(); }
form1 onsubmit attribute: (string) return valid()
// This should be a function, because in certain JavaScript engines (V8, for
// example, try block kills many optimizations).
function isFunction(func) {
// For some reason, function constructor doesn't accept anonymous functions.
// Also, this check finds callable objects that aren't function (such as,
// regular expressions in old WebKit versions), as according to EcmaScript
// specification, any callable object should have typeof set to function.
if (typeof func === 'function')
return true
// If the function isn't a string, it's probably good idea to return false,
// as eval cannot process values that aren't strings.
if (typeof func !== 'string')
return false
// So, the value is a string. Try creating a function, in order to detect
// syntax error.
try {
// Create a function with string func, in order to detect whatever it's
// an actual function. Unlike examples with eval, it should be actually
// safe to use with any string (provided you don't call returned value).
Function(func)
return true
}
catch (e) {
// While usually only SyntaxError could be thrown (unless somebody
// modified definition of something used in this function, like
// SyntaxError or Function, it's better to prepare for unexpected.
if (!(e instanceof SyntaxError)) {
throw e
}
return false
}
}
if ( window.onsubmit ) {
//
} else {
alert("Function does not exist.");
}
Beware that es6 class is also a function but not callable
class C {}
typeof C === "function" // true
C instanceof Function // true
C() // error
C.call() // error
new C() // okay
new C // okay
A simple check like this will let you know if it exists/defined:
if (this.onsubmit)
{
// do stuff;
}

Categories

Resources