@@ -1290,6 +1290,15 @@ const(void)* toWebUIBuffer(const(ubyte)[] data, int* length) @system
12901290
12911291// -- Callback adaptation -----------------------------------------------------
12921292
1293+ // / Get the argument at `index` as raw bytes the callback owns.
1294+ const (ubyte )[] copyRawAt (Event* e, size_t index) @trusted
1295+ {
1296+ // `getRawAt` borrows from WebUI and dies when the handler returns, so the
1297+ // copy happens here rather than in the caller. That keeps this `@trusted`
1298+ // honest and lets a `@safe` handler take a `const(ubyte)[]` parameter.
1299+ return e.getRawAt(index).dup ;
1300+ }
1301+
12931302// / Wrap any supported callable into the uniform handler the dispatcher calls.
12941303EventHandler makeEventHandler (F)(F fn)
12951304{
@@ -1326,13 +1335,7 @@ EventHandler makeEventHandler(F)(F fn)
13261335 else static if (is (P == string ) || is (P == const (char )[]))
13271336 args[i] = e.getStringAt(argIndex++ );
13281337 else static if (is (P == const (ubyte )[]) || is (P == const (void )[]))
1329- {
1330- // Hand the callback an owned copy rather than the slice
1331- // borrowed from WebUI, so a `@safe` handler cannot end up
1332- // holding a dangling reference after it returns.
1333- const rawIndex = argIndex++ ;
1334- args[i] = () @trusted { return e.getRawAt(rawIndex).dup ; }();
1335- }
1338+ args[i] = copyRawAt(e, argIndex++ );
13361339 else
13371340 static assert (false ,
13381341 " webui.bind: unsupported parameter type `" ~ P.stringof
0 commit comments