diff options
context:
space:
mode:
-rw-r--r--source/shared.c25
-rwxr-xr-xtests/t0201-limits.sh26
2 files changed, 48 insertions, 3 deletions
diff --git a/source/shared.c b/source/shared.c
index 24f9c3c..59f1c8e 100644
--- a/source/shared.c
+++ b/source/shared.c
@@ -311,12 +311,31 @@ int cgit_diff_files(const struct object_id *old_oid,
xpparam_t diff_params;
xdemitconf_t emit_params;
xdemitcb_t emit_cb;
+ unsigned long size1 = 0, size2 = 0;
- if (!load_mmfile(&file1, old_oid) || !load_mmfile(&file2, new_oid))
+ // Read the object headers first so an oversized blob is never
+ // inflated into memory just to be diffed. Report it as binary,
+ // which suppresses inlining the same way max-blob-size does for
+ // the blob, plain and tree views.
+ if (!is_null_oid(old_oid) &&
+ odb_read_object_info(the_repository->objects, old_oid, &size1) < 0)
+ return 1;
+ if (!is_null_oid(new_oid) &&
+ odb_read_object_info(the_repository->objects, new_oid, &size2) < 0)
return 1;
- *old_size = file1.size;
- *new_size = file2.size;
+ *old_size = size1;
+ *new_size = size2;
+
+ if (ctx.cfg.max_blob_size &&
+ (size1 / 1024 > (unsigned long)ctx.cfg.max_blob_size ||
+ size2 / 1024 > (unsigned long)ctx.cfg.max_blob_size)) {
+ *binary = 1;
+ return 0;
+ }
+
+ if (!load_mmfile(&file1, old_oid) || !load_mmfile(&file2, new_oid))
+ return 1;
if ((file1.ptr && buffer_is_binary(file1.ptr, file1.size)) ||
(file2.ptr && buffer_is_binary(file2.ptr, file2.size))) {
diff --git a/tests/t0201-limits.sh b/tests/t0201-limits.sh
index 1ab3ce6..5f04952 100755
--- a/tests/t0201-limits.sh
+++ b/tests/t0201-limits.sh
@@ -100,6 +100,32 @@ test_expect_success 'the single-file page is not limited by max-diff-files' '
grep "class=.hunk." tmp
'
+# --- max-blob-size also bounds the diff path --------------------------------
+# The diff family must not inflate a blob larger than max-blob-size just to
+# render it. Such a file is reported as binary instead of inlined.
+test_expect_success 'a diff of an oversized blob is not inlined' '
+ mkrepo repos/blobdiff 1 &&
+ (
+ cd repos/blobdiff &&
+ awk "BEGIN{for(i=0;i<400;i++)print \"aaaaaaaa\"}" >big.txt &&
+ git add -A &&
+ git commit -m add &&
+ awk "BEGIN{for(i=0;i<401;i++)print \"aaaaaaaa\"}" >big.txt &&
+ git commit -am change
+ ) &&
+ {
+ echo "virtual-root=/" &&
+ echo "cache-size=0" &&
+ echo "max-blob-size=1" &&
+ echo "repo.url=blobdiff" &&
+ echo "repo.path=$PWD/repos/blobdiff/.git"
+ } >blobdiffrc &&
+ sha=$(git -C repos/blobdiff rev-parse HEAD) &&
+ CGIT_CONFIG="$PWD/blobdiffrc" QUERY_STRING="url=blobdiff/commit/&id=$sha" cgit >tmp &&
+ grep "Binary files differ" tmp &&
+ ! grep "aaaaaaaa" tmp
+'
+
# --- The shipped highlight filter degrades to escaped passthrough -----------
test_expect_success LUA 'highlight filter passes text through without scintillua' '
{