سؤال

I am trying to overwrite timer methods (setTimeout, clearTimeout, setInterval and clearInterval) on an MSHTML instance, so I can track functions that have been added to setTimeout/setInterval and block the script from exiting until those functions have been called or removed.

I am getting a Permission denied error when the original setTimeout is called within the wrapper setTimeout function:

var window = new ActiveXObject('htmlfile').parentWindow.window;
var _setTimeout = window.setTimeout;

var timeouts = {};
setTimeout = function (code, ms, lang) {
    //script fails here - Permission denied
    var id = _setTimeout(code, ms, lang || 'javascript');
    timeouts[id] = true;
    return id;
};
setTimeout(function () {
    window.alert('Timed function');
}, 1000);

var testTimeouts = function () {
    var i;
    for (i in timeouts) {
        if (timeouts[i]) {return false;}
    }
};
while (!testTimeouts()) {
    WScript.Sleep(100);
}
window.alert('At end of script');

I can pass code to the original setTimeout before it's been overwritten:

window.setTimeout(function () {
    window.alert('Timed function');
}, 1000);
WScript.Sleep(2500);
window.alert('At end of script');

Preserving the original context (as suggested in an answer that seems to have vanished) doesn't work:

window._setTimeout = window.setTimeout;

var timeouts = {};
window.setTimeout = function (code, ms, lang) {
    var id = window._setTimeout(code, ms, lang || 'javascript');
    timeouts[id] = true;
    return id;
};
window.setTimeout(function () {
    window.alert('Timed function');
}, 1000);

It fails at the call to window._setTimeout with Object doesn't support this property or method.

I should note that I am running IE8, WinXP SP3, JScript 5.8.

هل كانت مفيدة؟

المحلول

Why don't you call setTimeout from the window that you have stored?

var setTimeout;
var timeouts = {};
(function() {
    var window = new ActiveXObject('htmlfile').parentWindow;
    setTimeout = function(code, delay, lang){
        var id = window.setTimeout(code, delay, lang || 'javascript');
        timeouts[id] = true;
        return id;
    };
})();
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top