Skip to content

Commit 7b02f2d

Browse files
committed
rewrite zlib decompression loop (#1656)
1 parent 46b9b94 commit 7b02f2d

File tree

1 file changed

+23
-13
lines changed

1 file changed

+23
-13
lines changed

libheif/compression_zlib.cc

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -91,17 +91,17 @@ Result<std::vector<uint8_t>> do_inflate(const std::vector<uint8_t>& compressed_i
9191

9292
// decompress data with zlib
9393

94-
const int outBufferSize = 8192;
95-
uint8_t dst[outBufferSize];
94+
std::vector<uint8_t> dst;
95+
dst.resize(8192);
9696

9797
z_stream strm;
9898
memset(&strm, 0, sizeof(z_stream));
9999

100100
strm.avail_in = (int)compressed_input.size();
101101
strm.next_in = (Bytef*) compressed_input.data();
102102

103-
strm.avail_out = outBufferSize;
104-
strm.next_out = (Bytef*) dst;
103+
strm.avail_out = (uInt)dst.size();
104+
strm.next_out = (Bytef*) dst.data();
105105

106106
strm.zalloc = Z_NULL;
107107
strm.zfree = Z_NULL;
@@ -117,23 +117,33 @@ Result<std::vector<uint8_t>> do_inflate(const std::vector<uint8_t>& compressed_i
117117
}
118118

119119
do {
120-
strm.next_out = dst;
121-
strm.avail_out = outBufferSize;
122-
123-
err = inflate(&strm, Z_FINISH);
124-
if (err == Z_BUF_ERROR || err == Z_OK) {
125-
// this is the usual case when we run out of buffer space
126-
// -> do nothing
120+
strm.avail_out = (uInt)dst.size();
121+
strm.next_out = (Bytef*) dst.data();
122+
123+
err = inflate(&strm, Z_NO_FLUSH);
124+
125+
if (err == Z_BUF_ERROR) {
126+
if (dst.size() >= 65536) { // TODO: make this a security limit
127+
std::stringstream sstr;
128+
sstr << "Error performing zlib inflate: maximum output buffer size exceeded\n";
129+
return Error(heif_error_Memory_allocation_error, heif_suberror_Compression_initialisation_error, sstr.str());
130+
}
131+
132+
dst.resize(dst.size() * 2);
133+
strm.next_out = dst.data();
134+
strm.avail_out = (uInt)dst.size();
135+
continue;
127136
}
128-
else if (err == Z_NEED_DICT || err == Z_DATA_ERROR || err == Z_STREAM_ERROR) {
137+
138+
if (err == Z_NEED_DICT || err == Z_DATA_ERROR || err == Z_STREAM_ERROR) {
129139
inflateEnd(&strm);
130140
std::stringstream sstr;
131141
sstr << "Error performing zlib inflate: " << (strm.msg ? strm.msg : "NULL") << " (" << err << ")\n";
132142
return Error(heif_error_Invalid_input, heif_suberror_Decompression_invalid_data, sstr.str());
133143
}
134144

135145
// append decoded data to output
136-
output.insert(output.end(), dst, dst + outBufferSize - strm.avail_out);
146+
output.insert(output.end(), dst.begin(), dst.end() - strm.avail_out);
137147
} while (err != Z_STREAM_END);
138148

139149

0 commit comments

Comments
 (0)