summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/odb_loose.c109
1 files changed, 24 insertions, 85 deletions
diff --git a/src/odb_loose.c b/src/odb_loose.c
index 156586fc2..f01debf62 100644
--- a/src/odb_loose.c
+++ b/src/odb_loose.c
@@ -131,7 +131,10 @@ static int parse_header_packlike(
}
out->size = size;
- *out_len = used;
+
+ if (out_len)
+ *out_len = used;
+
return 0;
on_error:
@@ -192,67 +195,6 @@ on_error:
return -1;
}
-/***********************************************************
- *
- * ZLIB RELATED FUNCTIONS
- *
- ***********************************************************/
-
-static void init_stream(z_stream *s, void *out, size_t len)
-{
- memset(s, 0, sizeof(*s));
- s->next_out = out;
- s->avail_out = (uInt)len;
-}
-
-static void set_stream_input(z_stream *s, void *in, size_t len)
-{
- s->next_in = in;
- s->avail_in = (uInt)len;
-}
-
-static void set_stream_output(z_stream *s, void *out, size_t len)
-{
- s->next_out = out;
- s->avail_out = (uInt)len;
-}
-
-
-static int start_inflate(z_stream *s, git_buf *obj, void *out, size_t len)
-{
- int status;
-
- init_stream(s, out, len);
- set_stream_input(s, obj->ptr, git_buf_len(obj));
-
- if ((status = inflateInit(s)) < Z_OK)
- return status;
-
- return inflate(s, 0);
-}
-
-static void abort_inflate(z_stream *s)
-{
- inflateEnd(s);
-}
-
-static int finish_inflate(z_stream *s)
-{
- int status = Z_OK;
-
- while (status == Z_OK)
- status = inflate(s, Z_FINISH);
-
- inflateEnd(s);
-
- if ((status != Z_STREAM_END) || (s->avail_in != 0)) {
- giterr_set(GITERR_ZLIB, "failed to finish zlib inflation; stream aborted prematurely");
- return -1;
- }
-
- return 0;
-}
-
static int is_zlib_compressed_data(unsigned char *data)
{
unsigned int w;
@@ -423,12 +365,11 @@ done:
static int read_header_loose(git_rawobj *out, git_buf *loc)
{
- int error = 0, z_return = Z_ERRNO, read_bytes;
- git_file fd;
- z_stream zs;
- obj_hdr header_obj;
- size_t header_len;
- unsigned char raw_buffer[16], inflated_buffer[HEADER_LEN];
+ git_zstream zs = GIT_ZSTREAM_INIT;
+ unsigned char obj[1024], inflated[HEADER_LEN];
+ size_t inflated_len, header_len;
+ obj_hdr hdr;
+ int fd, obj_len, error;
assert(out && loc);
@@ -440,30 +381,28 @@ static int read_header_loose(git_rawobj *out, git_buf *loc)
if ((fd = git_futils_open_ro(loc->ptr)) < 0)
return fd;
- init_stream(&zs, inflated_buffer, sizeof(inflated_buffer));
+ if ((error = obj_len = p_read(fd, obj, sizeof(obj))) < 0)
+ goto done;
- z_return = inflateInit(&zs);
+ inflated_len = sizeof(inflated);
- while (z_return == Z_OK) {
- if ((read_bytes = p_read(fd, raw_buffer, sizeof(raw_buffer))) > 0) {
- set_stream_input(&zs, raw_buffer, read_bytes);
- z_return = inflate(&zs, 0);
- } else
- z_return = Z_STREAM_END;
- }
+ if ((error = git_zstream_init(&zs, GIT_ZSTREAM_INFLATE)) < 0 ||
+ (error = git_zstream_set_input(&zs, obj, obj_len)) < 0 ||
+ (error = git_zstream_get_output_chunk(inflated, &inflated_len, &zs)) < 0 ||
+ (error = parse_header(&hdr, &header_len, inflated, inflated_len)) < 0)
+ goto done;
- if ((z_return != Z_STREAM_END && z_return != Z_BUF_ERROR)
- || parse_header(&header_obj, &header_len, inflated_buffer, sizeof(inflated_buffer)) < 0
- || git_object_typeisloose(header_obj.type) == 0)
- {
+ if (!git_object_typeisloose(hdr.type)) {
giterr_set(GITERR_ZLIB, "failed to read loose object header");
error = -1;
- } else {
- out->len = header_obj.size;
- out->type = header_obj.type;
+ goto done;
}
- finish_inflate(&zs);
+ out->len = hdr.size;
+ out->type = hdr.type;
+
+done:
+ git_zstream_free(&zs);
p_close(fd);
return error;