diff options
context:
space:
mode:
-rw-r--r--cgitrc.5.txt6
-rw-r--r--source/cgit.c2
-rw-r--r--source/ui-blame.c6
-rw-r--r--source/ui-blob.c10
-rw-r--r--source/ui-plain.c8
-rw-r--r--source/ui-tree.c15
6 files changed, 37 insertions, 10 deletions
diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index b5315cc..b15505f 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -283,8 +283,10 @@ max-atom-items::
value: "10".
max-blob-size::
- Specifies the maximum size of a blob to display HTML for in KBytes.
- Default value: "0" (limit disabled).
+ Specifies the maximum size in KBytes of a blob that cgit will read into
+ memory to serve. It caps both the HTML blob view and the raw "plain" and
+ "blob" output, and a larger object is refused rather than loaded whole.
+ Default value: "10240" (10 MB). Set to "0" to disable the limit.
max-commit-count::
Specifies the number of entries to list per page in "log" view. Default
diff --git a/source/cgit.c b/source/cgit.c
index 8a7027c..d80aebd 100644
--- a/source/cgit.c
+++ b/source/cgit.c
@@ -403,7 +403,7 @@ static void prepare_context(void)
ctx.cfg.max_lock_attempts = 5;
ctx.cfg.max_msg_len = 80;
ctx.cfg.max_repodesc_len = 80;
- ctx.cfg.max_blob_size = 0;
+ ctx.cfg.max_blob_size = 10 * 1024; /* 10 MB; bounds per-request memory */
ctx.cfg.max_stats = 0;
ctx.cfg.project_list = NULL;
ctx.cfg.renamelimit = -1;
diff --git a/source/ui-blame.c b/source/ui-blame.c
index 1b9df88..99f6de0 100644
--- a/source/ui-blame.c
+++ b/source/ui-blame.c
@@ -127,6 +127,12 @@ static void print_object(const struct object_id *oid, const char *path,
oid_to_hex(oid));
return;
}
+ if (ctx.cfg.max_blob_size && size / 1024 > (unsigned long)ctx.cfg.max_blob_size) {
+ cgit_print_error_page(413, "Too large",
+ "blob size (%luKB) exceeds display size limit (%dKB)",
+ size / 1024, ctx.cfg.max_blob_size);
+ return;
+ }
buf = odb_read_object(the_repository->objects, oid, &type, &size);
if (!buf) {
diff --git a/source/ui-blob.c b/source/ui-blob.c
index ad84f3d..67c718b 100644
--- a/source/ui-blob.c
+++ b/source/ui-blob.c
@@ -102,6 +102,8 @@ int cgit_print_file(char *path, const char *head, int file_only, int html_escape
}
if (type == OBJ_BAD)
return -1;
+ if (ctx.cfg.max_blob_size && size / 1024 > (unsigned long)ctx.cfg.max_blob_size)
+ return -1;
buf = odb_read_object(the_repository->objects, &oid, &type, &size);
if (!buf)
return -1;
@@ -170,6 +172,14 @@ void cgit_print_blob(const char *hex, char *path, const char *head, int file_onl
return;
}
+ /* Reject an oversized object before reading it whole into memory. */
+ if (ctx.cfg.max_blob_size && size / 1024 > (unsigned long)ctx.cfg.max_blob_size) {
+ cgit_print_error_page(413, "Too large",
+ "Object size (%luKB) exceeds limit (%dKB)",
+ size / 1024, ctx.cfg.max_blob_size);
+ return;
+ }
+
buf = odb_read_object(the_repository->objects, &oid, &type, &size);
if (!buf) {
cgit_print_error_page(500, "Internal server error",
diff --git a/source/ui-plain.c b/source/ui-plain.c
index c041711..8486fa4 100644
--- a/source/ui-plain.c
+++ b/source/ui-plain.c
@@ -30,6 +30,14 @@ static int print_object(const struct object_id *oid, const char *path)
return 1;
}
+ /* Reject an oversized object before reading it whole into memory. */
+ if (ctx.cfg.max_blob_size && size / 1024 > (unsigned long)ctx.cfg.max_blob_size) {
+ cgit_print_error_page(413, "Too large",
+ "Object size (%luKB) exceeds limit (%dKB)",
+ size / 1024, ctx.cfg.max_blob_size);
+ return 1;
+ }
+
buf = odb_read_object(the_repository->objects, oid, &type, &size);
if (!buf) {
cgit_print_error_page(404, "Not found", "Not found");
diff --git a/source/ui-tree.c b/source/ui-tree.c
index 292bfc6..f820f1f 100644
--- a/source/ui-tree.c
+++ b/source/ui-tree.c
@@ -117,6 +117,14 @@ static int print_object(const struct object_id *oid, const char *path, const cha
return 0;
}
+ /* Reject an oversized object before reading it whole into memory. */
+ if (ctx.cfg.max_blob_size && size / 1024 > (unsigned long)ctx.cfg.max_blob_size) {
+ cgit_print_error_page(413, "Too large",
+ "blob size (%luKB) exceeds display size limit (%dKB)",
+ size / 1024, ctx.cfg.max_blob_size);
+ return 0;
+ }
+
buf = odb_read_object(the_repository->objects, oid, &type, &size);
if (!buf) {
cgit_print_error_page(500, "Internal server error",
@@ -138,13 +146,6 @@ static int print_object(const struct object_id *oid, const char *path, const cha
}
html(")\n");
- if (ctx.cfg.max_blob_size && size / 1024 > ctx.cfg.max_blob_size) {
- htmlf("<div class='error'>blob size (%ldKB) exceeds display size limit (%dKB).</div>",
- size / 1024, ctx.cfg.max_blob_size);
- free(buf);
- return 1;
- }
-
if (is_binary)
print_binary_buffer(buf, size);
else