Skip to content

Commit 141b6b8

Browse files
committed
Merge branch 'lt/maint-wrap-zlib' into maint
* lt/maint-wrap-zlib: Wrap inflate and other zlib routines for better error reporting Conflicts: http-push.c http-walker.c sha1_file.c
2 parents cc91e1b + 39c6854 commit 141b6b8

File tree

9 files changed

+99
-34
lines changed

9 files changed

+99
-34
lines changed

builtin-apply.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1253,8 +1253,9 @@ static char *inflate_it(const void *data, unsigned long size,
12531253
stream.avail_in = size;
12541254
stream.next_out = out = xmalloc(inflated_size);
12551255
stream.avail_out = inflated_size;
1256-
inflateInit(&stream);
1257-
st = inflate(&stream, Z_FINISH);
1256+
git_inflate_init(&stream);
1257+
st = git_inflate(&stream, Z_FINISH);
1258+
git_inflate_end(&stream);
12581259
if ((st != Z_STREAM_END) || stream.total_out != inflated_size) {
12591260
free(out);
12601261
return NULL;

builtin-pack-objects.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -195,16 +195,16 @@ static int check_pack_inflate(struct packed_git *p,
195195
int st;
196196

197197
memset(&stream, 0, sizeof(stream));
198-
inflateInit(&stream);
198+
git_inflate_init(&stream);
199199
do {
200200
in = use_pack(p, w_curs, offset, &stream.avail_in);
201201
stream.next_in = in;
202202
stream.next_out = fakebuf;
203203
stream.avail_out = sizeof(fakebuf);
204-
st = inflate(&stream, Z_FINISH);
204+
st = git_inflate(&stream, Z_FINISH);
205205
offset += stream.next_in - in;
206206
} while (st == Z_OK || st == Z_BUF_ERROR);
207-
inflateEnd(&stream);
207+
git_inflate_end(&stream);
208208
return (st == Z_STREAM_END &&
209209
stream.total_out == expect &&
210210
stream.total_in == len) ? 0 : -1;

builtin-unpack-objects.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,10 @@ static void *get_data(unsigned long size)
9999
stream.avail_out = size;
100100
stream.next_in = fill(1);
101101
stream.avail_in = len;
102-
inflateInit(&stream);
102+
git_inflate_init(&stream);
103103

104104
for (;;) {
105-
int ret = inflate(&stream, 0);
105+
int ret = git_inflate(&stream, 0);
106106
use(len - stream.avail_in);
107107
if (stream.total_out == size && ret == Z_STREAM_END)
108108
break;
@@ -118,7 +118,7 @@ static void *get_data(unsigned long size)
118118
stream.next_in = fill(1);
119119
stream.avail_in = len;
120120
}
121-
inflateEnd(&stream);
121+
git_inflate_end(&stream);
122122
return buf;
123123
}
124124

cache.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@
1818
#define deflateBound(c,s) ((s) + (((s) + 7) >> 3) + (((s) + 63) >> 6) + 11)
1919
#endif
2020

21+
void git_inflate_init(z_streamp strm);
22+
void git_inflate_end(z_streamp strm);
23+
int git_inflate(z_streamp strm, int flush);
24+
2125
#if defined(DT_UNKNOWN) && !defined(NO_D_TYPE_IN_DIRENT)
2226
#define DTYPE(de) ((de)->d_type)
2327
#else

http-push.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ static size_t fwrite_sha1_file(void *ptr, size_t eltsize, size_t nmemb,
209209
do {
210210
request->stream.next_out = expn;
211211
request->stream.avail_out = sizeof(expn);
212-
request->zret = inflate(&request->stream, Z_SYNC_FLUSH);
212+
request->zret = git_inflate(&request->stream, Z_SYNC_FLUSH);
213213
git_SHA1_Update(&request->c, expn,
214214
sizeof(expn) - request->stream.avail_out);
215215
} while (request->stream.avail_in && request->zret == Z_OK);
@@ -269,7 +269,7 @@ static void start_fetch_loose(struct transfer_request *request)
269269

270270
memset(&request->stream, 0, sizeof(request->stream));
271271

272-
inflateInit(&request->stream);
272+
git_inflate_init(&request->stream);
273273

274274
git_SHA1_Init(&request->c);
275275

@@ -310,7 +310,7 @@ static void start_fetch_loose(struct transfer_request *request)
310310
file; also rewind to the beginning of the local file. */
311311
if (prev_read == -1) {
312312
memset(&request->stream, 0, sizeof(request->stream));
313-
inflateInit(&request->stream);
313+
git_inflate_init(&request->stream);
314314
git_SHA1_Init(&request->c);
315315
if (prev_posn>0) {
316316
prev_posn = 0;
@@ -742,7 +742,7 @@ static void finish_request(struct transfer_request *request)
742742
if (request->http_code == 416)
743743
fprintf(stderr, "Warning: requested range invalid; we may already have all the data.\n");
744744

745-
inflateEnd(&request->stream);
745+
git_inflate_end(&request->stream);
746746
git_SHA1_Final(request->real_sha1, &request->c);
747747
if (request->zret != Z_STREAM_END) {
748748
unlink(request->tmpfile);

http-walker.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ static size_t fwrite_sha1_file(void *ptr, size_t eltsize, size_t nmemb,
8282
do {
8383
obj_req->stream.next_out = expn;
8484
obj_req->stream.avail_out = sizeof(expn);
85-
obj_req->zret = inflate(&obj_req->stream, Z_SYNC_FLUSH);
85+
obj_req->zret = git_inflate(&obj_req->stream, Z_SYNC_FLUSH);
8686
git_SHA1_Update(&obj_req->c, expn,
8787
sizeof(expn) - obj_req->stream.avail_out);
8888
} while (obj_req->stream.avail_in && obj_req->zret == Z_OK);
@@ -142,7 +142,7 @@ static void start_object_request(struct walker *walker,
142142

143143
memset(&obj_req->stream, 0, sizeof(obj_req->stream));
144144

145-
inflateInit(&obj_req->stream);
145+
git_inflate_init(&obj_req->stream);
146146

147147
git_SHA1_Init(&obj_req->c);
148148

@@ -183,7 +183,7 @@ static void start_object_request(struct walker *walker,
183183
file; also rewind to the beginning of the local file. */
184184
if (prev_read == -1) {
185185
memset(&obj_req->stream, 0, sizeof(obj_req->stream));
186-
inflateInit(&obj_req->stream);
186+
git_inflate_init(&obj_req->stream);
187187
git_SHA1_Init(&obj_req->c);
188188
if (prev_posn>0) {
189189
prev_posn = 0;
@@ -243,7 +243,7 @@ static void finish_object_request(struct object_request *obj_req)
243243
return;
244244
}
245245

246-
inflateEnd(&obj_req->stream);
246+
git_inflate_end(&obj_req->stream);
247247
git_SHA1_Final(obj_req->real_sha1, &obj_req->c);
248248
if (obj_req->zret != Z_STREAM_END) {
249249
unlink(obj_req->tmpfile);

index-pack.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -275,10 +275,10 @@ static void *unpack_entry_data(unsigned long offset, unsigned long size)
275275
stream.avail_out = size;
276276
stream.next_in = fill(1);
277277
stream.avail_in = input_len;
278-
inflateInit(&stream);
278+
git_inflate_init(&stream);
279279

280280
for (;;) {
281-
int ret = inflate(&stream, 0);
281+
int ret = git_inflate(&stream, 0);
282282
use(input_len - stream.avail_in);
283283
if (stream.total_out == size && ret == Z_STREAM_END)
284284
break;
@@ -287,7 +287,7 @@ static void *unpack_entry_data(unsigned long offset, unsigned long size)
287287
stream.next_in = fill(1);
288288
stream.avail_in = input_len;
289289
}
290-
inflateEnd(&stream);
290+
git_inflate_end(&stream);
291291
return buf;
292292
}
293293

@@ -382,9 +382,9 @@ static void *get_data_from_pack(struct object_entry *obj)
382382
stream.avail_out = obj->size;
383383
stream.next_in = src;
384384
stream.avail_in = len;
385-
inflateInit(&stream);
386-
while ((st = inflate(&stream, Z_FINISH)) == Z_OK);
387-
inflateEnd(&stream);
385+
git_inflate_init(&stream);
386+
while ((st = git_inflate(&stream, Z_FINISH)) == Z_OK);
387+
git_inflate_end(&stream);
388388
if (st != Z_STREAM_END || stream.total_out != obj->size)
389389
die("serious inflate inconsistency");
390390
free(src);

sha1_file.c

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1196,8 +1196,8 @@ static int unpack_sha1_header(z_stream *stream, unsigned char *map, unsigned lon
11961196
stream->avail_out = bufsiz;
11971197

11981198
if (legacy_loose_object(map)) {
1199-
inflateInit(stream);
1200-
return inflate(stream, 0);
1199+
git_inflate_init(stream);
1200+
return git_inflate(stream, 0);
12011201
}
12021202

12031203

@@ -1217,7 +1217,7 @@ static int unpack_sha1_header(z_stream *stream, unsigned char *map, unsigned lon
12171217
/* Set up the stream for the rest.. */
12181218
stream->next_in = map;
12191219
stream->avail_in = mapsize;
1220-
inflateInit(stream);
1220+
git_inflate_init(stream);
12211221

12221222
/* And generate the fake traditional header */
12231223
stream->total_out = 1 + snprintf(buffer, bufsiz, "%s %lu",
@@ -1254,11 +1254,11 @@ static void *unpack_sha1_rest(z_stream *stream, void *buffer, unsigned long size
12541254
stream->next_out = buf + bytes;
12551255
stream->avail_out = size - bytes;
12561256
while (status == Z_OK)
1257-
status = inflate(stream, Z_FINISH);
1257+
status = git_inflate(stream, Z_FINISH);
12581258
}
12591259
buf[size] = 0;
12601260
if (status == Z_STREAM_END && !stream->avail_in) {
1261-
inflateEnd(stream);
1261+
git_inflate_end(stream);
12621262
return buf;
12631263
}
12641264

@@ -1348,15 +1348,15 @@ unsigned long get_size_from_delta(struct packed_git *p,
13481348
stream.next_out = delta_head;
13491349
stream.avail_out = sizeof(delta_head);
13501350

1351-
inflateInit(&stream);
1351+
git_inflate_init(&stream);
13521352
do {
13531353
in = use_pack(p, w_curs, curpos, &stream.avail_in);
13541354
stream.next_in = in;
1355-
st = inflate(&stream, Z_FINISH);
1355+
st = git_inflate(&stream, Z_FINISH);
13561356
curpos += stream.next_in - in;
13571357
} while ((st == Z_OK || st == Z_BUF_ERROR) &&
13581358
stream.total_out < sizeof(delta_head));
1359-
inflateEnd(&stream);
1359+
git_inflate_end(&stream);
13601360
if ((st != Z_STREAM_END) && stream.total_out != sizeof(delta_head)) {
13611361
error("delta data unpack-initial failed");
13621362
return 0;
@@ -1585,14 +1585,14 @@ static void *unpack_compressed_entry(struct packed_git *p,
15851585
stream.next_out = buffer;
15861586
stream.avail_out = size;
15871587

1588-
inflateInit(&stream);
1588+
git_inflate_init(&stream);
15891589
do {
15901590
in = use_pack(p, w_curs, curpos, &stream.avail_in);
15911591
stream.next_in = in;
1592-
st = inflate(&stream, Z_FINISH);
1592+
st = git_inflate(&stream, Z_FINISH);
15931593
curpos += stream.next_in - in;
15941594
} while (st == Z_OK || st == Z_BUF_ERROR);
1595-
inflateEnd(&stream);
1595+
git_inflate_end(&stream);
15961596
if ((st != Z_STREAM_END) || stream.total_out != size) {
15971597
free(buffer);
15981598
return NULL;
@@ -2017,7 +2017,7 @@ static int sha1_loose_object_info(const unsigned char *sha1, unsigned long *size
20172017
status = error("unable to parse %s header", sha1_to_hex(sha1));
20182018
else if (sizep)
20192019
*sizep = size;
2020-
inflateEnd(&stream);
2020+
git_inflate_end(&stream);
20212021
munmap(map, mapsize);
20222022
return status;
20232023
}

wrapper.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,3 +196,63 @@ int xmkstemp(char *template)
196196
die("Unable to create temporary file: %s", strerror(errno));
197197
return fd;
198198
}
199+
200+
/*
201+
* zlib wrappers to make sure we don't silently miss errors
202+
* at init time.
203+
*/
204+
void git_inflate_init(z_streamp strm)
205+
{
206+
const char *err;
207+
208+
switch (inflateInit(strm)) {
209+
case Z_OK:
210+
return;
211+
212+
case Z_MEM_ERROR:
213+
err = "out of memory";
214+
break;
215+
case Z_VERSION_ERROR:
216+
err = "wrong version";
217+
break;
218+
default:
219+
err = "error";
220+
}
221+
die("inflateInit: %s (%s)", err, strm->msg ? strm->msg : "no message");
222+
}
223+
224+
void git_inflate_end(z_streamp strm)
225+
{
226+
if (inflateEnd(strm) != Z_OK)
227+
error("inflateEnd: %s", strm->msg ? strm->msg : "failed");
228+
}
229+
230+
int git_inflate(z_streamp strm, int flush)
231+
{
232+
int ret = inflate(strm, flush);
233+
const char *err;
234+
235+
switch (ret) {
236+
/* Out of memory is fatal. */
237+
case Z_MEM_ERROR:
238+
die("inflate: out of memory");
239+
240+
/* Data corruption errors: we may want to recover from them (fsck) */
241+
case Z_NEED_DICT:
242+
err = "needs dictionary"; break;
243+
case Z_DATA_ERROR:
244+
err = "data stream error"; break;
245+
case Z_STREAM_ERROR:
246+
err = "stream consistency error"; break;
247+
default:
248+
err = "unknown error"; break;
249+
250+
/* Z_BUF_ERROR: normal, needs more space in the output buffer */
251+
case Z_BUF_ERROR:
252+
case Z_OK:
253+
case Z_STREAM_END:
254+
return ret;
255+
}
256+
error("inflate: %s (%s)", err, strm->msg ? strm->msg : "no message");
257+
return ret;
258+
}

0 commit comments

Comments
 (0)