switch to parse_allocator = .none (fix production segfaults)
All checks were successful
Generic zig build / build (push) Successful in 4m35s
Generic zig build / publish-macos (push) Successful in 13s
Generic zig build / deploy (push) Successful in 20s

This commit is contained in:
Emil Lerch 2026-06-02 15:16:11 -07:00
parent b7b492e494
commit fdd0c97480
Signed by: lobo
GPG key ID: A7B62D657EF764F8
7 changed files with 16 additions and 9 deletions

View file

@ -212,7 +212,7 @@ pub fn parseAccountsFile(allocator: std.mem.Allocator, data: []const u8) !Accoun
}
var reader = std.Io.Reader.fixed(data);
var it = srf.iterator(&reader, allocator, .{}) catch return error.InvalidData;
var it = srf.iterator(&reader, allocator, .{ .parse_allocator = .none }) catch return error.InvalidData;
defer it.deinit();
while (try it.next()) |fields| {

View file

@ -494,7 +494,7 @@ pub fn parseProjectionsConfig(data: ?[]const u8) UserConfig {
const scratch = fba.allocator();
var reader = std.Io.Reader.fixed(raw);
var it = srf.iterator(&reader, scratch, .{}) catch return config;
var it = srf.iterator(&reader, scratch, .{ .parse_allocator = .none }) catch return config;
defer it.deinit();
var saw_horizon = false;

8
src/cache/store.zig vendored
View file

@ -352,7 +352,7 @@ pub const Store = struct {
}
var reader = std.Io.Reader.fixed(data);
var it = srf.iterator(&reader, self.allocator, .{}) catch return null;
var it = srf.iterator(&reader, self.allocator, .{ .parse_allocator = .none }) catch return null;
defer it.deinit();
if (freshness == .fresh_only) {
@ -1132,7 +1132,7 @@ pub const Store = struct {
if (std.mem.indexOf(u8, data, "# fetch_failed")) |_| return true;
var reader = std.Io.Reader.fixed(data);
const it = srf.iterator(&reader, self.allocator, .{}) catch return false;
const it = srf.iterator(&reader, self.allocator, .{ .parse_allocator = .none }) catch return false;
defer it.deinit();
if (it.expires == null) return false;
@ -1609,7 +1609,7 @@ pub fn deserializePortfolio(allocator: std.mem.Allocator, data: []const u8) !Por
}
var reader = std.Io.Reader.fixed(data);
var it = srf.iterator(&reader, allocator, .{}) catch return error.InvalidData;
var it = srf.iterator(&reader, allocator, .{ .parse_allocator = .none }) catch return error.InvalidData;
defer it.deinit();
var skipped: usize = 0;
@ -1856,7 +1856,7 @@ test "writeMerged Dividend: no-change merge still rewrites to refresh expires" {
defer allocator.free(data);
var reader = std.Io.Reader.fixed(data);
const it = try srf.iterator(&reader, allocator, .{});
const it = try srf.iterator(&reader, allocator, .{ .parse_allocator = .none });
defer it.deinit();
const new_expires = it.expires orelse return error.ExpiresMissing;

View file

@ -78,7 +78,7 @@ pub fn parseSnapshotBytes(
// fallback arena and are freed by `it.deinit()`. Snapshot
// consumers dupe what they need into the caller's allocator
// before the iterator dies.
var it = srf.iterator(&reader, allocator, .{}) catch return error.InvalidSrf;
var it = srf.iterator(&reader, allocator, .{ .parse_allocator = .none }) catch return error.InvalidSrf;
defer it.deinit();
var meta_opt: ?snapshot.MetaRow = null;

View file

@ -57,7 +57,7 @@ pub fn parseClassificationFile(allocator: std.mem.Allocator, data: []const u8) !
}
var reader = std.Io.Reader.fixed(data);
var it = srf.iterator(&reader, allocator, .{}) catch return error.InvalidData;
var it = srf.iterator(&reader, allocator, .{ .parse_allocator = .none }) catch return error.InvalidData;
defer it.deinit();
while (try it.next()) |fields| {

View file

@ -260,7 +260,7 @@ pub fn parseTransactionLogFile(
}
var reader = std.Io.Reader.fixed(data);
var it = srf.iterator(&reader, allocator, .{}) catch return error.InvalidData;
var it = srf.iterator(&reader, allocator, .{ .parse_allocator = .none }) catch return error.InvalidData;
defer it.deinit();
while (try it.next()) |fields| {

View file

@ -452,6 +452,13 @@ pub fn loadFromData(allocator: std.mem.Allocator, data: []const u8) ?KeyMap {
pub fn loadFromDataChecked(allocator: std.mem.Allocator, data: []const u8) LoadOutcome {
var reader = std.Io.Reader.fixed(data);
// `.{}` here defaults to `.parse_allocator = .parse_arena`, which
// is the lifetime model this function depends on: srf copies every
// parsed string into its internal arena, and we transfer ownership
// of that arena to the returned `KeyMap` below (rather than calling
// `ri.deinit()`). All other srf.iterator call sites in zfin use
// `.parse_allocator = .none` so strings slice into the input
// buffer; this is the one exception.
var ri = srf.iterator(&reader, allocator, .{}) catch return .fallback;
// Don't deinit `ri` until the end its arena owns the
// string slices we'll borrow into the returned KeyMap. We