Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(32)

Side by Side Diff: ios/web/web_state/ui/crw_web_controller.mm

Issue 2581883002: [ios] Do not JSON encode messages sent from WebView to native code. (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ios/web/web_state/js/resources/message.js ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import "ios/web/web_state/ui/crw_web_controller.h" 5 #import "ios/web/web_state/ui/crw_web_controller.h"
6 6
7 #import <WebKit/WebKit.h> 7 #import <WebKit/WebKit.h>
8 8
9 #import <objc/runtime.h> 9 #import <objc/runtime.h>
10 #include <stddef.h> 10 #include <stddef.h>
11 11
12 #include <cmath> 12 #include <cmath>
13 #include <memory> 13 #include <memory>
14 #include <utility> 14 #include <utility>
15 15
16 #include "base/callback.h" 16 #include "base/callback.h"
17 #include "base/containers/mru_cache.h" 17 #include "base/containers/mru_cache.h"
18 #include "base/ios/block_types.h" 18 #include "base/ios/block_types.h"
19 #include "base/ios/ios_util.h" 19 #include "base/ios/ios_util.h"
20 #import "base/ios/ns_error_util.h" 20 #import "base/ios/ns_error_util.h"
21 #include "base/ios/weak_nsobject.h" 21 #include "base/ios/weak_nsobject.h"
22 #include "base/json/json_reader.h"
23 #include "base/json/string_escape.h" 22 #include "base/json/string_escape.h"
24 #include "base/logging.h" 23 #include "base/logging.h"
25 #include "base/mac/bind_objc_block.h" 24 #include "base/mac/bind_objc_block.h"
26 #include "base/mac/bundle_locations.h" 25 #include "base/mac/bundle_locations.h"
27 #include "base/mac/foundation_util.h" 26 #include "base/mac/foundation_util.h"
28 #include "base/mac/objc_property_releaser.h" 27 #include "base/mac/objc_property_releaser.h"
29 #include "base/mac/scoped_cftyperef.h" 28 #include "base/mac/scoped_cftyperef.h"
30 #include "base/mac/scoped_nsobject.h" 29 #include "base/mac/scoped_nsobject.h"
31 #include "base/metrics/histogram.h" 30 #include "base/metrics/histogram.h"
32 #include "base/metrics/user_metrics.h" 31 #include "base/metrics/user_metrics.h"
(...skipping 2665 matching lines...) Expand 10 before | Expand all | Expand 10 after
2698 return [NSString 2697 return [NSString
2699 stringWithFormat:kTemplate, [_windowIDJSManager windowID], script]; 2698 stringWithFormat:kTemplate, [_windowIDJSManager windowID], script];
2700 } 2699 }
2701 2700
2702 - (BOOL)respondToWKScriptMessage:(WKScriptMessage*)scriptMessage { 2701 - (BOOL)respondToWKScriptMessage:(WKScriptMessage*)scriptMessage {
2703 if (!scriptMessage.frameInfo.mainFrame) { 2702 if (!scriptMessage.frameInfo.mainFrame) {
2704 // Messages from iframes are not currently supported. 2703 // Messages from iframes are not currently supported.
2705 return NO; 2704 return NO;
2706 } 2705 }
2707 2706
2708 int errorCode = 0; 2707 std::unique_ptr<base::Value> messageAsValue =
2709 std::string errorMessage; 2708 web::ValueResultFromWKResult(scriptMessage.body);
2710 std::unique_ptr<base::Value> inputJSONData(
2711 base::JSONReader::ReadAndReturnError(
2712 base::SysNSStringToUTF8(scriptMessage.body), false, &errorCode,
2713 &errorMessage));
2714 if (errorCode) {
2715 DLOG(WARNING) << "JSON parse error: %s" << errorMessage.c_str();
2716 return NO;
2717 }
2718 base::DictionaryValue* message = nullptr; 2709 base::DictionaryValue* message = nullptr;
2719 if (!inputJSONData->GetAsDictionary(&message)) { 2710 if (!messageAsValue || !messageAsValue->GetAsDictionary(&message)) {
2720 return NO; 2711 return NO;
2721 } 2712 }
2722 std::string windowID; 2713 std::string windowID;
2723 message->GetString("crwWindowId", &windowID); 2714 message->GetString("crwWindowId", &windowID);
2724 // Check for correct windowID 2715 // Check for correct windowID
2725 if (base::SysNSStringToUTF8([_windowIDJSManager windowID]) != windowID) { 2716 if (base::SysNSStringToUTF8([_windowIDJSManager windowID]) != windowID) {
2726 DLOG(WARNING) << "Message from JS ignored due to non-matching windowID: " << 2717 DLOG(WARNING) << "Message from JS ignored due to non-matching windowID: " <<
2727 [_windowIDJSManager windowID] 2718 [_windowIDJSManager windowID]
2728 << " != " << base::SysUTF8ToNSString(windowID); 2719 << " != " << base::SysUTF8ToNSString(windowID);
2729 return NO; 2720 return NO;
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
2921 std::string value; 2912 std::string value;
2922 int keyCode = web::WebStateObserver::kInvalidFormKeyCode; 2913 int keyCode = web::WebStateObserver::kInvalidFormKeyCode;
2923 bool inputMissing = false; 2914 bool inputMissing = false;
2924 if (!message->GetString("formName", &formName) || 2915 if (!message->GetString("formName", &formName) ||
2925 !message->GetString("fieldName", &fieldName) || 2916 !message->GetString("fieldName", &fieldName) ||
2926 !message->GetString("type", &type) || 2917 !message->GetString("type", &type) ||
2927 !message->GetString("value", &value)) { 2918 !message->GetString("value", &value)) {
2928 inputMissing = true; 2919 inputMissing = true;
2929 } 2920 }
2930 2921
2931 if (!message->GetInteger("keyCode", &keyCode) || keyCode < 0) 2922 double keyCodeAsDouble = 0;
2923 if (!message->GetDouble("keyCode", &keyCodeAsDouble) || keyCodeAsDouble < 0) {
2932 keyCode = web::WebStateObserver::kInvalidFormKeyCode; 2924 keyCode = web::WebStateObserver::kInvalidFormKeyCode;
2925 } else {
2926 keyCode = static_cast<double>(keyCode);
sdefresne 2016/12/21 13:05:38 I think this should instead be: keyCode = sta
Eugene But (OOO till 7-30) 2016/12/21 15:58:46 Good catch. I don't think that casting to |int| wi
2927 }
2933 _webStateImpl->OnFormActivityRegistered(formName, fieldName, type, value, 2928 _webStateImpl->OnFormActivityRegistered(formName, fieldName, type, value,
2934 keyCode, inputMissing); 2929 keyCode, inputMissing);
2935 return YES; 2930 return YES;
2936 } 2931 }
2937 2932
2938 - (BOOL)handleCredentialsRequestedMessage:(base::DictionaryValue*)message 2933 - (BOOL)handleCredentialsRequestedMessage:(base::DictionaryValue*)message
2939 context:(NSDictionary*)context { 2934 context:(NSDictionary*)context {
2940 int request_id = -1; 2935 double request_id = -1;
2941 if (!message->GetInteger("requestId", &request_id)) { 2936 if (!message->GetDouble("requestId", &request_id)) {
2942 DLOG(WARNING) << "JS message parameter not found: requestId"; 2937 DLOG(WARNING) << "JS message parameter not found: requestId";
2943 return NO; 2938 return NO;
2944 } 2939 }
2945 bool unmediated = false; 2940 bool unmediated = false;
2946 if (!message->GetBoolean("unmediated", &unmediated)) { 2941 if (!message->GetBoolean("unmediated", &unmediated)) {
2947 DLOG(WARNING) << "JS message parameter not found: unmediated"; 2942 DLOG(WARNING) << "JS message parameter not found: unmediated";
2948 return NO; 2943 return NO;
2949 } 2944 }
2950 base::ListValue* federations_value = nullptr; 2945 base::ListValue* federations_value = nullptr;
2951 if (!message->GetList("federations", &federations_value)) { 2946 if (!message->GetList("federations", &federations_value)) {
2952 DLOG(WARNING) << "JS message parameter not found: federations"; 2947 DLOG(WARNING) << "JS message parameter not found: federations";
2953 return NO; 2948 return NO;
2954 } 2949 }
2955 std::vector<std::string> federations; 2950 std::vector<std::string> federations;
2956 for (const auto& federation_value : *federations_value) { 2951 for (const auto& federation_value : *federations_value) {
2957 std::string federation; 2952 std::string federation;
2958 if (!federation_value->GetAsString(&federation)) { 2953 if (!federation_value->GetAsString(&federation)) {
2959 DLOG(WARNING) << "JS message parameter 'federations' contains wrong type"; 2954 DLOG(WARNING) << "JS message parameter 'federations' contains wrong type";
2960 return NO; 2955 return NO;
2961 } 2956 }
2962 federations.push_back(federation); 2957 federations.push_back(federation);
2963 } 2958 }
2964 DCHECK(context[web::kUserIsInteractingKey]); 2959 DCHECK(context[web::kUserIsInteractingKey]);
2965 _webStateImpl->OnCredentialsRequested( 2960 _webStateImpl->OnCredentialsRequested(
2966 request_id, net::GURLWithNSURL(context[web::kOriginURLKey]), unmediated, 2961 static_cast<int>(request_id),
2967 federations, [context[web::kUserIsInteractingKey] boolValue]); 2962 net::GURLWithNSURL(context[web::kOriginURLKey]), unmediated, federations,
2963 [context[web::kUserIsInteractingKey] boolValue]);
2968 return YES; 2964 return YES;
2969 } 2965 }
2970 2966
2971 - (BOOL)handleSignedInMessage:(base::DictionaryValue*)message 2967 - (BOOL)handleSignedInMessage:(base::DictionaryValue*)message
2972 context:(NSDictionary*)context { 2968 context:(NSDictionary*)context {
2973 int request_id = -1; 2969 double request_id = -1;
2974 if (!message->GetInteger("requestId", &request_id)) { 2970 if (!message->GetDouble("requestId", &request_id)) {
2975 DLOG(WARNING) << "JS message parameter not found: requestId"; 2971 DLOG(WARNING) << "JS message parameter not found: requestId";
2976 return NO; 2972 return NO;
2977 } 2973 }
2978 base::DictionaryValue* credential_data = nullptr; 2974 base::DictionaryValue* credential_data = nullptr;
2979 web::Credential credential; 2975 web::Credential credential;
2980 if (message->GetDictionary("credential", &credential_data)) { 2976 if (message->GetDictionary("credential", &credential_data)) {
2981 if (!web::DictionaryValueToCredential(*credential_data, &credential)) { 2977 if (!web::DictionaryValueToCredential(*credential_data, &credential)) {
2982 DLOG(WARNING) << "JS message parameter 'credential' is invalid"; 2978 DLOG(WARNING) << "JS message parameter 'credential' is invalid";
2983 return NO; 2979 return NO;
2984 } 2980 }
2985 _webStateImpl->OnSignedIn(request_id, 2981 _webStateImpl->OnSignedIn(static_cast<int>(request_id),
2986 net::GURLWithNSURL(context[web::kOriginURLKey]), 2982 net::GURLWithNSURL(context[web::kOriginURLKey]),
2987 credential); 2983 credential);
2988 } else { 2984 } else {
2989 _webStateImpl->OnSignedIn(request_id, 2985 _webStateImpl->OnSignedIn(static_cast<int>(request_id),
2990 net::GURLWithNSURL(context[web::kOriginURLKey])); 2986 net::GURLWithNSURL(context[web::kOriginURLKey]));
2991 } 2987 }
2992 return YES; 2988 return YES;
2993 } 2989 }
2994 2990
2995 - (BOOL)handleSignedOutMessage:(base::DictionaryValue*)message 2991 - (BOOL)handleSignedOutMessage:(base::DictionaryValue*)message
2996 context:(NSDictionary*)context { 2992 context:(NSDictionary*)context {
2997 int request_id = -1; 2993 double request_id = -1;
2998 if (!message->GetInteger("requestId", &request_id)) { 2994 if (!message->GetDouble("requestId", &request_id)) {
2999 DLOG(WARNING) << "JS message parameter not found: requestId"; 2995 DLOG(WARNING) << "JS message parameter not found: requestId";
3000 return NO; 2996 return NO;
3001 } 2997 }
3002 _webStateImpl->OnSignedOut(request_id, 2998 _webStateImpl->OnSignedOut(static_cast<int>(request_id),
3003 net::GURLWithNSURL(context[web::kOriginURLKey])); 2999 net::GURLWithNSURL(context[web::kOriginURLKey]));
3004 return YES; 3000 return YES;
3005 } 3001 }
3006 3002
3007 - (BOOL)handleSignInFailedMessage:(base::DictionaryValue*)message 3003 - (BOOL)handleSignInFailedMessage:(base::DictionaryValue*)message
3008 context:(NSDictionary*)context { 3004 context:(NSDictionary*)context {
3009 int request_id = -1; 3005 double request_id = -1;
3010 if (!message->GetInteger("requestId", &request_id)) { 3006 if (!message->GetDouble("requestId", &request_id)) {
3011 DLOG(WARNING) << "JS message parameter not found: requestId"; 3007 DLOG(WARNING) << "JS message parameter not found: requestId";
3012 return NO; 3008 return NO;
3013 } 3009 }
3014 base::DictionaryValue* credential_data = nullptr; 3010 base::DictionaryValue* credential_data = nullptr;
3015 web::Credential credential; 3011 web::Credential credential;
3016 if (message->GetDictionary("credential", &credential_data)) { 3012 if (message->GetDictionary("credential", &credential_data)) {
3017 if (!web::DictionaryValueToCredential(*credential_data, &credential)) { 3013 if (!web::DictionaryValueToCredential(*credential_data, &credential)) {
3018 DLOG(WARNING) << "JS message parameter 'credential' is invalid"; 3014 DLOG(WARNING) << "JS message parameter 'credential' is invalid";
3019 return NO; 3015 return NO;
3020 } 3016 }
3021 _webStateImpl->OnSignInFailed( 3017 _webStateImpl->OnSignInFailed(
3022 request_id, net::GURLWithNSURL(context[web::kOriginURLKey]), 3018 static_cast<int>(request_id),
3023 credential); 3019 net::GURLWithNSURL(context[web::kOriginURLKey]), credential);
3024 } else { 3020 } else {
3025 _webStateImpl->OnSignInFailed( 3021 _webStateImpl->OnSignInFailed(
3026 request_id, net::GURLWithNSURL(context[web::kOriginURLKey])); 3022 static_cast<int>(request_id),
3023 net::GURLWithNSURL(context[web::kOriginURLKey]));
3027 } 3024 }
3028 return YES; 3025 return YES;
3029 } 3026 }
3030 3027
3031 - (BOOL)handleResetExternalRequestMessage:(base::DictionaryValue*)message 3028 - (BOOL)handleResetExternalRequestMessage:(base::DictionaryValue*)message
3032 context:(NSDictionary*)context { 3029 context:(NSDictionary*)context {
3033 _externalRequest.reset(); 3030 _externalRequest.reset();
3034 return YES; 3031 return YES;
3035 } 3032 }
3036 3033
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
3077 } 3074 }
3078 3075
3079 - (BOOL)handleWindowHistoryForwardMessage:(base::DictionaryValue*)message 3076 - (BOOL)handleWindowHistoryForwardMessage:(base::DictionaryValue*)message
3080 context:(NSDictionary*)context { 3077 context:(NSDictionary*)context {
3081 [self goDelta:1]; 3078 [self goDelta:1];
3082 return YES; 3079 return YES;
3083 } 3080 }
3084 3081
3085 - (BOOL)handleWindowHistoryGoMessage:(base::DictionaryValue*)message 3082 - (BOOL)handleWindowHistoryGoMessage:(base::DictionaryValue*)message
3086 context:(NSDictionary*)context { 3083 context:(NSDictionary*)context {
3087 int delta = 0; 3084 double delta = 0;
3088 if (message->GetInteger("value", &delta)) { 3085 if (message->GetDouble("value", &delta)) {
3089 [self goDelta:delta]; 3086 [self goDelta:static_cast<int>(delta)];
3090 return YES; 3087 return YES;
3091 } 3088 }
3092 return NO; 3089 return NO;
3093 } 3090 }
3094 3091
3095 - (BOOL)handleWindowHistoryWillChangeStateMessage:(base::DictionaryValue*)unused 3092 - (BOOL)handleWindowHistoryWillChangeStateMessage:(base::DictionaryValue*)unused
3096 context:(NSDictionary*)unusedContext { 3093 context:(NSDictionary*)unusedContext {
3097 _changingHistoryState = YES; 3094 _changingHistoryState = YES;
3098 return YES; 3095 return YES;
3099 } 3096 }
(...skipping 2692 matching lines...) Expand 10 before | Expand all | Expand 10 after
5792 } 5789 }
5793 5790
5794 return web::WEB_VIEW_DOCUMENT_TYPE_GENERIC; 5791 return web::WEB_VIEW_DOCUMENT_TYPE_GENERIC;
5795 } 5792 }
5796 5793
5797 - (NSString*)refererFromNavigationAction:(WKNavigationAction*)action { 5794 - (NSString*)refererFromNavigationAction:(WKNavigationAction*)action {
5798 return [action.request valueForHTTPHeaderField:@"Referer"]; 5795 return [action.request valueForHTTPHeaderField:@"Referer"];
5799 } 5796 }
5800 5797
5801 @end 5798 @end
OLDNEW
« no previous file with comments | « ios/web/web_state/js/resources/message.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698