Thread (1 message) 1 message, 1 author, 2016-06-15

Re: parse_object does check_sha1_signature but not parse_object_buffer?

From: Junio C Hamano <hidden>
Date: 2016-06-15 23:08:06

Jeff King [off-list ref] writes:
For local repository operations, most of them are about reading data.
And there I generally favor performance over extra validation, with the
caveat that we should always be aware of the tradeoff. An extra
comparison to make sure we are not going out-of-bounds on a pack .idx
pointer is cheap. Loading a blob just to make sure its sha1 is valid
before we mention it in `diff --raw` output is stupid. Checking the sha1
on objects we are otherwise accessing is somewhere in between. :)

For local write operations, like repacking, we should err on the careful
side. And I think we do a good job of balancing performance and
validation there (e.g., we reuse deltas without reconstructing the
object, but _with_ a crc check on the delta data itself).
OK, that is a reasonable set of rules.  We can say "checkout" is
writing out the contents to the filesystem, and make the "somewhere
in between" be closer to the "error on the careful side".
quoted
In fact, we do this, which is quite suboptimal:

        static int fsck_sha1(const unsigned char *sha1)
        {
                struct object *obj = parse_object(sha1);
                if (!obj) {
                        errors_found |= ERROR_OBJECT;
                        return error("%s: object corrupt or missing",
                                     sha1_to_hex(sha1));
                }
                obj->flags |= HAS_OBJ;
                return fsck_obj(obj);
        }

This function is called for each loose object file we find in
fsck_object_dir(), and there are a few problems:

 * The function parse_object() called from here would issue an error
   message and returns NULL; then you get another "corrupt or
   missing" error message, because this code cannot tell from the
   NULL which is the case.

 * The intent of the callchain to fsck_sha1() is to iterate over
   loose object files xx/x{38} and validate what is contained in
   them, but that behaviour is not guaranteed because it calls
   parse_object(), which may get the object data from a packfile
   if the loose object is also in the packfile.

This function should instead take "path" (the only caller of this
function fsck_loose() has it), read the data in the file, hash the
data to validate that it matches "sha1" and then create the object
out of that data it read by calling parse_object_buffer().
Yeah, I agree. I think as it is written, we also end up loading the
loose objects twice (once in parse_object, and then later again in
fsck_object to do the real work). Your solution would fix that, too.
...
I guess nobody has really noticed either issue, because repositories
large enough for it to make a difference will usually be packed.
I'll throw it in the leftover-bits list, then ;-)
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help