summaryrefslogtreecommitdiffabout
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--html.c16
-rw-r--r--html.h1
-rwxr-xr-xtests/setup.sh13
-rwxr-xr-xtests/t0101-index.sh2
-rwxr-xr-xtests/t0104-tree.sh12
-rw-r--r--ui-shared.c20
6 files changed, 53 insertions, 11 deletions
diff --git a/html.c b/html.c
index 36e9a2f..167127f 100644
--- a/html.c
+++ b/html.c
@@ -115,32 +115,48 @@ void html_attr(char *txt)
115 if (c=='<' || c=='>' || c=='\'') { 115 if (c=='<' || c=='>' || c=='\'') {
116 write(htmlfd, txt, t - txt); 116 write(htmlfd, txt, t - txt);
117 if (c=='>') 117 if (c=='>')
118 html("&gt;"); 118 html("&gt;");
119 else if (c=='<') 119 else if (c=='<')
120 html("&lt;"); 120 html("&lt;");
121 else if (c=='\'') 121 else if (c=='\'')
122 html("&quote;"); 122 html("&quote;");
123 txt = t+1; 123 txt = t+1;
124 } 124 }
125 t++; 125 t++;
126 } 126 }
127 if (t!=txt) 127 if (t!=txt)
128 html(txt); 128 html(txt);
129} 129}
130 130
131void html_url_arg(char *txt)
132{
133 char *t = txt;
134 while(t && *t){
135 int c = *t;
136 if (c=='"' || c=='#' || c=='%' || c=='&' || c=='\'' || c=='+' || c=='?') {
137 write(htmlfd, txt, t - txt);
138 write(htmlfd, fmt("%%%2x", c), 3);
139 txt = t+1;
140 }
141 t++;
142 }
143 if (t!=txt)
144 html(txt);
145}
146
131void html_hidden(char *name, char *value) 147void html_hidden(char *name, char *value)
132{ 148{
133 html("<input type='hidden' name='"); 149 html("<input type='hidden' name='");
134 html_attr(name); 150 html_attr(name);
135 html("' value='"); 151 html("' value='");
136 html_attr(value); 152 html_attr(value);
137 html("'/>"); 153 html("'/>");
138} 154}
139 155
140void html_option(char *value, char *text, char *selected_value) 156void html_option(char *value, char *text, char *selected_value)
141{ 157{
142 html("<option value='"); 158 html("<option value='");
143 html_attr(value); 159 html_attr(value);
144 html("'"); 160 html("'");
145 if (selected_value && !strcmp(selected_value, value)) 161 if (selected_value && !strcmp(selected_value, value))
146 html(" selected='selected'"); 162 html(" selected='selected'");
diff --git a/html.h b/html.h
index 3c32935..038cf60 100644
--- a/html.h
+++ b/html.h
@@ -1,22 +1,23 @@
1#ifndef HTML_H 1#ifndef HTML_H
2#define HTML_H 2#define HTML_H
3 3
4extern int htmlfd; 4extern int htmlfd;
5 5
6extern void html_raw(const char *txt, size_t size); 6extern void html_raw(const char *txt, size_t size);
7extern void html(const char *txt); 7extern void html(const char *txt);
8extern void htmlf(const char *format,...); 8extern void htmlf(const char *format,...);
9extern void html_status(int code, const char *msg, int more_headers); 9extern void html_status(int code, const char *msg, int more_headers);
10extern void html_txt(char *txt); 10extern void html_txt(char *txt);
11extern void html_ntxt(int len, char *txt); 11extern void html_ntxt(int len, char *txt);
12extern void html_attr(char *txt); 12extern void html_attr(char *txt);
13extern void html_url_arg(char *txt);
13extern void html_hidden(char *name, char *value); 14extern void html_hidden(char *name, char *value);
14extern void html_option(char *value, char *text, char *selected_value); 15extern void html_option(char *value, char *text, char *selected_value);
15extern void html_link_open(char *url, char *title, char *class); 16extern void html_link_open(char *url, char *title, char *class);
16extern void html_link_close(void); 17extern void html_link_close(void);
17extern void html_fileperm(unsigned short mode); 18extern void html_fileperm(unsigned short mode);
18extern int html_include(const char *filename); 19extern int html_include(const char *filename);
19 20
20extern int http_parse_querystring(char *txt, void (*fn)(const char *name, const char *value)); 21extern int http_parse_querystring(char *txt, void (*fn)(const char *name, const char *value));
21 22
22#endif /* HTML_H */ 23#endif /* HTML_H */
diff --git a/tests/setup.sh b/tests/setup.sh
index e37306e..1457dd5 100755
--- a/tests/setup.sh
+++ b/tests/setup.sh
@@ -18,62 +18,74 @@
18 18
19mkrepo() { 19mkrepo() {
20 name=$1 20 name=$1
21 count=$2 21 count=$2
22 dir=$PWD 22 dir=$PWD
23 test -d $name && return 23 test -d $name && return
24 printf "Creating testrepo %s\n" $name 24 printf "Creating testrepo %s\n" $name
25 mkdir -p $name 25 mkdir -p $name
26 cd $name 26 cd $name
27 git init 27 git init
28 for ((n=1; n<=count; n++)) 28 for ((n=1; n<=count; n++))
29 do 29 do
30 echo $n >file-$n 30 echo $n >file-$n
31 git add file-$n 31 git add file-$n
32 git commit -m "commit $n" 32 git commit -m "commit $n"
33 done 33 done
34 if test "$3" = "testplus"
35 then
36 echo "hello" >a+b
37 git add a+b
38 git commit -m "add a+b"
39 git branch "1+2"
40 fi
34 cd $dir 41 cd $dir
35} 42}
36 43
37setup_repos() 44setup_repos()
38{ 45{
39 rm -rf trash/cache 46 rm -rf trash/cache
40 mkdir -p trash/cache 47 mkdir -p trash/cache
41 mkrepo trash/repos/foo 5 >/dev/null 48 mkrepo trash/repos/foo 5 >/dev/null
42 mkrepo trash/repos/bar 50 >/dev/null 49 mkrepo trash/repos/bar 50 >/dev/null
50 mkrepo trash/repos/foo+bar 10 testplus >/dev/null
43 cat >trash/cgitrc <<EOF 51 cat >trash/cgitrc <<EOF
44virtual-root=/ 52virtual-root=/
45cache-root=$PWD/trash/cache 53cache-root=$PWD/trash/cache
46 54
47cache-size=1021 55cache-size=1021
48snapshots=tar.gz tar.bz zip 56snapshots=tar.gz tar.bz zip
49enable-log-filecount=1 57enable-log-filecount=1
50enable-log-linecount=1 58enable-log-linecount=1
51summary-log=5 59summary-log=5
52summary-branches=5 60summary-branches=5
53summary-tags=5 61summary-tags=5
54 62
55repo.url=foo 63repo.url=foo
56repo.path=$PWD/trash/repos/foo/.git 64repo.path=$PWD/trash/repos/foo/.git
57# Do not specify a description for this repo, as it then will be assigned 65# Do not specify a description for this repo, as it then will be assigned
58# the constant value "[no description]" (which actually used to cause a 66# the constant value "[no description]" (which actually used to cause a
59# segfault). 67# segfault).
60 68
61repo.url=bar 69repo.url=bar
62repo.path=$PWD/trash/repos/bar/.git 70repo.path=$PWD/trash/repos/bar/.git
63repo.desc=the bar repo 71repo.desc=the bar repo
72
73repo.url=foo+bar
74repo.path=$PWD/trash/repos/foo+bar/.git
75repo.desc=the foo+bar repo
64EOF 76EOF
65} 77}
66 78
67prepare_tests() 79prepare_tests()
68{ 80{
69 setup_repos 81 setup_repos
70 rm -f test-output.log 2>/dev/null 82 rm -f test-output.log 2>/dev/null
71 test_count=0 83 test_count=0
72 test_failed=0 84 test_failed=0
73 echo "[$0]" "$@" >test-output.log 85 echo "[$0]" "$@" >test-output.log
74 echo "$@" "($0)" 86 echo "$@" "($0)"
75} 87}
76 88
77tests_done() 89tests_done()
78{ 90{
79 printf "\n" 91 printf "\n"
@@ -100,17 +112,16 @@ run_test()
100 printf " %2d) %-60s [ok]\n" $test_count "$desc" 112 printf " %2d) %-60s [ok]\n" $test_count "$desc"
101 else 113 else
102 ((test_failed++)) 114 ((test_failed++))
103 printf " %2d) %-60s [failed]\n" $test_count "$desc" 115 printf " %2d) %-60s [failed]\n" $test_count "$desc"
104 fi 116 fi
105} 117}
106 118
107cgit_query() 119cgit_query()
108{ 120{
109 CGIT_CONFIG="$PWD/trash/cgitrc" QUERY_STRING="$1" "$PWD/../cgit" 121 CGIT_CONFIG="$PWD/trash/cgitrc" QUERY_STRING="$1" "$PWD/../cgit"
110} 122}
111 123
112cgit_url() 124cgit_url()
113{ 125{
114 CGIT_CONFIG="$PWD/trash/cgitrc" QUERY_STRING="url=$1" "$PWD/../cgit" 126 CGIT_CONFIG="$PWD/trash/cgitrc" QUERY_STRING="url=$1" "$PWD/../cgit"
115} 127}
116
diff --git a/tests/t0101-index.sh b/tests/t0101-index.sh
index 445af6a..07e39f9 100755
--- a/tests/t0101-index.sh
+++ b/tests/t0101-index.sh
@@ -1,15 +1,17 @@
1#!/bin/sh 1#!/bin/sh
2 2
3. ./setup.sh 3. ./setup.sh
4 4
5prepare_tests "Check content on index page" 5prepare_tests "Check content on index page"
6 6
7run_test 'generate index page' 'cgit_url "" >trash/tmp' 7run_test 'generate index page' 'cgit_url "" >trash/tmp'
8run_test 'find foo repo' 'grep -e "foo" trash/tmp' 8run_test 'find foo repo' 'grep -e "foo" trash/tmp'
9run_test 'find foo description' 'grep -e "\[no description\]" trash/tmp' 9run_test 'find foo description' 'grep -e "\[no description\]" trash/tmp'
10run_test 'find bar repo' 'grep -e "bar" trash/tmp' 10run_test 'find bar repo' 'grep -e "bar" trash/tmp'
11run_test 'find bar description' 'grep -e "the bar repo" trash/tmp' 11run_test 'find bar description' 'grep -e "the bar repo" trash/tmp'
12run_test 'find foo+bar repo' 'grep -e ">foo+bar<" trash/tmp'
13run_test 'verify foo+bar link' 'grep -e "/foo+bar/" trash/tmp'
12run_test 'no tree-link' '! grep -e "foo/tree" trash/tmp' 14run_test 'no tree-link' '! grep -e "foo/tree" trash/tmp'
13run_test 'no log-link' '! grep -e "foo/log" trash/tmp' 15run_test 'no log-link' '! grep -e "foo/log" trash/tmp'
14 16
15tests_done 17tests_done
diff --git a/tests/t0104-tree.sh b/tests/t0104-tree.sh
index 2516c72..0d62cc8 100755
--- a/tests/t0104-tree.sh
+++ b/tests/t0104-tree.sh
@@ -5,17 +5,29 @@
5prepare_tests "Check content on tree page" 5prepare_tests "Check content on tree page"
6 6
7run_test 'generate bar/tree' 'cgit_url "bar/tree" >trash/tmp' 7run_test 'generate bar/tree' 'cgit_url "bar/tree" >trash/tmp'
8run_test 'find file-1' 'grep -e "file-1" trash/tmp' 8run_test 'find file-1' 'grep -e "file-1" trash/tmp'
9run_test 'find file-50' 'grep -e "file-50" trash/tmp' 9run_test 'find file-50' 'grep -e "file-50" trash/tmp'
10 10
11run_test 'generate bar/tree/file-50' 'cgit_url "bar/tree/file-50" >trash/tmp' 11run_test 'generate bar/tree/file-50' 'cgit_url "bar/tree/file-50" >trash/tmp'
12 12
13run_test 'find line 1' ' 13run_test 'find line 1' '
14 grep -e "<a id=.n1. name=.n1. href=.#n1.>1</a>" trash/tmp 14 grep -e "<a id=.n1. name=.n1. href=.#n1.>1</a>" trash/tmp
15' 15'
16 16
17run_test 'no line 2' ' 17run_test 'no line 2' '
18 grep -e "<a id=.n2. name=.n2. href=.#n2.>2</a>" trash/tmp 18 grep -e "<a id=.n2. name=.n2. href=.#n2.>2</a>" trash/tmp
19' 19'
20 20
21run_test 'generate foo+bar/tree' 'cgit_url "foo%2bbar/tree" >trash/tmp'
22
23run_test 'verify a+b link' '
24 grep -e "/foo+bar/tree/a+b" trash/tmp
25'
26
27run_test 'generate foo+bar/tree?h=1+2' 'cgit_url "foo%2bbar/tree&h=1%2b2" >trash/tmp'
28
29run_test 'verify a+b?h=1+2 link' '
30 grep -e "/foo+bar/tree/a+b?h=1%2b2" trash/tmp
31'
32
21tests_done 33tests_done
diff --git a/ui-shared.c b/ui-shared.c
index c23bc75..a2f636c 100644
--- a/ui-shared.c
+++ b/ui-shared.c
@@ -208,100 +208,100 @@ static char *repolink(char *title, char *class, char *page, char *head,
208 if (ctx.cfg.virtual_root) { 208 if (ctx.cfg.virtual_root) {
209 html_attr(ctx.cfg.virtual_root); 209 html_attr(ctx.cfg.virtual_root);
210 if (ctx.cfg.virtual_root[strlen(ctx.cfg.virtual_root) - 1] != '/') 210 if (ctx.cfg.virtual_root[strlen(ctx.cfg.virtual_root) - 1] != '/')
211 html("/"); 211 html("/");
212 html_attr(ctx.repo->url); 212 html_attr(ctx.repo->url);
213 if (ctx.repo->url[strlen(ctx.repo->url) - 1] != '/') 213 if (ctx.repo->url[strlen(ctx.repo->url) - 1] != '/')
214 html("/"); 214 html("/");
215 if (page) { 215 if (page) {
216 html(page); 216 html(page);
217 html("/"); 217 html("/");
218 if (path) 218 if (path)
219 html_attr(path); 219 html_attr(path);
220 } 220 }
221 } else { 221 } else {
222 html(ctx.cfg.script_name); 222 html(ctx.cfg.script_name);
223 html("?url="); 223 html("?url=");
224 html_attr(ctx.repo->url); 224 html_url_arg(ctx.repo->url);
225 if (ctx.repo->url[strlen(ctx.repo->url) - 1] != '/') 225 if (ctx.repo->url[strlen(ctx.repo->url) - 1] != '/')
226 html("/"); 226 html("/");
227 if (page) { 227 if (page) {
228 html(page); 228 html_url_arg(page);
229 html("/"); 229 html("/");
230 if (path) 230 if (path)
231 html_attr(path); 231 html_url_arg(path);
232 } 232 }
233 delim = "&amp;"; 233 delim = "&amp;";
234 } 234 }
235 if (head && strcmp(head, ctx.repo->defbranch)) { 235 if (head && strcmp(head, ctx.repo->defbranch)) {
236 html(delim); 236 html(delim);
237 html("h="); 237 html("h=");
238 html_attr(head); 238 html_url_arg(head);
239 delim = "&amp;"; 239 delim = "&amp;";
240 } 240 }
241 return fmt("%s", delim); 241 return fmt("%s", delim);
242} 242}
243 243
244static void reporevlink(char *page, char *name, char *title, char *class, 244static void reporevlink(char *page, char *name, char *title, char *class,
245 char *head, char *rev, char *path) 245 char *head, char *rev, char *path)
246{ 246{
247 char *delim; 247 char *delim;
248 248
249 delim = repolink(title, class, page, head, path); 249 delim = repolink(title, class, page, head, path);
250 if (rev && strcmp(rev, ctx.qry.head)) { 250 if (rev && strcmp(rev, ctx.qry.head)) {
251 html(delim); 251 html(delim);
252 html("id="); 252 html("id=");
253 html_attr(rev); 253 html_url_arg(rev);
254 } 254 }
255 html("'>"); 255 html("'>");
256 html_txt(name); 256 html_txt(name);
257 html("</a>"); 257 html("</a>");
258} 258}
259 259
260void cgit_tree_link(char *name, char *title, char *class, char *head, 260void cgit_tree_link(char *name, char *title, char *class, char *head,
261 char *rev, char *path) 261 char *rev, char *path)
262{ 262{
263 reporevlink("tree", name, title, class, head, rev, path); 263 reporevlink("tree", name, title, class, head, rev, path);
264} 264}
265 265
266void cgit_plain_link(char *name, char *title, char *class, char *head, 266void cgit_plain_link(char *name, char *title, char *class, char *head,
267 char *rev, char *path) 267 char *rev, char *path)
268{ 268{
269 reporevlink("plain", name, title, class, head, rev, path); 269 reporevlink("plain", name, title, class, head, rev, path);
270} 270}
271 271
272void cgit_log_link(char *name, char *title, char *class, char *head, 272void cgit_log_link(char *name, char *title, char *class, char *head,
273 char *rev, char *path, int ofs, char *grep, char *pattern) 273 char *rev, char *path, int ofs, char *grep, char *pattern)
274{ 274{
275 char *delim; 275 char *delim;
276 276
277 delim = repolink(title, class, "log", head, path); 277 delim = repolink(title, class, "log", head, path);
278 if (rev && strcmp(rev, ctx.qry.head)) { 278 if (rev && strcmp(rev, ctx.qry.head)) {
279 html(delim); 279 html(delim);
280 html("id="); 280 html("id=");
281 html_attr(rev); 281 html_url_arg(rev);
282 delim = "&"; 282 delim = "&";
283 } 283 }
284 if (grep && pattern) { 284 if (grep && pattern) {
285 html(delim); 285 html(delim);
286 html("qt="); 286 html("qt=");
287 html_attr(grep); 287 html_url_arg(grep);
288 delim = "&"; 288 delim = "&";
289 html(delim); 289 html(delim);
290 html("q="); 290 html("q=");
291 html_attr(pattern); 291 html_url_arg(pattern);
292 } 292 }
293 if (ofs > 0) { 293 if (ofs > 0) {
294 html(delim); 294 html(delim);
295 html("ofs="); 295 html("ofs=");
296 htmlf("%d", ofs); 296 htmlf("%d", ofs);
297 } 297 }
298 html("'>"); 298 html("'>");
299 html_txt(name); 299 html_txt(name);
300 html("</a>"); 300 html("</a>");
301} 301}
302 302
303void cgit_commit_link(char *name, char *title, char *class, char *head, 303void cgit_commit_link(char *name, char *title, char *class, char *head,
304 char *rev) 304 char *rev)
305{ 305{
306 if (strlen(name) > ctx.cfg.max_msg_len && ctx.cfg.max_msg_len >= 15) { 306 if (strlen(name) > ctx.cfg.max_msg_len && ctx.cfg.max_msg_len >= 15) {
307 name[ctx.cfg.max_msg_len] = '\0'; 307 name[ctx.cfg.max_msg_len] = '\0';
@@ -320,39 +320,39 @@ void cgit_refs_link(char *name, char *title, char *class, char *head,
320 320
321void cgit_snapshot_link(char *name, char *title, char *class, char *head, 321void cgit_snapshot_link(char *name, char *title, char *class, char *head,
322 char *rev, char *archivename) 322 char *rev, char *archivename)
323{ 323{
324 reporevlink("snapshot", name, title, class, head, rev, archivename); 324 reporevlink("snapshot", name, title, class, head, rev, archivename);
325} 325}
326 326
327void cgit_diff_link(char *name, char *title, char *class, char *head, 327void cgit_diff_link(char *name, char *title, char *class, char *head,
328 char *new_rev, char *old_rev, char *path) 328 char *new_rev, char *old_rev, char *path)
329{ 329{
330 char *delim; 330 char *delim;
331 331
332 delim = repolink(title, class, "diff", head, path); 332 delim = repolink(title, class, "diff", head, path);
333 if (new_rev && strcmp(new_rev, ctx.qry.head)) { 333 if (new_rev && strcmp(new_rev, ctx.qry.head)) {
334 html(delim); 334 html(delim);
335 html("id="); 335 html("id=");
336 html_attr(new_rev); 336 html_url_arg(new_rev);
337 delim = "&amp;"; 337 delim = "&amp;";
338 } 338 }
339 if (old_rev) { 339 if (old_rev) {
340 html(delim); 340 html(delim);
341 html("id2="); 341 html("id2=");
342 html_attr(old_rev); 342 html_url_arg(old_rev);
343 } 343 }
344 html("'>"); 344 html("'>");
345 html_txt(name); 345 html_txt(name);
346 html("</a>"); 346 html("</a>");
347} 347}
348 348
349void cgit_patch_link(char *name, char *title, char *class, char *head, 349void cgit_patch_link(char *name, char *title, char *class, char *head,
350 char *rev) 350 char *rev)
351{ 351{
352 reporevlink("patch", name, title, class, head, rev, NULL); 352 reporevlink("patch", name, title, class, head, rev, NULL);
353} 353}
354 354
355void cgit_object_link(struct object *obj) 355void cgit_object_link(struct object *obj)
356{ 356{
357 char *page, *arg, *url; 357 char *page, *arg, *url;
358 358