Skip to content

Optional Fields in toStruct do not get null value #171

@tmrlvi

Description

@tmrlvi

Summary

When a struct contains an optional field without a default value, an arbitrary value is assign (I suspect it is the uninitialized memory).

Possible solution

I noticed that if I change

ziglua/src/lib.zig

Lines 4856 to 4862 in 6889b2d

if (lua_field_type == .nil) {
if (field.defaultValue()) |default| {
@field(result, field.name) = default;
} else if (field_type_info != .optional) {
return error.LuaTableMissingValue;
}
} else {

to

 if (lua_field_type == .nil) { 
     if (field.defaultValue()) |default| { 
         @field(result, field.name) = default; 
     } else if (field_type_info != .optional) { 
         return error.LuaTableMissingValue; 
     } else {
         @field(result, field.name) = null;
      }
 } else { 

resolves the issue, but I'm not sure this is the right approach (hence issue and not PR)

Reproducing

Code

const zlua = @import("zlua");
const std = @import("std");

const Lua = zlua.Lua;

const A = struct {
    a: ?u64,
};


pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    const allocator = gpa.allocator();
    defer _ = gpa.deinit();

    var lua = try Lua.init(allocator);
    defer lua.deinit();

    try lua.doString("return {a=4};");
    std.debug.print("{}\n", .{try lua.toStruct(A, null, false, 1)});
    lua.pop(1);

    try lua.doString("return {a=nil};");
    std.debug.print("{}\n", .{try lua.toStruct(A, null, false, 1)});
    lua.pop(1);
}

Expected

main.A{ .a = 4 }
main.A{ .a = null }

Result

main.A{ .a = 4 }
main.A{ .a = 12297829382473034410 }

Workaround

Defining a default value of null circumvent this issue. In the example above:

const A = struct {
    a: ?u64 = null,
};

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions