[SCM] WebKit Debian packaging branch, debian/unstable, updated. debian/1.1.15-1-40151-g37bb677

sullivan sullivan at 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Sat Sep 26 08:28:59 UTC 2009


The following commit has been merged in the debian/unstable branch:
commit a280e60f5ee61ca2e979679745c26779b3cabd18
Author: sullivan <sullivan at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Tue Mar 9 21:03:30 2004 +0000

    WebKit:
    
            - fixed the following bugs:
            <rdar://problem/3579715>: Going to an error page in back/forward list doesn't work
            correctly in some cases
            <rdar://problem/3581031>: REGRESSION (130+): World Leak of WebFrame after trying
            to load page with unknown scheme
    
            Reviewed by Darin.
    
            * WebView.subproj/WebDataSourcePrivate.h:
            renamed __setRequest -> __adoptRequest
            * WebView.subproj/WebDataSource.m:
            (-[WebDataSource _URLForHistory]):
            updated comment
            (-[WebDataSource __adoptRequest:]):
            Renamed from __setRequest; now takes an NSMutableURLRequest and uses it as-is.
            (-[WebDataSource _setRequest:]):
            now saves a mutable copy, instead of relying on the caller to do so. The
            (only) caller wasn't doing so in all cases, leading to trouble in River City.
            Also, special-case unreachable URL handling to allow alternate content to
            replace a URL in a redirect-like way without sending a redirect callback.
    
            * WebView.subproj/WebFrame.m:
            (-[WebFrame loadAlternateHTMLString:baseURL:forUnreachableURL:]):
            renamed after discussion with Richard (was loadPlaceholderHTMLString:baseURL:unreachableURL:)
            (-[WebFrame _shouldReloadToHandleUnreachableURLFromRequest:]):
            new helper method, returns YES only if we receive a load request for alternate
            content from a delegate for an unreachable URL while we are going back or forward.
            That's a lot of prepositions!
            (-[WebFrame _loadRequest:subresources:]):
            if _shouldReloadToHandleUnreachableURLFromRequest: returns YES, change load type
            to WebFrameLoadTypeReload so b/f list is preserved appropriately.
            (-[WebFrame _transitionToCommitted:]):
            Update currentItem in the unreachableURL case.
            (-[WebFrame _isLoadComplete]):
            Don't reset b/f list before calling provisionalLoadDidFail delegate; instead, determine
            where to reset b/f list beforehand, and then actually reset list afterwards only if we
            didn't start an alternate content load in the delegate. Also, set new boolean ivar so we
            know when we're processing a provisionalLoadDidFail delegate callback.
            (-[WebFrame _loadItem:withLoadType:]):
            don't make extra copy before calling __adoptRequest; just pass it the one we made here.
            (-[WebFrame _checkNavigationPolicyForRequest:dataSource:formState:andCall:withSelector:]):
            If we're loading alternate content for an unreachableURL, don't ask the decision listener,
            just do it. (This avoids problem with nested calls to checking the navigation policy that
            led to a WebFrame leak, and is conceptually the right thing to do also.) Also added some
            asserts that helped me track down the WebFrame leak. Set new boolean ivar so we know
            when we're processing a navigation policy delegate decision.
            (-[WebFrame _currentBackForwardListItemToResetTo]):
            new method, replaces _resetBackForwardListToCurrent. Does the same test as the
            latter but returns a boolean rather than actually resetting.
            (-[WebFrame _continueLoadRequestAfterNavigationPolicy:formState:]):
            save dataSource in a local var before calling stopLoading, and use it for
            _setProvisionalDataSource, because otherwise stopLoading was clobbering the dataSource
            for an unreachable URL handling case.
    
            * WebView.subproj/WebFramePrivate.h:
            two new boolean ivars
    
            * WebView.subproj/WebView.m:
            (+[WebView _canHandleRequest:]):
            return YES when we're loading alternate content for an unreachable URL
    
    WebBrowser:
    
            Reviewed by Darin.
    
            * BrowserWebController.m:
            (-[BrowserWebView showErrorPageForURL:withTitle:message:]):
            update call to renamed method
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@6189 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebKit/ChangeLog b/WebKit/ChangeLog
index fb62c0e..26ebf6c 100644
--- a/WebKit/ChangeLog
+++ b/WebKit/ChangeLog
@@ -1,3 +1,66 @@
+2004-03-09  John Sullivan  <sullivan at apple.com>
+
+        - fixed the following bugs:
+        <rdar://problem/3579715>: Going to an error page in back/forward list doesn't work 
+        correctly in some cases
+        <rdar://problem/3581031>: REGRESSION (130+): World Leak of WebFrame after trying 
+        to load page with unknown scheme
+
+        Reviewed by Darin.
+
+        * WebView.subproj/WebDataSourcePrivate.h:
+        renamed __setRequest -> __adoptRequest
+        * WebView.subproj/WebDataSource.m:
+        (-[WebDataSource _URLForHistory]): 
+        updated comment
+        (-[WebDataSource __adoptRequest:]):
+        Renamed from __setRequest; now takes an NSMutableURLRequest and uses it as-is.
+        (-[WebDataSource _setRequest:]):
+        now saves a mutable copy, instead of relying on the caller to do so. The
+        (only) caller wasn't doing so in all cases, leading to trouble in River City.
+        Also, special-case unreachable URL handling to allow alternate content to 
+        replace a URL in a redirect-like way without sending a redirect callback.
+        
+        * WebView.subproj/WebFrame.m:
+        (-[WebFrame loadAlternateHTMLString:baseURL:forUnreachableURL:]):
+        renamed after discussion with Richard (was loadPlaceholderHTMLString:baseURL:unreachableURL:)
+        (-[WebFrame _shouldReloadToHandleUnreachableURLFromRequest:]):
+        new helper method, returns YES only if we receive a load request for alternate
+        content from a delegate for an unreachable URL while we are going back or forward.
+        That's a lot of prepositions!
+        (-[WebFrame _loadRequest:subresources:]):
+        if _shouldReloadToHandleUnreachableURLFromRequest: returns YES, change load type
+        to WebFrameLoadTypeReload so b/f list is preserved appropriately.
+        (-[WebFrame _transitionToCommitted:]):
+        Update currentItem in the unreachableURL case.
+        (-[WebFrame _isLoadComplete]):
+        Don't reset b/f list before calling provisionalLoadDidFail delegate; instead, determine 
+        where to reset b/f list beforehand, and then actually reset list afterwards only if we 
+        didn't start an alternate content load in the delegate. Also, set new boolean ivar so we
+        know when we're processing a provisionalLoadDidFail delegate callback.
+        (-[WebFrame _loadItem:withLoadType:]):
+        don't make extra copy before calling __adoptRequest; just pass it the one we made here.
+        (-[WebFrame _checkNavigationPolicyForRequest:dataSource:formState:andCall:withSelector:]):
+        If we're loading alternate content for an unreachableURL, don't ask the decision listener,
+        just do it. (This avoids problem with nested calls to checking the navigation policy that
+        led to a WebFrame leak, and is conceptually the right thing to do also.) Also added some
+        asserts that helped me track down the WebFrame leak. Set new boolean ivar so we know
+        when we're processing a navigation policy delegate decision.
+        (-[WebFrame _currentBackForwardListItemToResetTo]):
+        new method, replaces _resetBackForwardListToCurrent. Does the same test as the
+        latter but returns a boolean rather than actually resetting.
+        (-[WebFrame _continueLoadRequestAfterNavigationPolicy:formState:]):
+        save dataSource in a local var before calling stopLoading, and use it for
+        _setProvisionalDataSource, because otherwise stopLoading was clobbering the dataSource
+        for an unreachable URL handling case.
+        
+        * WebView.subproj/WebFramePrivate.h:
+        two new boolean ivars
+        
+        * WebView.subproj/WebView.m:
+        (+[WebView _canHandleRequest:]):
+        return YES when we're loading alternate content for an unreachable URL
+
 === Safari-131 ===
 
 2004-03-08  Ken Kocienda  <kocienda at apple.com>
diff --git a/WebKit/WebView.subproj/WebDataSource.m b/WebKit/WebView.subproj/WebDataSource.m
index bc93740..094a600 100644
--- a/WebKit/WebView.subproj/WebDataSource.m
+++ b/WebKit/WebView.subproj/WebDataSource.m
@@ -383,7 +383,7 @@
 - (NSURL *)_URLForHistory
 {
     // Return the URL to be used for history and B/F list.
-    // Returns nil for WebDataProtocol URLs that aren't placeholders 
+    // Returns nil for WebDataProtocol URLs that aren't alternates 
     // for unreachable URLs, because these can't be stored in history.
     NSURL *URL = [_private->originalRequestCopy URL];
     if ([WebDataProtocol _webIsDataProtocolURL:URL]) {
@@ -454,7 +454,7 @@
     _private->request = newRequest;
 }
 
-- (void)__setRequest:(NSURLRequest *)request
+- (void)__adoptRequest:(NSMutableURLRequest *)request
 {
     if (request != _private->request){
         [_private->request release];
@@ -464,17 +464,27 @@
 
 - (void)_setRequest:(NSURLRequest *)request
 {
+    ASSERT_ARG(request, request != _private->request);
+    
+    // Replacing an unreachable URL with alternate content looks like a server-side
+    // redirect at this point, but we can replace a committed dataSource.
+    BOOL handlingUnreachableURL = [request _webDataRequestUnreachableURL] != nil;
+    if (handlingUnreachableURL) {
+        _private->committed = NO;
+    }
+    
     // We should never be getting a redirect callback after the data
-    // source is committed. It would be a WebFoundation bug if it sent
-    // a redirect callback after commit.
+    // source is committed, except in the unreachable URL case. It 
+    // would be a WebFoundation bug if it sent a redirect callback after commit.
     ASSERT(!_private->committed);
 
     NSURLRequest *oldRequest = _private->request;
 
-    _private->request = [request retain];
+    _private->request = [request mutableCopy];
 
     // Only send webView:didReceiveServerRedirectForProvisionalLoadForFrame: if URL changed.
-    if (![[oldRequest URL] isEqual: [request URL]]) {
+    // Also, don't send it when replacing unreachable URLs with alternate content.
+    if (!handlingUnreachableURL && ![[oldRequest URL] isEqual: [request URL]]) {
         LOG(Redirect, "Server redirect to: %@", [request URL]);
         [[_private->webView _frameLoadDelegateForwarder] webView:_private->webView
                       didReceiveServerRedirectForProvisionalLoadForFrame:[self webFrame]];
diff --git a/WebKit/WebView.subproj/WebDataSourcePrivate.h b/WebKit/WebView.subproj/WebDataSourcePrivate.h
index 93fc9d6..eff79eb 100644
--- a/WebKit/WebView.subproj/WebDataSourcePrivate.h
+++ b/WebKit/WebView.subproj/WebDataSourcePrivate.h
@@ -148,7 +148,7 @@
 - (double)_loadingStartedTime;
 - (void)_setTitle:(NSString *)title;
 - (void)_setURL:(NSURL *)URL;
-- (void)__setRequest:(NSURLRequest *)request;
+- (void)__adoptRequest:(NSMutableURLRequest *)request;
 - (void)_setRequest:(NSURLRequest *)request;
 - (void)_setResponse:(NSURLResponse *)response;
 - (void)_clearErrors;
diff --git a/WebKit/WebView.subproj/WebFrame.m b/WebKit/WebView.subproj/WebFrame.m
index 3e853d2..2fc195a 100644
--- a/WebKit/WebView.subproj/WebFrame.m
+++ b/WebKit/WebView.subproj/WebFrame.m
@@ -134,7 +134,7 @@ NSString *WebPageCacheDocumentViewKey = @"WebPageCacheDocumentViewKey";
 - (WebHistoryItem *)_createItem: (BOOL)useOriginal;
 - (WebHistoryItem *)_createItemTreeWithTargetFrame:(WebFrame *)targetFrame clippedAtTarget:(BOOL)doClip;
 
-- (void)_resetBackForwardListToCurrent;
+- (WebHistoryItem *)_currentBackForwardListItemToResetTo;
 @end
 
 @implementation WebFramePrivate
@@ -257,7 +257,7 @@ NSString *WebPageCacheDocumentViewKey = @"WebPageCacheDocumentViewKey";
 
 @implementation WebFrame (WebPrivate)
 
-- (void)loadPlaceholderHTMLString:(NSString *)string baseURL:(NSURL *)URL unreachableURL:(NSURL *)unreachableURL
+- (void)loadAlternateHTMLString:(NSString *)string baseURL:(NSURL *)URL forUnreachableURL:(NSURL *)unreachableURL
 {
     [self _loadHTMLString:string baseURL:URL unreachableURL:unreachableURL];
 }
@@ -294,6 +294,35 @@ NSString *WebPageCacheDocumentViewKey = @"WebPageCacheDocumentViewKey";
     return request;
 }
 
+
+- (BOOL)_shouldReloadToHandleUnreachableURLFromRequest:(NSURLRequest *)request
+{
+    NSURL *unreachableURL = [request _webDataRequestUnreachableURL];
+    if (unreachableURL == nil) {
+        return NO;
+    }
+    
+    if (_private->policyLoadType != WebFrameLoadTypeForward
+        && _private->policyLoadType != WebFrameLoadTypeBack
+        && _private->policyLoadType != WebFrameLoadTypeIndexedBackForward) {
+        return NO;
+    }
+    
+    // We only treat unreachableURLs specially during the delegate callbacks
+    // for provisional load errors and navigation policy decisions. The former
+    // case handles well-formed URLs that can't be loaded, and the latter
+    // case handles malformed URLs and unknown schemes. Loading alternate content
+    // at other times behaves like a standard load.
+    WebDataSource *compareDataSource = nil;
+    if (_private->delegateIsDecidingNavigationPolicy) {
+        compareDataSource = _private->policyDataSource;
+    } else if (_private->delegateIsHandlingProvisionalLoadError) {
+        compareDataSource = [self provisionalDataSource];
+    }
+    
+    return compareDataSource != nil && [unreachableURL isEqual:[[compareDataSource request] URL]];
+}
+
 - (void)_loadRequest:(NSURLRequest *)request subresources:(NSArray *)subresources
 {
     WebFrameLoadType loadType;
@@ -312,6 +341,14 @@ NSString *WebPageCacheDocumentViewKey = @"WebPageCacheDocumentViewKey";
     [newDataSource _setOverrideEncoding:[[self dataSource] _overrideEncoding]];
     [newDataSource addSubresources:subresources];
     
+    // When we loading alternate content for an unreachable URL that we're
+    // visiting in the b/f list, we treat it as a reload so the b/f list 
+    // is appropriately maintained.
+    if ([self _shouldReloadToHandleUnreachableURLFromRequest:request]) {
+        ASSERT(loadType == WebFrameLoadTypeStandard);
+        loadType = WebFrameLoadTypeReload;
+    }
+    
     [self _loadDataSource:newDataSource withLoadType:loadType formState:nil];
     [newDataSource release];
 }
@@ -685,7 +722,8 @@ NSString *WebPageCacheDocumentViewKey = @"WebPageCacheDocumentViewKey";
             WebFrameLoadType loadType = [self _loadType];
             if (loadType == WebFrameLoadTypeForward ||
                 loadType == WebFrameLoadTypeBack ||
-                loadType == WebFrameLoadTypeIndexedBackForward)
+                loadType == WebFrameLoadTypeIndexedBackForward ||
+                (loadType == WebFrameLoadTypeReload && [_private->provisionalDataSource unreachableURL] != nil))
             {
                 // Once committed, we want to use current item for saving DocState, and
                 // the provisional item for restoring state.
@@ -1011,14 +1049,17 @@ static CFAbsoluteTime _timeOfLastCompletedLoad;
             if ([pd _mainDocumentError]) {
                 // Check all children first.
                 LOG(Loading, "%@:  checking complete, current state WebFrameStateProvisional", [self name]);
-                [self _resetBackForwardListToCurrent];
+                WebHistoryItem *resetItem = [self _currentBackForwardListItemToResetTo];
+                BOOL shouldReset = YES;
                 if (![pd isLoading]) {
                     LOG(Loading, "%@:  checking complete in WebFrameStateProvisional, load done", [self name]);
 
                     [[self webView] _didFailProvisionalLoadWithError:[pd _mainDocumentError] forFrame:self];
+                    _private->delegateIsHandlingProvisionalLoadError = YES;
                     [[[self webView] _frameLoadDelegateForwarder] webView:_private->webView
                                           didFailProvisionalLoadWithError:[pd _mainDocumentError]
                                                                  forFrame:self];
+                    _private->delegateIsHandlingProvisionalLoadError = NO;
                     
                     [pd _stopLoading];
                     // Finish resetting the load state, but only if another load hasn't been started by the
@@ -1029,9 +1070,15 @@ static CFAbsoluteTime _timeOfLastCompletedLoad;
                         [[self webView] _progressCompleted: self];
                         
                         [self _setState:WebFrameStateComplete];
+                    } else {
+                        NSURL *unreachableURL = [_private->provisionalDataSource unreachableURL];
+                        if (unreachableURL != nil && [unreachableURL isEqual:[[pd request] URL]]) {
+                            shouldReset = NO;
+                        }
                     }
-
-                    return;
+                }
+                if (shouldReset && resetItem != nil) {
+                    [[[self webView] backForwardList] goToItem:resetItem];
                 }
             }
             return;
@@ -1274,7 +1321,7 @@ static CFAbsoluteTime _timeOfLastCompletedLoad;
         // be necessary if we do the better fix described above.
         NSMutableURLRequest *hackedRequest = [[[self dataSource] request] mutableCopy];
         [hackedRequest setURL: itemURL];
-        [[self dataSource] __setRequest: [[hackedRequest copy] autorelease]];
+        [[self dataSource] __adoptRequest:hackedRequest];
         [hackedRequest release];
         
         [[[self webView] _frameLoadDelegateForwarder] webView:_private->webView
@@ -1618,23 +1665,41 @@ static CFAbsoluteTime _timeOfLastCompletedLoad;
         [target performSelector:selector withObject:request withObject:nil];
         return;
     }
-
+    
+    // We are always willing to show alternate content for unreachable URLs;
+    // treat it like a reload so it maintains the right state for b/f list.
+    if ([request _webDataRequestUnreachableURL] != nil) {
+        if (_private->policyLoadType == WebFrameLoadTypeForward
+            || _private->policyLoadType == WebFrameLoadTypeBack
+            || _private->policyLoadType == WebFrameLoadTypeIndexedBackForward) {
+            _private->policyLoadType = WebFrameLoadTypeReload;
+        }
+        [target performSelector:selector withObject:request withObject:nil];
+        return;
+    }
+    
     [dataSource _setLastCheckedRequest:request];
 
     WebPolicyDecisionListener *listener = [[WebPolicyDecisionListener alloc] _initWithTarget:self action:@selector(_continueAfterNavigationPolicy:)];
     
+    ASSERT(_private->policyRequest == nil);
     _private->policyRequest = [request retain];
+    ASSERT(_private->policyTarget == nil);
     _private->policyTarget = [target retain];
     _private->policySelector = selector;
+    ASSERT(_private->listener == nil);
     _private->listener = [listener retain];
+    ASSERT(_private->policyFormState == nil);
     _private->policyFormState = [formState retain];
 
     WebView *wv = [self webView];
+    _private->delegateIsDecidingNavigationPolicy = YES;
     [[wv _policyDelegateForwarder] webView:wv
            decidePolicyForNavigationAction:action
                                    request:request
                                      frame:self
                           decisionListener:listener];
+    _private->delegateIsDecidingNavigationPolicy = NO;
     
     [listener release];
 }
@@ -2078,18 +2143,20 @@ static CFAbsoluteTime _timeOfLastCompletedLoad;
     return path;
 }
 
-// If we bailed out of a b/f navigation, we need to set the b/f cursor back to the current
-// item, because we optimistically move it right away at the start of the operation
-- (void)_resetBackForwardListToCurrent {
+// If we bailed out of a b/f navigation, we might need to set the b/f cursor back to the current
+// item, because we optimistically move it right away at the start of the operation. But when
+// alternate content is loaded for an unreachableURL, we don't want to reset the b/f cursor.
+// Return the item that we would reset to, so we can decide later whether to actually reset.
+- (WebHistoryItem *)_currentBackForwardListItemToResetTo
+{
     WebFrameLoadType loadType = [self _loadType];
     if ((loadType == WebFrameLoadTypeForward
-        || loadType == WebFrameLoadTypeBack
-        || loadType == WebFrameLoadTypeIndexedBackForward)
-        && [_private currentItem]
-        && self == [[self webView] mainFrame])
-    {
-        [[[self webView] backForwardList] goToItem:[_private currentItem]];
+         || loadType == WebFrameLoadTypeBack
+         || loadType == WebFrameLoadTypeIndexedBackForward)
+        && self == [[self webView] mainFrame]) {
+        return [_private currentItem];
     }
+    return nil;
 }
 
 - (WebHistoryItem *)_itemForSavingDocState
@@ -2165,10 +2232,12 @@ static CFAbsoluteTime _timeOfLastCompletedLoad;
     }
 
     WebFrameLoadType loadType = _private->policyLoadType;
+    WebDataSource *dataSource = [_private->policyDataSource retain];
     
     [self stopLoading];
     [self _setLoadType:loadType];
-    [self _setProvisionalDataSource:_private->policyDataSource];
+    [self _setProvisionalDataSource:dataSource];
+    [dataSource release];
 
     [self _setPolicyDataSource:nil];
     
diff --git a/WebKit/WebView.subproj/WebFramePrivate.h b/WebKit/WebView.subproj/WebFramePrivate.h
index 6666270..5aac0e4 100644
--- a/WebKit/WebView.subproj/WebFramePrivate.h
+++ b/WebKit/WebView.subproj/WebFramePrivate.h
@@ -88,6 +88,8 @@ extern NSString *WebPageCacheDocumentViewKey;
     BOOL justOpenedForTargetedLink;
     BOOL quickRedirectComing;
     BOOL isStoppingLoad;
+    BOOL delegateIsHandlingProvisionalLoadError;
+    BOOL delegateIsDecidingNavigationPolicy;
 }
 
 - (void)setName:(NSString *)name;
@@ -118,7 +120,7 @@ extern NSString *WebPageCacheDocumentViewKey;
 - (void)loadPropertyList:(id)HTMLPropertyList;
 
 // unreachableURL represents a URL that couldn't be loaded; the HTML string acts as an error page for that URL
-- (void)loadPlaceholderHTMLString:(NSString *)string baseURL:(NSURL *)URL unreachableURL:(NSURL *)unreachableURL;
+- (void)loadAlternateHTMLString:(NSString *)string baseURL:(NSURL *)URL forUnreachableURL:(NSURL *)unreachableURL;
 
 - (NSURLRequest *)_webDataRequestForData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)encodingName baseURL:(NSURL *)URL unreachableURL:(NSURL *)unreachableURL;
 - (void)_loadRequest:(NSURLRequest *)request subresources:(NSArray *)subresources;
diff --git a/WebKit/WebView.subproj/WebView.m b/WebKit/WebView.subproj/WebView.m
index 9bce40b..2ae06a8 100644
--- a/WebKit/WebView.subproj/WebView.m
+++ b/WebKit/WebView.subproj/WebView.m
@@ -10,6 +10,7 @@
 #import <WebKit/WebBaseNetscapePluginView.h>
 #import <WebKit/WebBridge.h>
 #import <WebKit/WebControllerSets.h>
+#import <WebKit/WebDataProtocol.h>
 #import <WebKit/WebDataSourcePrivate.h>
 #import <WebKit/WebDefaultFrameLoadDelegate.h>
 #import <WebKit/WebDefaultPolicyDelegate.h>
@@ -754,6 +755,11 @@ NSString *_WebMainFrameURLKey =         @"mainFrameURL";
     if ([NSURLConnection canHandleRequest:request]) {
         return YES;
     }
+    
+    // We're always willing to load alternate content for unreachable URLs
+    if ([request _webDataRequestUnreachableURL]) {
+        return YES;
+    }
 
     return [self _representationExistsForURLScheme:[[request URL] scheme]];
 }

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list