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

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: Actually addressed review comments :) Created 3 years, 12 months 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 2658 matching lines...) Expand 10 before | Expand all | Expand 10 after
2691 return [NSString 2690 return [NSString
2692 stringWithFormat:kTemplate, [_windowIDJSManager windowID], script]; 2691 stringWithFormat:kTemplate, [_windowIDJSManager windowID], script];
2693 } 2692 }
2694 2693
2695 - (BOOL)respondToWKScriptMessage:(WKScriptMessage*)scriptMessage { 2694 - (BOOL)respondToWKScriptMessage:(WKScriptMessage*)scriptMessage {
2696 if (!scriptMessage.frameInfo.mainFrame) { 2695 if (!scriptMessage.frameInfo.mainFrame) {
2697 // Messages from iframes are not currently supported. 2696 // Messages from iframes are not currently supported.
2698 return NO; 2697 return NO;
2699 } 2698 }
2700 2699
2701 int errorCode = 0; 2700 std::unique_ptr<base::Value> messageAsValue =
2702 std::string errorMessage; 2701 web::ValueResultFromWKResult(scriptMessage.body);
2703 std::unique_ptr<base::Value> inputJSONData(
2704 base::JSONReader::ReadAndReturnError(
2705 base::SysNSStringToUTF8(scriptMessage.body), false, &errorCode,
2706 &errorMessage));
2707 if (errorCode) {
2708 DLOG(WARNING) << "JSON parse error: %s" << errorMessage.c_str();
2709 return NO;
2710 }
2711 base::DictionaryValue* message = nullptr; 2702 base::DictionaryValue* message = nullptr;
2712 if (!inputJSONData->GetAsDictionary(&message)) { 2703 if (!messageAsValue || !messageAsValue->GetAsDictionary(&message)) {
2713 return NO; 2704 return NO;
2714 } 2705 }
2715 std::string windowID; 2706 std::string windowID;
2716 message->GetString("crwWindowId", &windowID); 2707 message->GetString("crwWindowId", &windowID);
2717 // Check for correct windowID 2708 // Check for correct windowID
2718 if (base::SysNSStringToUTF8([_windowIDJSManager windowID]) != windowID) { 2709 if (base::SysNSStringToUTF8([_windowIDJSManager windowID]) != windowID) {
2719 DLOG(WARNING) << "Message from JS ignored due to non-matching windowID: " << 2710 DLOG(WARNING) << "Message from JS ignored due to non-matching windowID: " <<
2720 [_windowIDJSManager windowID] 2711 [_windowIDJSManager windowID]
2721 << " != " << base::SysUTF8ToNSString(windowID); 2712 << " != " << base::SysUTF8ToNSString(windowID);
2722 return NO; 2713 return NO;
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
2914 std::string value; 2905 std::string value;
2915 int keyCode = web::WebStateObserver::kInvalidFormKeyCode; 2906 int keyCode = web::WebStateObserver::kInvalidFormKeyCode;
2916 bool inputMissing = false; 2907 bool inputMissing = false;
2917 if (!message->GetString("formName", &formName) || 2908 if (!message->GetString("formName", &formName) ||
2918 !message->GetString("fieldName", &fieldName) || 2909 !message->GetString("fieldName", &fieldName) ||
2919 !message->GetString("type", &type) || 2910 !message->GetString("type", &type) ||
2920 !message->GetString("value", &value)) { 2911 !message->GetString("value", &value)) {
2921 inputMissing = true; 2912 inputMissing = true;
2922 } 2913 }
2923 2914
2924 if (!message->GetInteger("keyCode", &keyCode) || keyCode < 0) 2915 double keyCodeAsDouble = 0;
2916 if (!message->GetDouble("keyCode", &keyCodeAsDouble) || keyCodeAsDouble < 0) {
2925 keyCode = web::WebStateObserver::kInvalidFormKeyCode; 2917 keyCode = web::WebStateObserver::kInvalidFormKeyCode;
2918 } else {
2919 keyCode = static_cast<int>(keyCodeAsDouble);
2920 }
2926 _webStateImpl->OnFormActivityRegistered(formName, fieldName, type, value, 2921 _webStateImpl->OnFormActivityRegistered(formName, fieldName, type, value,
2927 keyCode, inputMissing); 2922 keyCode, inputMissing);
2928 return YES; 2923 return YES;
2929 } 2924 }
2930 2925
2931 - (BOOL)handleCredentialsRequestedMessage:(base::DictionaryValue*)message 2926 - (BOOL)handleCredentialsRequestedMessage:(base::DictionaryValue*)message
2932 context:(NSDictionary*)context { 2927 context:(NSDictionary*)context {
2933 int request_id = -1; 2928 double request_id = -1;
2934 if (!message->GetInteger("requestId", &request_id)) { 2929 if (!message->GetDouble("requestId", &request_id)) {
2935 DLOG(WARNING) << "JS message parameter not found: requestId"; 2930 DLOG(WARNING) << "JS message parameter not found: requestId";
2936 return NO; 2931 return NO;
2937 } 2932 }
2938 bool unmediated = false; 2933 bool unmediated = false;
2939 if (!message->GetBoolean("unmediated", &unmediated)) { 2934 if (!message->GetBoolean("unmediated", &unmediated)) {
2940 DLOG(WARNING) << "JS message parameter not found: unmediated"; 2935 DLOG(WARNING) << "JS message parameter not found: unmediated";
2941 return NO; 2936 return NO;
2942 } 2937 }
2943 base::ListValue* federations_value = nullptr; 2938 base::ListValue* federations_value = nullptr;
2944 if (!message->GetList("federations", &federations_value)) { 2939 if (!message->GetList("federations", &federations_value)) {
2945 DLOG(WARNING) << "JS message parameter not found: federations"; 2940 DLOG(WARNING) << "JS message parameter not found: federations";
2946 return NO; 2941 return NO;
2947 } 2942 }
2948 std::vector<std::string> federations; 2943 std::vector<std::string> federations;
2949 for (const auto& federation_value : *federations_value) { 2944 for (const auto& federation_value : *federations_value) {
2950 std::string federation; 2945 std::string federation;
2951 if (!federation_value->GetAsString(&federation)) { 2946 if (!federation_value->GetAsString(&federation)) {
2952 DLOG(WARNING) << "JS message parameter 'federations' contains wrong type"; 2947 DLOG(WARNING) << "JS message parameter 'federations' contains wrong type";
2953 return NO; 2948 return NO;
2954 } 2949 }
2955 federations.push_back(federation); 2950 federations.push_back(federation);
2956 } 2951 }
2957 DCHECK(context[web::kUserIsInteractingKey]); 2952 DCHECK(context[web::kUserIsInteractingKey]);
2958 _webStateImpl->OnCredentialsRequested( 2953 _webStateImpl->OnCredentialsRequested(
2959 request_id, net::GURLWithNSURL(context[web::kOriginURLKey]), unmediated, 2954 static_cast<int>(request_id),
2960 federations, [context[web::kUserIsInteractingKey] boolValue]); 2955 net::GURLWithNSURL(context[web::kOriginURLKey]), unmediated, federations,
2956 [context[web::kUserIsInteractingKey] boolValue]);
2961 return YES; 2957 return YES;
2962 } 2958 }
2963 2959
2964 - (BOOL)handleSignedInMessage:(base::DictionaryValue*)message 2960 - (BOOL)handleSignedInMessage:(base::DictionaryValue*)message
2965 context:(NSDictionary*)context { 2961 context:(NSDictionary*)context {
2966 int request_id = -1; 2962 double request_id = -1;
2967 if (!message->GetInteger("requestId", &request_id)) { 2963 if (!message->GetDouble("requestId", &request_id)) {
2968 DLOG(WARNING) << "JS message parameter not found: requestId"; 2964 DLOG(WARNING) << "JS message parameter not found: requestId";
2969 return NO; 2965 return NO;
2970 } 2966 }
2971 base::DictionaryValue* credential_data = nullptr; 2967 base::DictionaryValue* credential_data = nullptr;
2972 web::Credential credential; 2968 web::Credential credential;
2973 if (message->GetDictionary("credential", &credential_data)) { 2969 if (message->GetDictionary("credential", &credential_data)) {
2974 if (!web::DictionaryValueToCredential(*credential_data, &credential)) { 2970 if (!web::DictionaryValueToCredential(*credential_data, &credential)) {
2975 DLOG(WARNING) << "JS message parameter 'credential' is invalid"; 2971 DLOG(WARNING) << "JS message parameter 'credential' is invalid";
2976 return NO; 2972 return NO;
2977 } 2973 }
2978 _webStateImpl->OnSignedIn(request_id, 2974 _webStateImpl->OnSignedIn(static_cast<int>(request_id),
2979 net::GURLWithNSURL(context[web::kOriginURLKey]), 2975 net::GURLWithNSURL(context[web::kOriginURLKey]),
2980 credential); 2976 credential);
2981 } else { 2977 } else {
2982 _webStateImpl->OnSignedIn(request_id, 2978 _webStateImpl->OnSignedIn(static_cast<int>(request_id),
2983 net::GURLWithNSURL(context[web::kOriginURLKey])); 2979 net::GURLWithNSURL(context[web::kOriginURLKey]));
2984 } 2980 }
2985 return YES; 2981 return YES;
2986 } 2982 }
2987 2983
2988 - (BOOL)handleSignedOutMessage:(base::DictionaryValue*)message 2984 - (BOOL)handleSignedOutMessage:(base::DictionaryValue*)message
2989 context:(NSDictionary*)context { 2985 context:(NSDictionary*)context {
2990 int request_id = -1; 2986 double request_id = -1;
2991 if (!message->GetInteger("requestId", &request_id)) { 2987 if (!message->GetDouble("requestId", &request_id)) {
2992 DLOG(WARNING) << "JS message parameter not found: requestId"; 2988 DLOG(WARNING) << "JS message parameter not found: requestId";
2993 return NO; 2989 return NO;
2994 } 2990 }
2995 _webStateImpl->OnSignedOut(request_id, 2991 _webStateImpl->OnSignedOut(static_cast<int>(request_id),
2996 net::GURLWithNSURL(context[web::kOriginURLKey])); 2992 net::GURLWithNSURL(context[web::kOriginURLKey]));
2997 return YES; 2993 return YES;
2998 } 2994 }
2999 2995
3000 - (BOOL)handleSignInFailedMessage:(base::DictionaryValue*)message 2996 - (BOOL)handleSignInFailedMessage:(base::DictionaryValue*)message
3001 context:(NSDictionary*)context { 2997 context:(NSDictionary*)context {
3002 int request_id = -1; 2998 double request_id = -1;
3003 if (!message->GetInteger("requestId", &request_id)) { 2999 if (!message->GetDouble("requestId", &request_id)) {
3004 DLOG(WARNING) << "JS message parameter not found: requestId"; 3000 DLOG(WARNING) << "JS message parameter not found: requestId";
3005 return NO; 3001 return NO;
3006 } 3002 }
3007 base::DictionaryValue* credential_data = nullptr; 3003 base::DictionaryValue* credential_data = nullptr;
3008 web::Credential credential; 3004 web::Credential credential;
3009 if (message->GetDictionary("credential", &credential_data)) { 3005 if (message->GetDictionary("credential", &credential_data)) {
3010 if (!web::DictionaryValueToCredential(*credential_data, &credential)) { 3006 if (!web::DictionaryValueToCredential(*credential_data, &credential)) {
3011 DLOG(WARNING) << "JS message parameter 'credential' is invalid"; 3007 DLOG(WARNING) << "JS message parameter 'credential' is invalid";
3012 return NO; 3008 return NO;
3013 } 3009 }
3014 _webStateImpl->OnSignInFailed( 3010 _webStateImpl->OnSignInFailed(
3015 request_id, net::GURLWithNSURL(context[web::kOriginURLKey]), 3011 static_cast<int>(request_id),
3016 credential); 3012 net::GURLWithNSURL(context[web::kOriginURLKey]), credential);
3017 } else { 3013 } else {
3018 _webStateImpl->OnSignInFailed( 3014 _webStateImpl->OnSignInFailed(
3019 request_id, net::GURLWithNSURL(context[web::kOriginURLKey])); 3015 static_cast<int>(request_id),
3016 net::GURLWithNSURL(context[web::kOriginURLKey]));
3020 } 3017 }
3021 return YES; 3018 return YES;
3022 } 3019 }
3023 3020
3024 - (BOOL)handleResetExternalRequestMessage:(base::DictionaryValue*)message 3021 - (BOOL)handleResetExternalRequestMessage:(base::DictionaryValue*)message
3025 context:(NSDictionary*)context { 3022 context:(NSDictionary*)context {
3026 _externalRequest.reset(); 3023 _externalRequest.reset();
3027 return YES; 3024 return YES;
3028 } 3025 }
3029 3026
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
3070 } 3067 }
3071 3068
3072 - (BOOL)handleWindowHistoryForwardMessage:(base::DictionaryValue*)message 3069 - (BOOL)handleWindowHistoryForwardMessage:(base::DictionaryValue*)message
3073 context:(NSDictionary*)context { 3070 context:(NSDictionary*)context {
3074 [self goDelta:1]; 3071 [self goDelta:1];
3075 return YES; 3072 return YES;
3076 } 3073 }
3077 3074
3078 - (BOOL)handleWindowHistoryGoMessage:(base::DictionaryValue*)message 3075 - (BOOL)handleWindowHistoryGoMessage:(base::DictionaryValue*)message
3079 context:(NSDictionary*)context { 3076 context:(NSDictionary*)context {
3080 int delta = 0; 3077 double delta = 0;
3081 if (message->GetInteger("value", &delta)) { 3078 if (message->GetDouble("value", &delta)) {
3082 [self goDelta:delta]; 3079 [self goDelta:static_cast<int>(delta)];
3083 return YES; 3080 return YES;
3084 } 3081 }
3085 return NO; 3082 return NO;
3086 } 3083 }
3087 3084
3088 - (BOOL)handleWindowHistoryWillChangeStateMessage:(base::DictionaryValue*)unused 3085 - (BOOL)handleWindowHistoryWillChangeStateMessage:(base::DictionaryValue*)unused
3089 context:(NSDictionary*)unusedContext { 3086 context:(NSDictionary*)unusedContext {
3090 _changingHistoryState = YES; 3087 _changingHistoryState = YES;
3091 return YES; 3088 return YES;
3092 } 3089 }
(...skipping 2691 matching lines...) Expand 10 before | Expand all | Expand 10 after
5784 } 5781 }
5785 5782
5786 return web::WEB_VIEW_DOCUMENT_TYPE_GENERIC; 5783 return web::WEB_VIEW_DOCUMENT_TYPE_GENERIC;
5787 } 5784 }
5788 5785
5789 - (NSString*)refererFromNavigationAction:(WKNavigationAction*)action { 5786 - (NSString*)refererFromNavigationAction:(WKNavigationAction*)action {
5790 return [action.request valueForHTTPHeaderField:@"Referer"]; 5787 return [action.request valueForHTTPHeaderField:@"Referer"];
5791 } 5788 }
5792 5789
5793 @end 5790 @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