diff --git a/lib/std/crypto/tls/Client.zig b/lib/std/crypto/tls/Client.zig index 9ab9197dc8..260441295d 100644 --- a/lib/std/crypto/tls/Client.zig +++ b/lib/std/crypto/tls/Client.zig @@ -725,8 +725,11 @@ pub fn writeAll(c: *Client, stream: net.Stream, bytes: []const u8) !void { /// Returns number of bytes that have been read, which are now populated inside /// `buffer`. A return value of zero bytes does not necessarily mean end of -/// stream. +/// stream. Instead, the `eof` flag is set upon end of stream. The `eof` flag +/// may be set after any call to `read`, including when greater than zero bytes +/// are returned, and this function asserts that `eof` is `false`. pub fn read(c: *Client, stream: net.Stream, buffer: []u8) !usize { + assert(!c.eof); const prev_len = c.partially_read_len; var in_buf: [max_ciphertext_len * 4]u8 = undefined; mem.copy(u8, &in_buf, c.partially_read_buffer[0..prev_len]); @@ -738,8 +741,8 @@ pub fn read(c: *Client, stream: net.Stream, buffer: []u8) !usize { const actual_read_len = try stream.read(ask_slice); const frag = in_buf[0 .. prev_len + actual_read_len]; if (frag.len == 0) { - c.eof = true; - return 0; + // This is either a truncation attack, or a bug in the server. + return error.TlsConnectionTruncated; } var in: usize = 0; var out: usize = 0; diff --git a/lib/std/http/Client.zig b/lib/std/http/Client.zig index 4e5bd3da0c..f1f61cae0c 100644 --- a/lib/std/http/Client.zig +++ b/lib/std/http/Client.zig @@ -66,13 +66,11 @@ pub const Request = struct { var index: usize = 0; while (index < len) { const amt = try req.read(buffer[index..]); - if (amt == 0) { - switch (req.protocol) { - .http => break, - .https => if (req.tls_client.eof) break, - } - } index += amt; + switch (req.protocol) { + .http => if (amt == 0) break, + .https => if (req.tls_client.eof) break, + } } return index; }