From 458057d0db06277f1a9d73e27223682f5b4abd8c Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Tue, 17 Mar 2026 16:07:46 +0100 Subject: [PATCH 1/2] fix: safer integer conversion and external buffer support in to_from_value --- src/to_from_value.zig | 55 ++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/src/to_from_value.zig b/src/to_from_value.zig index 5840aa8..ebecae3 100644 --- a/src/to_from_value.zig +++ b/src/to_from_value.zig @@ -13,20 +13,19 @@ pub fn fromValue( return try value.getValueBool(); }, .int => |i| { - if (T == i32) { - return try value.getValueInt32(); + if (i.signedness == .signed) { + const n: i64 = if (i.bits <= 32) + try value.getValueInt32() + else + try value.getValueInt64(); + return std.math.cast(T, n) orelse error.InvalidArg; } - if (T == u32) { - return try value.getValueUint32(); - } - if (i.bits < 32) { - if (i.signedness == .signed) { - return @intCast(try value.getValueInt32()); - } else { - return @intCast(try value.getValueUint32()); - } - } - return @intCast(try value.getValueInt64()); + + const n: i64 = if (i.bits <= 32) + @as(i64, try value.getValueUint32()) + else + try value.getValueInt64(); + return std.math.cast(T, n) orelse error.InvalidArg; }, .float => { if (T == f64) { @@ -61,20 +60,19 @@ pub fn toValue( return try env.getBoolean(v); }, .int => |i| { - if (T == i32) { - return try env.createInt32(v); - } - if (T == u32) { - return try env.createUint32(v); - } - if (i.bits < 32) { - if (i.signedness == .signed) { - return try env.createInt32(v); - } else { - return try env.createUint32(v); + if (i.signedness == .signed) { + const n = std.math.cast(i64, v) orelse return error.InvalidArg; + if (i.bits <= 32) { + return try env.createInt32(std.math.cast(i32, n) orelse return error.InvalidArg); } + return try env.createInt64(n); + } + + const n = std.math.cast(u64, v) orelse return error.InvalidArg; + if (i.bits <= 32) { + return try env.createUint32(std.math.cast(u32, n) orelse return error.InvalidArg); } - return try env.createInt64(@intCast(v)); + return try env.createInt64(std.math.cast(i64, n) orelse return error.InvalidArg); }, .float => { if (T == f64) { @@ -86,10 +84,13 @@ pub fn toValue( .pointer => |p| { const h = hint; if (p.child == u8 and p.size == .slice) { + const bytes: []const u8 = @ptrCast(v); if (h == .string) { - return try env.createStringUtf8(@ptrCast(v)); + return try env.createStringUtf8(bytes); + } else if (h == .external_buffer) { + return try env.createExternalBuffer(bytes, null, null); } else if (h == .buffer or h == .auto) { - return try env.createBufferCopy(@ptrCast(v), null); + return try env.createBufferCopy(bytes, null); } } const child_type_info = @typeInfo(p.child); From c09ceba0c32d8e967cc2c89899098b7f3585c7f3 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Mon, 23 Mar 2026 17:15:43 +0100 Subject: [PATCH 2/2] update the casting strategy --- src/to_from_value.zig | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/to_from_value.zig b/src/to_from_value.zig index ebecae3..57bc7f8 100644 --- a/src/to_from_value.zig +++ b/src/to_from_value.zig @@ -61,18 +61,16 @@ pub fn toValue( }, .int => |i| { if (i.signedness == .signed) { - const n = std.math.cast(i64, v) orelse return error.InvalidArg; if (i.bits <= 32) { - return try env.createInt32(std.math.cast(i32, n) orelse return error.InvalidArg); + return try env.createInt32(std.math.cast(i32, v) orelse return error.InvalidArg); } - return try env.createInt64(n); + return try env.createInt64(std.math.cast(i64, v) orelse return error.InvalidArg); } - const n = std.math.cast(u64, v) orelse return error.InvalidArg; if (i.bits <= 32) { - return try env.createUint32(std.math.cast(u32, n) orelse return error.InvalidArg); + return try env.createUint32(std.math.cast(u32, v) orelse return error.InvalidArg); } - return try env.createInt64(std.math.cast(i64, n) orelse return error.InvalidArg); + return try env.createInt64(std.math.cast(i64, v) orelse return error.InvalidArg); }, .float => { if (T == f64) {