Closed Bug 114461 Opened 23 years ago Closed 19 years ago

document.open/document.write clobbers js scope/context

Categories

(Core :: DOM: Core & HTML, defect)

defect
Not set
major

Tracking

()

RESOLVED FIXED
mozilla1.3final

People

(Reporter: basic, Unassigned)

References

()

Details

(Keywords: testcase, topembed-, Whiteboard: [ADT3] need info)

Attachments

(3 files, 10 obsolete files)

after calling document.open() previously defined javascript functions seems to disappear... This works in NN4.78 ( via http only, for some reason doesn't work when loaded locally) This works in IE5.01 SP2 (everywhere) This doesn't seem to work in win32 Opera5 related to bug 57107 maybe?
Attached file testcase js file (obsolete) —
Attached file testcase (obsolete) —
Comment on attachment 61136 [details] testcase after clicking the link in this testcase, it should doc.write the link again with a thick border div below it.
Attached file testcase js file (obsolete) —
ooops last one didn't work
Attachment #61134 - Attachment is obsolete: true
Attached file testcase (obsolete) —
ok this one should work
Attachment #61136 - Attachment is obsolete: true
Attached file testcase js file (obsolete) —
sorry about the spam (I'm sure it works this time)
Attachment #61141 - Attachment is obsolete: true
Attached file testcase (obsolete) —
finally!
Attachment #61142 - Attachment is obsolete: true
document's scope needs to be cleared after document.open() is called (directly or indirectly by document.write[ln]()) for security reasons, if nothing else, IIRC IE does this too, but IE seems to clear the scope *after* the script that executed document.open() is completely executed (does properties defined in the document.write()'n data also get cleared, I don't think so). Maybe we should only clear the context if the calling context is *different* than document's context? Could someone investigate closer what IE and 4x does in this situation?
Status: NEW → ASSIGNED
Target Milestone: --- → mozilla0.9.8
I don't believe that document.open preserved old window scope contents in 4.x, based on my memory and surfing http://lxr.mozilla.org/classic/search?doc_open. Cc'ing chouck. /be
It would seem to me that whatever JavaScript was running when document.open() is called should continue to run until it completes its operation. At least until the document.close() call (albeit I have heard that there is some disagreement as to the behavior of document.close()) I pointed out this problem because it jused seemed rather strange that a JavaScript based page could not rewrite the JavaScript. However, after checking in Netscape 4.x and 3.x and IE 4.x and IE 5.x and Opera (4.x I believe - not my system) and having this work, I thought it worth while to bring up to others who deal with Mozilla a bit more than I do. Given the timeframe when document.open() and document.open(...,"replace") were added to the JavaScript -- back in version 1.1 -- this would seem to be the reasonable behavior. However, I can understand the difficulty of making it work given the behavior of the document context. I do think, however, that it is rather strange that the document context gets ripped out from under the JavaScript as harshly as it is. I had a variant of my page where I did not do document.open() or document.write() but just built the whole HTML into one big string and then did, all at once, a document.open();document.write(bigString);document.close(); This also failed as the bigString variable ended up being undefined by the time the document.write() happened (only in NetScape 6.2 - all other systems seemed to deal with it just fine) This means that nasty things happen to the JavaScript context while it is still running even. The fact that the document.write(bigString) call happened after having completely removed the document context is a bug - one way or the other. Either (not my prefered answer) the JavaScript needs to be stopped if its document context is removed/trashed Or (my prefered answer) the JavaScript keeps a "shadow context" until it completes running (Which is what seems to be happening in the NS 4.x and IE cases - however it was accomplished) The current case is bad in both respects. Note that a document.open() of a separate frame is not a problem since the JavaScript is not running within that context. However, this does not really address the, what I see as a reasonable feature, of having a page update itself via JavaScript generated HTML without the need for frames (I don't see any)
This is a real bug, but it has nothing to do with document.open causing (synchronously) the window scope to be cleared. It appears that generated script tags don't work in Mozilla, at least not in 0.9.6. Attaching testcase in a minute. /be
Attached file trivial .js file for test (obsolete) —
Target Milestone: mozilla0.9.8 → mozilla0.9.9
Brendan's testcase is strange because Vidur implemented dynamic addition of <script> tags a while ago. Did something break or is this case blocked for some reason?
Someone please debug a little -- I have no time. I'd like to see this fixed in 0.9.9 though, so I'm happy it's targeted there. /be
Keywords: mozilla0.9.9
We might be able to hook up a ``termination function'' (http://lxr.mozilla.org/seamonkey/source/dom/src/base/nsJSEnvironment.cpp#1448) and delay the ::JS_ClearScope() call when document.open() is called so that the scope would be cleared when the JS that executed document.open() is done. I think this would match what IE does very closely.
Never mind IE, what did 4.x do? That (actually 2.0-4.0) is the DOM level 0 progenitor. /be
Netscape Navigator 2.02 and 3.04 works the same as moz, I get a foo is not defined error. Netscape Communicator 4.78 works with no js errors.
forgot to mention that I tested the win32 versions
Keywords: nsbeta1
Pushing to mozilla1.0
Target Milestone: mozilla0.9.9 → mozilla1.0
ADT3 per ADT triage.
Whiteboard: [ADT3]
Attachment #61328 - Attachment is obsolete: true
Attached file Correct testcase.
All the above testcases were invalid, this one shows the real problem here.
Attachment #61144 - Attachment is obsolete: true
Attachment #61145 - Attachment is obsolete: true
Attachment #61327 - Attachment is obsolete: true
Looks good to me, but I don't feel comfortable enough with JS internals to r=. Let's get r= and sr= and get this in.
Keywords: mozilla0.9.9mozilla1.0
*** Bug 138939 has been marked as a duplicate of this bug. ***
Can we get r= and sr= on this one and get it into trunk? jst, brendan? It is nsbeta1+, though it's adt3.
Changing nsbeta1+ [adt3] bugs to nsbeta1- on behalf of the adt. If you have any questions about this, please email adt@netscape.com. You can search for "changing adt3 bugs" to quickly find and delete these bug mails.
Keywords: nsbeta1-
Changing nsbeta1+ [adt3] bugs to nsbeta1- on behalf of the adt. If you have any questions about this, please email adt@netscape.com. You can search for "changing adt3 bugs" to quickly find and delete these bug mails.
Keywords: nsbeta1+
Attached patch Complete fix... (obsolete) — Splinter Review
The attached patch does two things. It makes us clear the scope when the script that executes document.open() is done executing, and it makes us support multiple termination functions on nsIScriptContext's, that's now needed since document.write(), document.open() and window.close() can now all cause termination functions to be added, IOW there can now (well, this is not really new, but it's easier to trigger now than ever) be more than one termination function per context...
http://bugscape.mcom.com/show_bug.cgi?id=14778 is tracking this due to some european topsites breaking because of this
Bad news. I did some more testing with this patch (or a newer version there of) and also with IE, and I'm afraid that this fix is not quite good enough, and I don't know that we can fully emulate what IE does :-( In a case like this, IE ends up clearing the scope where the document.open/write/close is done once that script is done executing, but it does not however clear methods in the scope used in the document from this point on, starting with the document.open(). At the point of the document.write() happening the script that's executing document.write() is running in scope A, if a script tag is written out, that script executes in a different scope B. From that point on, all scripts that run in the document that's being written out will run in scope B, so properties defined in scripts that are written out will remain defined in that scope, and properties from scope A are never reachable from scope B, i.e. the following will work: var foo = "bar"; document.open(); document.write(foo); document.close(); but this won't work: var foo = "bar <script>alert(foo);</script>" document.open(); document.write(foo); document.close(); alert(foo); here the document.write(foo) successfully writes out |foo|, and alert(foo); will slow you the value of |foo|, but when the script tag is written out and executed, it can't access |foo|. Furthermore, if there's an external reference to the window where this is executed, the external references will point to the global object in scope B. Or at least that's what it appears like, in reality, say window X sets 'w' to point to window Y, in Y, window == opener.w, but window !== opener.w. According to Brendan this is non-ECMA, so IE uses some kind of delegation scheme when dealing with these scopes n' all... Back to the drawing board...
Hardware: PC → All
To clarify my last comment, in the latter case, the alert(foo); that's immediately after the document.close() successfully shows the value of |foo|, but the alert(foo); in the script that's written out will not be able to reach the |foo| property defined in scope A.
This won't make it for mozilla1.0, pushing forward.
Target Milestone: mozilla1.0 → mozilla1.2alpha
Johnny, where are we at with this?
Keywords: nsbeta1-nsbeta1
Fixing this will be really really hard, there's no way to get this in for mozilla1.0, or mozilla1.0.1 :-(
Attached file a bunch of testcases (obsolete) —
*** Bug 158113 has been marked as a duplicate of this bug. ***
*** Bug 170719 has been marked as a duplicate of this bug. ***
retargeting to 1.3a since 1.2a is long gone. We REALLY should try to fix this; I had an ops guy here ask me why his scripts (used for monitoring clusters) no longer worked under mozilla. Interestingly, he said it worked in 1.0 but not in 1.1 (but I think he may have been lucky and/or mistaken). In any case, it was the classic "code in the Foo frame doing Foo.document.clear()/etc" problem this bug is about. Looks like there's been no work since May.
Severity: normal → major
Target Milestone: mozilla1.2alpha → mozilla1.3alpha
Keywords: mozilla1.0patch, testcase
FYI, the ops guy said it was broken but in a slightly different way in 1.0
Keywords: topembed
Attachment #82280 - Attachment is obsolete: true
Marking Topembed- as part of topembed triage. If anyone thinks this will occur/does occur in the real world, please renominate.
Keywords: topembedtopembed-
renominating I can guarantee this happens a lot in the real world. As I said, someone here wrote CGI's that generate HTML to monitor headend systems. Those CGI's hit this bug (and this bug forced them to rewrite their CGI's once I explained to them why they didn't work). Another person here has a personal webpage that was being bitten by this bug (msinz). There are plenty of sites in the real world that hit this bug. Apparently some european topsites are affected by this (I can't read it, but that's what the comment here says): http://bugscape.mcom.com/show_bug.cgi?id=14778 Feel free to topembed- it if you like, but not for the reason that it doesn't happen "in the field".
Keywords: topembed-topembed
*** Bug 182614 has been marked as a duplicate of this bug. ***
jst, what is your take on this? How hard and how important do you think this is?
Comment #c33 pretty much says how hard it would be to fix this, and as for the importance of this bug, my feeling is that it's not all that important, but other people, like Randell Jesup, seems to disagree. I don't know who's "right" here. If we decide that this is a must-fix for some release, we better know that months before the release, otherwise I doubt we can come up with a reliable fix.
Note two other issues: 1) The longer it is before this is fixed, the less likely it will matter. 2) Not fixing this will cause one of two things to happen at any given site: a) Changing of all pages this affects - which is sometimes easily done and sometimes not b) Dropping support for Mozilla at the site. In my personal case I had to change the site since I wanted to use Mozilla and a number of the other users of the site wanted to switch from IE to Mozilla (Mac OSX users in this case). The really sad part was that it works in Netscape and IE. (At least my site did) To fix my site to once again use the JavaScript mechanism (which significantly reduces the number of HTTP transations) without having Mozilla fixed would require that I use frames such that I could write into the other frame. That would end up breaking some other browsers that people use. (My universe of users happens to include many Mac users and they use a number of different browsers) Anyway, my site is no longer affected (other than the increased HTTP transactions and server load) and the longer Mozilla (and mozilla based browsers) are broken the more likely I will never spend the time to return to the JS form. Generally, this is annoying. And I can easily see some web sites going the other way (don't worry about the broken browsers), which I would have done had it not affected a large number of users, especially me :-)
Randall, can you be more specific about the top european sites affected? Given that jst says this is a lot of work and brendan sez it is non-standard we'll need a solid list of afflicted sites to make this topembed+ Thanks
Whiteboard: [ADT3] → [ADT3] need info
See bug 76495 comment 132. I claim the same fix for the problem described by that bug can and should suffice to fix this bug. I'll think about taking both bugs and doing the fix, and say more in a bit. jst, stop me if you think I'm crazy. /be
Depends on: 76495
Nope, Brendan, I think you're on the right track...
EDT is still awaiting a list of sites.
brendan, any headway here?
minusing for topembed at this point. if we can get a larger set of impacted URLs, please re-nominate.
Keywords: topembedtopembed-
Target Milestone: mozilla1.3alpha → mozilla1.3final
Mass-reassigning bugs to dom_bugs@netscape.com
Assignee: jst → dom_bugs
Status: ASSIGNED → NEW
*** Bug 202096 has been marked as a duplicate of this bug. ***
adt: nsbeta1-
Keywords: nsbeta1nsbeta1-
*** Bug 206173 has been marked as a duplicate of this bug. ***
Summary: document.open clobbers js context??? → document.open/document.write clobbers js scope/context
*** Bug 212817 has been marked as a duplicate of this bug. ***
*** Bug 213989 has been marked as a duplicate of this bug. ***
I keep running into this annoying little problem with the JS context going away when you try to rewrite the page in Mozilla. I first reported this when I did a photo album site and ended up having to do more of the work on the server side. However, I have been tripped up by this a number of times since. Each time I bang my head and say "darn! you can't do that in Mozilla even if it seems to make sense" because it just seems natural to be able to run a script and have that specific execution thread continue until the script exits. Loosing all of your variables and functions is just not expected. I have, however, worked around this by using foo.innerHTML= but that requires building the complete string all at once (you can not do foo.innerHTML+= - not sure why yet) However, this cuts off Netscape 4.x completely. (Netscape 4.x did work the document.write way, but Mozilla/Netscape 6+ do not...) So, the only reasonable workaround I have found is to use the innerHTML= mechanism. (Oh, and it is not really the same as the innerHTML= form is not like a document.write() in that in-line JS does not get evaluated during the load/write process. However, since I can now fix the document how I want, this no longer is an issue for me as I let the generating JS do what is needed at each point.) So, I would say that if this can not be fixed, at least document the work-around of using the innerHTML property. It works reasonably well in all of the current browsers (Safari, IE, Opera, and Mozilla/Netscape-based) with only minor limitations.
I use a cookie to pass any REQUIRED data into a new document. but that may be awkward for mucho data..... Use it for database and search engine where only a dozen or so vars need to be passed. but that is only a workaround till it is fixed ;-] ;-] john in niagara
mks@sinz.org: a simpler workaround is to document.write() the entire document at once.
Well, document.write of the whole document almost works - except if you want the behavior of document.open('text/html','replace'); (see bug 164821 for a problem with Mozilla in this case) Anyway, if you are going to write the whole document at once you may as well use the innerHTML trick and get the replace feature (no new history entry) and also be able to only replace the HTML parts and not the JavaScript parts (if you wish). Please excuse the tone of the last post I did as I was rather annoyed after having a site once again not work in Mozilla and having tracked it down to this problem. It would be nice to fix but if not possible, at least having people switch to the innerHTML trick will save a lot of headaches.
One alternative workaround that *may* work in some cases is to do the document.write() in a local scope (i.e. in a function) and make sure you hold local references to the data you're writing, that way your code will work as long as your code doesn't depend on the global scope not being cleared. And if your code does depend on some key functions being in the global scope, you can always set the global functions back to what they were supposed to be after you've called document.open(). It ain't pretty, but it may be a more workable alternative to using innerHTML.
*** Bug 224176 has been marked as a duplicate of this bug. ***
*** Bug 245830 has been marked as a duplicate of this bug. ***
*** Bug 251878 has been marked as a duplicate of this bug. ***
*** Bug 254678 has been marked as a duplicate of this bug. ***
*** Bug 259209 has been marked as a duplicate of this bug. ***
*** Bug 269408 has been marked as a duplicate of this bug. ***
" (you can not do foo.innerHTML+= - not sure why yet)" Because Gecko DOM closes the elements, thus document.write("<div>\r\n"); actually writes "<div>\r\n</div>".
*** Bug 274085 has been marked as a duplicate of this bug. ***
*** Bug 282201 has been marked as a duplicate of this bug. ***
*** Bug 283818 has been marked as a duplicate of this bug. ***
(In reply to comment #33) I say accept the patch to let the first case work. I would truly not expect the second case to even work as it is in a whole other context/scope. However I expect the first case to work since I'm still in the document that is creating the new document. > from scope B, i.e. the following will work: > > var foo = "bar"; > document.open(); > document.write(foo); > document.close(); > > but this won't work: > > var foo = "bar <script>alert(foo);</script>" > document.open(); > document.write(foo); > document.close(); > alert(foo); > I became aware of this bug while trying to help someone out in the mozillazine forums here: http://forums.mozillazine.org/viewtopic.php?p=1276761
(In reply to comment #50) I think the real bug is that creating a document destroys the current context and takes with it your window and document references. In other words document.open should have returned the new document object like window.open. But it isn't like that can be fixed now, you'd have to introduce a new method of the document or window object for that. There also is no way to save the reference to the current window so you can access the 'globals'. I think that if you save a window reference it should not get silently replaced like that. In code: var winRef = window; document.open(); // at this point winRef should be the original window not the new window object I think this is what you are proposing in bug 76495. If that is the case then great. But I still think you should take the patch as is now and implement the proxy if time permits. Coders are probably used to their window objects getting clobbered as even IE does it. > See bug 76495 comment 132. I claim the same fix for the problem described by > that bug can and should suffice to fix this bug. I'll think about taking both > bugs and doing the fix, and say more in a bit. > > jst, stop me if you think I'm crazy. > > /be
*** Bug 84634 has been marked as a duplicate of this bug. ***
*** Bug 290791 has been marked as a duplicate of this bug. ***
*** Bug 292330 has been marked as a duplicate of this bug. ***
I have a "killer favelet" that doesn't work in Firefox - but I can't tell whether it's due to this bug, or should be filed as a separate bug. What confuses me is it works the first time I use it, but on subsequent times it fails erratically by never writing the HTML to the document. Here it is - I have a keyword "find" associated with this. So I can type find the capital of Zanzibar in the address bar and I will get a frameset showing the search results on the four most popular search engines. javascript:var s = '%s'; if (s == '%' + 's') { s = prompt(%22Search for:%22, %22%22); } if (s != null) { s = escape(s).replace(/\+/g, %22%%22 + %222b%22); document.open(); document.write(%22<frameset rows='50%,50%' cols='50%,50%'><frame src='http://www.google.com/search?q=%22 + s + %22'><frame src='http://search.yahoo.com/search?p=%22 + s + %22'><frame src='http://search.msn.com/results.aspx?q=%22 + s + %22'><frame src='http://web.ask.com/web?q=%22 + s + %22'></frameset>%22); } void(0); What makes me think it might be this bug is that I declare s before the document.open() but use it after the document.write()
Depends on: splitwindows
1. This bug has been around since 2001 2. I admit that I'm not enough of an expert to argue the security issue but it is hard to accept the argument given that the end result (a preserved js context and a cleared body/new html) can be achieved in other--albeit more complex-- ways. 3. In my view, it is a bug and quite a serious one. (a) There is no language or environment that I have ever seen where the context is ripped out from under the code in mid execution. (b) It doesn't happen in IE--or at least the versions that I have worked in (c) It severely constrains or more realistically, all but eliminates, the usefulness of document.write, and in a manner clearly not expected in any documentation. 4. Surely the proper and intended design is for any javascript referenced in the head section to remain in a separate environment from anything in the body/html; since it is the latter that document.write should clear, the js context defined in the head should remain untouched. 5. Document.write is useful for any number of purposes, including debugging. At present, it's benefits are not available to many Firefox users. 6. Without wishing to appear unappreciative for all the hard work being done by open source contributors, isn't it time for this bug to get a definite date for a fix?
(In reply to comment #82) > 1. This bug has been around since 2001 > [other complaints deleted] Look, we're getting very close to being able to fix this bug thanks to the work in bug 296639, so I'm confident it will be fixed in 1.9 -- I will make sure that it is fixed in that milestone. But your comment here is worse than useless. All you do is add noise and drive developers away with this sort of list. What you just did is clearly against bugzilla etiquette. Please stop. /be
Attached file updated testcases
Here's the current state of the testcases posted back in 2002. This list was compiled after the checkin of split windows patch (bug 296639). Current versions of Firefox 1.5, IE6, and Opera8 tested.
Attachment #90090 - Attachment is obsolete: true
The root problem here is, believe it or not, fixed now. The splitwindow landing took care of this problem. Not sure what all the last testcase here is trying to show, but the "Correct testcase." (attachment 77354 [details]) now works as expected. Closing bug as FIXED, please open new bugs on any remaining related issues.
Status: NEW → RESOLVED
Closed: 19 years ago
Resolution: --- → FIXED
*** Bug 296544 has been marked as a duplicate of this bug. ***
Its fixed.
*** Bug 317764 has been marked as a duplicate of this bug. ***
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: