kobako 0.11.0 → 0.11.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,12 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "error"
4
- require_relative "../handle"
5
4
 
6
5
  module Kobako
7
6
  module Codec
8
- # Codec helpers shared by the host-side encoders and decoders.
9
- # Three concerns live here today:
7
+ # Byte-boundary helpers shared by the host-side encoder and decoder.
8
+ # Two concerns live here:
10
9
  #
11
10
  # - UTF-8 assertion at the codec boundary
12
11
  # ({docs/wire-codec.md}[link:../../../docs/wire-codec.md]
@@ -16,14 +15,9 @@ module Kobako
16
15
  # - +ArgumentError+ translation at the codec boundary
17
16
  # ({with_boundary}) so the public taxonomy stays
18
17
  # {Kobako::Codec::Error}.
19
- # - Representability predicate ({representable?}) and the symmetric
20
- # host→guest +#run+ argument walk ({deep_wrap}) used by
21
- # +Kobako::Transport::Run#encode+ to route non-representable leaves
22
- # through the Sandbox's +Kobako::Catalog::Handles+.
23
18
  #
24
- # All helpers are pure — they only inspect inputs, never mutate
25
- # them except {deep_wrap}, whose only side effect is allocating
26
- # new Handle ids into the supplied table.
19
+ # Both helpers are pure — they only inspect inputs, never mutate them.
20
+ # The host↔guest Handle substitution walk lives in {HandleWalk}.
27
21
  module Utils
28
22
  module_function
29
23
 
@@ -53,113 +47,6 @@ module Kobako
53
47
  rescue ::ArgumentError => e
54
48
  raise InvalidType, e.message
55
49
  end
56
-
57
- # Inclusive Integer range the msgpack gem encodes without raising
58
- # +RangeError+ at encode time — signed +int 64+ minimum through
59
- # unsigned +uint 64+ maximum
60
- # ({docs/wire-codec.md}[link:../../../docs/wire-codec.md] § Type
61
- # Mapping #3, the +fixint+ / +int 8..64+ / +uint 8..64+ union).
62
- # Anchored as a +Range+ so {primitive_type?} stays a single
63
- # dispatch line. This is the codec's encode domain — not to
64
- # be confused with the Handle id range, which lives on
65
- # +Kobako::Handle+ as +MIN_ID+ / +MAX_ID+ (1..2^31 − 1) and
66
- # represents a different concept entirely.
67
- MSGPACK_INT_RANGE = (-(2**63)..((2**64) - 1))
68
-
69
- # Codec-type predicate
70
- # ({docs/wire-codec.md}[link:../../../docs/wire-codec.md] § Type
71
- # Mapping). Returns +true+ when +value+ belongs to the closed
72
- # 12-entry codec type set — +nil+, +TrueClass+, +FalseClass+,
73
- # +Integer+ (in the +i64..u64+ value domain), +Float+, +String+,
74
- # +Symbol+, +Kobako::Handle+, +Array+ whose every element is itself
75
- # representable, or +Hash+ whose every key and value are
76
- # representable. Integers outside the codec's signed-64 /
77
- # unsigned-64 union are rejected so the predicate agrees with the
78
- # msgpack gem's encode-time +RangeError+ behaviour the codec
79
- # already surfaces as {UnsupportedType}.
80
- def representable?(value)
81
- primitive_type?(value) || container_representable?(value)
82
- end
83
-
84
- # Deep-walk Array / Hash containers in +value+ and replace every
85
- # leaf that fails {representable?} with a +Kobako::Handle+
86
- # allocated from +handler+. The
87
- # walk only descends through representable container shapes
88
- # (Array, Hash) one structural level at a time; a non-representable
89
- # leaf is wrapped as-is without inspecting its internal structure.
90
- # An existing +Kobako::Handle+ is representable and passes through
91
- # unchanged — auto-wrap never re-wraps a Handle.
92
- #
93
- # +value+ may be any Ruby value; +handler+ must respond to
94
- # +#alloc(object) -> Kobako::Handle+ (a host-side
95
- # +Kobako::Catalog::Handles+). Returns a structurally equivalent value
96
- # whose leaves are either representable or +Kobako::Handle+
97
- # tokens.
98
- #
99
- # The block bodies spell +Utils.deep_wrap+ explicitly rather than
100
- # the unqualified +deep_wrap+ because +module_function+ makes the
101
- # instance copy of these helpers private; an implicit receiver
102
- # inside a block would resolve against the enclosing +self+
103
- # (still +Utils+ at definition time, but the qualified form keeps
104
- # the dispatch readable when the recursive call sits inside a
105
- # Proc captured from elsewhere).
106
- def deep_wrap(value, handler)
107
- case value
108
- when ::Array then value.map { |element| Utils.deep_wrap(element, handler) }
109
- when ::Hash then value.transform_values { |val| Utils.deep_wrap(val, handler) }
110
- else
111
- representable?(value) ? value : handler.alloc(value)
112
- end
113
- end
114
-
115
- # Deep-walk Array / Hash containers in +value+ and replace every
116
- # +Kobako::Handle+ leaf with the host-side object +handler+ resolves
117
- # it to. The symmetric inverse of {deep_wrap}: that walk allocates objects
118
- # into Handles on the host→guest argument path; this walk resolves
119
- # Handles back to their objects on every guest→host value path — the
120
- # +#eval+ / +#run+ result and the yield-block result alike. The walk
121
- # descends through Array elements and Hash keys and values one
122
- # structural level at a time; any non-Handle leaf passes through
123
- # unchanged.
124
- #
125
- # +value+ is a decoded Ruby value (a Handle here is a wire-decoded
126
- # +Kobako::Handle+, never a guest-forged one); +handler+ must
127
- # respond to +#fetch(id) -> object+ (a host-side
128
- # +Kobako::Catalog::Handles+). +handler.fetch+ raises
129
- # +Kobako::SandboxError+ for an id with no live binding, the
130
- # corrupted-runtime fallback.
131
- def deep_restore(value, handler)
132
- case value
133
- when ::Array then value.map { |element| Utils.deep_restore(element, handler) }
134
- when ::Hash
135
- value.to_h { |key, val| [Utils.deep_restore(key, handler), Utils.deep_restore(val, handler)] }
136
- when Kobako::Handle then handler.fetch(value.id)
137
- else value
138
- end
139
- end
140
-
141
- # The non-container branch of {representable?}: returns +true+ for
142
- # the scalar leaves and an existing Handle. Not part of the
143
- # public surface; reach for {representable?} instead.
144
- def primitive_type?(value)
145
- case value
146
- when ::NilClass, ::TrueClass, ::FalseClass, ::Float, ::String, ::Symbol, Kobako::Handle then true
147
- when ::Integer then MSGPACK_INT_RANGE.cover?(value)
148
- else false
149
- end
150
- end
151
-
152
- # The container branch of {representable?}: recurses into Array
153
- # elements and Hash key+value pairs through the public
154
- # {representable?}. Not part of the public surface; reach for
155
- # {representable?} instead.
156
- def container_representable?(value)
157
- case value
158
- when ::Array then value.all? { |element| Utils.representable?(element) }
159
- when ::Hash then value.all? { |key, val| Utils.representable?(key) && Utils.representable?(val) }
160
- else false
161
- end
162
- end
163
50
  end
164
51
  end
165
52
  end
data/lib/kobako/codec.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative "codec/error"
4
4
  require_relative "codec/utils"
5
+ require_relative "codec/handle_walk"
5
6
  require_relative "codec/factory"
6
7
  require_relative "codec/encoder"
7
8
  require_relative "codec/decoder"
data/lib/kobako/handle.rb CHANGED
@@ -17,7 +17,7 @@ module Kobako
17
17
  # fields on raised error objects. The Host Gem itself constructs
18
18
  # Handles through {.restore}, which exists at exactly two call
19
19
  # sites: +Kobako::Codec::Factory#unpack_handle+ (wire decode) and
20
- # +Kobako::Codec::Utils.deep_wrap+ / +Kobako::Transport::Dispatcher#wrap_as_handle+
20
+ # +Kobako::Codec::HandleWalk.deep_wrap+ / +Kobako::Transport::Dispatcher#wrap_as_handle+
21
21
  # (allocator paths). Both live inside +lib/kobako/+ and are not part
22
22
  # of any public surface.
23
23
  #
@@ -14,13 +14,6 @@ module Kobako
14
14
  # +Kobako::Outcome::Panic+. The byte-level msgpack codec at
15
15
  # +Kobako::Codec+ is invoked for the body itself; otherwise
16
16
  # nothing in +Transport+ participates.
17
- #
18
- # * tag 0x01, decode OK → return decoded value
19
- # * tag 0x01, decode fails → SandboxError
20
- # * tag 0x02, origin="service" → ServiceError
21
- # * tag 0x02, origin="sandbox"/missing → SandboxError
22
- # * tag 0x02, decode fails → SandboxError
23
- # * unknown tag → TrapError
24
17
  module Outcome
25
18
  # First byte of the OUTCOME_BUFFER for the success branch — body is
26
19
  # the bare msgpack encoding of the returned value
@@ -47,9 +40,8 @@ module Kobako
47
40
  # TrapError for unknown or absent tag
48
41
  # ({docs/wire-codec.md ABI Signatures}[link:../../docs/wire-codec.md]:
49
42
  # zero-length output and unrecognised first byte both walk the trap
50
- # path). The user-facing message stays in caller vocabulary — the
51
- # raw tag byte (or absence) belongs in +details+ for operators, not
52
- # in the message a caller sees.
43
+ # path). The absent-vs-present distinction selects the message;
44
+ # the raw byte is not actionable to a caller and is not surfaced.
53
45
  def build_trap_error(tag)
54
46
  if tag.nil?
55
47
  TrapError.new("Sandbox exited without producing a result")
@@ -289,7 +289,7 @@ module Kobako
289
289
  # token; restore it to the host object the guest referenced before
290
290
  # handing the value to the Host App. @handler still holds this
291
291
  # invocation's table — reset only happens at the next #begin_invocation!.
292
- Codec::Utils.deep_restore(Outcome.decode(snapshot.return_bytes), @handler)
292
+ Codec::HandleWalk.deep_restore(Outcome.decode(snapshot.return_bytes), @handler)
293
293
  rescue Kobako::TrapError => e
294
294
  raise trap_class_for(e), "Sandbox##{verb} failed: #{e.message}"
295
295
  ensure
@@ -100,13 +100,9 @@ module Kobako
100
100
  end
101
101
 
102
102
  # Map an error caught at the dispatch boundary to a +Response.error+
103
- # envelope. +error+ is the +StandardError+ caught by {#dispatch}'s
104
- # rescue. Returns a msgpack-encoded Response envelope (binary). Four
105
- # error buckets:
106
- # +Kobako::Codec::Error+ → type="runtime" (malformed request);
107
- # +UndefinedTargetError+ → type="undefined"; +ArgumentError+ →
108
- # type="argument" (arity mismatch); everything else →
109
- # type="runtime".
103
+ # envelope (binary msgpack). +error+ is the +StandardError+ caught by
104
+ # {#dispatch}'s rescue; the +type+ field tells the guest which kind
105
+ # of failure it was so it can raise the matching proxy-side error.
110
106
  def encode_caught_error(error)
111
107
  case error
112
108
  when Kobako::Codec::Error then encode_error("runtime",
@@ -51,8 +51,8 @@ module Kobako
51
51
  # Encode this Run to the msgpack bytes the guest's +__kobako_run+
52
52
  # entry point consumes as its command-buffer payload
53
53
  # ({docs/wire-codec.md Invocation channels}[link:../../../docs/wire-codec.md]).
54
- # Walks +args+ / +kwargs+ through {Codec::Utils.deep_wrap} so any
55
- # non-wire-representable leaf is allocated into +handler+ and
54
+ # Walks +args+ / +kwargs+ through {Codec::HandleWalk.deep_wrap} so
55
+ # any non-wire-representable leaf is allocated into +handler+ and
56
56
  # replaced with a +Kobako::Handle+; the
57
57
  # +handler+ argument is the Sandbox's table, sharing the same
58
58
  # allocator the guest→host return path uses.
@@ -64,8 +64,8 @@ module Kobako
64
64
  def encode(handler)
65
65
  Codec::Encoder.encode(
66
66
  "entrypoint" => entrypoint,
67
- "args" => Codec::Utils.deep_wrap(args, handler),
68
- "kwargs" => Codec::Utils.deep_wrap(kwargs, handler)
67
+ "args" => Codec::HandleWalk.deep_wrap(args, handler),
68
+ "kwargs" => Codec::HandleWalk.deep_wrap(kwargs, handler)
69
69
  )
70
70
  end
71
71
 
@@ -82,7 +82,7 @@ module Kobako
82
82
  # Array / Hash one level at a time; a plain value passes through
83
83
  # unchanged.
84
84
  def restore(value)
85
- Kobako::Codec::Utils.deep_restore(value, @handler)
85
+ Kobako::Codec::HandleWalk.deep_restore(value, @handler)
86
86
  end
87
87
 
88
88
  # Reify a +YieldResponse+ tag 0x04 payload into a +RuntimeError+ the
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Kobako
4
- VERSION = "0.11.0"
4
+ VERSION = "0.11.2"
5
5
  end
@@ -0,0 +1,17 @@
1
+ module Kobako
2
+ module Codec
3
+ module HandleWalk
4
+ MSGPACK_INT_RANGE: Range[Integer]
5
+
6
+ def self?.representable?: (untyped value) -> bool
7
+
8
+ def self?.deep_wrap: (untyped value, Kobako::Catalog::Handles handler) -> untyped
9
+
10
+ def self?.deep_restore: (untyped value, Kobako::Catalog::Handles handler) -> untyped
11
+
12
+ def self?.primitive_type?: (untyped value) -> bool
13
+
14
+ def self?.container_representable?: (untyped value) -> bool
15
+ end
16
+ end
17
+ end
@@ -1,21 +1,9 @@
1
1
  module Kobako
2
2
  module Codec
3
3
  module Utils
4
- MSGPACK_INT_RANGE: Range[Integer]
5
-
6
4
  def self?.assert_utf8!: (String string, String label) -> void
7
5
 
8
6
  def self?.with_boundary: [T] () { () -> T } -> T
9
-
10
- def self?.representable?: (untyped value) -> bool
11
-
12
- def self?.deep_wrap: (untyped value, Kobako::Catalog::Handles handler) -> untyped
13
-
14
- def self?.deep_restore: (untyped value, Kobako::Catalog::Handles handler) -> untyped
15
-
16
- def self?.primitive_type?: (untyped value) -> bool
17
-
18
- def self?.container_representable?: (untyped value) -> bool
19
7
  end
20
8
  end
21
9
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kobako
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.0
4
+ version: 0.11.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aotokitsuruya
@@ -53,6 +53,7 @@ files:
53
53
  - Cargo.toml
54
54
  - LICENSE
55
55
  - README.md
56
+ - SECURITY.md
56
57
  - data/kobako.wasm
57
58
  - ext/kobako/Cargo.toml
58
59
  - ext/kobako/extconf.rb
@@ -63,7 +64,9 @@ files:
63
64
  - ext/kobako/src/runtime/capture.rs
64
65
  - ext/kobako/src/runtime/config.rs
65
66
  - ext/kobako/src/runtime/dispatch.rs
67
+ - ext/kobako/src/runtime/errors.rs
66
68
  - ext/kobako/src/runtime/exports.rs
69
+ - ext/kobako/src/runtime/frames.rs
67
70
  - ext/kobako/src/runtime/guest_mem.rs
68
71
  - ext/kobako/src/runtime/instance_pre.rs
69
72
  - ext/kobako/src/runtime/invocation.rs
@@ -80,6 +83,7 @@ files:
80
83
  - lib/kobako/codec/encoder.rb
81
84
  - lib/kobako/codec/error.rb
82
85
  - lib/kobako/codec/factory.rb
86
+ - lib/kobako/codec/handle_walk.rb
83
87
  - lib/kobako/codec/utils.rb
84
88
  - lib/kobako/errors.rb
85
89
  - lib/kobako/fault.rb
@@ -118,6 +122,7 @@ files:
118
122
  - sig/kobako/codec/encoder.rbs
119
123
  - sig/kobako/codec/error.rbs
120
124
  - sig/kobako/codec/factory.rbs
125
+ - sig/kobako/codec/handle_walk.rbs
121
126
  - sig/kobako/codec/utils.rbs
122
127
  - sig/kobako/errors.rbs
123
128
  - sig/kobako/fault.rbs