Skip to content

Commit 4bef593

Browse files
authored
Merge pull request #208 from gHashTag/feat/issue-205
fix(mcp): memory leak — WebSocket frame payload not freed in handleConnection loop
2 parents 344cd03 + 32e06d5 commit 4bef593

1 file changed

Lines changed: 7 additions & 0 deletions

File tree

tools/mcp/trinity_mcp/websocket_transport.zig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ pub const Frame = struct {
3131
fin: bool,
3232
opcode: Opcode,
3333
payload: []const u8,
34+
/// True if payload was allocated and must be freed by caller
35+
allocated: bool,
3436
};
3537

3638
/// WebSocket Server for MCP protocol
@@ -131,6 +133,8 @@ pub const WebSocketServer = struct {
131133
std.log.err("Frame parse error: {}", .{err});
132134
continue;
133135
};
136+
// Free allocated payload after processing (prevents memory leak on masked frames)
137+
defer if (frame.allocated) self.allocator.free(frame.payload);
134138

135139
// Handle different opcodes
136140
switch (frame.opcode) {
@@ -246,18 +250,21 @@ pub const WebSocketServer = struct {
246250

247251
// Unmask payload if needed
248252
var payload: []const u8 = payload_data;
253+
var allocated = false;
249254
if (masked) {
250255
const unmasked = try self.allocator.alloc(u8, payload_len);
251256
for (0..payload_len) |i| {
252257
unmasked[i] = payload_data[i] ^ masking_key[i % 4];
253258
}
254259
payload = unmasked;
260+
allocated = true;
255261
}
256262

257263
return Frame{
258264
.fin = fin,
259265
.opcode = opcode,
260266
.payload = payload,
267+
.allocated = allocated,
261268
};
262269
}
263270

0 commit comments

Comments
 (0)