I want to use the Java API, HTMLUnit, to detect the number of eval() calls being called on the webpage by the JavaScript program. However, HTMLUnit doesn't have a built in handler for this type of JavaScript function. How can this be done?
Thanks.
Just an idea. Maybe you can inject a script with this code into the start of the html that you are loading:
(function(){
const oldEval = window.eval;
window.eval = function () {
// communicate here with your Java program that eval has been
// called. Maybe you can use the postMessage method?
return oldEval.apply(this, arguments);
};
})();
With this, you hijack the eval function and you can execute some code each time eval is called. If you figure out a good way to communicate back with your program then maybe this works.
Not sure if an issue or not, but Javascript has multiple ways to evaluate code during runtime, not just eval. So, this is hijacking a direct call to eval, but not considering other evaluation possibilities like using the Function constructor or setTimeout.
Related
Is there a way for me to delay a function call in Google Apps Scripts? I'm currently testing for smaller time frames, but I would eventually like to have a 72-hour wait period between processing data and calling moveRows.
I was trying to achieve this by making this Javascript function call:
setTimeout(function() { moveRows(arrayOfRows); }, 3000);
I also tried doing it with a trigger but my function never got called.
ScriptApp.newTrigger('moveRows(arrayofRows)')
.timeBased()
.everyMinutes(1)
.create()
What am I doing wrong?
As others have pointed out, setTimeout cannot be used in GAS. Instead, you can use the function [Utilities.sleep()][1] (see this answer).
setTimeout() belongs to the 'window' object that is not present in GAS. Remember, the code is compiled on Google servers, not in your browser, so you don't have access to DOM in this environment. Similarly, you can't reference 'document' or other DOM objects. The only place where it's possible is client-side HTML that HtmlService creates and sends to your browser for rendering.
You can only pass function name as parameter to the newTrigger() method. You are passing the parameter, which is why it doesn't work.
How can I go about getting an instance of a script that is loaded in Java Script?
I'm using the function load("script.js") and I need to call a function on that script, but I need the instance in a variable so i can store it in a map.
I need something like var script = load("script.js")
Then I can call script.unload() // a function defined in script.js
When you load a script, it's executed and any bindings it creates in the environment are created. You cannot unload a script. If you know what all of its bindings and other effects are, you could clear them all (for instance, if loading Underscore, you could do _ = undefined to clear that binding), but it's unlikely that all of the effects of loading the script will be undone.
(This isn't a Nashorn thing, it's a JavaScript thing. There's one environment shared by all loaded scripts. ES2015's modules help organize that better, but there's still just one overall environment.)
Is there a way for me to delay a function call in Google Apps Scripts? I'm currently testing for smaller time frames, but I would eventually like to have a 72-hour wait period between processing data and calling moveRows.
I was trying to achieve this by making this Javascript function call:
setTimeout(function() { moveRows(arrayOfRows); }, 3000);
I also tried doing it with a trigger but my function never got called.
ScriptApp.newTrigger('moveRows(arrayofRows)')
.timeBased()
.everyMinutes(1)
.create()
What am I doing wrong?
As others have pointed out, setTimeout cannot be used in GAS. Instead, you can use the function [Utilities.sleep()][1] (see this answer).
setTimeout() belongs to the 'window' object that is not present in GAS. Remember, the code is compiled on Google servers, not in your browser, so you don't have access to DOM in this environment. Similarly, you can't reference 'document' or other DOM objects. The only place where it's possible is client-side HTML that HtmlService creates and sends to your browser for rendering.
You can only pass function name as parameter to the newTrigger() method. You are passing the parameter, which is why it doesn't work.
How can I run a string
as if it where javascript code?
//The user inputs javascript code and clicks run and it runs the javascript code
function getCode () {
retrun code();
}
funciton runCode() {
run(getCode());
}
The function you want is eval.
function funCode() {
eval(getCode());
};
While eval() certainly works, another option is to take the code, and pass it to the Function constructor. This creates a new function with your code as the function body.
Doing this has some benefits.
it's variable scope will be the global scope, so the code you run won't interfere with any local variables
it has much better performance
you can force the code into strict mode, and can shadow the window and self identifiers, making it difficult to create global variables
funciton runCode() {
// create `window` param---v v--- and `self` param
var f = new Function("window", "self", " 'use strict'; " + getCode())
// force strict mode -----------^
var self = {}
f.call(self, self, self); // pass an object to the `window` and `self` param
// and set the same object as the `this` value
}
This certainly doesn't provide full security, but can provide a little more of a "sandbox" for the code to run in.
You can also examine the self object after the call to see if it tried to create any globals.
It may also be useful to wrap the code or the function execution in a try/catch, and then examine any errors that were thrown.
eval() is the function you're looking for.
But use it wisely or not at all as it's fraught with security risks.
var exec_string = 'alert(\'Hello, World!\')';
eval(exec_string);
Outputs "Hello, World!" in an alert
You can use the built-in eval function:
function runCode() {
eval(getCode());
}
Note that this function is a bit "magical"; the interpreter gives it information from the surrounding lexical context. As a result, it has to be called as eval; you can't set run = eval and then call run. (You could, however, write function run(s) { return eval(s); }.)
As other posters have indicated, eval is the method that exists for this purpose. However, eval will execute any javascript code regardless of whether it is harmful or not (e.g. javascript from a third party source might have an infinite loop or, worse, malicious behaviour). There is the common refrain
eval == evil
and as such eval is generally regarded as an anti-pattern. However, taking such a simplistic approach is wrong. Instead, it is perfectly acceptable to use eval in cases where the string you wish to evaluate can be trusted. However it turns out there are relatively few cases where this is true. Obviously anything from a third party site is dangerous (even if you trust the owners, they may have been hacked). Even from your own server you may be susceptible to "man in the middle" attacks although this is fairly unlikely for most sites.
The most common reason to need to evaluate javascript strings is rendering third party web pages. In this case it is generally preferable to render the page on the server (e.g. http://phantomjs.org/) and then transmit the result to the browser. That way the browser is protected from running unsafe code.
Another, increasingly common, use case is interactive tutorial websites where the user gets to see the result of the code they have typed in. In this case you are less worried about malicious scripts as the only ones the user will suffer from are those that he/she has typed themselves. But in this case you are still worried about mistakes that will break the functionality of your site (e.g. infinite loops) and so it is still recommended to carry out the evaluation on your server (with appropriate safeguards) so that the inputed javascript cannot break anything.
A possible alternative to eval is Google's caja (https://code.google.com/p/google-caja/) which intends to solve all these problems, however I've never used it myself and can't comment on its usefulness.
I just found we can intercept the javascript alert() native call and hook the user code before the actual execution. check out the sample code..
function Test(){
var alertHook=function(aa){
this.alert(aa);
}
this.alert("aa");
this.alert = alertHook;
alert("aa");
}
so everytime i call alert("aa") is been intercepted by my alertHook local function. But the below implementation with the small change does not work.
function Test(){
var alertHook=function(aa){
alert(aa);
}
alert("aa");
alert = alertHook; //throws Microsoft JScript runtime error: Object doesn't support this action
alert("aa");
}
it throws Microsoft JScript runtime error: Object doesn't support this action.
I dont know how this.alert = alertHook; let me intercept the call, but alert=alertHook; not.??
So i assume using this to intercept any native js methods.? is that right?
And is that acceptable? because this way i can completely replacing any native JS calls with my own methods??
UPDATE:
I asked is that acceptable? because how this is a good approach having eval() and letting users to replace native function calls?
And its responsibility of a language to protect developers from the misleading features, replacing the native js calls in a window level(or in a common framework js file) would crash the whole system.. isn't it??
i may be wrong in my opinion because i dont understand the reason behind this feature..? I never seen a language that let developer to replace its own implementation..
Depending on how Test(); is being called, this should be the window Object.
I believe Microsoft allows overwriting native JS functions only by specifying the window object.
So window.alert = alertHook; should work anywhere.
is it acceptable?
Yes it is. This is a major strength for the flexibility of the language, although I'm sure there's better alternatives instead of overwriting native behavior.
Overwriting native JavaScript functions isn't really a security issue. It could be one if you're running someone elses code that does it; but if you're running someone elses code there's a lot of other security issues you should be concerned about.
In my opinion, it never is good practice to redefine the native functions. It's rather better to use wrappers (for instance, create a debug function that directs its output to alert or console.log or ignores the calls or whatever suits your needs).
As for why JScript throws an exception with your second example and not the first one, it's easy. In the first example, you create a property called alert in your local scope, so when you refer alert you'll be referring this.alert rather than window.alert. In the second example, the alert you're referencing is the one from window, so assigning a different function to it will fail.
And its responsibility of a language to protect developers from the misleading features, replacing the native js calls in a window level(or in a common framework js file) would crash the whole system.. isn't it??
Not true, replacing the native call only hooks into it, replaces it: it does not rewrite the native at all. Crashing the "whole" system; JavaScript runs in a Virtual Machine, it's interpreted, so the chance of crashing the "whole" system (i.e. Blue Screen of Death?) is very very small. If so: it's not the programmers fault, but the implementation of JavaScript which is causing the error.
You can consider it as a feature: for instance, if you load a JavaScript from someone else's hand, you can reimplement some functions to extend.
Protection to the programmer is like keeping a dog on the leash: only unleash it, when you trust the dog! Since JavaScript runs in a Virtual Machine, any programmer can be unleashed -- if the implementation is secure enough, which it is (most of the time?)