RESOLVED FIXED 14437
CRASH: RTÉ video crashes Safari
https://bugs.webkit.org/show_bug.cgi?id=14437
Summary CRASH: RTÉ video crashes Safari
Nicholas Shanks
Reported Wednesday, June 27, 2007 10:41:42 PM UTC
Watch any piece of video or audio (RealPlayer plug‐in reqd.) related to an article on the site http://www.rte.ie/news/ After the advert plays (looks like a flash div overlayed upon the plug‐in) the browser will crash. Could be javascript‐related or a buggy plug‐in not being walled off correctly into it's own address space and taking down the whole app.
Attachments
crash log number 1 (33.77 KB, text/plain)
2007-06-27 15:09 PDT, Nicholas Shanks
no flags
crash log number 2 (29.19 KB, text/plain)
2007-06-27 15:10 PDT, Nicholas Shanks
no flags
test case (DRT-only) (791 bytes, text/html)
2007-06-28 11:54 PDT, Alexey Proskuryakov
no flags
proposed fix (3.20 KB, patch)
2007-06-29 02:24 PDT, Maxime BRITTO
darin: review-
alternate fix (4.39 KB, patch)
2007-07-02 03:13 PDT, Maxime BRITTO
andersca: review-
Tweaked initial patch (4.95 KB, patch)
2007-07-03 11:52 PDT, Anders Carlsson
darin: review-
Address comments (6.55 KB, patch)
2007-07-03 12:57 PDT, Anders Carlsson
darin: review+
Nicholas Shanks
Comment 1 Wednesday, June 27, 2007 11:09:36 PM UTC
Created attachment 15279 [details] crash log number 1
Nicholas Shanks
Comment 2 Wednesday, June 27, 2007 11:10:31 PM UTC
Created attachment 15280 [details] crash log number 2
Alexey Proskuryakov
Comment 3 Thursday, June 28, 2007 6:29:52 PM UTC
Interestingly, I still get this crash if I remove RealPlayer plugin, although Safari does complain about it being unavailable.
Alexey Proskuryakov
Comment 4 Thursday, June 28, 2007 7:54:50 PM UTC
Created attachment 15295 [details] test case (DRT-only)
Alexey Proskuryakov
Comment 5 Thursday, June 28, 2007 8:08:44 PM UTC
Anders asked to assign this bug to him :)
Maxime BRITTO
Comment 6 Friday, June 29, 2007 8:48:51 AM UTC
So bad, I've been working on this bug yesterday and I have a fix. I havn't finished the layout test, that's why I havn't attached the patch yet.
Alexey Proskuryakov
Comment 7 Friday, June 29, 2007 9:16:53 AM UTC
I think it won't hurt if you both attach your fixes, if it's no additional work for any of you. The test I attached is a finished layout test AFAICT. We normally use bug assignment to avoid work duplication.
Maxime BRITTO
Comment 8 Friday, June 29, 2007 9:31:53 AM UTC
(In reply to comment #7) > I think it won't hurt if you both attach your fixes, if it's no additional work > for any of you. The test I attached is a finished layout test AFAICT. > > We normally use bug assignment to avoid work duplication. > I've just tried your test case and you're right it's great. If you agree I would like to put it in my patch because the one I was working on is clearly not as good as yours.
Maxime BRITTO
Comment 9 Friday, June 29, 2007 10:24:31 AM UTC
Created attachment 15311 [details] proposed fix With this fix Safari won't crash anymore and it will play the video. I don't know if this is the more efficient way but it works and no other test case is affected by this fix. The test case in the patch is the reduction provided by Alexey Proskuryakov in this page.
mitz
Comment 10 Friday, June 29, 2007 10:42:54 AM UTC
Comment on attachment 15311 [details] proposed fix It looks like -aeDescByEvaluatingJavaScriptFromString: is susceptible to the same bug. Can't you just protect the frame and return the result instead of returning nil?
Darin Adler
Comment 11 Saturday, June 30, 2007 4:09:43 PM UTC
Comment on attachment 15311 [details] proposed fix I think a better fix would be to put the frame pointer into a RefPtr rather than simply returning nil in this case. I believe that will fix the bug in a straightforward way. Just: RefPtr<Frame> frame = m_frame; And then use frame instead of m_frame throughout. Other small issues: ChangeLog is missing a name and email address, needs to be indented properly and misspells the word "function".
Maxime BRITTO
Comment 12 Monday, July 2, 2007 11:13:17 AM UTC
Created attachment 15346 [details] alternate fix We talk about this with Mitz (which prefers the "RefPtr" fix) and Andersca (which prefer the "return nil" fix) on friday on IRC and Andersca convinced us that returning nil what the best way to fix this. Still, I tried the RefPtr way and it doesn't work because we get a nil script proxy (KJSProxy) and it crashes when trying to interpret. I've found a third way to fix this if you really want to return something in all cases : protecting the ExecState instead of the frame.This way it works and no test case is affected.
Alexey Proskuryakov
Comment 13 Monday, July 2, 2007 8:04:35 PM UTC
(In reply to comment #12) > We talk about this with Mitz (which prefers the "RefPtr" fix) and Andersca > (which prefer the "return nil" fix) on friday on IRC and Andersca convinced us > that returning nil what the best way to fix this. Unfortunately, I have missed this conversation - what were the reasons given for returning nil? I think that a plugin may want to receive a response even after being stopped - it still can do something that doesn't require GUI interaction (e.g. write preferences or report back to origin site).
Anders Carlsson
Comment 14 Tuesday, July 3, 2007 7:17:21 PM UTC
(In reply to comment #13) > (In reply to comment #12) > > > I think that a plugin may want to receive a response even after being stopped - > it still can do something that doesn't require GUI interaction (e.g. write > preferences or report back to origin site). > That's a separate bug then - There's already code in evaluateJavaScriptPluginRequest: that does nothing if the plug-in has been stopped: // Don't continue if stringByEvaluatingJavaScriptFromString caused the plug-in to stop. if (!isStarted) { return; } FWIW, we do the same thing on Windows.
Anders Carlsson
Comment 15 Tuesday, July 3, 2007 7:24:51 PM UTC
Comment on attachment 15346 [details] alternate fix >Index: WebCore/page/mac/WebCoreFrameBridge.mm >=================================================================== >--- WebCore/page/mac/WebCoreFrameBridge.mm (revision 23926) >+++ WebCore/page/mac/WebCoreFrameBridge.mm (working copy) >@@ -682,20 +682,32 @@ static HTMLFormElement *formElementFromD > - (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)string forceUserGesture:(BOOL)forceUserGesture > { > ASSERT(m_frame->document()); >+ >+ //The main frame cannot be destroyed so we can backup the global exec state >+ ExecState *ex = m_frame->scriptProxy()->interpreter()->globalExec(); The above comment isn't really correct here. While it is true that a script can't cause the main frame to be destroyed, there's no guarantee that the main frame actually is passed in here. >+ //the script may destroy the frame if it's not the main frame > JSValue* result = m_frame->loader()->executeScript(0, string, forceUserGesture); Which means that m_frame could point to garbage memory here > JSLock lock; >- return String(result ? result->toString(m_frame->scriptProxy()->interpreter()->globalExec()) : ""); >+ return String(result ? result->toString(ex) : ""); And ex could point to garbage memory here too. > - (NSAppleEventDescriptor *)aeDescByEvaluatingJavaScriptFromString:(NSString *) > { From code inspection we do however know that the only place this function is called from is - (NSAppleEventDescriptor *)aeDescByEvaluatingJavaScriptFromString:(NSString *)script { return [[[self mainFrame] _bridge] aeDescByEvaluatingJavaScriptFromString:script]; } Which means that m_frame will be valid even after running the script. > ASSERT(m_frame->document()); >+ >+ //The main frame cannot be destroyed so we can backup the global exec state >+ ExecState *ex = m_frame->scriptProxy()->interpreter()->globalExec(); >+ >+ //the script may destroy the frame if it's not the main frame > JSValue* result = m_frame->loader()->executeScript(0, string, true); >+ > if (!result) // FIXME: pass errors > return 0; >+ > JSLock lock; >- return aeDescFromJSValue(m_frame->scriptProxy()->interpreter()->globalExec(), result); >+ return aeDescFromJSValue(ex, result); So this code does not need to change.
Anders Carlsson
Comment 16 Tuesday, July 3, 2007 7:52:00 PM UTC
Created attachment 15371 [details] Tweaked initial patch Here's the first patch with some added asserts.
Anders Carlsson
Comment 17 Tuesday, July 3, 2007 8:01:17 PM UTC
Comment on attachment 15371 [details] Tweaked initial patch Alexey is convinced but thinks Darin should review the patch since he r-:ed the first patch.
Darin Adler
Comment 18 Tuesday, July 3, 2007 8:28:30 PM UTC
Comment on attachment 15371 [details] Tweaked initial patch I just talked this over with Anders. It's clear that in cases where the JSValue is an object, we can't return the object, because we can't run its toString method in the right context -- the context is gone because the frame is destroyed. But in the simple cases where the JSValue is not an object, it seems there's no reason we can't return the value. So I suggest we make a version of toString that works on non-object JSValue, and use that if m_frame is nil. That way the common cases of plain old strings and such will work fine. That seems slightly better than always returning nil. review- until we at least consider that option.
Anders Carlsson
Comment 19 Tuesday, July 3, 2007 8:57:26 PM UTC
Created attachment 15375 [details] Address comments
Darin Adler
Comment 20 Tuesday, July 3, 2007 9:08:14 PM UTC
Comment on attachment 15375 [details] Address comments I think it would be more elegant if there was a call in JSValue we could use rather than having to do both JSImmediate::toString and getString. But this seems good. r=me
Anders Carlsson
Comment 21 Tuesday, July 3, 2007 9:17:31 PM UTC
Committed revision 23950.
David Kilzer (:ddkilzer)
Comment 22 Friday, July 6, 2007 5:36:12 AM UTC
Note You need to log in before you can comment on or make changes to this bug.