Commit c4330effadfe340c07b5709bc805de6a0b3764a7

Stefan Sperling 2021-06-22T19:11:54

expose got_pack_parse_ref_delta() for library-internal use This will be needed by a future 'gotadmin listpack' command.

diff --git a/lib/got_lib_pack.h b/lib/got_lib_pack.h
index b724471..e2c8744 100644
--- a/lib/got_lib_pack.h
+++ b/lib/got_lib_pack.h
@@ -28,6 +28,8 @@ const struct got_error *got_pack_close(struct got_pack *);
 
 const struct got_error *got_pack_parse_offset_delta(off_t *, size_t *,
     struct got_pack *, off_t, int);
+const struct got_error *got_pack_parse_ref_delta(struct got_object_id *,
+    struct got_pack *, off_t, int);
 const struct got_error *got_pack_resolve_delta_chain(struct got_delta_chain *,
     struct got_packidx *, struct got_pack *, off_t, size_t, int, size_t,
     unsigned int);
diff --git a/lib/pack.c b/lib/pack.c
index eb5f6b4..1b91703 100644
--- a/lib/pack.c
+++ b/lib/pack.c
@@ -809,6 +809,25 @@ resolve_offset_delta(struct got_delta_chain *deltas,
 	    base_tslen, base_type, base_size, recursion - 1);
 }
 
+const struct got_error *
+got_pack_parse_ref_delta(struct got_object_id *id,
+    struct got_pack *pack, off_t delta_offset, int tslen)
+{
+	if (pack->map) {
+		size_t mapoff = delta_offset + tslen;
+		memcpy(id, pack->map + mapoff, sizeof(*id));
+	} else {
+		ssize_t n;
+		n = read(pack->fd, id, sizeof(*id));
+		if (n < 0)
+			return got_error_from_errno("read");
+		if (n != sizeof(*id))
+			return got_error(GOT_ERR_BAD_PACKFILE);
+	}
+
+	return NULL;
+}
+
 static const struct got_error *
 resolve_ref_delta(struct got_delta_chain *deltas, struct got_packidx *packidx,
     struct got_pack *pack, off_t delta_offset, size_t tslen, int delta_type,
@@ -826,18 +845,12 @@ resolve_ref_delta(struct got_delta_chain *deltas, struct got_packidx *packidx,
 	if (delta_offset + tslen >= pack->filesize)
 		return got_error(GOT_ERR_PACK_OFFSET);
 
+	err = got_pack_parse_ref_delta(&id, pack, delta_offset, tslen);
+	if (err)
+		return err;
 	if (pack->map) {
-		size_t mapoff = delta_offset + tslen;
-		memcpy(&id, pack->map + mapoff, sizeof(id));
-		mapoff += sizeof(id);
-		delta_data_offset = (off_t)mapoff;
+		delta_data_offset = delta_offset + tslen + sizeof(id);
 	} else {
-		ssize_t n;
-		n = read(pack->fd, &id, sizeof(id));
-		if (n < 0)
-			return got_error_from_errno("read");
-		if (n != sizeof(id))
-			return got_error(GOT_ERR_BAD_PACKFILE);
 		delta_data_offset = lseek(pack->fd, 0, SEEK_CUR);
 		if (delta_data_offset == -1)
 			return got_error_from_errno("lseek");