- fixed <rdar://problem/
5220706> REGRESSION (TOT): repro crash in -[WebView(WebViewInternal) _addObject:forIdentifier:] [14425]
http://bugs.webkit.org/show_bug.cgi?id=14425
* bindings/js/kjs_window.cpp:
(KJS::createWindow): No longer take an immediate argument - always do immediate loads
on a newly created Window. Also, do a load of "" to make sure that the right info makes
it to the app.
(KJS::showModalDialog): Updated for above.
(KJS::WindowFunc::callAsFunction): Updated for above.
* dom/Document.cpp:
(WebCore::Document::shouldBeAllowedToLoadLocalResources): If our URL is about:blank,
we're allowed if our opener is (since the opener must have written the contents).
* loader/FrameLoader.cpp:
(WebCore::FrameLoader::changeLocation): Add a variant which takes a KURL, which it
expects to be pre-completed. This is to avoid completing "" to the opener URL.
(WebCore::FrameLoader::urlSelected): Allow loading empty URLs.
* loader/FrameLoader.h:
Test case is manual only, since it takes particular app behavior to reproduce:
* manual-tests/new-window-subresource-crash.html: Added.
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@24105
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2007-07-08 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by Sam.
+
+ - fixed <rdar://problem/5220706> REGRESSION (TOT): repro crash in -[WebView(WebViewInternal) _addObject:forIdentifier:] [14425]
+ http://bugs.webkit.org/show_bug.cgi?id=14425
+
+ * bindings/js/kjs_window.cpp:
+ (KJS::createWindow): No longer take an immediate argument - always do immediate loads
+ on a newly created Window. Also, do a load of "" to make sure that the right info makes
+ it to the app.
+ (KJS::showModalDialog): Updated for above.
+ (KJS::WindowFunc::callAsFunction): Updated for above.
+ * dom/Document.cpp:
+ (WebCore::Document::shouldBeAllowedToLoadLocalResources): If our URL is about:blank,
+ we're allowed if our opener is (since the opener must have written the contents).
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::changeLocation): Add a variant which takes a KURL, which it
+ expects to be pre-completed. This is to avoid completing "" to the opener URL.
+ (WebCore::FrameLoader::urlSelected): Allow loading empty URLs.
+ * loader/FrameLoader.h:
+
+ Test case is manual only, since it takes particular app behavior to reproduce:
+
+ * manual-tests/new-window-subresource-crash.html: Added.
+
2007-07-08 Mitz Pettel <mitz@webkit.org>
Reviewed by Maciej.
}
static Frame* createWindow(ExecState* exec, Frame* openerFrame, const String& url,
- const String& frameName, const WindowFeatures& windowFeatures, JSValue* dialogArgs, bool immediate)
+ const String& frameName, const WindowFeatures& windowFeatures, JSValue* dialogArgs)
{
Frame* activeFrame = Window::retrieveActive(exec)->frame();
if (dialogArgs)
newWindow->putDirect("dialogArguments", dialogArgs);
- if (created)
- if (Document* oldDoc = openerFrame->document()) {
- newFrame->document()->setDomain(oldDoc->domain(), true);
- newFrame->document()->setBaseURL(oldDoc->baseURL());
- }
-
- if (!url.isEmpty() && (!url.startsWith("javascript:", false) || newWindow->isSafeScript(exec))) {
- String completedURL = activeFrame->document()->completeURL(url);
+ if (!url.startsWith("javascript:", false) || newWindow->isSafeScript(exec)) {
+ String completedURL = url.isEmpty() ? url : activeFrame->document()->completeURL(url);
bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
- if (immediate)
- newFrame->loader()->changeLocation(completedURL, activeFrame->loader()->outgoingReferrer(), false, userGesture);
- else
+ if (created) {
+ newFrame->loader()->changeLocation(KURL(completedURL.deprecatedString()), activeFrame->loader()->outgoingReferrer(), false, userGesture);
+ if (Document* oldDoc = openerFrame->document()) {
+ newFrame->document()->setDomain(oldDoc->domain(), true);
+ newFrame->document()->setBaseURL(oldDoc->baseURL());
+ }
+ } else if (!url.isEmpty())
newFrame->loader()->scheduleLocationChange(completedURL, activeFrame->loader()->outgoingReferrer(), false, userGesture);
}
wargs.locationBarVisible = false;
wargs.fullscreen = false;
- Frame* dialogFrame = createWindow(exec, openerWindow->frame(), valueToStringWithUndefinedOrNullCheck(exec, args[0]), "", wargs, args[1], true);
+ Frame* dialogFrame = createWindow(exec, openerWindow->frame(), valueToStringWithUndefinedOrNullCheck(exec, args[0]), "", wargs, args[1]);
if (!dialogFrame)
return jsUndefined();
parseWindowFeatures(features, windowFeatures);
constrainToVisible(screenRect(page->mainFrame()->view()), windowFeatures);
- frame = createWindow(exec, frame, urlString, frameName, windowFeatures, 0, false);
+ frame = createWindow(exec, frame, urlString, frameName, windowFeatures, 0);
if (!frame)
return jsUndefined();
DocumentLoader* documentLoader = frame->loader()->documentLoader();
if (!documentLoader)
return false;
+
+ if (m_url == "about:blank" && frame->loader()->opener() && frame->loader()->opener()->document()->isAllowedToLoadLocalResources())
+ return true;
return documentLoader->substituteData().isValid();
}
void FrameLoader::changeLocation(const String& URL, const String& referrer, bool lockHistory, bool userGesture)
{
- if (URL.find("javascript:", 0, false) == 0) {
- String script = KURL::decode_string(URL.substring(strlen("javascript:")).deprecatedString());
+ changeLocation(completeURL(URL), referrer, lockHistory, userGesture);
+}
+
+void FrameLoader::changeLocation(const KURL& URL, const String& referrer, bool lockHistory, bool userGesture)
+{
+ if (URL.url().find("javascript:", 0, false) == 0) {
+ String script = KURL::decode_string(URL.url().mid(strlen("javascript:")));
JSValue* result = executeScript(0, script, userGesture);
String scriptResult;
if (getString(result, scriptResult)) {
ResourceRequestCachePolicy policy = (m_cachePolicy == CachePolicyReload) || (m_cachePolicy == CachePolicyRefresh)
? ReloadIgnoringCacheData : UseProtocolCachePolicy;
- ResourceRequest request(completeURL(URL), referrer, policy);
+ ResourceRequest request(URL, referrer, policy);
urlSelected(request, "_self", 0, lockHistory, userGesture);
}
return;
}
- if (!url.isValid())
+ if (!url.isValid() && !url.isEmpty())
return;
FrameLoadRequest frameRequest(request, target);
void setDefersLoading(bool);
void changeLocation(const String& URL, const String& referrer, bool lockHistory = true, bool userGesture = false);
+ void changeLocation(const KURL& URL, const String& referrer, bool lockHistory = true, bool userGesture = false);
void urlSelected(const ResourceRequest&, const String& target, Event*, bool lockHistory, bool userGesture);
void urlSelected(const FrameLoadRequest&, Event*, bool userGesture);
--- /dev/null
+<body onload="test()">
+<script>
+ function test()
+ {
+ var win = window.open("");
+ var doc = win.document;
+ var text = "<html><body><sc" + "ript src='data:text/javascript,'></scr" + "ipt></body></html>";
+ doc.write(text);
+ }
+</script>
+
+<p>This test verifies that document.writing into a newly-opened empty
+window does not cause crashes or assertion failures, even if it
+triggers subresource loads. If you have popup blocking enabled you can
+click the button below to test. The test only works in Safari, because
+it depends on behavior with resource identifiers, which are provided
+by the app.</p>
+
+<button onclick="test()">Crash</button>
+</body>