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 |