diff --git a/src/browser/ScriptManager.zig b/src/browser/ScriptManager.zig index facd86a6..e13ccbbf 100644 --- a/src/browser/ScriptManager.zig +++ b/src/browser/ScriptManager.zig @@ -480,7 +480,14 @@ const PendingScript = struct { // will fail. This assertion exists to catch incorrect assumptions about // how libcurl works, or about how we've configured it. std.debug.assert(self.script.source.remote.capacity == 0); - self.script.source = .{ .remote = self.manager.buffer_pool.get() }; + var buffer = self.manager.buffer_pool.get(); + if (transfer.getContentLength()) |cl| { + if (cl > 100 * 1024 * 1024) { + return error.ResponseTooLarge; + } + try buffer.ensureTotalCapacity(self.manager.allocator, cl); + } + self.script.source = .{ .remote = buffer }; } fn dataCallback(self: *PendingScript, transfer: *Http.Transfer, data: []const u8) !void { diff --git a/src/browser/xhr/xhr.zig b/src/browser/xhr/xhr.zig index 76ca98e9..2709f00b 100644 --- a/src/browser/xhr/xhr.zig +++ b/src/browser/xhr/xhr.zig @@ -438,6 +438,13 @@ pub const XMLHttpRequest = struct { self.state = .loading; self.dispatchEvt("readystatechange"); + + if (transfer.getContentLength()) |cl| { + if (cl > 100 * 1024 * 1024) { + return error.ResponseTooLarge; + } + try self.response_bytes.ensureTotalCapacity(self.arena, cl); + } } fn httpDataCallback(transfer: *Http.Transfer, data: []const u8) !void { diff --git a/src/http/Client.zig b/src/http/Client.zig index 02e45207..59625978 100644 --- a/src/http/Client.zig +++ b/src/http/Client.zig @@ -1040,6 +1040,16 @@ pub const Transfer = struct { try req.done_callback(req.ctx); } + + pub fn getContentLength(self: *const Transfer) ?u32 { + // It's possible for this to be null even with correct code, due to + // request fulfillment. If transfer.fulfill is called, we won't have + // a handle. + const handle = self._handle orelse return null; + + const cl = getResponseHeader(handle.conn.easy, "content-length", 0) orelse return null; + return std.fmt.parseInt(u32, cl.value, 10) catch null; + } }; pub const ResponseHeader = struct {