Closed Bug 845242 Opened 11 years ago Closed 10 years ago

nsIEventListenerService: get script location e.g. path/to/script.js:120

Categories

(Core :: JavaScript Engine, defect)

defect
Not set
normal

Tracking

()

RESOLVED INVALID

People

(Reporter: miker, Unassigned)

Details

Attachments

(1 file)

Attached file Leak hunter scratchpad
To help with leak hunting I am creating a simple developer tool to give information about events (chrome and content). I use the following code to find the events connected with a page but cannot find a way to get the event handler's location in the format e.g. path/to/script.js:120.

getOrigin(handler) always returns "unknown", most likely because handler is an EventListenerInfo object instead of a normal script.

We need some way of getting the script location e.g. path/to/script.js:120.

let eventListenerService = Components.classes["@mozilla.org/eventlistenerservice;1"]
          .getService(Components.interfaces.nsIEventListenerService);

let dbg = new Debugger();
let DOwindow = dbg.addDebuggee(content.window);

let nodes = content.window.document.querySelectorAll("*");
nodes = [content.window].concat(Array.prototype.slice.call(nodes));

for (let node of nodes) {
  let handlers = eventListenerService.getListenerInfoFor(node);
  
  for (let handler of handlers) {
    log("Node: " + node);
    log("Type: " + handler.type);
    log("DOM0: " + !!node["on" + handler.type]);
    log("Capturing: " + handler.capturing);
    log("Allows Untrusted: " + handler.allowsUntrusted);
    log("System Event: " + handler.inSystemEventGroup);
    log("Source: " + handler.toSource());
    log("Origin: " + getOrigin(handler)); // e.g. path/to/script.js:120
    log("---------------------------------------------------------");
  }
}

dbg.removeDebuggee(DOwindow);

/**
 * This method fails ... probably because handler is an EventListenerInfo object instead of a normal script.
 */
function getOrigin(handler) {
  let DOhandler = DOwindow.makeDebuggeeValue(handler); 
  log(DOhandler);
  let DOscript = DOhandler.script;
  if (DOscript) {
    return handlerUrl = DOscript.url + ":" + DOscript.startLine;
  }
  return "unknown";
}

function log(msg) {
  dump(msg + "\n");
}
By "This method fails" I mean that getOrigin(handler) always returns unknown.
>  let DOhandler = DOwindow.makeDebuggeeValue(handler); 

Shouldn't you try something along the lines of handler.getDebugObject() or whatever equivalent the new debugger API wants?
(In reply to Boris Zbarsky (:bz) from comment #2)
> >  let DOhandler = DOwindow.makeDebuggeeValue(handler); 
> 
> Shouldn't you try something along the lines of handler.getDebugObject() or
> whatever equivalent the new debugger API wants?

Thanks, I had tried that using jsd but didn't consider that jsd2 would give me extra info.
Status: NEW → RESOLVED
Closed: 11 years ago
Resolution: --- → INVALID
(In reply to Michael Ratcliffe [:miker] [:mratcliffe] from comment #3)
> (In reply to Boris Zbarsky (:bz) from comment #2)
> > >  let DOhandler = DOwindow.makeDebuggeeValue(handler); 
> > 
> > Shouldn't you try something along the lines of handler.getDebugObject() or
> > whatever equivalent the new debugger API wants?
> 
> Thanks, I had tried that using jsd but didn't consider that jsd2 would give
> me extra info.

Unfortunately, there isn't anything equivalent to nsIEventListenerInfo::getDebugObject for the new debugger; we should add one. Is there some reason nsIEventListenerInfo doesn't just hand out the actual listener object as a jsval?
Security reasons. See the bug where the code was added.
(In reply to Olli Pettay [:smaug] from comment #5)
> Security reasons. See the bug where the code was added.

I gather that's bug 506961. I wasn't able to understand the security concerns raised there. If nsIEventListenerServer is chrome-only, then only chrome is going to be able to get the handler values. And with compartment-based security, even if chrome does call the thing, it'll only run with content privileges.

In any case: to permit this bug to be solved, something needs to be changed in that interface.
Things have indeed changed after bug 506961. We have compartments, and cx pushing might
not be needed, at least not for security. bholley should know how we handle the security these days.
I'm not clear on the question being asked. Can someone summarize?
(In reply to Bobby Holley (:bholley) from comment #8)
> I'm not clear on the question being asked. Can someone summarize?

jimb: "Is there some reason nsIEventListenerInfo doesn't just hand out the actual listener object as a jsval?"

smaug: "Security reasons. See the bug where the code was added."

jimb: I gather that's bug 506961. I wasn't able to understand the security concerns raised there. If nsIEventListenerServer is chrome-only, then only chrome is going to be able to get the handler values. And with compartment-based security, even if chrome does call the thing, it'll only run with content privileges.

Jimb's point is a valid one, why does nsIEventListenerInfo not just hand out the actual listener object as a jsval?
Status: RESOLVED → REOPENED
Resolution: INVALID → ---
Ok, so digging through bug 506961, it appears that the concern is that a chrome caller might accidentally invoke the |handleEvent| method of an event listener. This would be incorrect as far as event handler semantics go (because we wouldn't end up with the right script entry point), but it isn't a security issue, since we'll enter the compartment before calling.
Status: REOPENED → RESOLVED
Closed: 11 years ago10 years ago
Resolution: --- → INVALID
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: