]>
git.ipfire.org Git - thirdparty/git.git/blob - zlib.c
2 * zlib wrappers to make sure we don't silently miss errors
7 static const char *zerr_to_string(int status
)
11 return "out of memory";
13 return "wrong version";
15 return "needs dictionary";
17 return "data stream error";
19 return "stream consistency error";
21 return "unknown error";
26 * avail_in and avail_out in zlib are counted in uInt, which typically
27 * limits the size of the buffer we can use to 4GB when interacting
28 * with zlib in a single call to inflate/deflate.
30 /* #define ZLIB_BUF_MAX ((uInt)-1) */
31 #define ZLIB_BUF_MAX ((uInt) 1024 * 1024 * 1024) /* 1GB */
32 static inline uInt
zlib_buf_cap(unsigned long len
)
34 return (ZLIB_BUF_MAX
< len
) ? ZLIB_BUF_MAX
: len
;
37 static void zlib_pre_call(git_zstream
*s
)
39 s
->z
.next_in
= s
->next_in
;
40 s
->z
.next_out
= s
->next_out
;
41 s
->z
.total_in
= s
->total_in
;
42 s
->z
.total_out
= s
->total_out
;
43 s
->z
.avail_in
= zlib_buf_cap(s
->avail_in
);
44 s
->z
.avail_out
= zlib_buf_cap(s
->avail_out
);
47 static void zlib_post_call(git_zstream
*s
)
49 unsigned long bytes_consumed
;
50 unsigned long bytes_produced
;
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 BUG("total_out mismatch");
56 if (s
->z
.total_in
!= s
->total_in
+ bytes_consumed
)
57 BUG("total_in mismatch");
59 s
->total_out
= s
->z
.total_out
;
60 s
->total_in
= s
->z
.total_in
;
61 s
->next_in
= s
->z
.next_in
;
62 s
->next_out
= s
->z
.next_out
;
63 s
->avail_in
-= bytes_consumed
;
64 s
->avail_out
-= bytes_produced
;
67 void git_inflate_init(git_zstream
*strm
)
72 status
= inflateInit(&strm
->z
);
76 die("inflateInit: %s (%s)", zerr_to_string(status
),
77 strm
->z
.msg
? strm
->z
.msg
: "no message");
80 void git_inflate_init_gzip_only(git_zstream
*strm
)
83 * Use default 15 bits, +16 is to accept only gzip and to
84 * yield Z_DATA_ERROR when fed zlib format.
86 const int windowBits
= 15 + 16;
90 status
= inflateInit2(&strm
->z
, windowBits
);
94 die("inflateInit2: %s (%s)", zerr_to_string(status
),
95 strm
->z
.msg
? strm
->z
.msg
: "no message");
98 void git_inflate_end(git_zstream
*strm
)
103 status
= inflateEnd(&strm
->z
);
104 zlib_post_call(strm
);
107 error("inflateEnd: %s (%s)", zerr_to_string(status
),
108 strm
->z
.msg
? strm
->z
.msg
: "no message");
111 int git_inflate(git_zstream
*strm
, int flush
)
117 /* Never say Z_FINISH unless we are feeding everything */
118 status
= inflate(&strm
->z
,
119 (strm
->z
.avail_in
!= strm
->avail_in
)
121 if (status
== Z_MEM_ERROR
)
122 die("inflate: out of memory");
123 zlib_post_call(strm
);
126 * Let zlib work another round, while we can still
129 if ((strm
->avail_out
&& !strm
->z
.avail_out
) &&
130 (status
== Z_OK
|| status
== Z_BUF_ERROR
))
136 /* Z_BUF_ERROR: normal, needs more space in the output buffer */
144 error("inflate: %s (%s)", zerr_to_string(status
),
145 strm
->z
.msg
? strm
->z
.msg
: "no message");
149 #if defined(NO_DEFLATE_BOUND) || ZLIB_VERNUM < 0x1200
150 #define deflateBound(c,s) ((s) + (((s) + 7) >> 3) + (((s) + 63) >> 6) + 11)
153 unsigned long git_deflate_bound(git_zstream
*strm
, unsigned long size
)
155 return deflateBound(&strm
->z
, size
);
158 void git_deflate_init(git_zstream
*strm
, int level
)
162 memset(strm
, 0, sizeof(*strm
));
164 status
= deflateInit(&strm
->z
, level
);
165 zlib_post_call(strm
);
168 die("deflateInit: %s (%s)", zerr_to_string(status
),
169 strm
->z
.msg
? strm
->z
.msg
: "no message");
172 static void do_git_deflate_init(git_zstream
*strm
, int level
, int windowBits
)
176 memset(strm
, 0, sizeof(*strm
));
178 status
= deflateInit2(&strm
->z
, level
,
179 Z_DEFLATED
, windowBits
,
180 8, Z_DEFAULT_STRATEGY
);
181 zlib_post_call(strm
);
184 die("deflateInit2: %s (%s)", zerr_to_string(status
),
185 strm
->z
.msg
? strm
->z
.msg
: "no message");
188 void git_deflate_init_gzip(git_zstream
*strm
, int level
)
191 * Use default 15 bits, +16 is to generate gzip header/trailer
192 * instead of the zlib wrapper.
194 do_git_deflate_init(strm
, level
, 15 + 16);
197 void git_deflate_init_raw(git_zstream
*strm
, int level
)
200 * Use default 15 bits, negate the value to get raw compressed
201 * data without zlib header and trailer.
203 do_git_deflate_init(strm
, level
, -15);
206 int git_deflate_abort(git_zstream
*strm
)
211 status
= deflateEnd(&strm
->z
);
212 zlib_post_call(strm
);
216 void git_deflate_end(git_zstream
*strm
)
218 int status
= git_deflate_abort(strm
);
222 error("deflateEnd: %s (%s)", zerr_to_string(status
),
223 strm
->z
.msg
? strm
->z
.msg
: "no message");
226 int git_deflate_end_gently(git_zstream
*strm
)
231 status
= deflateEnd(&strm
->z
);
232 zlib_post_call(strm
);
236 int git_deflate(git_zstream
*strm
, int flush
)
243 /* Never say Z_FINISH unless we are feeding everything */
244 status
= deflate(&strm
->z
,
245 (strm
->z
.avail_in
!= strm
->avail_in
)
247 if (status
== Z_MEM_ERROR
)
248 die("deflate: out of memory");
249 zlib_post_call(strm
);
252 * Let zlib work another round, while we can still
255 if ((strm
->avail_out
&& !strm
->z
.avail_out
) &&
256 (status
== Z_OK
|| status
== Z_BUF_ERROR
))
262 /* Z_BUF_ERROR: normal, needs more space in the output buffer */
270 error("deflate: %s (%s)", zerr_to_string(status
),
271 strm
->z
.msg
? strm
->z
.msg
: "no message");