Skip to content

Commit 10a6762

Browse files
pks-tgitster
authored andcommitted
object-file: adapt stream_object_signature() to take a stream
The function `stream_object_signature()` is responsible for verifying whether the given object ID matches the actual hash of the object's contents. In contrast to `check_object_signature()` it does so in a streaming fashion so that we don't have to load the full object into memory. In a subsequent commit we'll want to adapt one of its callsites to pass a preconstructed stream. Prepare for this by accepting a stream as input that the caller needs to assemble. While at it, improve the error reporting in `parse_object_with_flags()` to tell apart the two failure modes. Helped-by: Jeff King <peff@peff.net> Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 26fc7b5 commit 10a6762

4 files changed

Lines changed: 31 additions & 14 deletions

File tree

object-file.c

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -129,18 +129,15 @@ int check_object_signature(struct repository *r, const struct object_id *oid,
129129
return !oideq(oid, &real_oid) ? -1 : 0;
130130
}
131131

132-
int stream_object_signature(struct repository *r, const struct object_id *oid)
132+
int stream_object_signature(struct repository *r,
133+
struct odb_read_stream *st,
134+
const struct object_id *oid)
133135
{
134136
struct object_id real_oid;
135-
struct odb_read_stream *st;
136137
struct git_hash_ctx c;
137138
char hdr[MAX_HEADER_LEN];
138139
int hdrlen;
139140

140-
st = odb_read_stream_open(r->objects, oid, NULL);
141-
if (!st)
142-
return -1;
143-
144141
/* Generate the header */
145142
hdrlen = format_object_header(hdr, sizeof(hdr), st->type, st->size);
146143

@@ -160,7 +157,6 @@ int stream_object_signature(struct repository *r, const struct object_id *oid)
160157
git_hash_update(&c, buf, readlen);
161158
}
162159
git_hash_final_oid(&real_oid, &c);
163-
odb_read_stream_close(st);
164160
return !oideq(oid, &real_oid) ? -1 : 0;
165161
}
166162

object-file.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,9 @@ int check_object_signature(struct repository *r, const struct object_id *oid,
164164
* Try reading the object named with "oid" using
165165
* the streaming interface and rehash it to do the same.
166166
*/
167-
int stream_object_signature(struct repository *r, const struct object_id *oid);
167+
int stream_object_signature(struct repository *r,
168+
struct odb_read_stream *stream,
169+
const struct object_id *oid);
168170

169171
enum finalize_object_file_flags {
170172
FOF_SKIP_COLLISION_CHECK = 1,

object.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "object.h"
77
#include "replace-object.h"
88
#include "object-file.h"
9+
#include "odb/streaming.h"
910
#include "blob.h"
1011
#include "statinfo.h"
1112
#include "tree.h"
@@ -330,9 +331,21 @@ struct object *parse_object_with_flags(struct repository *r,
330331

331332
if ((!obj || obj->type == OBJ_NONE || obj->type == OBJ_BLOB) &&
332333
odb_read_object_info(r->objects, oid, NULL) == OBJ_BLOB) {
333-
if (!skip_hash && stream_object_signature(r, repl) < 0) {
334-
error(_("hash mismatch %s"), oid_to_hex(oid));
335-
return NULL;
334+
if (!skip_hash) {
335+
struct odb_read_stream *stream = odb_read_stream_open(r->objects, oid, NULL);
336+
337+
if (!stream) {
338+
error(_("unable to open object stream for %s"), oid_to_hex(oid));
339+
return NULL;
340+
}
341+
342+
if (stream_object_signature(r, stream, repl) < 0) {
343+
error(_("hash mismatch %s"), oid_to_hex(oid));
344+
odb_read_stream_close(stream);
345+
return NULL;
346+
}
347+
348+
odb_read_stream_close(stream);
336349
}
337350
parse_blob_buffer(lookup_blob(r, oid));
338351
return lookup_object(r, oid);

pack-check.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "packfile.h"
1010
#include "object-file.h"
1111
#include "odb.h"
12+
#include "odb/streaming.h"
1213

1314
struct idx_entry {
1415
off_t offset;
@@ -104,6 +105,7 @@ static int verify_packfile(struct repository *r,
104105
QSORT(entries, nr_objects, compare_entries);
105106

106107
for (i = 0; i < nr_objects; i++) {
108+
struct odb_read_stream *stream = NULL;
107109
void *data;
108110
struct object_id oid;
109111
enum object_type type;
@@ -152,7 +154,9 @@ static int verify_packfile(struct repository *r,
152154
type) < 0)
153155
err = error("packed %s from %s is corrupt",
154156
oid_to_hex(&oid), p->pack_name);
155-
else if (!data && stream_object_signature(r, &oid) < 0)
157+
else if (!data &&
158+
(!(stream = odb_read_stream_open(r->objects, &oid, NULL)) ||
159+
stream_object_signature(r, stream, &oid) < 0))
156160
err = error("packed %s from %s is corrupt",
157161
oid_to_hex(&oid), p->pack_name);
158162
else if (fn) {
@@ -163,12 +167,14 @@ static int verify_packfile(struct repository *r,
163167
}
164168
if (((base_count + i) & 1023) == 0)
165169
display_progress(progress, base_count + i);
166-
free(data);
167170

171+
if (stream)
172+
odb_read_stream_close(stream);
173+
free(data);
168174
}
175+
169176
display_progress(progress, base_count + i);
170177
free(entries);
171-
172178
return err;
173179
}
174180

0 commit comments

Comments
 (0)