Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
reload_capabilities.hpp
Go to the documentation of this file.
1#pragma once
2
3// Capability model for the scripted-UI bridge. A hot-reloaded UI declares the
4// capabilities it needs; the host grants a set; the WidgetBridge is constructed
5// capability-scoped so ungranted EFFECTFUL API groups are simply not registered —
6// the JS symbol is absent, not merely guarded. Pure-UI groups (canvas, css, layout,
7// widgets, gpu, …) carry no effect and are always registered.
8//
9// This is the blast-radius bound for an untrusted or compromised UI: a UI granted
10// no `network`/`filesystem`/`exec` cannot reach those native surfaces at all, even
11// if it is otherwise valid. It is deliberately NOT a sandbox for native code —
12// native modules are trusted by provenance (signature), never capability-gated.
13//
14// The enforcement seam is the `register_*_api()` grouping in WidgetBridge: every
15// effectful native function is reached only through one of those groups, so gating
16// at the group is complete.
17//
18// This lives in `view` (not a lower trust layer) because the bridge is the sole
19// enforcement point and `format` may depend on `view`, not the reverse.
20
21#include <cstdint>
22#include <optional>
23#include <string>
24#include <string_view>
25#include <vector>
26
27namespace pulp::view {
28
42
45inline std::string_view capability_name(ReloadCapability c) {
46 switch (c) {
47 case ReloadCapability::Exec: return "exec";
48 case ReloadCapability::Clipboard: return "clipboard";
49 case ReloadCapability::Filesystem: return "filesystem";
50 case ReloadCapability::Storage: return "storage";
51 case ReloadCapability::Ai: return "ai";
52 case ReloadCapability::RuntimeImport: return "runtime_import";
53 case ReloadCapability::Network: return "network";
54 }
55 return "unknown";
56}
57
60inline bool capability_from_name(std::string_view s, ReloadCapability& out) {
61 if (s == "exec") { out = ReloadCapability::Exec; return true; }
62 if (s == "clipboard") { out = ReloadCapability::Clipboard; return true; }
63 if (s == "filesystem") { out = ReloadCapability::Filesystem; return true; }
64 if (s == "storage") { out = ReloadCapability::Storage; return true; }
65 if (s == "ai") { out = ReloadCapability::Ai; return true; }
66 if (s == "runtime_import") { out = ReloadCapability::RuntimeImport; return true; }
67 if (s == "network") { out = ReloadCapability::Network; return true; }
68 return false;
69}
70
75public:
76 CapabilitySet() = default;
77
78 static CapabilitySet all() {
80 s.bits_ = kAllBits;
81 s.legacy_default_ = true;
82 return s;
83 }
84
85 void grant(ReloadCapability c) { bits_ |= bit(c); }
86 bool has(ReloadCapability c) const { return (bits_ & bit(c)) != 0; }
87 bool empty() const { return bits_ == 0; }
88
95 bool is_legacy_default() const noexcept {
96 return legacy_default_;
97 }
98
103 std::optional<ReloadCapability> first_effectful() const noexcept {
104 for (const auto capability : {
109 if (has(capability))
110 return capability;
111 }
112 return std::nullopt;
113 }
114
117 static bool parse(const std::vector<std::string>& names, CapabilitySet& out) {
119 for (const auto& n : names) {
121 if (!capability_from_name(n, c)) return false; // unknown → fail closed
122 s.grant(c);
123 }
124 out = s;
125 return true;
126 }
127
128private:
129 static std::uint32_t bit(ReloadCapability c) {
130 return std::uint32_t{1} << static_cast<std::uint8_t>(c);
131 }
132 static constexpr std::uint32_t kAllBits =
133 (std::uint32_t{1} << 7) - 1; // 7 capabilities (Exec..Network)
134
135 std::uint32_t bits_ = 0;
136 bool legacy_default_ = false;
137};
138
139} // namespace pulp::view
bool empty() const
Definition reload_capabilities.hpp:87
static CapabilitySet all()
Definition reload_capabilities.hpp:78
static bool parse(const std::vector< std::string > &names, CapabilitySet &out)
Parse a declared-capability name list (from the signed manifest).
Definition reload_capabilities.hpp:117
std::optional< ReloadCapability > first_effectful() const noexcept
Return the first granted effectful capability in stable declaration order.
Definition reload_capabilities.hpp:103
void grant(ReloadCapability c)
Definition reload_capabilities.hpp:85
bool has(ReloadCapability c) const
Definition reload_capabilities.hpp:86
bool is_legacy_default() const noexcept
True only for a set produced by all(): the unenforced grant every trusted/local realm still receives ...
Definition reload_capabilities.hpp:95
Hover-cursor tracking for platform window hosts.
Definition fwd.hpp:27
bool capability_from_name(std::string_view s, ReloadCapability &out)
Parse a wire name; returns false on an unknown token (caller fails closed — an unrecognized capabilit...
Definition reload_capabilities.hpp:60
@ s
Definition input_events.hpp:41
@ c
Definition input_events.hpp:39
@ n
Definition input_events.hpp:40
std::string_view capability_name(ReloadCapability c)
Stable wire name for a capability (used in the SIGNED pack manifest + config).
Definition reload_capabilities.hpp:45
ReloadCapability
A capability gates one effectful bridge-API group.
Definition reload_capabilities.hpp:31
@ RuntimeImport
evaluate a runtime-imported JS bundle (dynamic code load)
Definition reload_capabilities.hpp:38
@ Clipboard
read/write the system clipboard
Definition reload_capabilities.hpp:34
@ Ai
AI-CLI bridge.
Definition reload_capabilities.hpp:37
@ Storage
persistent key/value + preset temp files
Definition reload_capabilities.hpp:36
@ Exec
shell exec/execAsync — ALSO compiled out unless the PULP_DEV_BRIDGE_EXEC CMake option is ON (release/...
Definition reload_capabilities.hpp:32
@ Filesystem
read arbitrary file paths (asset file loads, native dialogs)
Definition reload_capabilities.hpp:35
@ Network
outbound network (reserved; used by remote-UX-push, not the bridge today)
Definition reload_capabilities.hpp:39