Commit 1118ba3e by Edward Thomson

odb_loose: `read_header` for packlike loose objects

Support `read_header` for "packlike loose objects", which were a
temporarily and uncommonly used format loose object format that encodes
the header before the zlib deflate data.

This will never actually be seen in the wild, but add support for it for
completeness and (more importantly) because our corpus of test data has
objects in this format, so it's easier to support it than to try to
special case it.
parent 4c7a16b7
...@@ -363,12 +363,48 @@ done: ...@@ -363,12 +363,48 @@ done:
return error; return error;
} }
static int read_header_loose(git_rawobj *out, git_buf *loc) static int read_header_loose_packlike(
git_rawobj *out, const unsigned char *data, size_t len)
{
obj_hdr hdr;
size_t header_len;
int error;
if ((error = parse_header_packlike(&hdr, &header_len, data, len)) < 0)
return error;
out->len = hdr.size;
out->type = hdr.type;
return error;
}
static int read_header_loose_standard(
git_rawobj *out, const unsigned char *data, size_t len)
{ {
git_zstream zs = GIT_ZSTREAM_INIT; git_zstream zs = GIT_ZSTREAM_INIT;
unsigned char obj[1024], inflated[HEADER_LEN];
size_t inflated_len, header_len;
obj_hdr hdr; obj_hdr hdr;
unsigned char inflated[HEADER_LEN];
size_t header_len, inflated_len = sizeof(inflated);
int error;
if ((error = git_zstream_init(&zs, GIT_ZSTREAM_INFLATE)) < 0 ||
(error = git_zstream_set_input(&zs, data, 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;
out->len = hdr.size;
out->type = hdr.type;
done:
git_zstream_free(&zs);
return error;
}
static int read_header_loose(git_rawobj *out, git_buf *loc)
{
unsigned char obj[1024];
int fd, obj_len, error; int fd, obj_len, error;
assert(out && loc); assert(out && loc);
...@@ -378,33 +414,23 @@ static int read_header_loose(git_rawobj *out, git_buf *loc) ...@@ -378,33 +414,23 @@ static int read_header_loose(git_rawobj *out, git_buf *loc)
out->data = NULL; out->data = NULL;
if ((fd = git_futils_open_ro(loc->ptr)) < 0) if ((error = fd = git_futils_open_ro(loc->ptr)) < 0 ||
return fd; (error = obj_len = p_read(fd, obj, sizeof(obj))) < 0)
if ((error = obj_len = p_read(fd, obj, sizeof(obj))) < 0)
goto done; goto done;
inflated_len = sizeof(inflated); if (!is_zlib_compressed_data(obj))
error = read_header_loose_packlike(out, obj, (size_t)obj_len);
if ((error = git_zstream_init(&zs, GIT_ZSTREAM_INFLATE)) < 0 || else
(error = git_zstream_set_input(&zs, obj, obj_len)) < 0 || error = read_header_loose_standard(out, obj, (size_t)obj_len);
(error = git_zstream_get_output_chunk(inflated, &inflated_len, &zs)) < 0 ||
(error = parse_header(&hdr, &header_len, inflated, inflated_len)) < 0)
goto done;
if (!git_object_typeisloose(hdr.type)) { if (!error && !git_object_typeisloose(out->type)) {
giterr_set(GITERR_ZLIB, "failed to read loose object header"); giterr_set(GITERR_ZLIB, "failed to read loose object header");
error = -1; error = -1;
goto done; goto done;
} }
out->len = hdr.size;
out->type = hdr.type;
done: done:
git_zstream_free(&zs);
p_close(fd); p_close(fd);
return error; return error;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment