authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-28 14:36:26-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-31 22:10:11-07:00
log73e5594c78a66fb943638d99f8540bec0b5ed839
tree3d497ebf7f0781342e35ae12921a3b8a8b7614e5
parent9c8cb777d461406c4185bdb38b9462abde5d5e52

std.compress.flate.Decompress: fix bit read at eof


1 files changed, 52 insertions(+), 3 deletions(-)

lib/std/compress/flate/Decompress.zig+52-3
......@@ -372,7 +372,10 @@ fn takeBits(d: *Decompress, comptime T: type) !T {
372372 };
373373 }
374374 const in = d.input;
375 const next_int = try in.takeInt(usize, .little);
375 const next_int = in.takeInt(usize, .little) catch |err| switch (err) {
376 error.ReadFailed => return error.ReadFailed,
377 error.EndOfStream => return takeBitsEnding(d, T),
378 };
376379 const needed_bits = @bitSizeOf(T) - remaining_bits;
377380 const u: U = @intCast((next_bits << needed_bits) | (next_int & ((@as(usize, 1) << needed_bits) - 1)));
378381 d.next_bits = next_int >> needed_bits;
......@@ -384,6 +387,35 @@ fn takeBits(d: *Decompress, comptime T: type) !T {
384387 };
385388}
386389
390fn takeBitsEnding(d: *Decompress, comptime T: type) !T {
391 const remaining_bits = d.remaining_bits;
392 const next_bits = d.next_bits;
393 const in = d.input;
394 const U = @Type(.{ .int = .{ .signedness = .unsigned, .bits = @bitSizeOf(T) } });
395 var u: U = 0;
396 var remaining_needed_bits = @bitSizeOf(U) - remaining_bits;
397 while (@bitSizeOf(U) >= 8 and remaining_needed_bits >= 8) {
398 const byte = try in.takeByte();
399 u = (u << 8) | byte;
400 remaining_needed_bits -= 8;
401 }
402 if (remaining_needed_bits == 0) {
403 d.next_bits = 0;
404 d.remaining_bits = 0;
405 } else {
406 const byte = try in.takeByte();
407 u = @intCast((@as(usize, u) << remaining_needed_bits) | (byte & ((@as(usize, 1) << remaining_needed_bits) - 1)));
408 d.next_bits = @as(usize, byte) >> remaining_needed_bits;
409 d.remaining_bits = @intCast(8 - remaining_needed_bits);
410 }
411 u = @intCast((@as(usize, u) << remaining_bits) | next_bits);
412 return switch (@typeInfo(T)) {
413 .int => u,
414 .@"enum" => @enumFromInt(u),
415 else => @bitCast(u),
416 };
417}
418
387419fn peekBits(d: *Decompress, comptime T: type) !T {
388420 const U = @Type(.{ .int = .{ .signedness = .unsigned, .bits = @bitSizeOf(T) } });
389421 const remaining_bits = d.remaining_bits;
......@@ -397,7 +429,10 @@ fn peekBits(d: *Decompress, comptime T: type) !T {
397429 };
398430 }
399431 const in = d.input;
400 const next_int = try in.peekInt(usize, .little);
432 const next_int = in.peekInt(usize, .little) catch |err| switch (err) {
433 error.ReadFailed => return error.ReadFailed,
434 error.EndOfStream => return peekBitsEnding(d, T),
435 };
401436 const needed_bits = @bitSizeOf(T) - remaining_bits;
402437 const u: U = @intCast((next_bits << needed_bits) | (next_int & ((@as(usize, 1) << needed_bits) - 1)));
403438 return switch (@typeInfo(T)) {
......@@ -407,6 +442,11 @@ fn peekBits(d: *Decompress, comptime T: type) !T {
407442 };
408443}
409444
445fn peekBitsEnding(d: *Decompress, comptime T: type) !T {
446 _ = d;
447 @panic("TODO");
448}
449
410450fn tossBits(d: *Decompress, n: u6) !void {
411451 const remaining_bits = d.remaining_bits;
412452 const next_bits = d.next_bits;
......@@ -415,13 +455,22 @@ fn tossBits(d: *Decompress, n: u6) !void {
415455 d.remaining_bits = remaining_bits - n;
416456 } else {
417457 const in = d.input;
418 const next_int = try in.takeInt(usize, .little);
458 const next_int = in.takeInt(usize, .little) catch |err| switch (err) {
459 error.ReadFailed => return error.ReadFailed,
460 error.EndOfStream => return tossBitsEnding(d, n),
461 };
419462 const needed_bits = n - remaining_bits;
420463 d.next_bits = next_int >> needed_bits;
421464 d.remaining_bits = @intCast(@bitSizeOf(usize) - @as(usize, needed_bits));
422465 }
423466}
424467
468fn tossBitsEnding(d: *Decompress, n: u6) !void {
469 _ = d;
470 _ = n;
471 @panic("TODO");
472}
473
425474fn takeNBitsBuffered(d: *Decompress, n: u4) !u16 {
426475 _ = d;
427476 _ = n;