vt: store DA1 feature buffer in wrapper struct

The DA1 trampoline was converting C feature codes into a local
stack buffer and returning a slice pointing into it. This is
unsound because the slice outlives the stack frame once the
trampoline returns, leaving reportDeviceAttributes reading
invalid memory.

Move the scratch buffer into the wrapper effects struct so that
its lifetime extends beyond the trampoline call, keeping the
returned slice valid for the caller.
pull/11814/head
Mitchell Hashimoto 2026-03-24 12:06:33 -07:00
parent e36b745314
commit d2c6a3c775
No known key found for this signature in database
GPG Key ID: 523D5DC389D273BC
1 changed files with 9 additions and 3 deletions

View File

@ -47,6 +47,13 @@ const Effects = struct {
title_changed: ?TitleChangedFn = null,
size_cb: ?SizeFn = null,
/// Scratch buffer for DA1 feature codes. The device attributes
/// trampoline converts C feature codes into this buffer and returns
/// a slice pointing into it. Storing it here ensures the slice
/// remains valid after the trampoline returns, since the caller
/// (`reportDeviceAttributes`) reads it before any re-entrant call.
da_features_buf: [64]device_attributes.Primary.Feature = undefined,
/// C function pointer type for the write_pty callback.
pub const WritePtyFn = *const fn (Terminal, ?*anyopaque, [*]const u8, usize) callconv(.c) void;
@ -142,13 +149,12 @@ const Effects = struct {
// because all our types are non-exhaustive enums.
const n: usize = @min(c_attrs.primary.num_features, 64);
var features: [64]device_attributes.Primary.Feature = undefined;
for (0..n) |i| features[i] = @enumFromInt(c_attrs.primary.features[i]);
for (0..n) |i| wrapper.effects.da_features_buf[i] = @enumFromInt(c_attrs.primary.features[i]);
return .{
.primary = .{
.conformance_level = @enumFromInt(c_attrs.primary.conformance_level),
.features = features[0..n],
.features = wrapper.effects.da_features_buf[0..n],
},
.secondary = .{
.device_type = @enumFromInt(c_attrs.secondary.device_type),