Closed
Bug 966477
Opened 10 years ago
Closed 9 years ago
The caller property on functions can sometimes -- contra ES5 -- return a strict mode function
Categories
(Core :: JavaScript Engine, defect)
Core
JavaScript Engine
Tracking
()
RESOLVED
FIXED
People
(Reporter: Waldo, Assigned: Waldo)
References
Details
ES5's algorithm for getting the caller property off functions is a little vague about mechanics, but it clearly wants any caller access that'd return a strict mode function to fail. We don't always do that. js> var Sandbox = Components.utils.Sandbox; js> var s1 = new Sandbox("http://example.com/"); js> s1.eval("function f() { return arguments.callee.caller; }"); js> var s2 = new Sandbox("http://example.com/"); js> s2.f = s1.f; function f() { return arguments.callee.caller; } js> s2.eval('function g() { "use strict"; return f(); } g()') function g() { "use strict"; return f(); } Not so good if we ever look into optimizing out strict mode code from having to be tracked in the stack. I'm likely to fix this in passing while making arguments/caller into accessors, seeing as I have to half-rewrite those algorithms when I do that. We'll see.
Comment 1•10 years ago
|
||
Is this the cause of https://gist.github.com/rwaldron/8720084#file-jquery-js-L40 ?
Flags: needinfo?(jwalden+bmo)
Assignee | ||
Comment 2•10 years ago
|
||
The current structure is so: // computed caller is the right callable from the stack if computed caller is a wrapper && wrapper type has a security policy: return null as caller elif computed caller is not a wrapper: if function is strict: throw a TypeError The first arm is fine. The problem is the test nested in the second arm, should be performed in the remaining possibility not covered by this if-elif: computed caller is a wrapper, and wrapper type *doesn't* have a security policy. It seems unlikely to me jquery's hitting this lapse in our logic. Far, far more likely is that they're hitting (not a wrapper && function is strict) causing a TypeError, correctly, and not realizing it's the specified behavior. (Yes, the implication is that a library can't be strict mode code, if it makes callbacks to user code, and it's allowed for that user code to walk its stack. And vice versa, if the library wants to walk the stack for debugging purposes, and the user code on the stack is strict.)
Flags: needinfo?(jwalden+bmo)
Assignee | ||
Comment 3•9 years ago
|
||
Fixed now (probably by bug 969478, the referent in comment 0): js> function test() { var Sandbox = Components.utils.Sandbox; var s1 = new Sandbox("http://example.com/"); s1.eval("function f() { return arguments.callee.caller; }"); var s2 = new Sandbox("http://example.com/"); s2.f = s1.f; try { s2.eval('function g() { "use strict"; return f(); } g()'); print("FAIL"); } catch (e) { if (e instanceof s1.TypeError) { print("PASS"); } else { print("FAIL"); } } } test(); PASS Oddly, xpcshell doesn't print anything when an uncaught exception occurs (testcase: |throw 5|), so the test in comment 0 is somewhat-not-usable: instead of printing a function it shouldn't be able to access, it prints *nothing* and silently swallows the exception. So it's necessary to catch it to distinguish proper failure from some other exception, or silent failure.
You need to log in
before you can comment on or make changes to this bug.
Description
•