atproto utils for zig zat.dev
atproto sdk zig

fix memory leak in HttpTransport.fetch() — toArrayList() transferred buffer ownership without freeing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

+17 -3
+16
src/internal/identity/did_resolver.zig
··· 128 128 try std.testing.expect(doc.handle() != null); 129 129 } 130 130 131 + test "resolve did:plc - leak check (no arena)" { 132 + // repro for memory leak report: use testing.allocator directly 133 + // (no arena) to see if std.http.Client leaks on deinit 134 + var resolver = DidResolver.init(std.testing.allocator); 135 + defer resolver.deinit(); 136 + 137 + const did = Did.parse("did:plc:z72i7hdynmk6r22z27h6tvur").?; 138 + var doc = resolver.resolve(did) catch |err| { 139 + std.debug.print("network error (expected in CI): {}\n", .{err}); 140 + return; 141 + }; 142 + defer doc.deinit(); 143 + 144 + try std.testing.expectEqualStrings("did:plc:z72i7hdynmk6r22z27h6tvur", doc.id); 145 + } 146 + 131 147 test "did:web url construction" { 132 148 // test url building without network 133 149 var resolver = DidResolver.init(std.testing.allocator);
+1 -3
src/internal/xrpc/transport.zig
··· 84 84 .keep_alive = self.keep_alive, 85 85 }) catch return error.RequestFailed; 86 86 87 - const body = aw.toArrayList().items; 88 - 89 87 return .{ 90 88 .status = result.status, 91 - .body = try self.allocator.dupe(u8, body), 89 + .body = try self.allocator.dupe(u8, aw.written()), 92 90 }; 93 91 } 94 92