Merge branch 'lt/maint-wrap-zlib'

* lt/maint-wrap-zlib:
  Wrap inflate and other zlib routines for better error reporting

Conflicts:
	http-push.c
	http-walker.c
	sha1_file.c
This commit is contained in:
Junio C Hamano 2009-01-21 16:55:17 -08:00
Родитель 664a3348b2 39c68542fc
Коммит 36dd939393
9 изменённых файлов: 99 добавлений и 34 удалений

Просмотреть файл

@ -1258,8 +1258,9 @@ static char *inflate_it(const void *data, unsigned long size,
stream.avail_in = size;
stream.next_out = out = xmalloc(inflated_size);
stream.avail_out = inflated_size;
inflateInit(&stream);
st = inflate(&stream, Z_FINISH);
git_inflate_init(&stream);
st = git_inflate(&stream, Z_FINISH);
git_inflate_end(&stream);
if ((st != Z_STREAM_END) || stream.total_out != inflated_size) {
free(out);
return NULL;

Просмотреть файл

@ -195,16 +195,16 @@ static int check_pack_inflate(struct packed_git *p,
int st;
memset(&stream, 0, sizeof(stream));
inflateInit(&stream);
git_inflate_init(&stream);
do {
in = use_pack(p, w_curs, offset, &stream.avail_in);
stream.next_in = in;
stream.next_out = fakebuf;
stream.avail_out = sizeof(fakebuf);
st = inflate(&stream, Z_FINISH);
st = git_inflate(&stream, Z_FINISH);
offset += stream.next_in - in;
} while (st == Z_OK || st == Z_BUF_ERROR);
inflateEnd(&stream);
git_inflate_end(&stream);
return (st == Z_STREAM_END &&
stream.total_out == expect &&
stream.total_in == len) ? 0 : -1;

Просмотреть файл

@ -99,10 +99,10 @@ static void *get_data(unsigned long size)
stream.avail_out = size;
stream.next_in = fill(1);
stream.avail_in = len;
inflateInit(&stream);
git_inflate_init(&stream);
for (;;) {
int ret = inflate(&stream, 0);
int ret = git_inflate(&stream, 0);
use(len - stream.avail_in);
if (stream.total_out == size && ret == Z_STREAM_END)
break;
@ -118,7 +118,7 @@ static void *get_data(unsigned long size)
stream.next_in = fill(1);
stream.avail_in = len;
}
inflateEnd(&stream);
git_inflate_end(&stream);
return buf;
}

Просмотреть файл

@ -18,6 +18,10 @@
#define deflateBound(c,s) ((s) + (((s) + 7) >> 3) + (((s) + 63) >> 6) + 11)
#endif
void git_inflate_init(z_streamp strm);
void git_inflate_end(z_streamp strm);
int git_inflate(z_streamp strm, int flush);
#if defined(DT_UNKNOWN) && !defined(NO_D_TYPE_IN_DIRENT)
#define DTYPE(de) ((de)->d_type)
#else

Просмотреть файл

@ -209,7 +209,7 @@ static size_t fwrite_sha1_file(void *ptr, size_t eltsize, size_t nmemb,
do {
request->stream.next_out = expn;
request->stream.avail_out = sizeof(expn);
request->zret = inflate(&request->stream, Z_SYNC_FLUSH);
request->zret = git_inflate(&request->stream, Z_SYNC_FLUSH);
git_SHA1_Update(&request->c, expn,
sizeof(expn) - request->stream.avail_out);
} while (request->stream.avail_in && request->zret == Z_OK);
@ -269,7 +269,7 @@ static void start_fetch_loose(struct transfer_request *request)
memset(&request->stream, 0, sizeof(request->stream));
inflateInit(&request->stream);
git_inflate_init(&request->stream);
git_SHA1_Init(&request->c);
@ -310,7 +310,7 @@ static void start_fetch_loose(struct transfer_request *request)
file; also rewind to the beginning of the local file. */
if (prev_read == -1) {
memset(&request->stream, 0, sizeof(request->stream));
inflateInit(&request->stream);
git_inflate_init(&request->stream);
git_SHA1_Init(&request->c);
if (prev_posn>0) {
prev_posn = 0;
@ -742,7 +742,7 @@ static void finish_request(struct transfer_request *request)
if (request->http_code == 416)
fprintf(stderr, "Warning: requested range invalid; we may already have all the data.\n");
inflateEnd(&request->stream);
git_inflate_end(&request->stream);
git_SHA1_Final(request->real_sha1, &request->c);
if (request->zret != Z_STREAM_END) {
unlink(request->tmpfile);

Просмотреть файл

@ -82,7 +82,7 @@ static size_t fwrite_sha1_file(void *ptr, size_t eltsize, size_t nmemb,
do {
obj_req->stream.next_out = expn;
obj_req->stream.avail_out = sizeof(expn);
obj_req->zret = inflate(&obj_req->stream, Z_SYNC_FLUSH);
obj_req->zret = git_inflate(&obj_req->stream, Z_SYNC_FLUSH);
git_SHA1_Update(&obj_req->c, expn,
sizeof(expn) - obj_req->stream.avail_out);
} while (obj_req->stream.avail_in && obj_req->zret == Z_OK);
@ -142,7 +142,7 @@ static void start_object_request(struct walker *walker,
memset(&obj_req->stream, 0, sizeof(obj_req->stream));
inflateInit(&obj_req->stream);
git_inflate_init(&obj_req->stream);
git_SHA1_Init(&obj_req->c);
@ -183,7 +183,7 @@ static void start_object_request(struct walker *walker,
file; also rewind to the beginning of the local file. */
if (prev_read == -1) {
memset(&obj_req->stream, 0, sizeof(obj_req->stream));
inflateInit(&obj_req->stream);
git_inflate_init(&obj_req->stream);
git_SHA1_Init(&obj_req->c);
if (prev_posn>0) {
prev_posn = 0;
@ -243,7 +243,7 @@ static void finish_object_request(struct object_request *obj_req)
return;
}
inflateEnd(&obj_req->stream);
git_inflate_end(&obj_req->stream);
git_SHA1_Final(obj_req->real_sha1, &obj_req->c);
if (obj_req->zret != Z_STREAM_END) {
unlink(obj_req->tmpfile);

Просмотреть файл

@ -275,10 +275,10 @@ static void *unpack_entry_data(unsigned long offset, unsigned long size)
stream.avail_out = size;
stream.next_in = fill(1);
stream.avail_in = input_len;
inflateInit(&stream);
git_inflate_init(&stream);
for (;;) {
int ret = inflate(&stream, 0);
int ret = git_inflate(&stream, 0);
use(input_len - stream.avail_in);
if (stream.total_out == size && ret == Z_STREAM_END)
break;
@ -287,7 +287,7 @@ static void *unpack_entry_data(unsigned long offset, unsigned long size)
stream.next_in = fill(1);
stream.avail_in = input_len;
}
inflateEnd(&stream);
git_inflate_end(&stream);
return buf;
}
@ -382,9 +382,9 @@ static void *get_data_from_pack(struct object_entry *obj)
stream.avail_out = obj->size;
stream.next_in = src;
stream.avail_in = len;
inflateInit(&stream);
while ((st = inflate(&stream, Z_FINISH)) == Z_OK);
inflateEnd(&stream);
git_inflate_init(&stream);
while ((st = git_inflate(&stream, Z_FINISH)) == Z_OK);
git_inflate_end(&stream);
if (st != Z_STREAM_END || stream.total_out != obj->size)
die("serious inflate inconsistency");
free(src);

Просмотреть файл

@ -1196,8 +1196,8 @@ static int unpack_sha1_header(z_stream *stream, unsigned char *map, unsigned lon
stream->avail_out = bufsiz;
if (legacy_loose_object(map)) {
inflateInit(stream);
return inflate(stream, 0);
git_inflate_init(stream);
return git_inflate(stream, 0);
}
@ -1217,7 +1217,7 @@ static int unpack_sha1_header(z_stream *stream, unsigned char *map, unsigned lon
/* Set up the stream for the rest.. */
stream->next_in = map;
stream->avail_in = mapsize;
inflateInit(stream);
git_inflate_init(stream);
/* And generate the fake traditional header */
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
stream->next_out = buf + bytes;
stream->avail_out = size - bytes;
while (status == Z_OK)
status = inflate(stream, Z_FINISH);
status = git_inflate(stream, Z_FINISH);
}
buf[size] = 0;
if (status == Z_STREAM_END && !stream->avail_in) {
inflateEnd(stream);
git_inflate_end(stream);
return buf;
}
@ -1348,15 +1348,15 @@ unsigned long get_size_from_delta(struct packed_git *p,
stream.next_out = delta_head;
stream.avail_out = sizeof(delta_head);
inflateInit(&stream);
git_inflate_init(&stream);
do {
in = use_pack(p, w_curs, curpos, &stream.avail_in);
stream.next_in = in;
st = inflate(&stream, Z_FINISH);
st = git_inflate(&stream, Z_FINISH);
curpos += stream.next_in - in;
} while ((st == Z_OK || st == Z_BUF_ERROR) &&
stream.total_out < sizeof(delta_head));
inflateEnd(&stream);
git_inflate_end(&stream);
if ((st != Z_STREAM_END) && stream.total_out != sizeof(delta_head)) {
error("delta data unpack-initial failed");
return 0;
@ -1585,14 +1585,14 @@ static void *unpack_compressed_entry(struct packed_git *p,
stream.next_out = buffer;
stream.avail_out = size;
inflateInit(&stream);
git_inflate_init(&stream);
do {
in = use_pack(p, w_curs, curpos, &stream.avail_in);
stream.next_in = in;
st = inflate(&stream, Z_FINISH);
st = git_inflate(&stream, Z_FINISH);
curpos += stream.next_in - in;
} while (st == Z_OK || st == Z_BUF_ERROR);
inflateEnd(&stream);
git_inflate_end(&stream);
if ((st != Z_STREAM_END) || stream.total_out != size) {
free(buffer);
return NULL;
@ -2020,7 +2020,7 @@ static int sha1_loose_object_info(const unsigned char *sha1, unsigned long *size
status = error("unable to parse %s header", sha1_to_hex(sha1));
else if (sizep)
*sizep = size;
inflateEnd(&stream);
git_inflate_end(&stream);
munmap(map, mapsize);
return status;
}

Просмотреть файл

@ -196,3 +196,63 @@ int xmkstemp(char *template)
die("Unable to create temporary file: %s", strerror(errno));
return fd;
}
/*
* zlib wrappers to make sure we don't silently miss errors
* at init time.
*/
void git_inflate_init(z_streamp strm)
{
const char *err;
switch (inflateInit(strm)) {
case Z_OK:
return;
case Z_MEM_ERROR:
err = "out of memory";
break;
case Z_VERSION_ERROR:
err = "wrong version";
break;
default:
err = "error";
}
die("inflateInit: %s (%s)", err, strm->msg ? strm->msg : "no message");
}
void git_inflate_end(z_streamp strm)
{
if (inflateEnd(strm) != Z_OK)
error("inflateEnd: %s", strm->msg ? strm->msg : "failed");
}
int git_inflate(z_streamp strm, int flush)
{
int ret = inflate(strm, flush);
const char *err;
switch (ret) {
/* Out of memory is fatal. */
case Z_MEM_ERROR:
die("inflate: out of memory");
/* Data corruption errors: we may want to recover from them (fsck) */
case Z_NEED_DICT:
err = "needs dictionary"; break;
case Z_DATA_ERROR:
err = "data stream error"; break;
case Z_STREAM_ERROR:
err = "stream consistency error"; break;
default:
err = "unknown error"; break;
/* Z_BUF_ERROR: normal, needs more space in the output buffer */
case Z_BUF_ERROR:
case Z_OK:
case Z_STREAM_END:
return ret;
}
error("inflate: %s (%s)", err, strm->msg ? strm->msg : "no message");
return ret;
}