diff --git a/src/textfile_gui.cpp b/src/textfile_gui.cpp index 5058def698..a95c15ac48 100644 --- a/src/textfile_gui.cpp +++ b/src/textfile_gui.cpp @@ -654,54 +654,38 @@ void TextfileWindow::ScrollToLine(size_t line) /** * Do an in-memory gunzip operation. This works on a raw deflate stream, * or a file with gzip or zlib header. - * @param bufp A pointer to a buffer containing the input data. This - * buffer will be freed and replaced by a buffer containing - * the uncompressed data. - * @param sizep A pointer to the buffer size. Before the call, the value - * pointed to should contain the size of the input buffer. - * After the call, it contains the size of the uncompressed - * data. + * @param input Buffer containing the input data. + * @return Decompressed buffer. * - * When decompressing fails, *bufp is set to nullptr and *sizep to 0. The - * compressed buffer passed in is still freed in this case. + * When decompressing fails, an empty buffer is returned. */ -static void Gunzip(uint8_t **bufp, size_t *sizep) +static std::vector Gunzip(std::span input) { - static const int BLOCKSIZE = 8192; - uint8_t *buf = nullptr; - size_t alloc_size = 0; - z_stream z; - int res; + static const int BLOCKSIZE = 8192; + std::vector output; + z_stream z; memset(&z, 0, sizeof(z)); - z.next_in = *bufp; - z.avail_in = (uInt)*sizep; + z.next_in = reinterpret_cast(input.data()); + z.avail_in = static_cast(input.size()); /* window size = 15, add 32 to enable gzip or zlib header processing */ - res = inflateInit2(&z, 15 + 32); + int res = inflateInit2(&z, 15 + 32); /* Z_BUF_ERROR just means we need more space */ while (res == Z_OK || (res == Z_BUF_ERROR && z.avail_out == 0)) { /* When we get here, we're either just starting, or * inflate is out of output space - allocate more */ - alloc_size += BLOCKSIZE; z.avail_out += BLOCKSIZE; - buf = ReallocT(buf, alloc_size); - z.next_out = buf + alloc_size - z.avail_out; + output.resize(output.size() + BLOCKSIZE); + z.next_out = reinterpret_cast(&*output.end() - z.avail_out); res = inflate(&z, Z_FINISH); } - free(*bufp); inflateEnd(&z); + if (res != Z_STREAM_END) return {}; - if (res == Z_STREAM_END) { - *bufp = buf; - *sizep = alloc_size - z.avail_out; - } else { - /* Something went wrong */ - *bufp = nullptr; - *sizep = 0; - free(buf); - } + output.resize(output.size() - z.avail_out); + return output; } #endif @@ -710,52 +694,36 @@ static void Gunzip(uint8_t **bufp, size_t *sizep) /** * Do an in-memory xunzip operation. This works on a .xz or (legacy) * .lzma file. - * @param bufp A pointer to a buffer containing the input data. This - * buffer will be freed and replaced by a buffer containing - * the uncompressed data. - * @param sizep A pointer to the buffer size. Before the call, the value - * pointed to should contain the size of the input buffer. - * After the call, it contains the size of the uncompressed - * data. + * @param input Buffer containing the input data. + * @return Decompressed buffer. * - * When decompressing fails, *bufp is set to nullptr and *sizep to 0. The - * compressed buffer passed in is still freed in this case. + * When decompressing fails, an empty buffer is returned. */ -static void Xunzip(uint8_t **bufp, size_t *sizep) +static std::vector Xunzip(std::span input) { - static const int BLOCKSIZE = 8192; - uint8_t *buf = nullptr; - size_t alloc_size = 0; - lzma_stream z = LZMA_STREAM_INIT; - int res; + static const int BLOCKSIZE = 8192; + std::vector output; - z.next_in = *bufp; - z.avail_in = *sizep; + lzma_stream z = LZMA_STREAM_INIT; + z.next_in = reinterpret_cast(input.data()); + z.avail_in = input.size(); - res = lzma_auto_decoder(&z, UINT64_MAX, LZMA_CONCATENATED); + int res = lzma_auto_decoder(&z, UINT64_MAX, LZMA_CONCATENATED); /* Z_BUF_ERROR just means we need more space */ while (res == LZMA_OK || (res == LZMA_BUF_ERROR && z.avail_out == 0)) { /* When we get here, we're either just starting, or * inflate is out of output space - allocate more */ - alloc_size += BLOCKSIZE; z.avail_out += BLOCKSIZE; - buf = ReallocT(buf, alloc_size); - z.next_out = buf + alloc_size - z.avail_out; + output.resize(output.size() + BLOCKSIZE); + z.next_out = reinterpret_cast(&*output.end() - z.avail_out); res = lzma_code(&z, LZMA_FINISH); } - free(*bufp); lzma_end(&z); + if (res != LZMA_STREAM_END) return {}; - if (res == LZMA_STREAM_END) { - *bufp = buf; - *sizep = alloc_size - z.avail_out; - } else { - /* Something went wrong */ - *bufp = nullptr; - *sizep = 0; - free(buf); - } + output.resize(output.size() - z.avail_out); + return output; } #endif @@ -779,28 +747,26 @@ static void Xunzip(uint8_t **bufp, size_t *sizep) /* Early return on empty files. */ if (filesize == 0) return; - char *buf = MallocT(filesize); - size_t read = fread(buf, 1, filesize, handle); + std::vector buf; + buf.resize(filesize); + size_t read = fread(buf.data(), 1, buf.size(), handle); fclose(handle); - if (read != filesize) { - free(buf); - return; - } + if (read != buf.size()) return; #if defined(WITH_ZLIB) /* In-place gunzip */ - if (textfile.ends_with(".gz")) Gunzip((uint8_t**)&buf, &filesize); + if (textfile.ends_with(".gz")) buf = Gunzip(buf); #endif #if defined(WITH_LIBLZMA) /* In-place xunzip */ - if (textfile.ends_with(".xz")) Xunzip((uint8_t**)&buf, &filesize); + if (textfile.ends_with(".xz")) buf = Xunzip(buf); #endif - if (buf == nullptr) return; + if (buf.empty()) return; - std::string_view sv_buf(buf, filesize); + std::string_view sv_buf(buf.data(), buf.size()); /* Check for the byte-order-mark, and skip it if needed. */ if (sv_buf.starts_with("\ufeff")) sv_buf.remove_prefix(3); @@ -813,7 +779,6 @@ static void Xunzip(uint8_t **bufp, size_t *sizep) /* Process the loaded text into lines, and do any further parsing needed. */ this->LoadText(sv_buf); - free(buf); } /**