Opened 10 years ago
Closed 9 years ago
#14189 closed bug (fixed)
globalEval handling of "use strict" pragma incorrect.
Reported by: | Owned by: | ||
---|---|---|---|
Priority: | low | Milestone: | 1.12/2.2 |
Component: | core | Version: | 2.0.3 |
Keywords: | Cc: | jaubourg | |
Blocked by: | Blocking: |
Description
The function globalEval() assumes that if a "use strict" pragma is present in the code, it must be the first thing:
if ( code.indexOf("use strict") === 1 ) { script = document.createElement("script"); script.text = code; document.head.appendChild( script ).parentNode.removeChild( script ); } else { // Otherwise, avoid the DOM node creation, insertion // and removal by using an indirect global eval indirect( code ); }
This is incorrect, as "use strict" must simply be the first statement, and may come after comments. I was unable to load the three.js library (http://threejs.org/build/three.min.js) through ajax (jQuery.get, jQuery.getScript, jQuery.ajax) because of this.
I think possible solutions would be to strip comments (instead of just trimming whitespace) before doing the test, or to test that "use strict" comes before the first semicolon.
Change History (9)
comment:1 Changed 10 years ago by
comment:2 Changed 10 years ago by
I think the time spent stripping leading comments would likely be less than that of inserting and removing unnecessary dom elements, but if it is too complicated, then it would probably be best to just always insert the script element, since it's the only way, without some preprocessing, to be sure the script will execute in the global context.
comment:3 Changed 10 years ago by
For ajax, you can just use crossDomaine: true
in your option to force usage of the script transport.
As for a fix for this for globalEval, yes, using inline script tag injection is neat but there is no guarantee it'll execute synchronously. It failed in the past.
comment:4 Changed 10 years ago by
I'm not sure I understand. If script tag injection is problematic, then why is it being used here for strict mode? What I'm suggesting is to always evaluate the code in the same way (injecting script tags) in both cases, and not have this broken test for strict mode. Or to fix the test for strict mode so that it actually works (stripping the comments, or otherwise properly checking for the directive).
Using eval on code in strict mode will not evaluate it in the global context, so this function simply does not work if there are any comments before the "use strict" directive in the code.
comment:5 Changed 10 years ago by
To me, any detection of "use strict" in *global* eval is incorrect since it should not be used in global scope. So the remaining question would be why we check for this at all. @jaubourg do you know?
comment:6 Changed 9 years ago by
Cc: | jaubourg added |
---|---|
Component: | unfiled → core |
Priority: | undecided → low |
Status: | new → open |
comment:7 Changed 9 years ago by
After careful consideration, I think we should use script tag injection all the time. I remember asking rick about the two code paths back in the days and he answered something about performance concerns. Not sure the impact of injecting a script tag is that much of a concern here.
comment:8 Changed 9 years ago by
Milestone: | None → 1.12/2.2 |
---|
We're planning to use script tags always in 1.12/2.2, see #14757. I'll leave this one open separately.
comment:9 Changed 9 years ago by
Resolution: | → fixed |
---|---|
Status: | open → closed |
#14757 was fixed so there doesn't seem to be much more to do here. Closing.
Seems like this just leads to a deeper rabbit hole. Trying to "parse" the script and ignore leading comments/spaces is going to be messy and time consuming.