Error 0x8007000e (NS_ERROR_OUT_OF_MEMORY)

0

I'm working on an addon to a forum and I get this error:

Error: Component returned failure code: 0x8007000e (NS_ERROR_OUT_OF_MEMORY) [nsIXPCComponents_Utils.evalInSandbox]

I read that the error means that the script goes into infinite loop until it fills the sandbox.

apparently the js file that leads to this error is script-compiler.js

this is the script:

var ddplus_gmCompiler={

// getUrlContents adapted from Greasemonkey Compiler
// http://www.letitblog.com/code/python/greasemonkey.py.txt
// used under GPL permission
//
// most everything else below based heavily off of Greasemonkey
// http://greasemonkey.mozdev.org/
// used under GPL permission

getUrlContents: function(aUrl){
    var    ioService=Components.classes["@mozilla.org/network/io-service;1"]
        .getService(Components.interfaces.nsIIOService);
    var    scriptableStream=Components
        .classes["@mozilla.org/scriptableinputstream;1"]
        .getService(Components.interfaces.nsIScriptableInputStream);

    var    channel=ioService.newChannel(aUrl, null, null);
    var    input=channel.open();
    scriptableStream.init(input);
    var    str=scriptableStream.read(input.available());
    scriptableStream.close();
    input.close();

    return str;
},

isGreasemonkeyable: function(url) {
    var scheme=Components.classes["@mozilla.org/network/io-service;1"]
        .getService(Components.interfaces.nsIIOService)
        .extractScheme(url);
    return (
        (scheme == "http" || scheme == "https" || scheme == "file") &&
        !/hiddenWindow\.html$/.test(url)
    );
},

contentLoad: function(e) {
    var unsafeWin=e.target.defaultView;
    if (unsafeWin.wrappedJSObject) unsafeWin=unsafeWin.wrappedJSObject;

    var unsafeLoc=new XPCNativeWrapper(unsafeWin, "location").location;
    var href=new XPCNativeWrapper(unsafeLoc, "href").href;

    if (
        ddplus_gmCompiler.isGreasemonkeyable(href)
        && ( /http:\/\/ddunlimited\.net/.test(href) )
        && true
    ) {
        var script=ddplus_gmCompiler.getUrlContents(
            'chrome://ddplus/content/ddplus.js'
        );
        ddplus_gmCompiler.injectScript(script, href, unsafeWin);
    }
},

injectScript: function(script, url, unsafeContentWin) {
    var sandbox, script, logger, storage, xmlhttpRequester;
    var safeWin=new XPCNativeWrapper(unsafeContentWin);

    sandbox=new Components.utils.Sandbox(safeWin);

    var storage=new ddplus_ScriptStorage();
    xmlhttpRequester=new ddplus_xmlhttpRequester(
        unsafeContentWin, window//appSvc.hiddenDOMWindow
    );

    sandbox.window=safeWin;
    sandbox.document=sandbox.window.document;
    sandbox.unsafeWindow=unsafeContentWin;

    // patch missing properties on xpcnw
    sandbox.XPathResult=Components.interfaces.nsIDOMXPathResult;

    // add our own APIs
    sandbox.GM_addStyle=function(css) { ddplus_gmCompiler.addStyle(sandbox.document, css) };
    sandbox.GM_setValue=ddplus_gmCompiler.hitch(storage, "setValue");
    sandbox.GM_getValue=ddplus_gmCompiler.hitch(storage, "getValue");
// kick : aggiunta la funzione
    sandbox.GM_remove=ddplus_gmCompiler.hitch(storage, "remove");

    sandbox.GM_openInTab=ddplus_gmCompiler.hitch(this, "openInTab", unsafeContentWin);
    sandbox.GM_xmlhttpRequest=ddplus_gmCompiler.hitch(
        xmlhttpRequester, "contentStartRequest"
    );
    //unsupported
    sandbox.GM_registerMenuCommand=function(){};
    sandbox.GM_log=function(){};
    sandbox.GM_getResourceURL=function(){};
    sandbox.GM_getResourceText=function(){};

    sandbox.__proto__=sandbox.window;

    try {
        this.evalInSandbox(
            "(function(){"+script+"})()",
            url,
            sandbox);
    } catch (e) {
        var e2=new Error(typeof e=="string" ? e : e.message);
        e2.fileName=script.filename;
        e2.lineNumber=0;
        //GM_logError(e2);
        alert(e2);
    }
},

evalInSandbox: function(code, codebase, sandbox) {
    if (Components.utils && Components.utils.Sandbox) {
        // DP beta+
        Components.utils.evalInSandbox(code, sandbox);
    } else if (Components.utils && Components.utils.evalInSandbox) {
        // DP alphas
        Components.utils.evalInSandbox(code, codebase, sandbox);
    } else if (Sandbox) {
        // 1.0.x
        evalInSandbox(code, sandbox, codebase);
    } else {
        throw new Error("Could not create sandbox.");
    }
},

openInTab: function(unsafeContentWin, url) {
    var tabBrowser = getBrowser(), browser, isMyWindow = false;
    for (var i = 0; browser = tabBrowser.browsers[i]; i++)
        if (browser.contentWindow == unsafeContentWin) {
            isMyWindow = true;
            break;
        }
    if (!isMyWindow) return;

    var loadInBackground, sendReferrer, referrer = null;
    loadInBackground = tabBrowser.mPrefs.getBoolPref("browser.tabs.loadInBackground");
    sendReferrer = tabBrowser.mPrefs.getIntPref("network.http.sendRefererHeader");
    if (sendReferrer) {
        var ios = Components.classes["@mozilla.org/network/io-service;1"]
                            .getService(Components.interfaces.nsIIOService);
        referrer = ios.newURI(content.document.location.href, null, null);
     }
     tabBrowser.loadOneTab(url, referrer, null, null, loadInBackground);
 },

 hitch: function(obj, meth) {
    var unsafeTop = new XPCNativeWrapper(unsafeContentWin, "top").top;

    for (var i = 0; i < this.browserWindows.length; i++) {
        this.browserWindows[i].openInTab(unsafeTop, url);
    }
},

apiLeakCheck: function(allowedCaller) {
    var stack=Components.stack;

    var leaked=false;
    do {
        if (2==stack.language) {
            if ('chrome'!=stack.filename.substr(0, 6) &&
                allowedCaller!=stack.filename 
            ) {
                leaked=true;
                break;
            }
        }

        stack=stack.caller;
    } while (stack);

    return leaked;
},

hitch: function(obj, meth) {
    if (!obj[meth]) {
        throw "method '" + meth + "' does not exist on object '" + obj + "'";
    }

    var hitchCaller=Components.stack.caller.filename;
    var staticArgs = Array.prototype.splice.call(arguments, 2, arguments.length);

    return function() {
        if (ddplus_gmCompiler.apiLeakCheck(hitchCaller)) {
            return;
        }

        // make a copy of staticArgs (don't modify it because it gets reused for
        // every invocation).
        var args = staticArgs.concat();

        // add all the new arguments
        for (var i = 0; i < arguments.length; i++) {
            args.push(arguments[i]);
        }

        // invoke the original function with the correct this obj and the combined
        // list of static and dynamic arguments.
        return obj[meth].apply(obj, args);
    };
},

addStyle:function(doc, css) {
    var head, style;
    head = doc.getElementsByTagName('head')[0];
    if (!head) { return; }
    style = doc.createElement('style');
    style.type = 'text/css';
    style.innerHTML = css;
    head.appendChild(style);
},

onLoad: function() {
    var    appcontent=window.document.getElementById("appcontent");
    if (appcontent && !appcontent.greased_ddplus_gmCompiler) {
        appcontent.greased_ddplus_gmCompiler=true;
        appcontent.addEventListener("DOMContentLoaded", ddplus_gmCompiler.contentLoad, false);
    }
},

onUnLoad: function() {
    //remove now unnecessary listeners
    window.removeEventListener('load', ddplus_gmCompiler.onLoad, false);
    window.removeEventListener('unload', ddplus_gmCompiler.onUnLoad, false);
    window.document.getElementById("appcontent")
        .removeEventListener("DOMContentLoaded", ddplus_gmCompiler.contentLoad, false);
},

}; //object ddplus_gmCompiler


function ddplus_ScriptStorage() {
    this.prefMan=new ddplus_PrefManager();
}
ddplus_ScriptStorage.prototype.setValue = function(name, val) {
    this.prefMan.setValue(name, val);
}
ddplus_ScriptStorage.prototype.getValue = function(name, defVal) {
    return this.prefMan.getValue(name, defVal);
}
ddplus_ScriptStorage.prototype.remove = function(name) {
    return this.prefMan.remove(name);
}

window.addEventListener('load', ddplus_gmCompiler.onLoad, false);
window.addEventListener('unload', ddplus_gmCompiler.onUnLoad, false);

The user script is massive and available in this gist.

To be able to see the error:

  • install the addon
  • go to the message board at http://ddunlimited.net/
  • open any thread and open click the reply link

The message will appear as soon as the reply page loads.

in practice is a tool created specifically for a forum ... with the functions targeted to simplify the daily actions of the moderator. Now the forum has changed domain and tried to make it compatible with the new forum. I'm editing the js file with a simple text editor. ettengo the error when I edit the script that I posted above. if you do not touch this script ... some functions disappear and are no longer present.

someone can help me? thank you very much: D

javascript
firefox-addon
asked on Stack Overflow Oct 25, 2013 by X_Men • edited Oct 25, 2013 by nmaier

1 Answer

1

OK, reproducible after all. The error in this case has a bogus message, as this isn't actually an OOM condition, but evalInSandbox() receiving a notification from the JS engine that the script was aborted (due to it being unresponsive) and evalInSandbox() not being able to tell the difference.

The reason is an infinite loop in your code at line 425 (cont.):

var max = textArea.parentNode.parentNode.clientHeight;
while (max == textArea.parentNode.parentNode.clientHeight)
  textArea.rows++;

This loop whill never abort as the condition will never get false.

answered on Stack Overflow Oct 25, 2013 by nmaier

User contributions licensed under CC BY-SA 3.0