Skip to content

Commit

Permalink
[Site Isolation] Aggregate find string match counts
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=269551
rdar://123067488

Reviewed by Alex Christensen.

The find string callback aggregator should sum the match counts from each web process response.

Also reuse the find delegate in `WKWebViewFindString.mm`.

* Source/WebKit/UIProcess/FindStringCallbackAggregator.cpp:
(WebKit::FindStringCallbackAggregator::foundString):
(WebKit::FindStringCallbackAggregator::~FindStringCallbackAggregator):
* Source/WebKit/UIProcess/FindStringCallbackAggregator.h:
* Source/WebKit/UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::findString):
* Tools/TestWebKitAPI/SourcesCocoa.txt:
* Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* Tools/TestWebKitAPI/Tests/WebKitCocoa/SiteIsolation.mm:
(TestWebKitAPI::TEST):
* Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebViewFindString.mm:
(-[WKWebViewFindStringFindDelegate findString]): Deleted.
(-[WKWebViewFindStringFindDelegate _webView:didCountMatches:forString:]): Deleted.
(-[WKWebViewFindStringFindDelegate _webView:didFindMatches:forString:withMatchIndex:]): Deleted.
(-[WKWebViewFindStringFindDelegate _webView:didFailToFindString:]): Deleted.
* Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebViewFindStringFindDelegate.h: Copied from Source/WebKit/UIProcess/FindStringCallbackAggregator.h.
* Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebViewFindStringFindDelegate.mm: Copied from Source/WebKit/UIProcess/FindStringCallbackAggregator.h.
(-[WKWebViewFindStringFindDelegate findString]):
(-[WKWebViewFindStringFindDelegate _webView:didCountMatches:forString:]):
(-[WKWebViewFindStringFindDelegate _webView:didFindMatches:forString:withMatchIndex:]):
(-[WKWebViewFindStringFindDelegate _webView:didFailToFindString:]):

Canonical link: https://commits.webkit.org/274897@main
  • Loading branch information
charliewolfe committed Feb 17, 2024
1 parent 39c785b commit 6c9a595
Show file tree
Hide file tree
Showing 9 changed files with 138 additions and 48 deletions.
5 changes: 3 additions & 2 deletions Source/WebKit/UIProcess/FindStringCallbackAggregator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,12 @@ Ref<FindStringCallbackAggregator> FindStringCallbackAggregator::create(WebPagePr
return adoptRef(*new FindStringCallbackAggregator(page, string, options, maxMatchCount, WTFMove(completionHandler)));
}

void FindStringCallbackAggregator::foundString(std::optional<FrameIdentifier> frameID, bool didWrap)
void FindStringCallbackAggregator::foundString(std::optional<FrameIdentifier> frameID, uint32_t matchCount, bool didWrap)
{
if (!frameID)
return;

m_matchCount += matchCount;
m_matches.set(*frameID, didWrap);
}

Expand Down Expand Up @@ -98,7 +99,7 @@ FindStringCallbackAggregator::~FindStringCallbackAggregator()
} while (frameContainingMatch && frameContainingMatch != focusedFrame);

auto message = Messages::WebPage::FindString(m_string, m_options, m_maxMatchCount);
auto completionHandler = [protectedPage = Ref { *protectedPage }, string = m_string, completionHandler = WTFMove(m_completionHandler)](std::optional<FrameIdentifier> frameID, Vector<IntRect>&& matchRects, uint32_t matchCount, int32_t matchIndex, bool didWrap) mutable {
auto completionHandler = [protectedPage = Ref { *protectedPage }, string = m_string, matchCount = m_matchCount, completionHandler = WTFMove(m_completionHandler)](std::optional<FrameIdentifier> frameID, Vector<IntRect>&& matchRects, uint32_t, int32_t matchIndex, bool didWrap) mutable {
if (!frameID)
protectedPage->findClient().didFailToFindString(protectedPage.ptr(), string);
else
Expand Down
3 changes: 2 additions & 1 deletion Source/WebKit/UIProcess/FindStringCallbackAggregator.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ enum class FindOptions : uint16_t;
class FindStringCallbackAggregator : public RefCounted<FindStringCallbackAggregator> {
public:
static Ref<FindStringCallbackAggregator> create(WebPageProxy&, const String&, OptionSet<FindOptions>, unsigned maxMatchCount, CompletionHandler<void(bool)>&&);
void foundString(std::optional<WebCore::FrameIdentifier>, bool didWrap);
void foundString(std::optional<WebCore::FrameIdentifier>, uint32_t matchCount, bool didWrap);
~FindStringCallbackAggregator();

private:
Expand All @@ -51,6 +51,7 @@ class FindStringCallbackAggregator : public RefCounted<FindStringCallbackAggrega
String m_string;
OptionSet<FindOptions> m_options;
unsigned m_maxMatchCount;
uint32_t m_matchCount { 0 };
CompletionHandler<void(bool)> m_completionHandler;
HashMap<WebCore::FrameIdentifier, bool> m_matches;
};
Expand Down
4 changes: 2 additions & 2 deletions Source/WebKit/UIProcess/WebPageProxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5348,8 +5348,8 @@ void WebPageProxy::findString(const String& string, OptionSet<FindOptions> optio
{
Ref callbackAggregator = FindStringCallbackAggregator::create(*this, string, options, maxMatchCount, std::forward<decltype(completionHandler)>(completionHandler));
forEachWebContentProcess([&](auto& webProcess, auto pageID) {
webProcess.sendWithAsyncReply(std::forward<M>(message), [callbackAggregator](std::optional<FrameIdentifier> frameID, Vector<IntRect>&&, uint32_t, int32_t, bool didWrap) {
callbackAggregator->foundString(frameID, didWrap);
webProcess.sendWithAsyncReply(std::forward<M>(message), [callbackAggregator](std::optional<FrameIdentifier> frameID, Vector<IntRect>&&, uint32_t matchCount, int32_t, bool didWrap) {
callbackAggregator->foundString(frameID, matchCount, didWrap);
}, pageID);
});
};
Expand Down
1 change: 1 addition & 0 deletions Tools/TestWebKitAPI/SourcesCocoa.txt
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,7 @@ Tests/WebKitCocoa/WKWebViewDoesNotLogDuringInitialization.mm
Tests/WebKitCocoa/WKWebViewEditActions.mm
Tests/WebKitCocoa/WKWebViewEvaluateJavaScript.mm
Tests/WebKitCocoa/WKWebViewFindString.mm
Tests/WebKitCocoa/WKWebViewFindStringFindDelegate.mm
Tests/WebKitCocoa/WKWebViewFirstResponderTests.mm
Tests/WebKitCocoa/WKWebViewGetContents.mm
Tests/WebKitCocoa/WKWebViewInspection.mm
Expand Down
4 changes: 4 additions & 0 deletions Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -2005,6 +2005,8 @@

/* Begin PBXFileReference section */
00CD9F6215BE312C002DA2CE /* BackForwardList.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = BackForwardList.mm; sourceTree = "<group>"; };
021CCE262B7F2E30002C26EF /* WKWebViewFindStringFindDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WKWebViewFindStringFindDelegate.h; sourceTree = "<group>"; };
021CCE332B7F31AB002C26EF /* WKWebViewFindStringFindDelegate.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = WKWebViewFindStringFindDelegate.mm; sourceTree = "<group>"; };
02238A3D2B2FB47C00442B86 /* VerifyUserGestureFromUIProcess.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = VerifyUserGestureFromUIProcess.mm; sourceTree = "<group>"; };
041A1E33216FFDBC00789E0A /* PublicSuffix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PublicSuffix.cpp; sourceTree = "<group>"; };
0451A5A6235E438E009DF945 /* BumpPointerAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BumpPointerAllocator.cpp; sourceTree = "<group>"; };
Expand Down Expand Up @@ -4321,6 +4323,8 @@
F4811E5821940B4400A5E0FD /* WKWebViewEditActions.mm */,
0F3B94A51A77266C00DE3272 /* WKWebViewEvaluateJavaScript.mm */,
CE449E1021AE0F7200E7ADA1 /* WKWebViewFindString.mm */,
021CCE262B7F2E30002C26EF /* WKWebViewFindStringFindDelegate.h */,
021CCE332B7F31AB002C26EF /* WKWebViewFindStringFindDelegate.mm */,
F4106C6821ACBF84004B89A1 /* WKWebViewFirstResponderTests.mm */,
D3BE5E341E4CE85E00FD563A /* WKWebViewGetContents.mm */,
63A33C552A339ED500EF94B8 /* WKWebViewInspection.mm */,
Expand Down
28 changes: 28 additions & 0 deletions Tools/TestWebKitAPI/Tests/WebKitCocoa/SiteIsolation.mm
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#import "TestNavigationDelegate.h"
#import "TestUIDelegate.h"
#import "Utilities.h"
#import "WKWebViewFindStringFindDelegate.h"
#import <WebKit/WKFrameInfoPrivate.h>
#import <WebKit/WKNavigationDelegatePrivate.h>
#import <WebKit/WKNavigationPrivate.h>
Expand Down Expand Up @@ -2263,6 +2264,33 @@ HTTPServer server({
findStringAndValidateResults(webView.get(), *it);
}

TEST(SiteIsolation, FindStringMatchCount)
{
auto mainframeHTML = "<p>Hello world</p>"
"<iframe src='https://domain2.com/subframe'></iframe>"
"<iframe src='https://domain3.com/subframe'></iframe>"_s;
HTTPServer server({
{ "/mainframe"_s, { mainframeHTML } },
{ "/subframe"_s, { "<p>Hello world</p>"_s } }
}, HTTPServer::Protocol::HttpsProxy);
auto [webView, navigationDelegate] = siteIsolatedViewAndDelegate(server);
auto findConfiguration = adoptNS([[WKFindConfiguration alloc] init]);
auto findDelegate = adoptNS([[WKWebViewFindStringFindDelegate alloc] init]);
[webView _setFindDelegate:findDelegate.get()];

[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://domain1.com/mainframe"]]];
[navigationDelegate waitForDidFinishNavigation];

__block bool done = false;
[webView findString:@"Hello world" withConfiguration:findConfiguration.get() completionHandler:^(WKFindResult *result) {
EXPECT_TRUE(result.matchFound);
done = true;
}];
Util::run(&done);

EXPECT_EQ(3ul, [findDelegate matchesCount]);
}

#if PLATFORM(MAC)
TEST(SiteIsolation, ProcessDisplayNames)
{
Expand Down
44 changes: 1 addition & 43 deletions Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebViewFindString.mm
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
#import "DeprecatedGlobalValues.h"
#import "PlatformUtilities.h"
#import "TestWKWebView.h"
#import "WKWebViewFindStringFindDelegate.h"
#import <WebKit/WKWebViewPrivate.h>
#import <WebKit/_WKFindDelegate.h>
#import <WebKit/_WKInputDelegate.h>

#if PLATFORM(IOS_FAMILY)
Expand All @@ -52,48 +52,6 @@ - (void)_webView:(WKWebView *)webView didStartInputSession:(id <_WKFormInputSess

@end

@interface WKWebViewFindStringFindDelegate : NSObject <_WKFindDelegate>
@property (nonatomic, readonly) NSString *findString;
@property (nonatomic, readonly) NSUInteger matchesCount;
@property (nonatomic, readonly) NSInteger matchIndex;
@property (nonatomic, readonly) BOOL didFail;
@end

@implementation WKWebViewFindStringFindDelegate {
RetainPtr<NSString> _findString;
}

- (NSString *)findString
{
return _findString.get();
}

- (void)_webView:(WKWebView *)webView didCountMatches:(NSUInteger)matches forString:(NSString *)string
{
_findString = string;
_matchesCount = matches;
_didFail = NO;
isDone = YES;
}

- (void)_webView:(WKWebView *)webView didFindMatches:(NSUInteger)matches forString:(NSString *)string withMatchIndex:(NSInteger)matchIndex
{
_findString = string;
_matchesCount = matches;
_matchIndex = matchIndex;
_didFail = NO;
isDone = YES;
}

- (void)_webView:(WKWebView *)webView didFailToFindString:(NSString *)string
{
_findString = string;
_didFail = YES;
isDone = YES;
}

@end

#if PLATFORM(IOS_FAMILY)
static BOOL returnNo()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright (C) 2024 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/

#import <WebKit/_WKFindDelegate.h>

@interface WKWebViewFindStringFindDelegate : NSObject <_WKFindDelegate>
@property (nonatomic, readonly) NSString *findString;
@property (nonatomic, readonly) NSUInteger matchesCount;
@property (nonatomic, readonly) NSInteger matchIndex;
@property (nonatomic, readonly) BOOL didFail;
@end
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Copyright (C) 2024 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/

#import "config.h"
#import "WKWebViewFindStringFindDelegate.h"

#import "DeprecatedGlobalValues.h"

@implementation WKWebViewFindStringFindDelegate {
RetainPtr<NSString> _findString;
}

- (NSString *)findString
{
return _findString.get();
}

- (void)_webView:(WKWebView *)webView didCountMatches:(NSUInteger)matches forString:(NSString *)string
{
_findString = string;
_matchesCount = matches;
_didFail = NO;
isDone = YES;
}

- (void)_webView:(WKWebView *)webView didFindMatches:(NSUInteger)matches forString:(NSString *)string withMatchIndex:(NSInteger)matchIndex
{
_findString = string;
_matchesCount = matches;
_matchIndex = matchIndex;
_didFail = NO;
isDone = YES;
}

- (void)_webView:(WKWebView *)webView didFailToFindString:(NSString *)string
{
_findString = string;
_didFail = YES;
isDone = YES;
}

@end

0 comments on commit 6c9a595

Please sign in to comment.