search for standard sites pub-search.waow.tech
search zig blog atproto
0

Configure Feed

Select the types of activity you want to include in your feed.

feat(backend): drivepatents ban + snapshot adoption + span use-after-free fix

three pieces, one deploy:
- indexer drops the banned bulk-archive DID (second gate behind the
ingester ban; replays and backfills can't reinsert purged docs)
- LocalDb adopts <path>.new at boot (atomic rename before open) — how
offline-built replicas ship without the serving box ever sharing a
file with a bulk writer
- doRequest no longer attaches the turso response preview to the span:
it was freed by a later-declared defer before the earlier-declared
span.end() deep-copied attributes — use-after-free in the otel copy
path, segfaulting the process on turso error responses

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

+46 -1
+4 -1
backend/src/db/Client.zig
··· 240 240 logfire.err("{s} turso error: {} | sql: {s} | response: {s}", .{ span_name, res.status, truncated, resp_preview }); 241 241 span.recordError(error.TursoError); 242 242 span.setAttribute("turso.status", @intFromEnum(res.status)); 243 - span.setAttribute("turso.response", resp_preview); 243 + // NEVER attach resp_preview to the span: it's freed by the defer 244 + // above before `defer span.end()` (declared earlier, runs later) 245 + // deep-copies attributes — use-after-free, segfault, process death. 246 + // The log line above carries the preview; the span gets the status. 244 247 return error.TursoError; 245 248 } 246 249
+27
backend/src/db/LocalDb.zig
··· 66 66 const path_env = if (std.c.getenv("LOCAL_DB_PATH")) |p| std.mem.span(p) else "/data/local.db"; 67 67 self.path = path_env; 68 68 69 + adoptPending(path_env); 69 70 try self.openDb(path_env, false); 71 + } 72 + 73 + /// Snapshot adoption: if `<path>.new` exists at boot, rename it over the live 74 + /// file (plus clear stale WAL/SHM) before opening. This is how offline-built 75 + /// replicas ship: upload as .new while the old process serves, restart, and 76 + /// the swap is atomic — the serving path never coexists with a bulk writer. 77 + fn adoptPending(path_env: []const u8) void { 78 + var new_buf: [256]u8 = undefined; 79 + const new_path = std.fmt.bufPrintZ(&new_buf, "{s}.new", .{path_env}) catch return; 80 + var cur_buf: [256]u8 = undefined; 81 + const cur_path = std.fmt.bufPrintZ(&cur_buf, "{s}", .{path_env}) catch return; 82 + 83 + const fd = std.c.open(new_path.ptr, .{ .ACCMODE = .RDONLY }, @as(std.c.mode_t, 0)); 84 + if (fd < 0) return; // nothing pending 85 + _ = std.c.close(fd); 86 + 87 + var aux_buf: [264]u8 = undefined; 88 + inline for (.{ "-wal", "-shm" }) |suffix| { 89 + const aux = std.fmt.bufPrintZ(&aux_buf, "{s}{s}", .{ path_env, suffix }) catch return; 90 + _ = std.c.unlink(aux.ptr); 91 + } 92 + if (std.c.rename(new_path.ptr, cur_path.ptr) == 0) { 93 + std.debug.print("local db: adopted pending snapshot {s}\n", .{new_path}); 94 + } else { 95 + std.debug.print("local db: snapshot adopt FAILED, serving existing file\n", .{}); 96 + } 70 97 } 71 98 72 99 fn openDb(self: *LocalDb, path_env: []const u8, is_retry: bool) !void {
+14
backend/src/ingest/indexer.zig
··· 59 59 ) !void { 60 60 const c = db.getClient() orelse return error.NotInitialized; 61 61 62 + // banned bulk-archive repos (purged 2026-06-10): second gate behind the 63 + // ingester's ban — nothing reinserts these, not even replays or backfills. 64 + if (std.mem.eql(u8, did, "did:plc:oql6ds5vnff4ugar6rruliwd")) { 65 + logfire.span("tap.dropped", .{ .reason = "banned_did", .uri = uri }).end(); 66 + return; 67 + } 68 + 62 69 // dedupe: if (did, rkey) exists with different uri, clean up old record first 63 70 // this handles cross-collection duplicates (e.g., pub.leaflet.document + site.standard.document) 64 71 var doc_exists = false; ··· 289 296 base_path: ?[]const u8, 290 297 ) !void { 291 298 const c = db.getClient() orelse return error.NotInitialized; 299 + 300 + // banned bulk-archive repos (purged 2026-06-10): second gate behind the 301 + // ingester's ban — nothing reinserts these, not even replays or backfills. 302 + if (std.mem.eql(u8, did, "did:plc:oql6ds5vnff4ugar6rruliwd")) { 303 + logfire.span("tap.dropped", .{ .reason = "banned_did", .uri = uri }).end(); 304 + return; 305 + } 292 306 293 307 // dedupe: if (did, rkey) exists with different uri, clean up old record first 294 308 if (c.query("SELECT uri FROM publications WHERE did = ? AND rkey = ?", &.{ did, rkey })) |result_val| {
+1
scripts/offline-replica-catchup
··· 73 73 client, 74 74 token, 75 75 f"SELECT {COLS} FROM documents WHERE (indexed_at, uri) > (?, ?) " 76 + "AND did != 'did:plc:oql6ds5vnff4ugar6rruliwd' " 76 77 "ORDER BY indexed_at, uri LIMIT ?", 77 78 [cursor_at, cursor_uri, PAGE], 78 79 )