If you think a bug might affect users in the 57 release, please set the correct tracking and status flags for Release Management.

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

RESOLVED INVALID

Status

()

Core
JavaScript Engine
RESOLVED INVALID
5 years ago
4 years ago

People

(Reporter: miker, Unassigned)

Tracking

Trunk
Points:
---

Firefox Tracking Flags

(Not tracked)

Details

Attachments

(1 attachment)

Created attachment 718337 [details]
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
Last Resolved: 5 years ago
Resolution: --- → INVALID

Comment 4

5 years ago
(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?

Comment 5

5 years ago
Security reasons. See the bug where the code was added.

Comment 6

5 years ago
(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.

Comment 7

5 years ago
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
Last Resolved: 5 years ago4 years ago
Resolution: --- → INVALID
You need to log in before you can comment on or make changes to this bug.