Fix bzip2 compression of files > 4 GiB
Bzip2's 'avail_in' parameter is declared as an unsigned int, so assigning a size_t length to it led to silent truncation. Fixes #2111.
This commit is contained in:
parent
3560654e6a
commit
4a2c948943
1 changed files with 14 additions and 3 deletions
|
@ -368,8 +368,21 @@ struct BzipSink : CompressionSink
|
||||||
}
|
}
|
||||||
|
|
||||||
void write(const unsigned char * data, size_t len) override
|
void write(const unsigned char * data, size_t len) override
|
||||||
|
{
|
||||||
|
/* Bzip2's 'avail_in' parameter is an unsigned int, so we need
|
||||||
|
to split the input into chunks of at most 4 GiB. */
|
||||||
|
while (len) {
|
||||||
|
auto n = std::min((size_t) std::numeric_limits<decltype(strm.avail_in)>::max(), len);
|
||||||
|
writeInternal(data, n);
|
||||||
|
data += n;
|
||||||
|
len -= n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeInternal(const unsigned char * data, size_t len)
|
||||||
{
|
{
|
||||||
assert(!finished);
|
assert(!finished);
|
||||||
|
assert(len <= std::numeric_limits<decltype(strm.avail_in)>::max());
|
||||||
|
|
||||||
strm.next_in = (char *) data;
|
strm.next_in = (char *) data;
|
||||||
strm.avail_in = len;
|
strm.avail_in = len;
|
||||||
|
@ -475,8 +488,6 @@ struct BrotliSink : CompressionSink
|
||||||
|
|
||||||
void write(const unsigned char * data, size_t len) override
|
void write(const unsigned char * data, size_t len) override
|
||||||
{
|
{
|
||||||
assert(!finished);
|
|
||||||
|
|
||||||
// Don't feed brotli too much at once
|
// Don't feed brotli too much at once
|
||||||
const size_t CHUNK_SIZE = sizeof(outbuf) << 2;
|
const size_t CHUNK_SIZE = sizeof(outbuf) << 2;
|
||||||
while (len) {
|
while (len) {
|
||||||
|
@ -486,7 +497,7 @@ struct BrotliSink : CompressionSink
|
||||||
len -= n;
|
len -= n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private:
|
|
||||||
void writeInternal(const unsigned char * data, size_t len)
|
void writeInternal(const unsigned char * data, size_t len)
|
||||||
{
|
{
|
||||||
assert(!finished);
|
assert(!finished);
|
||||||
|
|
Loading…
Reference in a new issue