Skip to content

Commit 5d1cb88

Browse files
author
dweiller
committed
std.compress.zstandard: fix crashes
1 parent d914563 commit 5d1cb88

File tree

2 files changed

+10
-6
lines changed

2 files changed

+10
-6
lines changed

lib/std/compress/zstandard/decode/block.zig

+2
Original file line numberDiff line numberDiff line change
@@ -981,6 +981,8 @@ fn decodeStreams(size_format: u2, stream_data: []const u8) !LiteralsSection.Stre
981981
const stream_3_start = stream_2_start + stream_2_length;
982982
const stream_4_start = stream_3_start + stream_3_length;
983983

984+
if (stream_data.len < stream_4_start) return error.MalformedLiteralsSection;
985+
984986
return .{ .four = .{
985987
stream_data[stream_1_start .. stream_1_start + stream_1_length],
986988
stream_data[stream_2_start .. stream_2_start + stream_2_length],

lib/std/compress/zstandard/decode/huffman.zig

+8-6
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ fn assignWeights(huff_bits: *readers.ReverseBitReader, accuracy_log: usize, entr
5959
var even_state: u32 = huff_bits.readBitsNoEof(u32, accuracy_log) catch return error.MalformedHuffmanTree;
6060
var odd_state: u32 = huff_bits.readBitsNoEof(u32, accuracy_log) catch return error.MalformedHuffmanTree;
6161

62-
while (i < 255) {
62+
while (i < 254) {
6363
const even_data = entries[even_state];
6464
var read_bits: usize = 0;
6565
const even_bits = huff_bits.readBits(u32, even_data.bits, &read_bits) catch unreachable;
@@ -78,7 +78,7 @@ fn assignWeights(huff_bits: *readers.ReverseBitReader, accuracy_log: usize, entr
7878
weights[i] = std.math.cast(u4, odd_data.symbol) orelse return error.MalformedHuffmanTree;
7979
i += 1;
8080
if (read_bits < odd_data.bits) {
81-
if (i == 256) return error.MalformedHuffmanTree;
81+
if (i == 255) return error.MalformedHuffmanTree;
8282
weights[i] = std.math.cast(u4, entries[even_state].symbol) orelse return error.MalformedHuffmanTree;
8383
i += 1;
8484
break;
@@ -147,16 +147,18 @@ fn assignSymbols(weight_sorted_prefixed_symbols: []LiteralsSection.HuffmanTree.P
147147
}
148148

149149
fn buildHuffmanTree(weights: *[256]u4, symbol_count: usize) error{MalformedHuffmanTree}!LiteralsSection.HuffmanTree {
150-
var weight_power_sum: u16 = 0;
150+
var weight_power_sum_big: u32 = 0;
151151
for (weights[0 .. symbol_count - 1]) |value| {
152152
if (value > 0) {
153-
weight_power_sum += @as(u16, 1) << (value - 1);
153+
weight_power_sum_big += @as(u16, 1) << (value - 1);
154154
}
155155
}
156-
if (weight_power_sum >= 1 << 11) return error.MalformedHuffmanTree;
156+
if (weight_power_sum_big >= 1 << 11) return error.MalformedHuffmanTree;
157+
const weight_power_sum = @intCast(u16, weight_power_sum_big);
157158

158159
// advance to next power of two (even if weight_power_sum is a power of 2)
159-
const max_number_of_bits = std.math.log2_int(u16, weight_power_sum) + 1;
160+
// TODO: is it valid to have weight_power_sum == 0?
161+
const max_number_of_bits = if (weight_power_sum == 0) 1 else std.math.log2_int(u16, weight_power_sum) + 1;
160162
const next_power_of_two = @as(u16, 1) << max_number_of_bits;
161163
weights[symbol_count - 1] = std.math.log2_int(u16, next_power_of_two - weight_power_sum) + 1;
162164

0 commit comments

Comments
 (0)