aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe-php-rpc
diff options
context:
space:
mode:
Diffstat (limited to 'crates/shirabe-php-rpc')
-rw-r--r--crates/shirabe-php-rpc/php/worker.php8
-rw-r--r--crates/shirabe-php-rpc/src/value.rs7
2 files changed, 14 insertions, 1 deletions
diff --git a/crates/shirabe-php-rpc/php/worker.php b/crates/shirabe-php-rpc/php/worker.php
index 164d73ea..6ed5df40 100644
--- a/crates/shirabe-php-rpc/php/worker.php
+++ b/crates/shirabe-php-rpc/php/worker.php
@@ -267,6 +267,12 @@ final class ShirabeRpcRuntime
/**
* Converts a decoded wire value: handle descriptor arrays become live objects. A
* materialized value arrives as a real instance already, revived by unserialize().
+ *
+ * TODO(type-model): a descriptor travels in-band as a plain array, so its exact key set is
+ * the only thing separating it from plugin data of the same shape. Every check below except
+ * __pclass matches on the reserved key alone, so an array a plugin built with a __rhandle or
+ * __phandle key of its own is read as a handle rather than kept as data. The Rust half
+ * (`decode_handle` in `src/value.rs`) matches the whole key set, and diverges the other way.
*/
public static function fromWire($value)
{
@@ -806,7 +812,7 @@ ShirabeRpcRuntime::$dispatch = [
},
// An already-fulfilled promise for a Rust-side call whose PHP signature declares
// PromiseInterface. The Rust future ran to completion before this is called, so there is
- // nothing left to defer; see .ken/plugin-arch/design.md ยง10.1.6.
+ // nothing left to defer.
'__shirabe_resolved_promise' => static function ($args) {
if (!function_exists('React\\Promise\\resolve')) {
throw new RuntimeException(
diff --git a/crates/shirabe-php-rpc/src/value.rs b/crates/shirabe-php-rpc/src/value.rs
index c19c386f..7203c9fb 100644
--- a/crates/shirabe-php-rpc/src/value.rs
+++ b/crates/shirabe-php-rpc/src/value.rs
@@ -612,6 +612,13 @@ fn parse_quoted(payload: &[u8], pos: &mut usize, terminator: u8) -> anyhow::Resu
}
/// Recognizes the reserved handle-descriptor arrays by their exact key sets.
+///
+/// TODO(type-model): a descriptor travels in-band as a plain array, so its exact key set is the
+/// only thing separating it from plugin data of the same shape. An array that carries a reserved
+/// key without matching a descriptor's whole key set is user data and should decode as an array;
+/// it is a decode error here instead, and that is the fatal lane, so a plugin passing
+/// `['__rhandle' => 1]` to a proxied method takes the channel down with it. The PHP half
+/// (`fromWire` in `php/worker.php`) diverges the other way, matching on the reserved key alone.
fn decode_handle(entries: &IndexMap<Vec<u8>, PluginValue>) -> anyhow::Result<Option<PluginValue>> {
let get = |key: &[u8]| entries.get(key);