int git_zstream_deflatebuf(git_buf *out, const void *in, size_t in_len) { git_zstream zs = GIT_ZSTREAM_INIT; int error = 0; if ((error = git_zstream_init(&zs)) < 0) return error; if ((error = git_zstream_set_input(&zs, in, in_len)) < 0) goto done; while (!git_zstream_done(&zs)) { size_t step = git_zstream_suggest_output_len(&zs), written; if ((error = git_buf_grow(out, out->size + step)) < 0) goto done; written = out->asize - out->size; if ((error = git_zstream_get_output( out->ptr + out->size, &written, &zs)) < 0) goto done; out->size += written; } /* NULL terminate for consistency if possible */ if (out->size < out->asize) out->ptr[out->size] = '\0'; done: git_zstream_free(&zs); return error; }
static int loose_backend__readstream_standard( obj_hdr *hdr, loose_readstream *stream) { unsigned char head[MAX_HEADER_LEN]; size_t init, head_len; int error; if ((error = git_zstream_set_input(&stream->zstream, stream->map.data, stream->map.len)) < 0) return error; init = sizeof(head); /* * inflate the initial part of the compressed buffer in order to * parse the header; read the largest header possible, then store * it in the `start` field of the stream object. */ if ((error = git_zstream_get_output(head, &init, &stream->zstream)) < 0 || (error = parse_header(hdr, &head_len, head, init)) < 0) return error; if (!git_object_typeisloose(hdr->type)) { giterr_set(GITERR_ODB, "failed to inflate disk object"); return -1; } if (init > head_len) { stream->start_len = init - head_len; memcpy(stream->start, head + head_len, init - head_len); } return 0; }
static int loose_backend__readstream_packlike( obj_hdr *hdr, loose_readstream *stream) { const unsigned char *data; size_t data_len, head_len; int error; data = stream->map.data; data_len = stream->map.len; /* * read the object header, which is an (uncompressed) * binary encoding of the object type and size. */ if ((error = parse_header_packlike(hdr, &head_len, data, data_len)) < 0) return error; if (!git_object_typeisloose(hdr->type)) { giterr_set(GITERR_ODB, "failed to inflate loose object"); return -1; } return git_zstream_set_input(&stream->zstream, data + head_len, data_len - head_len); }
static int read_header_loose_standard( git_rawobj *out, const unsigned char *data, size_t len) { git_zstream zs = GIT_ZSTREAM_INIT; obj_hdr hdr; unsigned char inflated[MAX_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_loose_standard(git_rawobj *out, git_buf *obj) { git_zstream zstream = GIT_ZSTREAM_INIT; unsigned char head[MAX_HEADER_LEN], *body = NULL; size_t decompressed, head_len, body_len, alloc_size; obj_hdr hdr; int error; if ((error = git_zstream_init(&zstream, GIT_ZSTREAM_INFLATE)) < 0 || (error = git_zstream_set_input(&zstream, git_buf_cstr(obj), git_buf_len(obj))) < 0) goto done; decompressed = sizeof(head); /* * inflate the initial part of the compressed buffer in order to * parse the header; read the largest header possible, then push the * remainder into the body buffer. */ if ((error = git_zstream_get_output(head, &decompressed, &zstream)) < 0 || (error = parse_header(&hdr, &head_len, head, decompressed)) < 0) goto done; if (!git_object_typeisloose(hdr.type)) { giterr_set(GITERR_ODB, "failed to inflate disk object"); error = -1; goto done; } /* * allocate a buffer and inflate the object data into it * (including the initial sequence in the head buffer). */ if (GIT_ADD_SIZET_OVERFLOW(&alloc_size, hdr.size, 1) || (body = git__malloc(alloc_size)) == NULL) { error = -1; goto done; } assert(decompressed >= head_len); body_len = decompressed - head_len; if (body_len) memcpy(body, head + head_len, body_len); decompressed = hdr.size - body_len; if ((error = git_zstream_get_output(body + body_len, &decompressed, &zstream)) < 0) goto done; if (!git_zstream_done(&zstream)) { giterr_set(GITERR_ZLIB, "failed to finish zlib inflation: stream aborted prematurely"); error = -1; goto done; } body[hdr.size] = '\0'; out->data = body; out->len = hdr.size; out->type = hdr.type; done: if (error < 0) git__free(body); git_zstream_free(&zstream); return error; }