Skip to content

Commit 90a398b

Browse files
dschogitster
authored andcommitted
fsck_object(): allow passing object data separately from the object itself
When fsck'ing an incoming pack, we need to fsck objects that cannot be read via read_sha1_file() because they are not local yet (and might even be rejected if transfer.fsckobjects is set to 'true'). For commits, there is a hack in place: we basically cache commit objects' buffers anyway, but the same is not true, say, for tag objects. By refactoring fsck_object() to take the object buffer and size as optional arguments -- optional, because we still fall back to the previous method to look at the cached commit objects if the caller passes NULL -- we prepare the machinery for the upcoming handling of tag objects. The assumption that such buffers are inherently NUL terminated is now wrong, of course, hence we pass the size of the buffer so that we can add a sanity check later, to prevent running past the end of the buffer. Signed-off-by: Johannes Schindelin <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent fe8e3b7 commit 90a398b

File tree

5 files changed

+31
-16
lines changed

5 files changed

+31
-16
lines changed

builtin/fsck.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ static int fsck_obj(struct object *obj)
298298

299299
if (fsck_walk(obj, mark_used, NULL))
300300
objerror(obj, "broken links");
301-
if (fsck_object(obj, check_strict, fsck_error_func))
301+
if (fsck_object(obj, NULL, 0, check_strict, fsck_error_func))
302302
return -1;
303303

304304
if (obj->type == OBJ_TREE) {

builtin/index-pack.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -773,7 +773,8 @@ static void sha1_object(const void *data, struct object_entry *obj_entry,
773773
if (!obj)
774774
die(_("invalid %s"), typename(type));
775775
if (do_fsck_object &&
776-
fsck_object(obj, 1, fsck_error_function))
776+
fsck_object(obj, buf, size, 1,
777+
fsck_error_function))
777778
die(_("Error in object"));
778779
if (fsck_walk(obj, mark_link, NULL))
779780
die(_("Not all child objects of %s are reachable"), sha1_to_hex(obj->sha1));

builtin/unpack-objects.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,10 +164,10 @@ static unsigned nr_objects;
164164
* Called only from check_object() after it verified this object
165165
* is Ok.
166166
*/
167-
static void write_cached_object(struct object *obj)
167+
static void write_cached_object(struct object *obj, struct obj_buffer *obj_buf)
168168
{
169169
unsigned char sha1[20];
170-
struct obj_buffer *obj_buf = lookup_object_buffer(obj);
170+
171171
if (write_sha1_file(obj_buf->buffer, obj_buf->size, typename(obj->type), sha1) < 0)
172172
die("failed to write object %s", sha1_to_hex(obj->sha1));
173173
obj->flags |= FLAG_WRITTEN;
@@ -180,6 +180,8 @@ static void write_cached_object(struct object *obj)
180180
*/
181181
static int check_object(struct object *obj, int type, void *data)
182182
{
183+
struct obj_buffer *obj_buf;
184+
183185
if (!obj)
184186
return 1;
185187

@@ -198,11 +200,15 @@ static int check_object(struct object *obj, int type, void *data)
198200
return 0;
199201
}
200202

201-
if (fsck_object(obj, 1, fsck_error_function))
203+
obj_buf = lookup_object_buffer(obj);
204+
if (!obj_buf)
205+
die("Whoops! Cannot find object '%s'", sha1_to_hex(obj->sha1));
206+
if (fsck_object(obj, obj_buf->buffer, obj_buf->size, 1,
207+
fsck_error_function))
202208
die("Error in object");
203209
if (fsck_walk(obj, check_object, NULL))
204210
die("Error on reachable objects of %s", sha1_to_hex(obj->sha1));
205-
write_cached_object(obj);
211+
write_cached_object(obj, obj_buf);
206212
return 0;
207213
}
208214

fsck.c

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ static int fsck_ident(const char **ident, struct object *obj, fsck_error error_f
277277
}
278278

279279
static int fsck_commit_buffer(struct commit *commit, const char *buffer,
280-
fsck_error error_func)
280+
unsigned long size, fsck_error error_func)
281281
{
282282
unsigned char tree_sha1[20], sha1[20];
283283
struct commit_graft *graft;
@@ -322,15 +322,18 @@ static int fsck_commit_buffer(struct commit *commit, const char *buffer,
322322
return 0;
323323
}
324324

325-
static int fsck_commit(struct commit *commit, fsck_error error_func)
325+
static int fsck_commit(struct commit *commit, const char *data,
326+
unsigned long size, fsck_error error_func)
326327
{
327-
const char *buffer = get_commit_buffer(commit, NULL);
328-
int ret = fsck_commit_buffer(commit, buffer, error_func);
329-
unuse_commit_buffer(commit, buffer);
328+
const char *buffer = data ? data : get_commit_buffer(commit, &size);
329+
int ret = fsck_commit_buffer(commit, buffer, size, error_func);
330+
if (!data)
331+
unuse_commit_buffer(commit, buffer);
330332
return ret;
331333
}
332334

333-
static int fsck_tag(struct tag *tag, fsck_error error_func)
335+
static int fsck_tag(struct tag *tag, const char *data,
336+
unsigned long size, fsck_error error_func)
334337
{
335338
struct object *tagged = tag->tagged;
336339

@@ -339,7 +342,8 @@ static int fsck_tag(struct tag *tag, fsck_error error_func)
339342
return 0;
340343
}
341344

342-
int fsck_object(struct object *obj, int strict, fsck_error error_func)
345+
int fsck_object(struct object *obj, void *data, unsigned long size,
346+
int strict, fsck_error error_func)
343347
{
344348
if (!obj)
345349
return error_func(obj, FSCK_ERROR, "no valid object to fsck");
@@ -349,9 +353,11 @@ int fsck_object(struct object *obj, int strict, fsck_error error_func)
349353
if (obj->type == OBJ_TREE)
350354
return fsck_tree((struct tree *) obj, strict, error_func);
351355
if (obj->type == OBJ_COMMIT)
352-
return fsck_commit((struct commit *) obj, error_func);
356+
return fsck_commit((struct commit *) obj, (const char *) data,
357+
size, error_func);
353358
if (obj->type == OBJ_TAG)
354-
return fsck_tag((struct tag *) obj, error_func);
359+
return fsck_tag((struct tag *) obj, (const char *) data,
360+
size, error_func);
355361

356362
return error_func(obj, FSCK_ERROR, "unknown type '%d' (internal fsck error)",
357363
obj->type);

fsck.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ int fsck_error_function(struct object *obj, int type, const char *fmt, ...);
2828
* 0 everything OK
2929
*/
3030
int fsck_walk(struct object *obj, fsck_walk_func walk, void *data);
31-
int fsck_object(struct object *obj, int strict, fsck_error error_func);
31+
/* If NULL is passed for data, we assume the object is local and read it. */
32+
int fsck_object(struct object *obj, void *data, unsigned long size,
33+
int strict, fsck_error error_func);
3234

3335
#endif

0 commit comments

Comments
 (0)