Diff options
Diffstat (limited to 'source/ui-tree.c')
| -rw-r--r-- | source/ui-tree.c | 22 |
1 file changed, 16 insertions, 6 deletions
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("<tr><th>ofs</th><th>hex dump</th><th>ascii</th></tr>\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, "<tr><td class='right'>%04zx</td><td class='hex'>", 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, " </td><td class='hex'>"); 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("</table>\n"); + if (shown < size) { + htmlf("<div class='truncated'>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(".</div>\n"); + } } /* @@ -179,7 +189,7 @@ static bool print_object(const struct object_id *oid, const char *path, html(")</div>\n"); if (is_binary) - print_binary_buffer(buf, size); + print_binary_buffer(buf, size, path, rev); else print_text_buffer(filename, buf, size); |
