File: isolated_world_manager.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (177 lines) | stat: -rw-r--r-- 7,009 bytes parent folder | download | duplicates (9)
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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef EXTENSIONS_RENDERER_ISOLATED_WORLD_MANAGER_H_
#define EXTENSIONS_RENDERER_ISOLATED_WORLD_MANAGER_H_

#include <map>
#include <optional>
#include <string>

#include "base/sequence_checker.h"
#include "extensions/common/mojom/execution_world.mojom.h"
#include "url/gurl.h"

class InjectionHost;

namespace extensions {

// A class responsible for managing the creation and maintenance of isolated
// worlds related to extensions APIs.
//
// There is a single instance of this class (per renderer), retrieved via
// `IsolatedWorldManager::GetInstance()`.
//
// This class is *not* thread-safe and is only designed to be accessed from the
// main renderer thread; this is not an issue because all
// script-injection-related functionality happens on the main thread (e.g.,
// there is no situation in which an extension service worker directly accesses
// isolated worlds).
//
// A note on Host IDs: Host IDs are unique identifiers for the entity causing
// the injection. This is *usually* an extension, but can also be WebUI in the
// case of WebUI injecting into an embedded <webview>. The Host ID for an
// extension is the extension's ID.
class IsolatedWorldManager {
 public:
  IsolatedWorldManager();
  IsolatedWorldManager(const IsolatedWorldManager&) = delete;
  IsolatedWorldManager& operator=(const IsolatedWorldManager&) = delete;
  ~IsolatedWorldManager();

  // Returns the shared instance of the isolated world manager.
  static IsolatedWorldManager& GetInstance();

  // Returns the id of the injection host associated with the given `world_id`
  // or an empty string if none exists.
  std::string GetHostIdForIsolatedWorld(int world_id);

  // Returns the execution world for the given `world_id`, if any exists.
  std::optional<mojom::ExecutionWorld> GetExecutionWorldForIsolatedWorld(
      int world_id);

  // Removes all isolated worlds associated with the given `host_id`, if any
  // exist.
  void RemoveIsolatedWorlds(const std::string& host_id);

  // Sets properties for newly-created user script worlds for the associated
  // `host_id`. Does not affect any already-created worlds, but does update the
  // world data stored in blink so that any newly-created worlds will be
  // properly initialized.
  void SetUserScriptWorldProperties(const std::string& host_id,
                                    const std::optional<std::string>& world_id,
                                    std::optional<std::string> csp,
                                    bool enable_messaging);

  // Clears any properties associated with the given `host_id` and `world_id`.
  // Note this does *not* update any existing worlds.
  void ClearUserScriptWorldProperties(
      const std::string& host_id,
      const std::optional<std::string>& world_id);

  // Returns whether messaging APIs should be enabled in worlds for the given
  // `host_id`.
  bool IsMessagingEnabledInUserScriptWorld(int blink_world_id);

  // Returns the id of the isolated world associated with the given
  // `injection_host`.  If none exists, creates a new world for it associated
  // with the host's name and CSP.
  int GetOrCreateIsolatedWorldForHost(
      const InjectionHost& injection_host,
      mojom::ExecutionWorld execution_world,
      const std::optional<std::string>& world_id);

  // Returns true if `blink_world_id` corresponds to the ID for an extension
  // isolated world (either a content script world or user script world).
  static bool IsExtensionIsolatedWorld(int blink_world_id);

 private:
  // A structure to track existing isolated world information, where an
  // isolated world is any world other than the main world (including both
  // "user script" worlds and default "isolated" worlds from extension content
  // scripts). Presence in this map indicates there has been a world (i.e., v8
  // context) created at the blink layer at least once in this process.
  struct IsolatedWorldInfo {
    // Defaults, to appease the Chromium clang plugin.
    IsolatedWorldInfo();
    ~IsolatedWorldInfo();
    IsolatedWorldInfo(IsolatedWorldInfo&&);

    // The integer ID of the world, used to reference the world with the
    // blink layer.
    int blink_world_id;

    // The id of the injection host the world is associated with. For
    // extensions, this is the extension ID.
    std::string host_id;

    // The execution world for the isolated world. Currently, this is restricted
    // to mojom::ExecutionWorld::kIsolated.
    mojom::ExecutionWorld execution_world;

    // An optional extension-provided ID for the world. If omitted, refers to
    // the "default" world of the given `exection_world` type.
    std::optional<std::string> world_id;

    // A human-friendly name for the isolated world host.
    std::string name;

    // The URL associated with the isolated world host.
    GURL url;

    // CSP to use for the isolated world, if any.
    std::optional<std::string> csp;

    // Whether messaging is enabled within this isolated world.
    bool enable_messaging;
  };

  // A set of data to store properties for user script worlds. There may or may
  // not be a created world at the blink layer (i.e., a v8 context) for these
  // entries.
  struct PendingWorldInfo {
    PendingWorldInfo();
    ~PendingWorldInfo();
    PendingWorldInfo(PendingWorldInfo&&);

    // The CSP to use for newly-created isolated worlds, if any.
    std::optional<std::string> csp;

    // Whether to enable messaging APIs in newly-created isolated worlds.
    bool enable_messaging = false;
  };

  // Finds the stored `IsolatedWorldInfo` for the given `host_id`,
  // `execution_world`, and `world_id`, if any.
  IsolatedWorldInfo* FindIsolatedWorldInfo(
      const std::string& host_id,
      mojom::ExecutionWorld execution_world,
      const std::optional<std::string>& world_id);

  // Finds the stored `PendingWorldInfo` for the given `host_id`,
  // `execution_world`, and `world_id`, if any.
  PendingWorldInfo* FindPendingWorldInfo(
      const std::string& host_id,
      const std::optional<std::string>& world_id);

  void UpdateBlinkIsolatedWorldInfo(int world_id,
                                    const IsolatedWorldInfo& world_info);

  // A map between the isolated world ID and injection host ID.
  using IsolatedWorldMap = std::map<int, IsolatedWorldInfo>;
  IsolatedWorldMap isolated_worlds_;

  // A map of configuration properties for user script worlds. A user script
  // world is unique based on the pairing of <host_id, world_id>, where the
  // world ID may be optional (in which case, it indicates the default world of
  // that type).
  using PendingWorldKey = std::pair<std::string, std::optional<std::string>>;
  std::map<PendingWorldKey, PendingWorldInfo> pending_worlds_info_;

  SEQUENCE_CHECKER(sequence_checker_);
};

}  // namespace extensions

#endif  // EXTENSIONS_RENDERER_ISOLATED_WORLD_MANAGER_H_