]> git.ipfire.org Git - thirdparty/git.git/commitdiff
commit-graph: check order while reading fanout chunk
authorJeff King <peff@peff.net>
Thu, 9 Nov 2023 07:25:07 +0000 (02:25 -0500)
committerJunio C Hamano <gitster@pobox.com>
Thu, 9 Nov 2023 10:07:53 +0000 (19:07 +0900)
We read the fanout chunk, storing a pointer to it, but only confirm that
the entries are monotonic in a final "lite" verification step. Let's
move that into the actual OIDF chunk callback, so that we can report
problems immediately (for all the reasons given in the previous
"commit-graph: abort as soon as we see a bogus chunk" commit).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
commit-graph.c
t/t5318-commit-graph.sh

index a7d2fe883fd2f714f31ad8a547aec7e3d27798ea..e5f9e75e185d8bb2b5a93480aa33051930fa3cd7 100644 (file)
@@ -277,8 +277,6 @@ struct commit_graph *load_commit_graph_one_fd_st(struct repository *r,
 
 static int verify_commit_graph_lite(struct commit_graph *g)
 {
-       int i;
-
        /*
         * Basic validation shared between parse_commit_graph()
         * which'll be called every time the graph is used, and the
@@ -291,16 +289,6 @@ static int verify_commit_graph_lite(struct commit_graph *g)
         * over g->num_commits, or runs a checksum on the commit-graph
         * itself.
         */
-       for (i = 0; i < 255; i++) {
-               uint32_t oid_fanout1 = ntohl(g->chunk_oid_fanout[i]);
-               uint32_t oid_fanout2 = ntohl(g->chunk_oid_fanout[i + 1]);
-
-               if (oid_fanout1 > oid_fanout2) {
-                       error("commit-graph fanout values out of order");
-                       return 1;
-               }
-       }
-
        return 0;
 }
 
@@ -308,10 +296,23 @@ static int graph_read_oid_fanout(const unsigned char *chunk_start,
                                 size_t chunk_size, void *data)
 {
        struct commit_graph *g = data;
+       int i;
+
        if (chunk_size != 256 * sizeof(uint32_t))
                return error("commit-graph oid fanout chunk is wrong size");
        g->chunk_oid_fanout = (const uint32_t *)chunk_start;
        g->num_commits = ntohl(g->chunk_oid_fanout[255]);
+
+       for (i = 0; i < 255; i++) {
+               uint32_t oid_fanout1 = ntohl(g->chunk_oid_fanout[i]);
+               uint32_t oid_fanout2 = ntohl(g->chunk_oid_fanout[i + 1]);
+
+               if (oid_fanout1 > oid_fanout2) {
+                       error("commit-graph fanout values out of order");
+                       return 1;
+               }
+       }
+
        return 0;
 }
 
index 9d186e7b13dd9b3f7f350ebfea6724e742b9f4a1..b0d436a6f0589a55bec507fd2bc384e46efe8b6d 100755 (executable)
@@ -867,6 +867,7 @@ test_expect_success 'reader notices out-of-bounds fanout' '
        check_corrupt_chunk OIDF 0 $(printf "%02x000000" $(test_seq 0 254)) &&
        cat >expect.err <<-\EOF &&
        error: commit-graph fanout values out of order
+       error: commit-graph required OID fanout chunk missing or corrupted
        EOF
        test_cmp expect.err err
 '