summaryrefslogtreecommitdiffstats
path: root/chrome/renderer/extensions/custom_bindings_util.cc
blob: 5d9277f431fe8f174d0b214b52323c374c58e97f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/renderer/extensions/custom_bindings_util.h"

#include <map>

#include "base/logging.h"
#include "base/string_util.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/renderer/extensions/chrome_v8_extension.h"
#include "chrome/renderer/extensions/chrome_private_custom_bindings.h"
#include "chrome/renderer/extensions/context_menus_custom_bindings.h"
#include "chrome/renderer/extensions/experimental.socket_custom_bindings.h"
#include "chrome/renderer/extensions/extension_custom_bindings.h"
#include "chrome/renderer/extensions/extension_dispatcher.h"
#include "chrome/renderer/extensions/file_browser_handler_custom_bindings.h"
#include "chrome/renderer/extensions/file_browser_private_custom_bindings.h"
#include "chrome/renderer/extensions/page_actions_custom_bindings.h"
#include "chrome/renderer/extensions/page_capture_custom_bindings.h"
#include "chrome/renderer/extensions/tabs_custom_bindings.h"
#include "chrome/renderer/extensions/tts_custom_bindings.h"
#include "chrome/renderer/extensions/web_request_custom_bindings.h"
#include "grit/renderer_resources.h"
#include "v8/include/v8.h"

namespace extensions {

namespace custom_bindings_util {

std::vector<v8::Extension*> GetAll(ExtensionDispatcher* extension_dispatcher) {
  // Must match kResourceIDs.
  static const char* kJavascriptFiles[] = {
    "extensions/browser_action_custom_bindings.js",
    "extensions/content_settings_custom_bindings.js",
    "extensions/experimental.declarative_custom_bindings.js",
    "extensions/devtools_custom_bindings.js",
    "extensions/input.ime_custom_bindings.js",
    "extensions/omnibox_custom_bindings.js",
    "extensions/page_action_custom_bindings.js",
    "extensions/storage_custom_bindings.js",
    "extensions/tts_engine_custom_bindings.js",
    "extensions/types_custom_bindings.js",
    "extensions/windows_custom_bindings.js",
  };
  static const size_t kJavascriptFilesSize = arraysize(kJavascriptFiles);

  // Must match kJavascriptFiles.
  static const int kResourceIDs[] = {
    IDR_BROWSER_ACTION_CUSTOM_BINDINGS_JS,
    IDR_CONTENT_SETTINGS_CUSTOM_BINDINGS_JS,
    IDR_EXPERIMENTAL_DECLARATIVE_CUSTOM_BINDINGS_JS,
    IDR_DEVTOOLS_CUSTOM_BINDINGS_JS,
    IDR_INPUT_IME_CUSTOM_BINDINGS_JS,
    IDR_OMNIBOX_CUSTOM_BINDINGS_JS,
    IDR_PAGE_ACTION_CUSTOM_BINDINGS_JS,
    IDR_STORAGE_CUSTOM_BINDINGS_JS,
    IDR_TTS_ENGINE_CUSTOM_BINDINGS_JS,
    IDR_TYPES_CUSTOM_BINDINGS_JS,
    IDR_WINDOWS_CUSTOM_BINDINGS_JS,
  };
  static const size_t kResourceIDsSize = arraysize(kResourceIDs);

  static const char* kDependencies[] = {
    "extensions/schema_generated_bindings.js",
  };
  static const size_t kDependencyCount = arraysize(kDependencies);

  std::vector<v8::Extension*> result;

  // Custom bindings that have native code parts.
  result.push_back(new ChromePrivateCustomBindings(
      kDependencyCount, kDependencies, extension_dispatcher));
  result.push_back(new ContextMenusCustomBindings(
      kDependencyCount, kDependencies));
  result.push_back(new ExtensionCustomBindings(
      kDependencyCount, kDependencies, extension_dispatcher));
  result.push_back(new ExperimentalSocketCustomBindings(
      kDependencyCount, kDependencies));
  result.push_back(new FileBrowserHandlerCustomBindings(
      kDependencyCount, kDependencies));
  result.push_back(new FileBrowserPrivateCustomBindings(
      kDependencyCount, kDependencies));
  result.push_back(new PageActionsCustomBindings(
      kDependencyCount, kDependencies, extension_dispatcher));
  result.push_back(new PageCaptureCustomBindings(
      kDependencyCount, kDependencies));
  result.push_back(new TabsCustomBindings(
      kDependencyCount, kDependencies));
  result.push_back(new TTSCustomBindings(
      kDependencyCount, kDependencies));
  result.push_back(new WebRequestCustomBindings(
      kDependencyCount, kDependencies));

  // Pure JavaScript custom bindings.
  CHECK_EQ(kJavascriptFilesSize, kResourceIDsSize);
  for (size_t i = 0; i < kJavascriptFilesSize; ++i) {
    result.push_back(new ChromeV8Extension(
        kJavascriptFiles[i],
        kResourceIDs[i],
        kDependencyCount, kDependencies,
        NULL));
  }

  return result;
}

// Extracts the name of an API from the name of the V8 extension which contains
// custom bindings for it (see kCustomBindingNames).
std::string GetAPIName(const std::string& v8_extension_name) {
  // Extract the name of the API from the v8 extension name.
  // This is "${api_name}" in "extensions/${api_name}_custom_bindings.js".
  std::string prefix = "extensions/";
  const bool kCaseSensitive = true;
  if (!StartsWithASCII(v8_extension_name, prefix, kCaseSensitive))
    return "";

  std::string suffix = "_custom_bindings.js";
  if (!EndsWith(v8_extension_name, suffix, kCaseSensitive))
    return "";

  // By convention, filenames are use unix_hacker_style, but the APIs we expose
  // to javascript use camelCase.
  std::string not_camelcase = v8_extension_name.substr(
      prefix.size(),
      v8_extension_name.size() - prefix.size() - suffix.size());

  std::string camelcase;
  bool next_to_upper = false;
  for (std::string::iterator it = not_camelcase.begin();
      it != not_camelcase.end(); ++it) {
    if (*it == '_') {
      next_to_upper = true;
    } else if (next_to_upper) {
      camelcase.push_back(base::ToUpperASCII(*it));
      next_to_upper = false;
    } else {
      camelcase.push_back(*it);
    }
  }

  return camelcase;
}

bool AllowAPIInjection(const std::string& api_name,
                       const Extension& extension) {
  CHECK(api_name != "");

  // As in ExtensionAPI::GetSchemasForExtension, we need to allow any bindings
  // for an API that the extension *might* have permission to use.
  return extension.required_permission_set()->HasAnyAccessToAPI(api_name) ||
         extension.optional_permission_set()->HasAnyAccessToAPI(api_name);
}

}  // namespace custom_bindings_util

}  // namespace extensions