coolaj86 / uuidv7

UUIDv7, written in Zig (and Go, and JS, and Swift - just for good measure, of course)
Other
1 stars 1 forks source link

wrong return type for u8 array #3

Closed coolaj86 closed 1 month ago

coolaj86 commented 1 month ago

https://github.com/coolaj86/zig-uuidv7/blob/02d997d22acf304c518313e91503b4ccef091b8e/uuidv7.zig#L65-L70

Just so ya know, the reason why this is a use-after-free is because you are returning a slice ([]const u8), i.e. a ptr+len, to a stack-allocated array that dies on function return. If you return the array instead, i.e. [32]u8, that has "by-value" semantics, then that does what you expect.

Validark commented 1 month ago

Fun fact: If you run your code in debug mode on my machine, it prints "01921442-432f-71@F��b426". However, if you update the function like so:

fn uuidToString(uuid: UUID) ![36]u8 {
    var buffer: [36]u8 = undefined;
    // time_h32-t_16-verh-varh-rand03rand04
    // 019212d3-87f4-7d25-902e-b8d39fe07f08
    _ = try std.fmt.bufPrint(&buffer, "{x:08}-{x}-{x}-{x:04}-{x:04}{x:08}", .{ uuid.time_high, uuid.time_low, uuid.version_random1, uuid.variant_random2, uuid.random3, uuid.random4 });

    return buffer;
}

Then it works just fine. Even in Release modes, you can observe the stack being overwritten if you were to call the function again:

const uuid7 = try generateUUIDv7(getrandom);
const uuid7str = try uuidToString(uuid7);
try stdout.print("{s}\n", .{uuid7str});
_ = try generateUUIDv7(getrandom);
try stdout.print("{s}\n", .{uuid7str}); // uuid7str has now changed!