authorgravatar for 4678790+dweiller@users.noreply.github.comDominic <4678790+dweiller@users.noreply.github.com> 2023-02-03 15:35:30+11:00
committergravatar for 4678790+dweiller@users.noreply.github.comDominic <4678790+dweiller@users.noreply.github.com> 2023-02-20 09:09:06+11:00
log1c509f483aef8b826f02ffc7ab8d1f2cfcec0d36
tree697a1d231ef9bc57444ce84f35035ffa8800b094
parent596a97fb556a380d9f3780363ee07fc5dfaf43c2

std.compress.zstandard: fix crashes


2 files changed, 10 insertions(+), 6 deletions(-)

lib/std/compress/zstandard/decode/block.zig+2
...@@ -981,6 +981,8 @@ fn decodeStreams(size_format: u2, stream_data: []const u8) !LiteralsSection.Stre...@@ -981,6 +981,8 @@ fn decodeStreams(size_format: u2, stream_data: []const u8) !LiteralsSection.Stre
981 const stream_3_start = stream_2_start + stream_2_length;981 const stream_3_start = stream_2_start + stream_2_length;
982 const stream_4_start = stream_3_start + stream_3_length;982 const stream_4_start = stream_3_start + stream_3_length;
983983
984 if (stream_data.len < stream_4_start) return error.MalformedLiteralsSection;
985
984 return .{ .four = .{986 return .{ .four = .{
985 stream_data[stream_1_start .. stream_1_start + stream_1_length],987 stream_data[stream_1_start .. stream_1_start + stream_1_length],
986 stream_data[stream_2_start .. stream_2_start + stream_2_length],988 stream_data[stream_2_start .. stream_2_start + stream_2_length],
lib/std/compress/zstandard/decode/huffman.zig+8-6
...@@ -59,7 +59,7 @@ fn assignWeights(huff_bits: *readers.ReverseBitReader, accuracy_log: usize, entr...@@ -59,7 +59,7 @@ fn assignWeights(huff_bits: *readers.ReverseBitReader, accuracy_log: usize, entr
59 var even_state: u32 = huff_bits.readBitsNoEof(u32, accuracy_log) catch return error.MalformedHuffmanTree;59 var even_state: u32 = huff_bits.readBitsNoEof(u32, accuracy_log) catch return error.MalformedHuffmanTree;
60 var odd_state: u32 = huff_bits.readBitsNoEof(u32, accuracy_log) catch return error.MalformedHuffmanTree;60 var odd_state: u32 = huff_bits.readBitsNoEof(u32, accuracy_log) catch return error.MalformedHuffmanTree;
6161
62 while (i < 255) {62 while (i < 254) {
63 const even_data = entries[even_state];63 const even_data = entries[even_state];
64 var read_bits: usize = 0;64 var read_bits: usize = 0;
65 const even_bits = huff_bits.readBits(u32, even_data.bits, &read_bits) catch unreachable;65 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...@@ -78,7 +78,7 @@ fn assignWeights(huff_bits: *readers.ReverseBitReader, accuracy_log: usize, entr
78 weights[i] = std.math.cast(u4, odd_data.symbol) orelse return error.MalformedHuffmanTree;78 weights[i] = std.math.cast(u4, odd_data.symbol) orelse return error.MalformedHuffmanTree;
79 i += 1;79 i += 1;
80 if (read_bits < odd_data.bits) {80 if (read_bits < odd_data.bits) {
81 if (i == 256) return error.MalformedHuffmanTree;81 if (i == 255) return error.MalformedHuffmanTree;
82 weights[i] = std.math.cast(u4, entries[even_state].symbol) orelse return error.MalformedHuffmanTree;82 weights[i] = std.math.cast(u4, entries[even_state].symbol) orelse return error.MalformedHuffmanTree;
83 i += 1;83 i += 1;
84 break;84 break;
...@@ -147,16 +147,18 @@ fn assignSymbols(weight_sorted_prefixed_symbols: []LiteralsSection.HuffmanTree.P...@@ -147,16 +147,18 @@ fn assignSymbols(weight_sorted_prefixed_symbols: []LiteralsSection.HuffmanTree.P
147}147}
148148
149fn buildHuffmanTree(weights: *[256]u4, symbol_count: usize) error{MalformedHuffmanTree}!LiteralsSection.HuffmanTree {149fn 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;
151 for (weights[0 .. symbol_count - 1]) |value| {151 for (weights[0 .. symbol_count - 1]) |value| {
152 if (value > 0) {152 if (value > 0) {
153 weight_power_sum += @as(u16, 1) << (value - 1);153 weight_power_sum_big += @as(u16, 1) << (value - 1);
154 }154 }
155 }155 }
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
158 // advance to next power of two (even if weight_power_sum is a power of 2)159 // 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;
160 const next_power_of_two = @as(u16, 1) << max_number_of_bits;162 const next_power_of_two = @as(u16, 1) << max_number_of_bits;
161 weights[symbol_count - 1] = std.math.log2_int(u16, next_power_of_two - weight_power_sum) + 1;163 weights[symbol_count - 1] = std.math.log2_int(u16, next_power_of_two - weight_power_sum) + 1;
162164