From: Han Xin <chiyutianyi@gmail.com>
To: Junio C Hamano <gitster@pobox.com>, Git List <git@vger.kernel.org>
Cc: Han Xin <hanxin.hx@alibaba-inc.com>
Subject: [PATCH] receive-pack: allow a maximum input object size specified
Date: Thu, 30 Sep 2021 20:10:58 +0800 [thread overview]
Message-ID: <20210930121058.5771-1-chiyutianyi@gmail.com> (raw)
From: Han Xin <hanxin.hx@alibaba-inc.com>
'receive.maxInputSize' help us to stop writing bytes
to disk by a global cutoff point, but sometimes we only
want to say no for large objects. Let's allow a new cutoff
point where we will stop writing big objects' bytes to disk.
Signed-off-by: Han Xin <hanxin.hx@alibaba-inc.com>
---
builtin/index-pack.c | 5 +++++
builtin/receive-pack.c | 12 ++++++++++++
builtin/unpack-objects.c | 8 ++++++++
t/t5546-receive-limits.sh | 33 +++++++++++++++++++++++++++++----
4 files changed, 54 insertions(+), 4 deletions(-)
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index 8336466865..0e62b356c6 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -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)
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 2d1f97e1ca..82ff0c61ff 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -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;
diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c
index 4a9466295b..04d9fa918f 100644
--- a/builtin/unpack-objects.c
+++ b/builtin/unpack-objects.c
@@ -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);
}
diff --git a/t/t5546-receive-limits.sh b/t/t5546-receive-limits.sh
index 0b0e987fdb..11fd374abc 100755
--- a/t/t5546-receive-limits.sh
+++ b/t/t5546-receive-limits.sh
@@ -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
'
}
--
2.33.0.1.g1026118a84
next reply other threads:[~2021-09-30 12:11 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-09-30 12:10 Han Xin [this message]
2021-09-30 13:20 ` [PATCH v2] receive-pack: not receive pack file with large object Han Xin
2021-09-30 13:42 ` Ævar Arnfjörð Bjarmason
2021-10-01 2:30 ` Jiang Xin
2021-10-01 6:17 ` Jeff King
2021-10-01 6:55 ` Jeff King
2021-10-01 18:43 ` Junio C Hamano
2021-09-30 16:49 ` Junio C Hamano
2021-10-01 2:52 ` Jiang Xin
2021-10-01 6:24 ` Jeff King
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210930121058.5771-1-chiyutianyi@gmail.com \
--to=chiyutianyi@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=hanxin.hx@alibaba-inc.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).