@@ -133,6 +133,7 @@ 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 off_t max_input_object_size;
static unsigned deepest_delta;
static git_hash_ctx input_ctx;
static uint32_t input_crc32;
@@ -519,6 +520,8 @@ static void *unpack_raw_entry(struct object_entry *obj,
shift += 7;
}
obj->size = size;
+ if (max_input_object_size && size > max_input_object_size)
+ die(_("object exceeds maximum allowed size "));
switch (obj->type) {
case OBJ_REF_DELTA:
@@ -1825,6 +1828,8 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
die(_("bad %s"), arg);
} else if (skip_prefix(arg, "--max-input-size=", &arg)) {
max_input_size = strtoumax(arg, NULL, 10);
+ } else if (skip_prefix(arg, "--max-input-object-size=", &arg)) {
+ max_input_object_size = strtoumax(arg, NULL, 10);
} else if (skip_prefix(arg, "--object-format=", &arg)) {
hash_algo = hash_algo_by_name(arg);
if (hash_algo == GIT_HASH_UNKNOWN)
@@ -57,6 +57,7 @@ static int advertise_push_options;
static int advertise_sid;
static int unpack_limit = 100;
static off_t max_input_size;
+static off_t max_input_object_size;
static int report_status;
static int report_status_v2;
static int use_sideband;
@@ -242,6 +243,11 @@ static int receive_pack_config(const char *var, const char *value, void *cb)
return 0;
}
+ if (strcmp(var, "receive.maxinputobjectsize") == 0) {
+ max_input_object_size = git_config_int64(var, value);
+ return 0;
+ }
+
if (strcmp(var, "receive.procreceiverefs") == 0) {
if (!value)
return config_error_nonbool(var);
@@ -2237,6 +2243,9 @@ static const char *unpack(int err_fd, struct shallow_info *si)
if (max_input_size)
strvec_pushf(&child.args, "--max-input-size=%"PRIuMAX,
(uintmax_t)max_input_size);
+ if (max_input_object_size)
+ strvec_pushf(&child.args, "--max-input-object-size=%"PRIuMAX,
+ (uintmax_t)max_input_object_size);
child.no_stdout = 1;
child.err = err_fd;
child.git_cmd = 1;
@@ -2268,6 +2277,9 @@ static const char *unpack(int err_fd, struct shallow_info *si)
if (max_input_size)
strvec_pushf(&child.args, "--max-input-size=%"PRIuMAX,
(uintmax_t)max_input_size);
+ if (max_input_object_size)
+ strvec_pushf(&child.args, "--max-input-object-size=%"PRIuMAX,
+ (uintmax_t)max_input_object_size);
child.out = -1;
child.err = err_fd;
child.git_cmd = 1;
@@ -22,6 +22,7 @@ static unsigned char buffer[4096];
static unsigned int offset, len;
static off_t consumed_bytes;
static off_t max_input_size;
+static off_t max_input_object_size;
static git_hash_ctx ctx;
static struct fsck_options fsck_options = FSCK_OPTIONS_STRICT;
static struct progress *progress;
@@ -466,6 +467,9 @@ static void unpack_one(unsigned nr)
shift += 7;
}
+ if (max_input_object_size && size > max_input_object_size)
+ die(_("object exceeds maximum allowed size "));
+
switch (type) {
case OBJ_COMMIT:
case OBJ_TREE:
@@ -568,6 +572,10 @@ int cmd_unpack_objects(int argc, const char **argv, const char *prefix)
max_input_size = strtoumax(arg, NULL, 10);
continue;
}
+ if (skip_prefix(arg, "--max-input-object-size=", &arg)) {
+ max_input_object_size = strtoumax(arg, NULL, 10);
+ continue;
+ }
usage(unpack_usage);
}
@@ -19,16 +19,16 @@ test_pack_input_limit () {
'
test_expect_success "set unpacklimit to $unpack_limit" '
- git --git-dir=dest config receive.unpacklimit "$unpack_limit"
+ git -C dest config receive.unpacklimit "$unpack_limit"
'
test_expect_success 'setting receive.maxInputSize to 512 rejects push' '
- git --git-dir=dest config receive.maxInputSize 512 &&
+ git -C dest config receive.maxInputSize 512 &&
test_must_fail git push dest HEAD
'
test_expect_success 'bumping limit to 4k allows push' '
- git --git-dir=dest config receive.maxInputSize 4k &&
+ git -C dest config receive.maxInputSize 4k &&
git push dest HEAD
'
@@ -38,7 +38,32 @@ test_pack_input_limit () {
'
test_expect_success 'lifting the limit allows push' '
- git --git-dir=dest config receive.maxInputSize 0 &&
+ git -C dest config receive.maxInputSize 0 &&
+ git push dest HEAD
+ '
+
+ test_expect_success 'prepare destination repository' '
+ rm -fr dest &&
+ git --bare init dest
+ '
+
+ test_expect_success 'setting receive.maxInputObjectSize to 512 rejects push' '
+ git -C dest config receive.maxInputObjectSize 512 &&
+ test_must_fail git push dest HEAD
+ '
+
+ test_expect_success 'bumping limit to 2k allows push' '
+ git -C dest config receive.maxInputObjectSize 2k &&
+ git push dest HEAD
+ '
+
+ test_expect_success 'prepare destination repository (again)' '
+ rm -fr dest &&
+ git --bare init dest
+ '
+
+ test_expect_success 'lifting the limit allows push' '
+ git --git-dir=dest config receive.maxInputObjectSize 0 &&
git push dest HEAD
'
}