@@ -27,12 +27,11 @@ static const char *zerr_to_string(int status)
27
27
* limits the size of the buffer we can use to 4GB when interacting
28
28
* with zlib in a single call to inflate/deflate.
29
29
*/
30
- #define ZLIB_BUF_MAX ((uInt)-1)
30
+ /* #define ZLIB_BUF_MAX ((uInt)-1) */
31
+ #define ZLIB_BUF_MAX ((uInt) 1024 * 1024 * 1024) /* 1GB */
31
32
static inline uInt zlib_buf_cap (unsigned long len )
32
33
{
33
- if (ZLIB_BUF_MAX < len )
34
- die ("working buffer for zlib too large" );
35
- return len ;
34
+ return (ZLIB_BUF_MAX < len ) ? ZLIB_BUF_MAX : len ;
36
35
}
37
36
38
37
static void zlib_pre_call (git_zstream * s )
@@ -47,12 +46,22 @@ static void zlib_pre_call(git_zstream *s)
47
46
48
47
static void zlib_post_call (git_zstream * s )
49
48
{
49
+ unsigned long bytes_consumed ;
50
+ unsigned long bytes_produced ;
51
+
52
+ bytes_consumed = s -> z .next_in - s -> next_in ;
53
+ bytes_produced = s -> z .next_out - s -> next_out ;
54
+ if (s -> z .total_out != s -> total_out + bytes_produced )
55
+ die ("BUG: total_out mismatch" );
56
+ if (s -> z .total_in != s -> total_in + bytes_consumed )
57
+ die ("BUG: total_in mismatch" );
58
+
59
+ s -> total_out = s -> z .total_out ;
60
+ s -> total_in = s -> z .total_in ;
50
61
s -> next_in = s -> z .next_in ;
51
62
s -> next_out = s -> z .next_out ;
52
- s -> total_in = s -> z .total_in ;
53
- s -> total_out = s -> z .total_out ;
54
- s -> avail_in = s -> z .avail_in ;
55
- s -> avail_out = s -> z .avail_out ;
63
+ s -> avail_in -= bytes_consumed ;
64
+ s -> avail_out -= bytes_produced ;
56
65
}
57
66
58
67
void git_inflate_init (git_zstream * strm )
@@ -103,18 +112,32 @@ int git_inflate(git_zstream *strm, int flush)
103
112
{
104
113
int status ;
105
114
106
- zlib_pre_call (strm );
107
- status = inflate (& strm -> z , flush );
108
- zlib_post_call (strm );
115
+ for (;;) {
116
+ zlib_pre_call (strm );
117
+ /* Never say Z_FINISH unless we are feeding everything */
118
+ status = inflate (& strm -> z ,
119
+ (strm -> z .avail_in != strm -> avail_in )
120
+ ? 0 : flush );
121
+ if (status == Z_MEM_ERROR )
122
+ die ("inflate: out of memory" );
123
+ zlib_post_call (strm );
124
+
125
+ /*
126
+ * Let zlib work another round, while we can still
127
+ * make progress.
128
+ */
129
+ if ((strm -> avail_out && !strm -> z .avail_out ) &&
130
+ (status == Z_OK || status == Z_BUF_ERROR ))
131
+ continue ;
132
+ break ;
133
+ }
134
+
109
135
switch (status ) {
110
136
/* Z_BUF_ERROR: normal, needs more space in the output buffer */
111
137
case Z_BUF_ERROR :
112
138
case Z_OK :
113
139
case Z_STREAM_END :
114
140
return status ;
115
-
116
- case Z_MEM_ERROR :
117
- die ("inflate: out of memory" );
118
141
default :
119
142
break ;
120
143
}
@@ -192,18 +215,33 @@ int git_deflate(git_zstream *strm, int flush)
192
215
{
193
216
int status ;
194
217
195
- zlib_pre_call (strm );
196
- status = deflate (& strm -> z , flush );
197
- zlib_post_call (strm );
218
+ for (;;) {
219
+ zlib_pre_call (strm );
220
+
221
+ /* Never say Z_FINISH unless we are feeding everything */
222
+ status = deflate (& strm -> z ,
223
+ (strm -> z .avail_in != strm -> avail_in )
224
+ ? 0 : flush );
225
+ if (status == Z_MEM_ERROR )
226
+ die ("deflate: out of memory" );
227
+ zlib_post_call (strm );
228
+
229
+ /*
230
+ * Let zlib work another round, while we can still
231
+ * make progress.
232
+ */
233
+ if ((strm -> avail_out && !strm -> z .avail_out ) &&
234
+ (status == Z_OK || status == Z_BUF_ERROR ))
235
+ continue ;
236
+ break ;
237
+ }
238
+
198
239
switch (status ) {
199
240
/* Z_BUF_ERROR: normal, needs more space in the output buffer */
200
241
case Z_BUF_ERROR :
201
242
case Z_OK :
202
243
case Z_STREAM_END :
203
244
return status ;
204
-
205
- case Z_MEM_ERROR :
206
- die ("deflate: out of memory" );
207
245
default :
208
246
break ;
209
247
}
0 commit comments