From 6fb59b3291a63445499f81b609171db0db0d90ee Mon Sep 17 00:00:00 2001 From: Bryce Kwon Date: Sun, 1 Nov 2026 11:29:40 -1000 Subject: Dump only the first 64 KB of a binary file --- source/ui-tree.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'source') diff --git a/source/ui-tree.c b/source/ui-tree.c index aff4f0f..8e17cc4 100644 --- a/source/ui-tree.c +++ b/source/ui-tree.c @@ -21,6 +21,10 @@ #define HEXDUMP_ROW_HALF (HEXDUMP_ROW_BYTES / 2) #define HEXDUMP_GAP_WIDTH 4 +// Every byte dumped costs about seven bytes of markup, so a blob near +// max-blob-size would make a page several times its own size. +#define HEXDUMP_MAX_BYTES (64 * 1024) + // How many single-child directories a listing row follows into one path. #define MAX_DIR_CHAIN_LEVELS 15 @@ -101,9 +105,9 @@ static int is_graphic(unsigned char ch) return isprint(ch) && !isspace(ch); } -static void print_binary_buffer(char *buf, size_t size) +static void print_binary_buffer(char *buf, size_t size, const char *path, const char *rev) { - size_t offset, idx; + size_t offset, idx, shown = size < HEXDUMP_MAX_BYTES ? size : HEXDUMP_MAX_BYTES; char ascii[HEXDUMP_ROW_BYTES + 1]; struct strbuf row = STRBUF_INIT; @@ -111,10 +115,10 @@ static void print_binary_buffer(char *buf, size_t size) html("ofshex dumpascii\n"); // A row goes out in one write rather than a write per byte. - for (offset = 0; offset < size; offset += HEXDUMP_ROW_BYTES, buf += HEXDUMP_ROW_BYTES) { + for (offset = 0; offset < shown; offset += HEXDUMP_ROW_BYTES, buf += HEXDUMP_ROW_BYTES) { strbuf_reset(&row); strbuf_addf(&row, "%04zx", offset); - for (idx = 0; idx < HEXDUMP_ROW_BYTES && offset + idx < size; idx++) { + for (idx = 0; idx < HEXDUMP_ROW_BYTES && offset + idx < shown; idx++) { int gap = idx == HEXDUMP_ROW_HALF ? HEXDUMP_GAP_WIDTH : 1; strbuf_addf(&row, "%*s%02x", gap, "", (unsigned char)buf[idx]); @@ -122,7 +126,7 @@ static void print_binary_buffer(char *buf, size_t size) strbuf_addstr(&row, " "); html_raw(row.buf, row.len); - for (idx = 0; idx < HEXDUMP_ROW_BYTES && offset + idx < size; idx++) + for (idx = 0; idx < HEXDUMP_ROW_BYTES && offset + idx < shown; idx++) ascii[idx] = is_graphic(buf[idx]) ? buf[idx] : '.'; ascii[idx] = '\0'; html_txt(ascii); @@ -130,6 +134,12 @@ static void print_binary_buffer(char *buf, size_t size) } strbuf_release(&row); html("\n"); + if (shown < size) { + htmlf("
Only the first %d KB of this file are shown. ", + HEXDUMP_MAX_BYTES / 1024); + cgit_plain_link("View the whole file", NULL, NULL, ctx.qry.head, rev, path); + html(".
\n"); + } } /* @@ -179,7 +189,7 @@ static bool print_object(const struct object_id *oid, const char *path, html(")\n"); if (is_binary) - print_binary_buffer(buf, size); + print_binary_buffer(buf, size, path, rev); else print_text_buffer(filename, buf, size); -- cgit 2.12.1