Merge branch 'jk/hash-object-fsck'

"git hash-object" now checks that the resulting object is well
formed with the same code as "git fsck".

* jk/hash-object-fsck:
  fsck: do not assume NUL-termination of buffers
  hash-object: use fsck for object checks
  fsck: provide a function to fsck buffer without object struct
  t: use hash-object --literally when created malformed objects
  t7030: stop using invalid tag name
  t1006: stop using 0-padded timestamps
  t1007: modernize malformed object tests
This commit is contained in:
Junio C Hamano
2023-01-30 14:24:22 -08:00
21 changed files with 293 additions and 95 deletions

View File

@ -33,6 +33,7 @@
#include "object-store.h"
#include "promisor-remote.h"
#include "submodule.h"
#include "fsck.h"
/* The maximum size for an object header. */
#define MAX_HEADER_LEN 32
@ -2284,32 +2285,21 @@ int repo_has_object_file(struct repository *r,
return repo_has_object_file_with_flags(r, oid, 0);
}
static void check_tree(const void *buf, size_t size)
/*
* We can't use the normal fsck_error_function() for index_mem(),
* because we don't yet have a valid oid for it to report. Instead,
* report the minimal fsck error here, and rely on the caller to
* give more context.
*/
static int hash_format_check_report(struct fsck_options *opts,
const struct object_id *oid,
enum object_type object_type,
enum fsck_msg_type msg_type,
enum fsck_msg_id msg_id,
const char *message)
{
struct tree_desc desc;
struct name_entry entry;
init_tree_desc(&desc, buf, size);
while (tree_entry(&desc, &entry))
/* do nothing
* tree_entry() will die() on malformed entries */
;
}
static void check_commit(const void *buf, size_t size)
{
struct commit c;
memset(&c, 0, sizeof(c));
if (parse_commit_buffer(the_repository, &c, buf, size, 0))
die(_("corrupt commit"));
}
static void check_tag(const void *buf, size_t size)
{
struct tag t;
memset(&t, 0, sizeof(t));
if (parse_tag_buffer(the_repository, &t, buf, size))
die(_("corrupt tag"));
error(_("object fails fsck: %s"), message);
return 1;
}
static int index_mem(struct index_state *istate,
@ -2336,12 +2326,13 @@ static int index_mem(struct index_state *istate,
}
}
if (flags & HASH_FORMAT_CHECK) {
if (type == OBJ_TREE)
check_tree(buf, size);
if (type == OBJ_COMMIT)
check_commit(buf, size);
if (type == OBJ_TAG)
check_tag(buf, size);
struct fsck_options opts = FSCK_OPTIONS_DEFAULT;
opts.strict = 1;
opts.error_func = hash_format_check_report;
if (fsck_buffer(null_oid(), type, buf, size, &opts))
die(_("refusing to create malformed object"));
fsck_finish(&opts);
}
if (write_object)