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…
	
	Add table
		Add a link
		
	
		Reference in a new issue