author | Georg Lukas <georg@op-co.de> | 2009-11-28 02:44:33 (UTC) |
---|---|---|
committer | Georg Lukas <georg@op-co.de> | 2009-11-28 02:44:33 (UTC) |
commit | ef07ccc72da0270e9298c36046a0187dc359b0da (patch) (unidiff) | |
tree | 57a2ffdeb929d9b4ed44dfae3a1fb7ca550aac63 /ui-tree.c | |
parent | 545b5a5dcae2a0c322381493ee90f6c37353da9c (diff) | |
download | cgit-ef07ccc72da0270e9298c36046a0187dc359b0da.zip cgit-ef07ccc72da0270e9298c36046a0187dc359b0da.tar.gz cgit-ef07ccc72da0270e9298c36046a0187dc359b0da.tar.bz2 |
"max-blob-size" config var to limit generated HTML size
Sometimes it is not feasible to generate the HTML pretty-print for large
files, especially if a source-filter is involved or binary data is to be
displayed. The "max-blob-size" config var allows to disable HTML output
for blobs bigger than X KBytes. Plain downloads are not affected.
Signed-off-by: Georg Lukas <georg@op-co.de>
-rw-r--r-- | ui-tree.c | 6 |
1 files changed, 6 insertions, 0 deletions
@@ -62,96 +62,102 @@ static void print_text_buffer(const char *name, char *buf, unsigned long size) | |||
62 | static void print_binary_buffer(char *buf, unsigned long size) | 62 | static void print_binary_buffer(char *buf, unsigned long size) |
63 | { | 63 | { |
64 | unsigned long ofs, idx; | 64 | unsigned long ofs, idx; |
65 | static char ascii[ROWLEN + 1]; | 65 | static char ascii[ROWLEN + 1]; |
66 | 66 | ||
67 | html("<table summary='blob content' class='bin-blob'>\n"); | 67 | html("<table summary='blob content' class='bin-blob'>\n"); |
68 | html("<tr><th>ofs</th><th>hex dump</th><th>ascii</th></tr>"); | 68 | html("<tr><th>ofs</th><th>hex dump</th><th>ascii</th></tr>"); |
69 | for (ofs = 0; ofs < size; ofs += ROWLEN, buf += ROWLEN) { | 69 | for (ofs = 0; ofs < size; ofs += ROWLEN, buf += ROWLEN) { |
70 | htmlf("<tr><td class='right'>%04x</td><td class='hex'>", ofs); | 70 | htmlf("<tr><td class='right'>%04x</td><td class='hex'>", ofs); |
71 | for (idx = 0; idx < ROWLEN && ofs + idx < size; idx++) | 71 | for (idx = 0; idx < ROWLEN && ofs + idx < size; idx++) |
72 | htmlf("%*s%02x", | 72 | htmlf("%*s%02x", |
73 | idx == 16 ? 4 : 1, "", | 73 | idx == 16 ? 4 : 1, "", |
74 | buf[idx] & 0xff); | 74 | buf[idx] & 0xff); |
75 | html(" </td><td class='hex'>"); | 75 | html(" </td><td class='hex'>"); |
76 | for (idx = 0; idx < ROWLEN && ofs + idx < size; idx++) | 76 | for (idx = 0; idx < ROWLEN && ofs + idx < size; idx++) |
77 | ascii[idx] = isgraph(buf[idx]) ? buf[idx] : '.'; | 77 | ascii[idx] = isgraph(buf[idx]) ? buf[idx] : '.'; |
78 | ascii[idx] = '\0'; | 78 | ascii[idx] = '\0'; |
79 | html_txt(ascii); | 79 | html_txt(ascii); |
80 | html("</td></tr>\n"); | 80 | html("</td></tr>\n"); |
81 | } | 81 | } |
82 | html("</table>\n"); | 82 | html("</table>\n"); |
83 | } | 83 | } |
84 | 84 | ||
85 | static void print_object(const unsigned char *sha1, char *path, const char *basename) | 85 | static void print_object(const unsigned char *sha1, char *path, const char *basename) |
86 | { | 86 | { |
87 | enum object_type type; | 87 | enum object_type type; |
88 | char *buf; | 88 | char *buf; |
89 | unsigned long size; | 89 | unsigned long size; |
90 | 90 | ||
91 | type = sha1_object_info(sha1, &size); | 91 | type = sha1_object_info(sha1, &size); |
92 | if (type == OBJ_BAD) { | 92 | if (type == OBJ_BAD) { |
93 | cgit_print_error(fmt("Bad object name: %s", | 93 | cgit_print_error(fmt("Bad object name: %s", |
94 | sha1_to_hex(sha1))); | 94 | sha1_to_hex(sha1))); |
95 | return; | 95 | return; |
96 | } | 96 | } |
97 | 97 | ||
98 | buf = read_sha1_file(sha1, &type, &size); | 98 | buf = read_sha1_file(sha1, &type, &size); |
99 | if (!buf) { | 99 | if (!buf) { |
100 | cgit_print_error(fmt("Error reading object %s", | 100 | cgit_print_error(fmt("Error reading object %s", |
101 | sha1_to_hex(sha1))); | 101 | sha1_to_hex(sha1))); |
102 | return; | 102 | return; |
103 | } | 103 | } |
104 | 104 | ||
105 | html(" ("); | 105 | html(" ("); |
106 | cgit_plain_link("plain", NULL, NULL, ctx.qry.head, | 106 | cgit_plain_link("plain", NULL, NULL, ctx.qry.head, |
107 | curr_rev, path); | 107 | curr_rev, path); |
108 | htmlf(")<br/>blob: %s\n", sha1_to_hex(sha1)); | 108 | htmlf(")<br/>blob: %s\n", sha1_to_hex(sha1)); |
109 | 109 | ||
110 | if (ctx.cfg.max_blob_size && size / 1024 > ctx.cfg.max_blob_size) { | ||
111 | htmlf("<div class='error'>blob size (%dKB) exceeds display size limit (%dKB).</div>", | ||
112 | size / 1024, ctx.cfg.max_blob_size); | ||
113 | return; | ||
114 | } | ||
115 | |||
110 | if (buffer_is_binary(buf, size)) | 116 | if (buffer_is_binary(buf, size)) |
111 | print_binary_buffer(buf, size); | 117 | print_binary_buffer(buf, size); |
112 | else | 118 | else |
113 | print_text_buffer(basename, buf, size); | 119 | print_text_buffer(basename, buf, size); |
114 | } | 120 | } |
115 | 121 | ||
116 | 122 | ||
117 | static int ls_item(const unsigned char *sha1, const char *base, int baselen, | 123 | static int ls_item(const unsigned char *sha1, const char *base, int baselen, |
118 | const char *pathname, unsigned int mode, int stage, | 124 | const char *pathname, unsigned int mode, int stage, |
119 | void *cbdata) | 125 | void *cbdata) |
120 | { | 126 | { |
121 | char *name; | 127 | char *name; |
122 | char *fullpath; | 128 | char *fullpath; |
123 | char *class; | 129 | char *class; |
124 | enum object_type type; | 130 | enum object_type type; |
125 | unsigned long size = 0; | 131 | unsigned long size = 0; |
126 | 132 | ||
127 | name = xstrdup(pathname); | 133 | name = xstrdup(pathname); |
128 | fullpath = fmt("%s%s%s", ctx.qry.path ? ctx.qry.path : "", | 134 | fullpath = fmt("%s%s%s", ctx.qry.path ? ctx.qry.path : "", |
129 | ctx.qry.path ? "/" : "", name); | 135 | ctx.qry.path ? "/" : "", name); |
130 | 136 | ||
131 | if (!S_ISGITLINK(mode)) { | 137 | if (!S_ISGITLINK(mode)) { |
132 | type = sha1_object_info(sha1, &size); | 138 | type = sha1_object_info(sha1, &size); |
133 | if (type == OBJ_BAD) { | 139 | if (type == OBJ_BAD) { |
134 | htmlf("<tr><td colspan='3'>Bad object: %s %s</td></tr>", | 140 | htmlf("<tr><td colspan='3'>Bad object: %s %s</td></tr>", |
135 | name, | 141 | name, |
136 | sha1_to_hex(sha1)); | 142 | sha1_to_hex(sha1)); |
137 | return 0; | 143 | return 0; |
138 | } | 144 | } |
139 | } | 145 | } |
140 | 146 | ||
141 | html("<tr><td class='ls-mode'>"); | 147 | html("<tr><td class='ls-mode'>"); |
142 | cgit_print_filemode(mode); | 148 | cgit_print_filemode(mode); |
143 | html("</td><td>"); | 149 | html("</td><td>"); |
144 | if (S_ISGITLINK(mode)) { | 150 | if (S_ISGITLINK(mode)) { |
145 | htmlf("<a class='ls-mod' href='"); | 151 | htmlf("<a class='ls-mod' href='"); |
146 | html_attr(fmt(ctx.repo->module_link, | 152 | html_attr(fmt(ctx.repo->module_link, |
147 | name, | 153 | name, |
148 | sha1_to_hex(sha1))); | 154 | sha1_to_hex(sha1))); |
149 | html("'>"); | 155 | html("'>"); |
150 | html_txt(name); | 156 | html_txt(name); |
151 | html("</a>"); | 157 | html("</a>"); |
152 | } else if (S_ISDIR(mode)) { | 158 | } else if (S_ISDIR(mode)) { |
153 | cgit_tree_link(name, NULL, "ls-dir", ctx.qry.head, | 159 | cgit_tree_link(name, NULL, "ls-dir", ctx.qry.head, |
154 | curr_rev, fullpath); | 160 | curr_rev, fullpath); |
155 | } else { | 161 | } else { |
156 | class = strrchr(name, '.'); | 162 | class = strrchr(name, '.'); |
157 | if (class != NULL) { | 163 | if (class != NULL) { |