Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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 #include "chrome/renderer/extensions/dispatcher.h" | 5 #include "chrome/renderer/extensions/dispatcher.h" |
| 6 | 6 |
| 7 #include "base/callback.h" | 7 #include "base/callback.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/debug/alias.h" | 9 #include "base/debug/alias.h" |
| 10 #include "base/json/json_reader.h" | 10 #include "base/json/json_reader.h" |
| (...skipping 704 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 715 } | 715 } |
| 716 | 716 |
| 717 v8::Handle<v8::Object> new_object = v8::Object::New(); | 717 v8::Handle<v8::Object> new_object = v8::Object::New(); |
| 718 object->Set(key, new_object); | 718 object->Set(key, new_object); |
| 719 return handle_scope.Close(new_object); | 719 return handle_scope.Close(new_object); |
| 720 } | 720 } |
| 721 | 721 |
| 722 void Dispatcher::RegisterSchemaGeneratedBindings( | 722 void Dispatcher::RegisterSchemaGeneratedBindings( |
| 723 ModuleSystem* module_system, | 723 ModuleSystem* module_system, |
| 724 ChromeV8Context* context) { | 724 ChromeV8Context* context) { |
| 725 std::set<std::string> apis = | 725 FeatureProvider* feature_provider = BaseFeatureProvider::GetByName("api"); |
| 726 ExtensionAPI::GetSharedInstance()->GetAllAPINames(); | 726 const std::vector<std::string>& apis = feature_provider->GetAllFeatureNames(); |
| 727 for (std::set<std::string>::iterator it = apis.begin(); | 727 for (std::vector<std::string>::const_iterator it = apis.begin(); |
| 728 it != apis.end(); ++it) { | 728 it != apis.end(); ++it) { |
| 729 const std::string& api_name = *it; | 729 const std::string& api_name = *it; |
| 730 | |
| 731 Feature* feature = feature_provider->GetFeature(api_name); | |
| 732 DCHECK(feature); | |
| 733 if (feature->HasParent() || feature->IsInternal()) | |
| 734 continue; | |
| 735 | |
| 730 if (!context->IsAnyFeatureAvailableToContext(api_name)) | 736 if (!context->IsAnyFeatureAvailableToContext(api_name)) |
| 731 continue; | 737 continue; |
|
not at google - send to devlin
2013/05/30 16:38:52
without the parent this is going to get trickier.
cduvall
2013/06/12 01:22:19
I ended up keeping the HasParent(), and just using
| |
| 732 | 738 |
| 733 Feature* feature = | |
| 734 BaseFeatureProvider::GetByName("api")->GetFeature(api_name); | |
| 735 if (feature && feature->IsInternal()) | |
| 736 continue; | |
| 737 | |
| 738 std::vector<std::string> split; | 739 std::vector<std::string> split; |
| 739 base::SplitString(api_name, '.', &split); | 740 base::SplitString(api_name, '.', &split); |
| 740 | 741 |
| 741 v8::Handle<v8::Object> bind_object = | 742 v8::Handle<v8::Object> bind_object = |
| 742 GetOrCreateChrome(context->v8_context()); | 743 GetOrCreateChrome(context->v8_context()); |
| 743 | 744 |
| 744 // Check if this API has an ancestor. If the API's ancestor is available and | 745 // Check if this API has an ancestor. If the API's ancestor is available and |
| 745 // the API is not available, don't install the bindings for this API. If | 746 // the API is not available, don't install the bindings for this API. If |
| 746 // the API is available and its ancestor is not, delete the ancestor and | 747 // the API is available and its ancestor is not, delete the ancestor and |
| 747 // install the bindings for the API. This is to prevent loading the ancestor | 748 // install the bindings for the API. This is to prevent loading the ancestor |
| 748 // API schema if it will not be needed. | 749 // API schema if it will not be needed. |
| 749 // | 750 // |
| 750 // For example: | 751 // For example: |
| 751 // If app is available and app.window is not, just install app. | 752 // If app is available and app.window is not, just install app. |
| 752 // If app.window is available and app is not, delete app and install | 753 // If app.window is available and app is not, delete app and install |
| 753 // app.window on a new object so app does not have to be loaded. | 754 // app.window on a new object so app does not have to be loaded. |
| 754 std::string ancestor_name; | 755 std::string ancestor_name; |
| 755 bool only_ancestor_available = false; | 756 bool only_ancestor_available = false; |
| 756 for (size_t i = 0; i < split.size() - 1; ++i) { | 757 for (size_t i = 0; i < split.size() - 1; ++i) { |
| 757 ancestor_name += (i ? ".": "") + split[i]; | 758 ancestor_name += (i ? ".": "") + split[i]; |
| 758 if (!ancestor_name.empty() && | 759 if (ancestor_name == "app" && |
| 759 context->GetAvailability(ancestor_name).is_available() && | 760 context->GetAvailability(ancestor_name).is_available() && |
| 760 !context->GetAvailability(api_name).is_available()) { | 761 !context->GetAvailability(api_name).is_available()) { |
| 761 only_ancestor_available = true; | 762 only_ancestor_available = true; |
| 762 break; | 763 break; |
| 763 } | 764 } |
| 764 bind_object = GetOrCreateObject(bind_object, split[i]); | 765 bind_object = GetOrCreateObject(bind_object, split[i]); |
| 765 } | 766 } |
| 766 if (only_ancestor_available) | 767 if (only_ancestor_available) |
| 767 continue; | 768 continue; |
| 768 | 769 |
| (...skipping 650 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1419 DLOG(ERROR) << "Not in a v8::Context"; | 1420 DLOG(ERROR) << "Not in a v8::Context"; |
| 1420 return false; | 1421 return false; |
| 1421 } | 1422 } |
| 1422 | 1423 |
| 1423 if (!context->extension()) { | 1424 if (!context->extension()) { |
| 1424 v8::ThrowException( | 1425 v8::ThrowException( |
| 1425 v8::Exception::Error(v8::String::New("Not in an extension."))); | 1426 v8::Exception::Error(v8::String::New("Not in an extension."))); |
| 1426 return false; | 1427 return false; |
| 1427 } | 1428 } |
| 1428 | 1429 |
| 1429 if (!context->extension()->HasAPIPermission(function_name)) { | |
| 1430 static const char kMessage[] = | |
| 1431 "You do not have permission to use '%s'. Be sure to declare" | |
| 1432 " in your manifest what permissions you need."; | |
| 1433 std::string error_msg = base::StringPrintf(kMessage, function_name.c_str()); | |
| 1434 APIActivityLogger::LogBlockedCall(context->extension()->id(), | |
| 1435 function_name); | |
| 1436 v8::ThrowException( | |
| 1437 v8::Exception::Error(v8::String::New(error_msg.c_str()))); | |
| 1438 return false; | |
| 1439 } | |
| 1440 | |
| 1441 if (ExtensionAPI::GetSharedInstance()->IsPrivileged(function_name) && | |
| 1442 context->context_type() != Feature::BLESSED_EXTENSION_CONTEXT) { | |
| 1443 static const char kMessage[] = | |
| 1444 "%s can only be used in an extension process."; | |
| 1445 std::string error_msg = base::StringPrintf(kMessage, function_name.c_str()); | |
| 1446 v8::ThrowException( | |
| 1447 v8::Exception::Error(v8::String::New(error_msg.c_str()))); | |
| 1448 return false; | |
| 1449 } | |
| 1450 | |
| 1451 // Theoretically we could end up with bindings being injected into sandboxed | 1430 // Theoretically we could end up with bindings being injected into sandboxed |
| 1452 // frames, for example content scripts. Don't let them execute API functions. | 1431 // frames, for example content scripts. Don't let them execute API functions. |
| 1453 WebKit::WebFrame* frame = context->web_frame(); | 1432 WebKit::WebFrame* frame = context->web_frame(); |
| 1454 ExtensionURLInfo url_info(frame->document().securityOrigin(), | 1433 ExtensionURLInfo url_info(frame->document().securityOrigin(), |
| 1455 UserScriptSlave::GetDataSourceURLForFrame(frame)); | 1434 UserScriptSlave::GetDataSourceURLForFrame(frame)); |
| 1456 if (extensions_.IsSandboxedPage(url_info)) { | 1435 if (extensions_.IsSandboxedPage(url_info)) { |
| 1457 static const char kMessage[] = | 1436 static const char kMessage[] = |
| 1458 "%s cannot be used within a sandboxed frame."; | 1437 "%s cannot be used within a sandboxed frame."; |
| 1459 std::string error_msg = base::StringPrintf(kMessage, function_name.c_str()); | 1438 std::string error_msg = base::StringPrintf(kMessage, function_name.c_str()); |
| 1460 v8::ThrowException( | 1439 v8::ThrowException( |
| 1461 v8::Exception::Error(v8::String::New(error_msg.c_str()))); | 1440 v8::Exception::Error(v8::String::New(error_msg.c_str()))); |
| 1462 return false; | 1441 return false; |
| 1463 } | 1442 } |
| 1464 | 1443 |
| 1465 return true; | 1444 Feature::Availability availability = context->GetAvailability(function_name); |
| 1445 if (!availability.is_available()) { | |
| 1446 v8::ThrowException(v8::Exception::Error( | |
| 1447 v8::String::New(availability.message().c_str()))); | |
| 1448 } | |
| 1449 | |
| 1450 return availability.is_available(); | |
| 1466 } | 1451 } |
| 1467 | 1452 |
| 1468 } // namespace extensions | 1453 } // namespace extensions |
| OLD | NEW |