OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 #include "chrome/renderer/extensions/automation_internal_custom_bindings.h" | 5 #include "chrome/renderer/extensions/automation_internal_custom_bindings.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <memory> | 10 #include <memory> |
(...skipping 29 matching lines...) Expand all Loading... | |
40 v8::String::NewFromUtf8( | 40 v8::String::NewFromUtf8( |
41 isolate, | 41 isolate, |
42 "Invalid arguments to AutomationInternalCustomBindings function", | 42 "Invalid arguments to AutomationInternalCustomBindings function", |
43 v8::NewStringType::kNormal) | 43 v8::NewStringType::kNormal) |
44 .ToLocalChecked()); | 44 .ToLocalChecked()); |
45 | 45 |
46 LOG(FATAL) << "Invalid arguments to AutomationInternalCustomBindings function" | 46 LOG(FATAL) << "Invalid arguments to AutomationInternalCustomBindings function" |
47 << automation_bindings->context()->GetStackTraceAsString(); | 47 << automation_bindings->context()->GetStackTraceAsString(); |
48 } | 48 } |
49 | 49 |
50 v8::Local<v8::Value> CreateV8String(v8::Isolate* isolate, const char* str) { | 50 v8::Local<v8::String> CreateV8String(v8::Isolate* isolate, |
51 return v8::String::NewFromUtf8(isolate, str, v8::String::kNormalString, | 51 const std::string& str) { |
52 strlen(str)); | 52 return v8::String::NewFromUtf8(isolate, str.c_str(), |
Devlin
2017/04/24 20:01:42
nit: Let's use gin::StringToSymbol()
dmazzoni
2017/04/26 00:09:35
Done.
| |
53 v8::String::kNormalString, str.length()); | |
53 } | 54 } |
54 | 55 |
55 v8::Local<v8::Value> CreateV8String(v8::Isolate* isolate, | 56 // Note: when building up an object to return from one of the |
56 const std::string& str) { | 57 // automation API bindings like a rect ({left: 0, top: 0, ...}) or |
57 return v8::String::NewFromUtf8(isolate, str.c_str(), | 58 // something like that, we should use this function instead of |
58 v8::String::kNormalString, str.length()); | 59 // v8::Object::Set, because a malicious extension author could use |
60 // Object.defineProperty to override a setter and trigger all sorts of | |
61 // things to happen in the middle of one of our functions below. | |
Devlin
2017/04/24 20:01:42
I'd expand this to say that this is only safe if t
dmazzoni
2017/04/26 00:09:35
Done.
| |
62 void SafeSetV8Property(v8::Isolate* isolate, | |
63 v8::Local<v8::Object> object, | |
64 const std::string& key, | |
Devlin
2017/04/24 20:01:42
s/const std::string&/base::StringPiece.
Since the
dmazzoni
2017/04/26 00:09:35
Done.
| |
65 v8::Local<v8::Value> value) { | |
66 v8::Maybe<bool> maybe = object->CreateDataProperty( | |
67 isolate->GetCurrentContext(), CreateV8String(isolate, key), value); | |
68 if (!maybe.IsJust() || !maybe.FromJust()) | |
69 LOG(ERROR) << "Failed to set property with key " << key; | |
Devlin
2017/04/24 20:01:42
We should at least NOTREACHED() here. Maybe even
dmazzoni
2017/04/26 00:09:35
Done. Note that maybe.ToChecked() is the same as m
| |
59 } | 70 } |
60 | 71 |
61 v8::Local<v8::Object> RectToV8Object(v8::Isolate* isolate, | 72 v8::Local<v8::Object> RectToV8Object(v8::Isolate* isolate, |
62 const gfx::Rect& rect) { | 73 const gfx::Rect& rect) { |
63 v8::Local<v8::Object> result(v8::Object::New(isolate)); | 74 v8::Local<v8::Object> result(v8::Object::New(isolate)); |
64 result->Set(CreateV8String(isolate, "left"), | 75 SafeSetV8Property(isolate, result, "left", |
65 v8::Integer::New(isolate, rect.x())); | 76 v8::Integer::New(isolate, rect.x())); |
66 result->Set(CreateV8String(isolate, "top"), | 77 SafeSetV8Property(isolate, result, "top", |
67 v8::Integer::New(isolate, rect.y())); | 78 v8::Integer::New(isolate, rect.y())); |
68 result->Set(CreateV8String(isolate, "width"), | 79 SafeSetV8Property(isolate, result, "width", |
69 v8::Integer::New(isolate, rect.width())); | 80 v8::Integer::New(isolate, rect.width())); |
70 result->Set(CreateV8String(isolate, "height"), | 81 SafeSetV8Property(isolate, result, "height", |
71 v8::Integer::New(isolate, rect.height())); | 82 v8::Integer::New(isolate, rect.height())); |
72 return result; | 83 return result; |
73 } | 84 } |
74 | 85 |
75 // Compute the bounding box of a node, fixing nodes with empty bounds by | 86 // Compute the bounding box of a node, fixing nodes with empty bounds by |
76 // unioning the bounds of their children. | 87 // unioning the bounds of their children. |
77 static gfx::RectF ComputeLocalNodeBounds(TreeCache* cache, ui::AXNode* node) { | 88 static gfx::RectF ComputeLocalNodeBounds(TreeCache* cache, ui::AXNode* node) { |
78 gfx::RectF bounds = node->data().location; | 89 gfx::RectF bounds = node->data().location; |
79 if (bounds.width() > 0 && bounds.height() > 0) | 90 if (bounds.width() > 0 && bounds.height() > 0) |
80 return bounds; | 91 return bounds; |
81 | 92 |
(...skipping 856 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
938 if (!cache) | 949 if (!cache) |
939 return; | 950 return; |
940 | 951 |
941 TreeCache* focused_tree_cache = nullptr; | 952 TreeCache* focused_tree_cache = nullptr; |
942 ui::AXNode* focused_node = nullptr; | 953 ui::AXNode* focused_node = nullptr; |
943 if (!GetFocusInternal(cache, &focused_tree_cache, &focused_node)) | 954 if (!GetFocusInternal(cache, &focused_tree_cache, &focused_node)) |
944 return; | 955 return; |
945 | 956 |
946 v8::Isolate* isolate = GetIsolate(); | 957 v8::Isolate* isolate = GetIsolate(); |
947 v8::Local<v8::Object> result(v8::Object::New(isolate)); | 958 v8::Local<v8::Object> result(v8::Object::New(isolate)); |
948 result->Set(CreateV8String(isolate, "treeId"), | 959 SafeSetV8Property(isolate, result, "treeId", |
949 v8::Integer::New(isolate, focused_tree_cache->tree_id)); | 960 v8::Integer::New(isolate, focused_tree_cache->tree_id)); |
950 result->Set(CreateV8String(isolate, "nodeId"), | 961 SafeSetV8Property(isolate, result, "nodeId", |
951 v8::Integer::New(isolate, focused_node->id())); | 962 v8::Integer::New(isolate, focused_node->id())); |
952 args.GetReturnValue().Set(result); | 963 args.GetReturnValue().Set(result); |
953 } | 964 } |
954 | 965 |
955 void AutomationInternalCustomBindings::GetHtmlAttributes( | 966 void AutomationInternalCustomBindings::GetHtmlAttributes( |
956 const v8::FunctionCallbackInfo<v8::Value>& args) { | 967 const v8::FunctionCallbackInfo<v8::Value>& args) { |
957 v8::Isolate* isolate = GetIsolate(); | 968 v8::Isolate* isolate = GetIsolate(); |
958 if (args.Length() < 2 || !args[0]->IsNumber() || !args[1]->IsNumber()) | 969 if (args.Length() < 2 || !args[0]->IsNumber() || !args[1]->IsNumber()) |
959 ThrowInvalidArgumentsException(this); | 970 ThrowInvalidArgumentsException(this); |
960 | 971 |
961 int tree_id = args[0]->Int32Value(); | 972 int tree_id = args[0]->Int32Value(); |
962 int node_id = args[1]->Int32Value(); | 973 int node_id = args[1]->Int32Value(); |
963 | 974 |
964 TreeCache* cache = GetTreeCacheFromTreeID(tree_id); | 975 TreeCache* cache = GetTreeCacheFromTreeID(tree_id); |
965 if (!cache) | 976 if (!cache) |
966 return; | 977 return; |
967 | 978 |
968 ui::AXNode* node = cache->tree.GetFromId(node_id); | 979 ui::AXNode* node = cache->tree.GetFromId(node_id); |
969 if (!node) | 980 if (!node) |
970 return; | 981 return; |
971 | 982 |
972 v8::Local<v8::Object> dst(v8::Object::New(isolate)); | 983 v8::Local<v8::Object> dst(v8::Object::New(isolate)); |
973 base::StringPairs src = node->data().html_attributes; | 984 base::StringPairs src = node->data().html_attributes; |
974 for (size_t i = 0; i < src.size(); i++) { | 985 for (size_t i = 0; i < src.size(); i++) { |
975 std::string& key = src[i].first; | 986 std::string& key = src[i].first; |
976 std::string& value = src[i].second; | 987 std::string& value = src[i].second; |
977 dst->Set(CreateV8String(isolate, key), CreateV8String(isolate, value)); | 988 SafeSetV8Property(isolate, dst, key, CreateV8String(isolate, value)); |
978 } | 989 } |
979 args.GetReturnValue().Set(dst); | 990 args.GetReturnValue().Set(dst); |
980 } | 991 } |
981 | 992 |
982 void AutomationInternalCustomBindings::GetState( | 993 void AutomationInternalCustomBindings::GetState( |
983 const v8::FunctionCallbackInfo<v8::Value>& args) { | 994 const v8::FunctionCallbackInfo<v8::Value>& args) { |
984 v8::Isolate* isolate = GetIsolate(); | 995 v8::Isolate* isolate = GetIsolate(); |
985 if (args.Length() < 2 || !args[0]->IsNumber() || !args[1]->IsNumber()) | 996 if (args.Length() < 2 || !args[0]->IsNumber() || !args[1]->IsNumber()) |
986 ThrowInvalidArgumentsException(this); | 997 ThrowInvalidArgumentsException(this); |
987 | 998 |
988 int tree_id = args[0]->Int32Value(); | 999 int tree_id = args[0]->Int32Value(); |
989 int node_id = args[1]->Int32Value(); | 1000 int node_id = args[1]->Int32Value(); |
990 | 1001 |
991 TreeCache* cache = GetTreeCacheFromTreeID(tree_id); | 1002 TreeCache* cache = GetTreeCacheFromTreeID(tree_id); |
992 if (!cache) | 1003 if (!cache) |
993 return; | 1004 return; |
994 | 1005 |
995 ui::AXNode* node = cache->tree.GetFromId(node_id); | 1006 ui::AXNode* node = cache->tree.GetFromId(node_id); |
996 if (!node) | 1007 if (!node) |
997 return; | 1008 return; |
998 | 1009 |
999 v8::Local<v8::Object> state(v8::Object::New(isolate)); | 1010 v8::Local<v8::Object> state(v8::Object::New(isolate)); |
1000 uint32_t state_pos = 0, state_shifter = node->data().state; | 1011 uint32_t state_pos = 0, state_shifter = node->data().state; |
1001 while (state_shifter) { | 1012 while (state_shifter) { |
1002 if (state_shifter & 1) { | 1013 if (state_shifter & 1) { |
1003 std::string key = ToString(static_cast<ui::AXState>(state_pos)); | 1014 std::string key = ToString(static_cast<ui::AXState>(state_pos)); |
1004 state->Set(CreateV8String(isolate, key), v8::Boolean::New(isolate, true)); | 1015 SafeSetV8Property(isolate, state, key, v8::Boolean::New(isolate, true)); |
1005 } | 1016 } |
1006 state_shifter = state_shifter >> 1; | 1017 state_shifter = state_shifter >> 1; |
1007 state_pos++; | 1018 state_pos++; |
1008 } | 1019 } |
1009 | 1020 |
1010 TreeCache* top_cache = GetTreeCacheFromTreeID(0); | 1021 TreeCache* top_cache = GetTreeCacheFromTreeID(0); |
1011 if (!top_cache) | 1022 if (!top_cache) |
1012 top_cache = cache; | 1023 top_cache = cache; |
1013 TreeCache* focused_cache = nullptr; | 1024 TreeCache* focused_cache = nullptr; |
1014 ui::AXNode* focused_node = nullptr; | 1025 ui::AXNode* focused_node = nullptr; |
1015 if (GetFocusInternal(top_cache, &focused_cache, &focused_node)) { | 1026 if (GetFocusInternal(top_cache, &focused_cache, &focused_node)) { |
1016 if (focused_cache == cache && focused_node == node) { | 1027 if (focused_cache == cache && focused_node == node) { |
1017 state->Set(CreateV8String(isolate, "focused"), | 1028 SafeSetV8Property(isolate, state, "focused", |
1018 v8::Boolean::New(isolate, true)); | 1029 v8::Boolean::New(isolate, true)); |
1019 } | 1030 } |
1020 } | 1031 } |
1021 if (cache->tree.data().focus_id == node->id()) { | 1032 if (cache->tree.data().focus_id == node->id()) { |
1022 state->Set(CreateV8String(isolate, "focused"), | 1033 SafeSetV8Property(isolate, state, "focused", |
1023 v8::Boolean::New(isolate, true)); | 1034 v8::Boolean::New(isolate, true)); |
1024 } | 1035 } |
1025 | 1036 |
1026 args.GetReturnValue().Set(state); | 1037 args.GetReturnValue().Set(state); |
1027 } | 1038 } |
1028 | 1039 |
1029 void AutomationInternalCustomBindings::UpdateOverallTreeChangeObserverFilter() { | 1040 void AutomationInternalCustomBindings::UpdateOverallTreeChangeObserverFilter() { |
1030 tree_change_observer_overall_filter_ = 0; | 1041 tree_change_observer_overall_filter_ = 0; |
1031 for (const auto& observer : tree_change_observers_) | 1042 for (const auto& observer : tree_change_observers_) |
1032 tree_change_observer_overall_filter_ |= 1 << observer.filter; | 1043 tree_change_observer_overall_filter_ |= 1 << observer.filter; |
1033 } | 1044 } |
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1413 for (auto id : ids) | 1424 for (auto id : ids) |
1414 nodes->AppendInteger(id); | 1425 nodes->AppendInteger(id); |
1415 args.Append(std::move(nodes)); | 1426 args.Append(std::move(nodes)); |
1416 } | 1427 } |
1417 | 1428 |
1418 bindings_system_->DispatchEventInContext("automationInternal.onNodesRemoved", | 1429 bindings_system_->DispatchEventInContext("automationInternal.onNodesRemoved", |
1419 &args, nullptr, context()); | 1430 &args, nullptr, context()); |
1420 } | 1431 } |
1421 | 1432 |
1422 } // namespace extensions | 1433 } // namespace extensions |
OLD | NEW |