From 4c26b5f65ac9b302adf3f88f377544b24980d22f Mon Sep 17 00:00:00 2001 From: Bryce Kwon Date: Sat, 25 Jul 2026 09:11:47 -1000 Subject: Cap diff blobs by `max-blob-size` The diff family inflated a blob of any size just to render it. A file over the limit is reported as binary instead. --- source/shared.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) (limited to 'source') diff --git a/source/shared.c b/source/shared.c index 24f9c3c..59f1c8e 100644 --- a/source/shared.c +++ b/source/shared.c @@ -311,13 +311,32 @@ 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; + + // 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 = 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; - *old_size = file1.size; - *new_size = file2.size; - if ((file1.ptr && buffer_is_binary(file1.ptr, file1.size)) || (file2.ptr && buffer_is_binary(file2.ptr, file2.size))) { *binary = 1; -- cgit v2.8.0