Merge branch 'vs/submodule-clone-nested-submodules-alternates'
[gitweb.git] / builtin / index-pack.c
index 1d2ea583a45507935ec2007d6c44f5e968a1aed5..0a27bab11b6b5a1b162c4dfef34c645c7d5f14ad 100644 (file)
@@ -87,6 +87,7 @@ static struct progress *progress;
 static unsigned char input_buffer[4096];
 static unsigned int input_offset, input_len;
 static off_t consumed_bytes;
+static off_t max_input_size;
 static unsigned deepest_delta;
 static git_SHA_CTX input_ctx;
 static uint32_t input_crc32;
@@ -297,6 +298,8 @@ static void use(int bytes)
        if (signed_add_overflows(consumed_bytes, bytes))
                die(_("pack too large for current definition of off_t"));
        consumed_bytes += bytes;
+       if (max_input_size && consumed_bytes > max_input_size)
+               die(_("pack exceeds maximum allowed size"));
 }
 
 static const char *open_pack_file(const char *pack_name)
@@ -1187,10 +1190,8 @@ static void resolve_deltas(void)
                return;
 
        /* Sort deltas by base SHA1/offset for fast searching */
-       qsort(ofs_deltas, nr_ofs_deltas, sizeof(struct ofs_delta_entry),
-             compare_ofs_delta_entry);
-       qsort(ref_deltas, nr_ref_deltas, sizeof(struct ref_delta_entry),
-             compare_ref_delta_entry);
+       QSORT(ofs_deltas, nr_ofs_deltas, compare_ofs_delta_entry);
+       QSORT(ref_deltas, nr_ref_deltas, compare_ref_delta_entry);
 
        if (verbose || show_resolving_progress)
                progress = start_progress(_("Resolving deltas"),
@@ -1353,7 +1354,7 @@ static void fix_unresolved_deltas(struct sha1file *f)
        ALLOC_ARRAY(sorted_by_pos, nr_ref_deltas);
        for (i = 0; i < nr_ref_deltas; i++)
                sorted_by_pos[i] = &ref_deltas[i];
-       qsort(sorted_by_pos, nr_ref_deltas, sizeof(*sorted_by_pos), delta_pos_compare);
+       QSORT(sorted_by_pos, nr_ref_deltas, delta_pos_compare);
 
        for (i = 0; i < nr_ref_deltas; i++) {
                struct ref_delta_entry *d = sorted_by_pos[i];
@@ -1530,8 +1531,7 @@ static void read_v2_anomalous_offsets(struct packed_git *p,
                opts->anomaly[opts->anomaly_nr++] = ntohl(idx2[off * 2 + 1]);
        }
 
-       if (1 < opts->anomaly_nr)
-               qsort(opts->anomaly, opts->anomaly_nr, sizeof(uint32_t), cmp_uint32);
+       QSORT(opts->anomaly, opts->anomaly_nr, cmp_uint32);
 }
 
 static void read_idx_option(struct pack_idx_option *opts, const char *pack_name)
@@ -1714,6 +1714,8 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
                                        opts.off32_limit = strtoul(c+1, &c, 0);
                                if (*c || opts.off32_limit & 0x80000000)
                                        die(_("bad %s"), arg);
+                       } else if (skip_prefix(arg, "--max-input-size=", &arg)) {
+                               max_input_size = strtoumax(arg, NULL, 10);
                        } else
                                usage(index_pack_usage);
                        continue;