Commit a85917112992dbff7d0827f6cf65c6b5a3fb7bd2

Stefan Sperling 2021-06-18T13:52:26

raw object size should not include the length of the object's header This way, the size of a raw object is the same regardless of whether the object was found in a loose object file or in a pack file.

diff --git a/lib/object.c b/lib/object.c
index 52d8dac..7ebffb4 100644
--- a/lib/object.c
+++ b/lib/object.c
@@ -569,11 +569,6 @@ got_object_raw_open(struct got_raw_object **obj, struct got_repository *repo,
 		    repo, fd);
 	}
 
-	if (hdrlen > size) {
-		err = got_error(GOT_ERR_BAD_OBJ_HDR);
-		goto done;
-	}
-
 	*obj = calloc(1, sizeof(**obj));
 	if (*obj == NULL) {
 		err = got_error_from_errno("calloc");
@@ -605,7 +600,7 @@ got_object_raw_open(struct got_raw_object **obj, struct got_repository *repo,
 			goto done;
 		}
 
-		if (sb.st_size != size) {
+		if (sb.st_size != hdrlen + size) {
 			err = got_error(GOT_ERR_PRIVSEP_LEN);
 			goto done;
 		}
diff --git a/lib/privsep.c b/lib/privsep.c
index 61891c5..ebbe86b 100644
--- a/lib/privsep.c
+++ b/lib/privsep.c
@@ -296,8 +296,8 @@ got_privsep_send_raw_obj(struct imsgbuf *ibuf, off_t size, size_t hdrlen,
 	iobj.hdrlen = hdrlen;
 	iobj.size = size;
 
-	if (data && size <= GOT_PRIVSEP_INLINE_OBJECT_DATA_MAX)
-		len += (size_t)size;
+	if (data && size + hdrlen <= GOT_PRIVSEP_INLINE_OBJECT_DATA_MAX)
+		len += (size_t)size + hdrlen;
 
 	wbuf = imsg_create(ibuf, GOT_IMSG_RAW_OBJECT, 0, 0, len);
 	if (wbuf == NULL) {
@@ -311,8 +311,8 @@ got_privsep_send_raw_obj(struct imsgbuf *ibuf, off_t size, size_t hdrlen,
 		return err;
 	}
 
-	if (data && size <= GOT_PRIVSEP_INLINE_OBJECT_DATA_MAX) {
-		if (imsg_add(wbuf, data, size) == -1) {
+	if (data && size + hdrlen <= GOT_PRIVSEP_INLINE_OBJECT_DATA_MAX) {
+		if (imsg_add(wbuf, data, size + hdrlen) == -1) {
 			err = got_error_from_errno("imsg_add RAW_OBJECT");
 			ibuf_free(wbuf);
 			return err;
@@ -357,17 +357,17 @@ got_privsep_recv_raw_obj(uint8_t **outbuf, off_t *size, size_t *hdrlen,
 			break;
 		}
 
-		if (*size > GOT_PRIVSEP_INLINE_OBJECT_DATA_MAX) {
+		if (*size + *hdrlen > GOT_PRIVSEP_INLINE_OBJECT_DATA_MAX) {
 			err = got_error(GOT_ERR_PRIVSEP_LEN);
 			break;
 		}
 
-		*outbuf = malloc(*size);
+		*outbuf = malloc(*size + *hdrlen);
 		if (*outbuf == NULL) {
 			err = got_error_from_errno("malloc");
 			break;
 		}
-		memcpy(*outbuf, imsg.data + sizeof(*iobj), *size);
+		memcpy(*outbuf, imsg.data + sizeof(*iobj), *size + *hdrlen);
 		break;
 	default:
 		err = got_error(GOT_ERR_PRIVSEP_MSG);
diff --git a/libexec/got-read-object/got-read-object.c b/libexec/got-read-object/got-read-object.c
index 42395ba..8cb2bc3 100644
--- a/libexec/got-read-object/got-read-object.c
+++ b/libexec/got-read-object/got-read-object.c
@@ -77,7 +77,7 @@ send_raw_obj(struct imsgbuf *ibuf, struct got_object *obj, int fd, int outfd)
 		return err;
 	}
 
-	if (obj->size <= GOT_PRIVSEP_INLINE_OBJECT_DATA_MAX)
+	if (obj->size + obj->hdrlen <= GOT_PRIVSEP_INLINE_OBJECT_DATA_MAX)
 		err = got_inflate_to_mem(&data, &len, &consumed, f);
 	else
 		err = got_inflate_to_fd(&len, f, outfd);
@@ -89,7 +89,8 @@ send_raw_obj(struct imsgbuf *ibuf, struct got_object *obj, int fd, int outfd)
 		goto done;
 	}
 
-	err = got_privsep_send_raw_obj(ibuf, len, obj->hdrlen, data);
+	err = got_privsep_send_raw_obj(ibuf, obj->size, obj->hdrlen, data);
+
 done:
 	free(data);
 	if (fclose(f) == EOF && err == NULL)