From dd207fcee42f54aa219c5e1b61c7e7254018c5fb Mon Sep 17 00:00:00 2001 From: Mike Dougherty Date: Mon, 27 Jun 2022 16:52:30 +0000 Subject: [PATCH] Always create JavaScriptContentWorld with a WKContentWorld This ensures that the execution of JavaScript goes through WKFrameInfo instead of `WebFrameImpl::EncryptPayload`. The `__gCrWeb.message.routeMessage` API is not yet removed in this CL, but a NOTREACHED() call is added at the point where this code is called. Since it is no longer used, outdated tests which verify these code paths are removed in this CL. The API itself will be removed in a follow-up CL. Bug: 1322482 Change-Id: I33eb36e3f0d26c902ca2541b1624817e5cca55ed Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3696560 Commit-Queue: Mike Dougherty Reviewed-by: Ali Juma Cr-Commit-Position: refs/heads/main@{#1018275} --- ios/web/js_messaging/BUILD.gn | 18 +- .../js_messaging/java_script_content_world.h | 4 - .../js_messaging/java_script_content_world.mm | 5 - .../java_script_content_world_unittest.mm | 15 +- .../java_script_feature_manager.h | 7 + .../java_script_feature_manager.mm | 12 +- ios/web/js_messaging/web_frame_impl.mm | 21 +- .../js_messaging/web_frame_impl_unittest.mm | 306 +----------------- .../test/web_view_interaction_test_util.mm | 3 + 9 files changed, 65 insertions(+), 326 deletions(-) diff --git a/ios/web/js_messaging/BUILD.gn b/ios/web/js_messaging/BUILD.gn index 0be0e5343e866c..0181a9f25e444b 100644 --- a/ios/web/js_messaging/BUILD.gn +++ b/ios/web/js_messaging/BUILD.gn @@ -10,6 +10,7 @@ source_set("js_messaging") { deps = [ ":frame_listeners_js", ":java_script_content_world_header", + ":java_script_feature_manager_header", ":scoped_wk_script_message_handler", ":setup_frame_js", ":web_frames_manager_impl_header", @@ -58,7 +59,10 @@ source_set("web_frames_manager_impl_header") { source_set("java_script_feature") { configs += [ "//build/config/compiler:enable_arc" ] - public_deps = [ ":java_script_content_world_header" ] + public_deps = [ + ":java_script_content_world_header", + ":java_script_feature_manager_header", + ] deps = [ ":js_messaging", ":scoped_wk_script_message_handler", @@ -73,7 +77,6 @@ source_set("java_script_feature") { sources = [ "java_script_content_world.mm", "java_script_feature.mm", - "java_script_feature_manager.h", "java_script_feature_manager.mm", "script_message.mm", ] @@ -91,6 +94,17 @@ source_set("java_script_content_world_header") { sources = [ "java_script_content_world.h" ] } +source_set("java_script_feature_manager_header") { + configs += [ "//build/config/compiler:enable_arc" ] + + deps = [ + ":java_script_content_world_header", + "//base", + ] + + sources = [ "java_script_feature_manager.h" ] +} + source_set("java_script_feature_util") { configs += [ "//build/config/compiler:enable_arc" ] diff --git a/ios/web/js_messaging/java_script_content_world.h b/ios/web/js_messaging/java_script_content_world.h index 6a9c1bf579f057..09385b7e1cb4d9 100644 --- a/ios/web/js_messaging/java_script_content_world.h +++ b/ios/web/js_messaging/java_script_content_world.h @@ -33,10 +33,6 @@ class JavaScriptContentWorld { ~JavaScriptContentWorld(); JavaScriptContentWorld(const JavaScriptContentWorld&) = delete; - // Creates a content world for features which will interact with the page - // content world shared by the webpage's JavaScript. - explicit JavaScriptContentWorld(BrowserState* browser_state); - // Creates a content world for features which will interact with the given // |content_world|. JavaScriptContentWorld(BrowserState* browser_state, diff --git a/ios/web/js_messaging/java_script_content_world.mm b/ios/web/js_messaging/java_script_content_world.mm index d103f7e35d42d8..d59ba84b4196f1 100644 --- a/ios/web/js_messaging/java_script_content_world.mm +++ b/ios/web/js_messaging/java_script_content_world.mm @@ -53,11 +53,6 @@ WKUserScriptInjectionTime InjectionTimeToWKUserScriptInjectionTime( } // namespace -JavaScriptContentWorld::JavaScriptContentWorld(BrowserState* browser_state) - : browser_state_(browser_state), - user_content_controller_(GetUserContentController(browser_state)), - weak_factory_(this) {} - #if defined(__IPHONE_14_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_14_0 JavaScriptContentWorld::JavaScriptContentWorld(BrowserState* browser_state, WKContentWorld* content_world) diff --git a/ios/web/js_messaging/java_script_content_world_unittest.mm b/ios/web/js_messaging/java_script_content_world_unittest.mm index f147c32b3b2573..c6b3df493bdc81 100644 --- a/ios/web/js_messaging/java_script_content_world_unittest.mm +++ b/ios/web/js_messaging/java_script_content_world_unittest.mm @@ -30,13 +30,14 @@ [[user_content_controller userScripts] count]; ASSERT_GT(initial_scripts_count, 0ul); - web::JavaScriptContentWorld world(GetBrowserState()); + web::JavaScriptContentWorld world(GetBrowserState(), + WKContentWorld.pageWorld); FakeJavaScriptFeature feature( JavaScriptFeature::ContentWorld::kAnyContentWorld); world.AddFeature(&feature); EXPECT_TRUE(world.HasFeature(&feature)); - EXPECT_FALSE(world.GetWKContentWorld()); + EXPECT_EQ(WKContentWorld.pageWorld, world.GetWKContentWorld()); unsigned long scripts_count = [[user_content_controller userScripts] count]; ASSERT_GT(scripts_count, initial_scripts_count); @@ -54,14 +55,14 @@ FakeJavaScriptFeature feature( ASSERT_GT(initial_scripts_count, 0ul); web::JavaScriptContentWorld world(GetBrowserState(), - [WKContentWorld defaultClientWorld]); + WKContentWorld.defaultClientWorld); FakeJavaScriptFeature feature( JavaScriptFeature::ContentWorld::kAnyContentWorld); world.AddFeature(&feature); EXPECT_TRUE(world.HasFeature(&feature)); - EXPECT_EQ([WKContentWorld defaultClientWorld], world.GetWKContentWorld()); + EXPECT_EQ(WKContentWorld.defaultClientWorld, world.GetWKContentWorld()); unsigned long scripts_count = [[user_content_controller userScripts] count]; ASSERT_GT(scripts_count, initial_scripts_count); @@ -79,14 +80,14 @@ FakeJavaScriptFeature feature( ASSERT_GT(initial_scripts_count, 0ul); web::JavaScriptContentWorld world(GetBrowserState(), - [WKContentWorld defaultClientWorld]); + WKContentWorld.defaultClientWorld); FakeJavaScriptFeature feature( JavaScriptFeature::ContentWorld::kIsolatedWorldOnly); world.AddFeature(&feature); EXPECT_TRUE(world.HasFeature(&feature)); - EXPECT_EQ([WKContentWorld defaultClientWorld], world.GetWKContentWorld()); + EXPECT_EQ(WKContentWorld.defaultClientWorld, world.GetWKContentWorld()); unsigned long scripts_count = [[user_content_controller userScripts] count]; ASSERT_GT(scripts_count, initial_scripts_count); @@ -96,7 +97,7 @@ FakeJavaScriptFeature feature( // content world triggers a DCHECK. TEST_F(JavaScriptContentWorldTest, AddIsolatedWorldFeatureToPageWorld) { web::JavaScriptContentWorld world(GetBrowserState(), - [WKContentWorld pageWorld]); + WKContentWorld.pageWorld); FakeJavaScriptFeature feature( JavaScriptFeature::ContentWorld::kIsolatedWorldOnly); diff --git a/ios/web/js_messaging/java_script_feature_manager.h b/ios/web/js_messaging/java_script_feature_manager.h index e8bb8d84e2323b..b76c8a0f0eaf84 100644 --- a/ios/web/js_messaging/java_script_feature_manager.h +++ b/ios/web/js_messaging/java_script_feature_manager.h @@ -32,6 +32,13 @@ class JavaScriptFeatureManager : public base::SupportsUserData::Data { static JavaScriptFeatureManager* FromBrowserState( BrowserState* browser_state); + // Returns the JavaScriptContentWorld for the page content world associated + // with |browser_state|. If a JavaScriptFeatureManager does not already exist, + // one will be created and associated with |browser_state|. |browser_state| + // must not be null. + static JavaScriptContentWorld* GetPageContentWorldForBrowserState( + BrowserState* browser_state); + // Configures |features| on |user_content_controller_| by adding user scripts // and script message handlers. // NOTE: |page_content_world_| and |isolated_world_| will be recreated. diff --git a/ios/web/js_messaging/java_script_feature_manager.mm b/ios/web/js_messaging/java_script_feature_manager.mm index 3effbbbb48cf90..c5b7eaa106dac8 100644 --- a/ios/web/js_messaging/java_script_feature_manager.mm +++ b/ios/web/js_messaging/java_script_feature_manager.mm @@ -58,10 +58,18 @@ void AddSharedCommonFeatures(web::JavaScriptContentWorld* world) { return feature_manager; } +JavaScriptContentWorld* +JavaScriptFeatureManager::GetPageContentWorldForBrowserState( + BrowserState* browser_state) { + DCHECK(browser_state); + JavaScriptFeatureManager* feature_manager = FromBrowserState(browser_state); + return feature_manager->page_content_world_.get(); +} + void JavaScriptFeatureManager::ConfigureFeatures( std::vector features) { - page_content_world_ = - std::make_unique(browser_state_); + page_content_world_ = std::make_unique( + browser_state_, WKContentWorld.pageWorld); AddSharedCommonFeatures(page_content_world_.get()); isolated_world_ = std::make_unique( diff --git a/ios/web/js_messaging/web_frame_impl.mm b/ios/web/js_messaging/web_frame_impl.mm index 10bc355dfb371d..34f8e8f048ab1a 100644 --- a/ios/web/js_messaging/web_frame_impl.mm +++ b/ios/web/js_messaging/web_frame_impl.mm @@ -20,6 +20,7 @@ #include "crypto/aead.h" #include "crypto/random.h" #import "ios/web/js_messaging/java_script_content_world.h" +#import "ios/web/js_messaging/java_script_feature_manager.h" #import "ios/web/js_messaging/web_view_js_utils.h" #include "ios/web/public/thread/web_task_traits.h" #include "ios/web/public/thread/web_thread.h" @@ -114,7 +115,7 @@ // because calling the function directly on the webstate with // |ExecuteJavaScript| is secure. However, iframes require an encryption key // in order to securely pass the function name and parameters to the frame. - return is_main_frame_ || frame_key_; + return is_main_frame_ || frame_key_ || frame_info_; } BrowserState* WebFrameImpl::GetBrowserState() { @@ -173,6 +174,11 @@ reply_with_result); } + // There should always be a content_world now and + // `__gCrWeb.message.routeMessage` calls shouldn't be necessary. + // TODO(crbug.com/1339441): Remove custom iFrame messaging system. + NOTREACHED(); + base::Value message_payload(base::Value::Type::DICTIONARY); message_payload.SetKey("messageId", base::Value(message_id)); message_payload.SetKey("replyWithResult", base::Value(reply_with_result)); @@ -203,8 +209,11 @@ bool WebFrameImpl::CallJavaScriptFunction( const std::string& name, const std::vector& parameters) { - return CallJavaScriptFunctionInContentWorld(name, parameters, - /*content_world=*/nullptr, + JavaScriptContentWorld* content_world = + JavaScriptFeatureManager::GetPageContentWorldForBrowserState( + GetBrowserState()); + + return CallJavaScriptFunctionInContentWorld(name, parameters, content_world, /*reply_with_result=*/false); } @@ -221,8 +230,10 @@ const std::vector& parameters, base::OnceCallback callback, base::TimeDelta timeout) { - return CallJavaScriptFunctionInContentWorld(name, parameters, - /*content_world=*/nullptr, + JavaScriptContentWorld* content_world = + JavaScriptFeatureManager::GetPageContentWorldForBrowserState( + GetBrowserState()); + return CallJavaScriptFunctionInContentWorld(name, parameters, content_world, std::move(callback), timeout); } diff --git a/ios/web/js_messaging/web_frame_impl_unittest.mm b/ios/web/js_messaging/web_frame_impl_unittest.mm index 9db06c7e27f0b8..d6fe93a24078c1 100644 --- a/ios/web/js_messaging/web_frame_impl_unittest.mm +++ b/ios/web/js_messaging/web_frame_impl_unittest.mm @@ -41,51 +41,6 @@ decoded_frame_key_string); } -struct RouteMessageParameters { - NSString* encoded_message_payload = nil; - NSString* encoded_message_iv = nil; - NSString* encoded_function_payload = nil; - NSString* encoded_function_iv = nil; - NSString* frame_id = nil; -}; - -RouteMessageParameters ParametersFromFunctionCallString( - NSString* function_call) { - NSRange parameters_start = [function_call rangeOfString:@"("]; - NSRange parameters_end = [function_call rangeOfString:@")"]; - NSMutableString* parameter_string = [[function_call - substringWithRange:NSMakeRange(parameters_start.location + 1, - parameters_end.location - - parameters_start.location - 1)] - mutableCopy]; - // Create array string and replace single quotes with double quotes in - // preparation for JSON serialization. - [parameter_string insertString:@"[" atIndex:0]; - [parameter_string appendString:@"]"]; - NSString* final_string = - [parameter_string stringByReplacingOccurrencesOfString:@"'" - withString:@"\""]; - - NSData* data = [final_string dataUsingEncoding:NSUTF8StringEncoding]; - NSError* error = nil; - NSArray* jsonArray = - [NSJSONSerialization JSONObjectWithData:data - options:NSJSONReadingMutableContainers | - NSJSONReadingMutableLeaves - error:&error]; - - RouteMessageParameters parsed_params; - if (jsonArray.count == 3 && !error) { - parsed_params.encoded_message_iv = jsonArray[0][@"iv"]; - parsed_params.encoded_message_payload = jsonArray[0][@"payload"]; - parsed_params.encoded_function_iv = jsonArray[1][@"iv"]; - parsed_params.encoded_function_payload = jsonArray[1][@"payload"]; - parsed_params.frame_id = jsonArray[2]; - } - - return parsed_params; -} - } // namespace namespace web { @@ -123,22 +78,6 @@ WebFrameImpl web_frame([[WKFrameInfo alloc] init], kFrameId, EXPECT_EQ(kFrameId, web_frame.GetFrameId()); } -// Tests creation of a WebFrame for a frame which is not the main frame without -// an encryption key. -TEST_F(WebFrameImplTest, CreateWebFrameForIFrame) { - FakeWebState fake_web_state; - GURL security_origin; - WebFrameImpl web_frame([[WKFrameInfo alloc] init], kFrameId, - /*is_main_frame=*/false, security_origin, - &fake_web_state); - - EXPECT_EQ(&fake_web_state, web_frame.GetWebState()); - EXPECT_FALSE(web_frame.IsMainFrame()); - EXPECT_FALSE(web_frame.CanCallJavaScriptFunction()); - EXPECT_EQ(security_origin, web_frame.GetSecurityOrigin()); - EXPECT_EQ(kFrameId, web_frame.GetFrameId()); -} - // Tests creation of a WebFrame for a frame which is not the main frame with an // encryption key. TEST_F(WebFrameImplTest, CreateWebFrameForIFrameWithKey) { @@ -156,250 +95,11 @@ WebFrameImpl web_frame([[WKFrameInfo alloc] init], kFrameId, EXPECT_EQ(kFrameId, web_frame.GetFrameId()); } -// Tests that |CallJavaScriptFunction| encrypts the message and passes it to -// __gCrWeb.message.routeMessage in the main frame. -TEST_F(WebFrameImplTest, CallJavaScriptFunction) { - FakeWebState fake_web_state; - GURL security_origin; - WebFrameImpl web_frame([[WKFrameInfo alloc] init], kFrameId, - /*is_main_frame=*/false, security_origin, - &fake_web_state); - web_frame.SetEncryptionKey(CreateKey()); - - std::vector function_params; - function_params.push_back(base::Value("plaintextParam")); - EXPECT_TRUE( - web_frame.CallJavaScriptFunction("functionName", function_params)); - - NSString* last_script = - base::SysUTF16ToNSString(fake_web_state.GetLastExecutedJavascript()); - EXPECT_TRUE([last_script hasPrefix:@"__gCrWeb.message.routeMessage"]); - // Verify the message does not contain the plaintext function name or - // parameters. - EXPECT_FALSE([last_script containsString:@"functionName"]); - EXPECT_FALSE([last_script containsString:@"plaintextParam"]); - - RouteMessageParameters params = ParametersFromFunctionCallString(last_script); - - // Verify that the message and function payload are properly base64 encoded - // strings. - std::string decoded_function_payload; - EXPECT_TRUE(base::Base64Decode( - base::SysNSStringToUTF8(params.encoded_function_payload), - &decoded_function_payload)); - std::string decoded_message_payload; - EXPECT_TRUE(base::Base64Decode( - base::SysNSStringToUTF8(params.encoded_message_payload), - &decoded_message_payload)); - // Verify the function does not contain the plaintext function name or - // parameters. - EXPECT_FALSE([base::SysUTF8ToNSString(decoded_function_payload) - containsString:@"functionName"]); - EXPECT_FALSE([base::SysUTF8ToNSString(decoded_function_payload) - containsString:@"plaintextParam"]); - - // Verify that the initialization vector is a properly base64 encoded string - // for both payloads. - std::string function_iv_string = - base::SysNSStringToUTF8(params.encoded_function_iv); - std::string decoded_function_iv; - EXPECT_TRUE(base::Base64Decode(function_iv_string, &decoded_function_iv)); - std::string message_iv_string = - base::SysNSStringToUTF8(params.encoded_message_iv); - std::string decoded_message_iv; - EXPECT_TRUE(base::Base64Decode(message_iv_string, &decoded_message_iv)); - - // Ensure the frame ID matches. - EXPECT_NSEQ(base::SysUTF8ToNSString(kFrameId), params.frame_id); -} - -// Tests that the WebFrame uses different initialization vectors for two -// sequential calls to |CallJavaScriptFunction|. -TEST_F(WebFrameImplTest, CallJavaScriptFunctionUniqueInitializationVector) { - FakeWebState fake_web_state; - GURL security_origin; - WebFrameImpl web_frame([[WKFrameInfo alloc] init], kFrameId, - /*is_main_frame=*/false, security_origin, - &fake_web_state); - web_frame.SetEncryptionKey(CreateKey()); - - std::vector function_params; - function_params.push_back(base::Value("plaintextParam")); - EXPECT_TRUE( - web_frame.CallJavaScriptFunction("functionName", function_params)); - - NSString* last_script1 = - base::SysUTF16ToNSString(fake_web_state.GetLastExecutedJavascript()); - RouteMessageParameters params1 = - ParametersFromFunctionCallString(last_script1); - - // Call JavaScript Function again to verify that the same initialization - // vector is not reused and that the ciphertext is different. - EXPECT_TRUE( - web_frame.CallJavaScriptFunction("functionName", function_params)); - NSString* last_script2 = - base::SysUTF16ToNSString(fake_web_state.GetLastExecutedJavascript()); - RouteMessageParameters params2 = - ParametersFromFunctionCallString(last_script2); - - EXPECT_NSNE(params1.encoded_function_payload, - params2.encoded_function_payload); - EXPECT_NSNE(params1.encoded_function_iv, params2.encoded_function_iv); -} - -// Tests that the WebFrame properly encodes and encrypts all parameters for -// |CallJavaScriptFunction|. -TEST_F(WebFrameImplTest, CallJavaScriptFunctionMessageProperlyEncoded) { - std::unique_ptr key = CreateKey(); - const std::string key_string = key->key(); - // Use an arbitrary nonzero message id to ensure it isn't matching a zero - // value by chance. - const int initial_message_id = 11; - - FakeWebState fake_web_state; - GURL security_origin; - WebFrameImpl web_frame([[WKFrameInfo alloc] init], kFrameId, - /*is_main_frame=*/false, security_origin, - &fake_web_state); - web_frame.SetEncryptionKey(std::move(key)); - web_frame.SetNextMessageId(initial_message_id); - - std::vector function_params; - std::string plaintext_param("plaintextParam"); - function_params.push_back(base::Value(plaintext_param)); - EXPECT_TRUE( - web_frame.CallJavaScriptFunction("functionName", function_params)); - - NSString* last_script = - base::SysUTF16ToNSString(fake_web_state.GetLastExecutedJavascript()); - RouteMessageParameters params = ParametersFromFunctionCallString(last_script); - - std::string decoded_function_ciphertext; - EXPECT_TRUE(base::Base64Decode( - base::SysNSStringToUTF8(params.encoded_function_payload), - &decoded_function_ciphertext)); - - std::string decoded_function_iv; - EXPECT_TRUE( - base::Base64Decode(base::SysNSStringToUTF8(params.encoded_function_iv), - &decoded_function_iv)); - - std::string decoded_message_ciphertext; - EXPECT_TRUE(base::Base64Decode( - base::SysNSStringToUTF8(params.encoded_message_payload), - &decoded_message_ciphertext)); - - std::string decoded_message_iv; - EXPECT_TRUE(base::Base64Decode( - base::SysNSStringToUTF8(params.encoded_message_iv), &decoded_message_iv)); - - // Decrypt message - crypto::Aead aead(crypto::Aead::AES_256_GCM); - aead.Init(&key_string); - std::string function_plaintext; - EXPECT_TRUE(aead.Open(decoded_function_ciphertext, decoded_function_iv, - base::NumberToString(initial_message_id), - &function_plaintext)); - std::string message_plaintext; - EXPECT_TRUE(aead.Open(decoded_message_ciphertext, decoded_message_iv, - /*additional_data=*/"", &message_plaintext)); - - absl::optional parsed_function_result = - base::JSONReader::Read(function_plaintext, false); - EXPECT_TRUE(parsed_function_result.has_value()); - ASSERT_TRUE(parsed_function_result.value().is_dict()); - - const std::string* decrypted_function_name = - parsed_function_result.value().FindStringKey("functionName"); - ASSERT_TRUE(decrypted_function_name); - EXPECT_EQ("functionName", *decrypted_function_name); - - base::Value* decrypted_parameters = - parsed_function_result.value().FindKeyOfType("parameters", - base::Value::Type::LIST); - ASSERT_TRUE(decrypted_parameters); - ASSERT_EQ(function_params.size(), - decrypted_parameters->GetListDeprecated().size()); - EXPECT_EQ(plaintext_param, - decrypted_parameters->GetListDeprecated()[0].GetString()); - - absl::optional parsed_message_result = - base::JSONReader::Read(message_plaintext, false); - EXPECT_TRUE(parsed_message_result.has_value()); - ASSERT_TRUE(parsed_message_result.value().is_dict()); - - absl::optional decrypted_message_id = - parsed_message_result.value().FindIntKey("messageId"); - ASSERT_TRUE(decrypted_message_id.has_value()); - EXPECT_EQ(decrypted_message_id.value(), initial_message_id); - - absl::optional decrypted_respond_with_result = - parsed_message_result.value().FindBoolKey("replyWithResult"); - ASSERT_TRUE(decrypted_respond_with_result.has_value()); - EXPECT_FALSE(decrypted_respond_with_result.value()); -} - -// Tests that the WebFrame properly encodes and encrypts the respondWithResult -// value when |CallJavaScriptFunction| is called with a callback. -TEST_F(WebFrameImplTest, CallJavaScriptFunctionRespondWithResult) { - std::unique_ptr key = CreateKey(); - const std::string key_string = key->key(); - // Use an arbitrary nonzero message id to ensure it isn't matching a zero - // value by chance. - const int initial_message_id = 11; - - FakeWebState fake_web_state; - GURL security_origin; - WebFrameImpl web_frame([[WKFrameInfo alloc] init], kFrameId, - /*is_main_frame=*/false, security_origin, - &fake_web_state); - web_frame.SetEncryptionKey(std::move(key)); - web_frame.SetNextMessageId(initial_message_id); - - std::vector function_params; - std::string plaintext_param("plaintextParam"); - function_params.push_back(base::Value(plaintext_param)); - EXPECT_TRUE(web_frame.CallJavaScriptFunction( - "functionName", function_params, - base::BindOnce(^(const base::Value* value){ - }), - base::Seconds(5))); - - NSString* last_script = - base::SysUTF16ToNSString(fake_web_state.GetLastExecutedJavascript()); - RouteMessageParameters params = ParametersFromFunctionCallString(last_script); - - std::string decoded_message_ciphertext; - EXPECT_TRUE(base::Base64Decode( - base::SysNSStringToUTF8(params.encoded_message_payload), - &decoded_message_ciphertext)); - - std::string decoded_message_iv; - EXPECT_TRUE(base::Base64Decode( - base::SysNSStringToUTF8(params.encoded_message_iv), &decoded_message_iv)); - - // Decrypt message - crypto::Aead aead(crypto::Aead::AES_256_GCM); - aead.Init(&key_string); - std::string message_plaintext; - EXPECT_TRUE(aead.Open(decoded_message_ciphertext, decoded_message_iv, - /*additional_data=*/"", &message_plaintext)); - - absl::optional parsed_result = - base::JSONReader::Read(message_plaintext, false); - EXPECT_TRUE(parsed_result.has_value()); - ASSERT_TRUE(parsed_result.value().is_dict()); - - absl::optional decrypted_respond_with_result = - parsed_result.value().FindBoolKey("replyWithResult"); - ASSERT_TRUE(decrypted_respond_with_result.has_value()); - EXPECT_TRUE(decrypted_respond_with_result.value()); -} - // Tests that the WebFrame properly creates JavaScript for the main frame when // there is no encryption key. TEST_F(WebFrameImplTest, CallJavaScriptFunctionMainFrameWithoutKey) { FakeWebState fake_web_state; + fake_web_state.SetBrowserState(GetBrowserState()); GURL security_origin; WebFrameImpl web_frame([[WKFrameInfo alloc] init], kFrameId, /*is_main_frame=*/true, security_origin, @@ -434,6 +134,7 @@ WebFrameImpl web_frame([[WKFrameInfo alloc] init], kFrameId, // is no encryption key. TEST_F(WebFrameImplTest, CallJavaScriptFunctionIFrameFrameWithoutKey) { FakeWebState fake_web_state; + fake_web_state.SetBrowserState(GetBrowserState()); GURL security_origin; WebFrameImpl web_frame([[WKFrameInfo alloc] init], kFrameId, /*is_main_frame=*/false, security_origin, @@ -453,6 +154,7 @@ WebFrameImpl web_frame([[WKFrameInfo alloc] init], kFrameId, // if and only if it is a main frame. TEST_F(WebFrameImplTest, ExecuteJavaScript) { FakeWebState fake_web_state; + fake_web_state.SetBrowserState(GetBrowserState()); GURL security_origin; NSString* script = @"__gCrWeb = {};" @@ -477,6 +179,8 @@ WebFrameImpl web_frame2([[WKFrameInfo alloc] init], kFrameId, // a callback if and only if it is a main frame. TEST_F(WebFrameImplTest, ExecuteJavaScriptWithCallback) { FakeWebState fake_web_state; + fake_web_state.SetBrowserState(GetBrowserState()); + GURL security_origin; NSString* script = @"__gCrWeb = {};" diff --git a/ios/web/public/test/web_view_interaction_test_util.mm b/ios/web/public/test/web_view_interaction_test_util.mm index aaf45289710ca5..39e25713f49361 100644 --- a/ios/web/public/test/web_view_interaction_test_util.mm +++ b/ios/web/public/test/web_view_interaction_test_util.mm @@ -102,6 +102,9 @@ << "JavaScriptFeature does not appear to be configured."; return nullptr; } + } else { + world = JavaScriptFeatureManager::GetPageContentWorldForBrowserState( + web_state->GetBrowserState()); } WebFrameImpl* frame = static_cast(GetMainFrame(web_state));