commit - c65fcef2fb5ed060705587a71de3fc3eff245082
commit + ac544f8c6ffbe7126fa9ae6c7dd09c6661d1ef2d
blob - 14bd628bae7ca8d8048fca27f37f546c5aca6701
blob + 628c56137d7ed88aea67d80ba7b95c6be67bdecf
--- lib/got_lib_object.h
+++ lib/got_lib_object.h
struct got_blob_object {
FILE *f;
+ uint8_t *data;
struct got_zstream_buf zb;
size_t hdrlen;
size_t blocksize;
blob - 63c033d6f774a39c9e2058276608a89c1daa1342
blob + 827635172297ba1c08d85c6c7e6d1ce7a2fcc7bb
--- lib/got_lib_pack.h
+++ lib/got_lib_pack.h
const struct got_error *got_packfile_open_object(struct got_object **,
struct got_pack *, struct got_packidx *, int, struct got_object_id *);
+const struct got_error *got_pack_get_object_size(uint64_t *,
+ struct got_object *);
const struct got_error *got_packfile_extract_object(struct got_pack *,
struct got_object *, FILE *, FILE *, FILE *);
const struct got_error *got_packfile_extract_object_to_mem(uint8_t **, size_t *,
blob - 265fdf3b2b2444e83f6f86acd875fa01bb1da614
blob + 9d915bb9d69bfcf9dac03d5d3595636bfecfebec
--- lib/got_lib_privsep.h
+++ lib/got_lib_privsep.h
struct got_imsg_blob {
size_t size;
size_t hdrlen;
+
+ /*
+ * If size <= GOT_PRIVSEP_INLINE_BLOB_DATA_MAX, blob data follows
+ * in the imsg buffer. Otherwise, blob data has been written to a
+ * file descriptor passed via the GOT_IMSG_BLOB_OUTFD imsg.
+ */
+#define GOT_PRIVSEP_INLINE_BLOB_DATA_MAX \
+ (MAX_IMSGSIZE - IMSG_HEADER_SIZE - sizeof(struct got_imsg_blob))
};
+
/* Structure for GOT_IMSG_TAG data. */
struct got_imsg_tag_object {
uint8_t id[SHA1_DIGEST_LENGTH];
struct imsgbuf *);
const struct got_error *got_privsep_send_tree(struct imsgbuf *,
struct got_tree_object *);
-const struct got_error *got_privsep_send_blob(struct imsgbuf *, size_t, size_t);
-const struct got_error *got_privsep_recv_blob(size_t *, size_t *,
+const struct got_error *got_privsep_send_blob(struct imsgbuf *, size_t, size_t,
+ const uint8_t *);
+const struct got_error *got_privsep_recv_blob(uint8_t **, size_t *, size_t *,
struct imsgbuf *);
const struct got_error *got_privsep_send_tag(struct imsgbuf *,
struct got_tag_object *);
blob - daab8a5a6c149bb4f48f9aa3f6c7e0b89d1bb1cb
blob + 2e2c89ad38123377ed31f13eb51696332766d8dd
--- lib/object.c
+++ lib/object.c
}
static const struct got_error *
-request_packed_blob(size_t *size, size_t *hdrlen, int outfd,
+request_packed_blob(uint8_t **outbuf, size_t *size, size_t *hdrlen, int outfd,
struct got_pack *pack, struct got_packidx *packidx, int idx,
struct got_object_id *id)
{
return err;
}
- err = got_privsep_recv_blob(size, hdrlen,
+ err = got_privsep_recv_blob(outbuf, size, hdrlen,
pack->privsep_child->ibuf);
if (err)
return err;
}
static const struct got_error *
-read_packed_blob_privsep(size_t *size, size_t *hdrlen, int outfd,
- struct got_pack *pack, struct got_packidx *packidx, int idx,
+read_packed_blob_privsep(uint8_t **outbuf, size_t *size, size_t *hdrlen,
+ int outfd, struct got_pack *pack, struct got_packidx *packidx, int idx,
struct got_object_id *id)
{
const struct got_error *err = NULL;
return err;
}
- return request_packed_blob(size, hdrlen, outfd, pack, packidx, idx, id);
+ return request_packed_blob(outbuf, size, hdrlen, outfd, pack, packidx,
+ idx, id);
}
static const struct got_error *
-request_blob(size_t *size, size_t *hdrlen, int outfd, int infd,
- struct imsgbuf *ibuf)
+request_blob(uint8_t **outbuf, size_t *size, size_t *hdrlen, int outfd,
+ int infd, struct imsgbuf *ibuf)
{
const struct got_error *err = NULL;
int outfd_child;
return err;
}
- err = got_privsep_recv_blob(size, hdrlen, ibuf);
+ err = got_privsep_recv_blob(outbuf, size, hdrlen, ibuf);
if (err)
return err;
}
static const struct got_error *
-read_blob_privsep(size_t *size, size_t *hdrlen,
+read_blob_privsep(uint8_t **outbuf, size_t *size, size_t *hdrlen,
int outfd, int infd, struct got_repository *repo)
{
int imsg_fds[2];
if (repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_BLOB].imsg_fd != -1) {
ibuf = repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_BLOB].ibuf;
- return request_blob(size, hdrlen, outfd, infd, ibuf);
+ return request_blob(outbuf, size, hdrlen, outfd, infd, ibuf);
}
ibuf = calloc(1, sizeof(*ibuf));
imsg_init(ibuf, imsg_fds[0]);
repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_BLOB].ibuf = ibuf;
- return request_blob(size, hdrlen, outfd, infd, ibuf);
+ return request_blob(outbuf, size, hdrlen, outfd, infd, ibuf);
}
static const struct got_error *
struct got_packidx *packidx = NULL;
int idx;
char *path_packfile;
+ uint8_t *outbuf;
int outfd;
size_t size, hdrlen;
struct stat sb;
if (err)
goto done;
}
- err = read_packed_blob_privsep(&size, &hdrlen, outfd, pack,
- packidx, idx, id);
+ err = read_packed_blob_privsep(&outbuf, &size, &hdrlen, outfd,
+ pack, packidx, idx, id);
} else if (err->code == GOT_ERR_NO_OBJ) {
int infd;
err = open_loose_object(&infd, id, repo);
if (err)
goto done;
- err = read_blob_privsep(&size, &hdrlen, outfd, infd, repo);
+ err = read_blob_privsep(&outbuf, &size, &hdrlen, outfd, infd,
+ repo);
close(infd);
}
if (err)
- goto done;
-
- if (fstat(outfd, &sb) == -1) {
- err = got_error_from_errno();
- goto done;
- }
-
- if (sb.st_size != size) {
- err = got_error(GOT_ERR_PRIVSEP_LEN);
goto done;
- }
if (hdrlen > size) {
err = got_error(GOT_ERR_BAD_OBJ_HDR);
goto done;
}
- (*blob)->f = fdopen(outfd, "rb");
- if ((*blob)->f == NULL) {
- err = got_error_from_errno();
+ if (outbuf) {
close(outfd);
- goto done;
+ outfd = -1;
+ (*blob)->f = fmemopen(outbuf, size, "rb");
+ if ((*blob)->f == NULL) {
+ err = got_error_from_errno();
+ free(outbuf);
+ goto done;
+ }
+ (*blob)->data = outbuf;
+ } else {
+ if (fstat(outfd, &sb) == -1) {
+ err = got_error_from_errno();
+ goto done;
+ }
+
+ if (sb.st_size != size) {
+ err = got_error(GOT_ERR_PRIVSEP_LEN);
+ goto done;
+ }
+
+ (*blob)->f = fdopen(outfd, "rb");
+ if ((*blob)->f == NULL) {
+ err = got_error_from_errno();
+ close(outfd);
+ outfd = -1;
+ goto done;
+ }
}
(*blob)->hdrlen = hdrlen;
if ((*blob)->f)
fclose((*blob)->f);
free((*blob)->read_buf);
+ free((*blob)->data);
free(*blob);
*blob = NULL;
} else if (outfd != -1)
{
free(blob->read_buf);
fclose(blob->f);
+ free(blob->data);
free(blob);
}
blob - 73190458ebaf7433d7caacf33a385c026139d5dd
blob + 9a2d1c22cb22cb80e0474babc8eb35cd717132e2
--- lib/pack.c
+++ lib/pack.c
}
return NULL;
+}
+
+const struct got_error *
+got_pack_get_object_size(uint64_t *size, struct got_object *obj)
+{
+ return get_delta_chain_max_size(size, &obj->deltas);
}
static const struct got_error *
blob - 923a10bad969053dcbbfd987f29c08ae6547123e
blob + 2f9a594c755105e26826e0f439de56d36ce7923f
--- lib/privsep.c
+++ lib/privsep.c
}
const struct got_error *
-got_privsep_send_blob(struct imsgbuf *ibuf, size_t size, size_t hdrlen)
+got_privsep_send_blob(struct imsgbuf *ibuf, size_t size, size_t hdrlen,
+ const uint8_t *data)
{
struct got_imsg_blob iblob;
iblob.size = size;
iblob.hdrlen = hdrlen;
- /* Data has already been written to file descriptor. */
- if (imsg_compose(ibuf, GOT_IMSG_BLOB, 0, 0, -1, &iblob, sizeof(iblob))
- == -1)
- return got_error_from_errno();
+ if (data) {
+ uint8_t *buf;
+
+ if (size > GOT_PRIVSEP_INLINE_BLOB_DATA_MAX)
+ return got_error(GOT_ERR_NO_SPACE);
+
+ buf = malloc(sizeof(iblob) + size);
+ if (buf == NULL)
+ return got_error_from_errno();
+ memcpy(buf, &iblob, sizeof(iblob));
+ memcpy(buf + sizeof(iblob), data, size);
+ if (imsg_compose(ibuf, GOT_IMSG_BLOB, 0, 0, -1, buf,
+ sizeof(iblob) + size) == -1) {
+ free(buf);
+ return got_error_from_errno();
+ }
+ free(buf);
+ } else {
+ /* Data has already been written to file descriptor. */
+ if (imsg_compose(ibuf, GOT_IMSG_BLOB, 0, 0, -1, &iblob,
+ sizeof(iblob)) == -1)
+ return got_error_from_errno();
+ }
+
+
return flush_imsg(ibuf);
}
const struct got_error *
-got_privsep_recv_blob(size_t *size, size_t *hdrlen, struct imsgbuf *ibuf)
+got_privsep_recv_blob(uint8_t **outbuf, size_t *size, size_t *hdrlen,
+ struct imsgbuf *ibuf)
{
const struct got_error *err = NULL;
struct imsg imsg;
struct got_imsg_blob *iblob;
size_t datalen;
+ *outbuf = NULL;
+
err = got_privsep_recv_imsg(&imsg, ibuf, 0);
if (err)
return err;
switch (imsg.hdr.type) {
case GOT_IMSG_BLOB:
- if (datalen != sizeof(*iblob)) {
+ if (datalen < sizeof(*iblob)) {
err = got_error(GOT_ERR_PRIVSEP_LEN);
break;
}
iblob = imsg.data;
*size = iblob->size;
*hdrlen = iblob->hdrlen;
- /* Data has been written to file descriptor. */
+
+ if (datalen == sizeof(*iblob)) {
+ /* Data has been written to file descriptor. */
+ break;
+ }
+
+ if (*size > GOT_PRIVSEP_INLINE_BLOB_DATA_MAX) {
+ err = got_error(GOT_ERR_PRIVSEP_LEN);
+ break;
+ }
+
+ *outbuf = malloc(*size);
+ if (*outbuf == NULL) {
+ err = got_error_from_errno();
+ break;
+ }
+ memcpy(*outbuf, imsg.data + sizeof(*iblob), *size);
break;
default:
err = got_error(GOT_ERR_PRIVSEP_MSG);
blob - d795af670c71cbef29833b04357bb80f33c64241
blob + bbb68a823b8ddb245f3587fcb016c803b4c35fa9
--- libexec/got-read-blob/got-read-blob.c
+++ libexec/got-read-blob/got-read-blob.c
FILE *f = NULL;
size_t size;
struct got_object *obj = NULL;
+ uint8_t *buf = NULL;
memset(&imsg, 0, sizeof(imsg));
imsg.fd = -1;
goto done;
}
- err = got_inflate_to_fd(&size, f, imsg_outfd.fd);
- if (err)
- goto done;
+ if (obj->size <= GOT_PRIVSEP_INLINE_BLOB_DATA_MAX) {
+ err = got_inflate_to_mem(&buf, &size, f);
+ if (err)
+ goto done;
+ } else {
+ err = got_inflate_to_fd(&size, f, imsg_outfd.fd);
+ if (err)
+ goto done;
+ }
if (size < obj->hdrlen) {
err = got_error(GOT_ERR_BAD_OBJ_HDR);
goto done;
}
- err = got_privsep_send_blob(&ibuf, size, obj->hdrlen);
+ err = got_privsep_send_blob(&ibuf, size, obj->hdrlen, buf);
done:
if (f)
fclose(f);
blob - eec0b58eb918e3e41527914b3675a5b9a7b62032
blob + 1d422ec4629d227ba9bd55fb9a302f3ac9ef4c27
--- libexec/got-read-pack/got-read-pack.c
+++ libexec/got-read-pack/got-read-pack.c
FILE *outfile = NULL, *basefile = NULL, *accumfile = NULL;
struct got_object_id id;
size_t datalen;
+ uint64_t blob_size;
+ uint8_t *buf = NULL;
datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
if (datalen != sizeof(iobj))
err = receive_file(&outfile, ibuf, GOT_IMSG_BLOB_OUTFD);
if (err)
- return err;
+ goto done;
err = receive_file(&basefile, ibuf, GOT_IMSG_TMPFD);
if (err)
- return err;
+ goto done;
err = receive_file(&accumfile, ibuf, GOT_IMSG_TMPFD);
if (err)
- return err;
+ goto done;
- err = got_packfile_extract_object(pack, obj, outfile, basefile,
- accumfile);
+ if (obj->flags & GOT_OBJ_FLAG_DELTIFIED) {
+ err = got_pack_get_object_size(&blob_size, obj);
+ if (err)
+ goto done;
+ } else
+ blob_size = obj->size;
+
+ if (blob_size <= GOT_PRIVSEP_INLINE_BLOB_DATA_MAX)
+ err = got_packfile_extract_object_to_mem(&buf, &obj->size,
+ obj, pack);
+ else
+ err = got_packfile_extract_object(pack, obj, outfile, basefile,
+ accumfile);
if (err)
goto done;
- err = got_privsep_send_blob(ibuf, obj->size, obj->hdrlen);
+ err = got_privsep_send_blob(ibuf, obj->size, obj->hdrlen, buf);
done:
+ free(buf);
if (outfile)
fclose(outfile);
if (basefile)