about summary refs log tree commit diff stats
path: root/ui-summary.c
diff options
context:
space:
mode:
authorJason A. Donenfeld2013-05-26 15:20:02 +0200
committerJason A. Donenfeld2013-05-26 16:30:03 +0200
commitdcbc0438b2543a733858d62170f3110a89edbed6 (patch)
treebdacfe4546c88bf6b03860ea69a0cad885fa6af4 /ui-summary.c
parentui-summary: Disallow directory traversal (diff)
downloadcgit-dcbc0438b2543a733858d62170f3110a89edbed6.tar.gz
cgit-dcbc0438b2543a733858d62170f3110a89edbed6.zip
readme: use string_list instead of space deliminations
Now this is possible in cgitrc -

readme=:README.md
readme=:readme.md
readme=:README.mkd
readme=:readme.mkd
readme=:README.rst
readme=:readme.rst
readme=:README.html
readme=:readme.html
readme=:README.htm
readme=:readme.htm
readme=:README.txt
readme=:readme.txt
readme=:README
readme=:readme
readme=:INSTALL.txt
readme=:install.txt
readme=:INSTALL
readme=:install

Suggested-by: John Keeping <john@keeping.me.uk>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'ui-summary.c')
-rw-r--r--ui-summary.c100
1 files changed, 45 insertions, 55 deletions
diff --git a/ui-summary.c b/ui-summary.c index 57206dd..d8500d6 100644 --- a/ui-summary.c +++ b/ui-summary.c
@@ -1,7 +1,7 @@
1/* ui-summary.c: functions for generating repo summary page 1/* ui-summary.c: functions for generating repo summary page
2 * 2 *
3 * Copyright (C) 2006 Lars Hjemli 3 * Copyright (C) 2006 Lars Hjemli
4 * Copyright (C) 2010 Jason A. Donenfeld <Jason@zx2c4.com> 4 * Copyright (C) 2010-2013 Jason A. Donenfeld <Jason@zx2c4.com>
5 * 5 *
6 * Licensed under GNU General Public License v2 6 * Licensed under GNU General Public License v2
7 * (see COPYING for full license text) 7 * (see COPYING for full license text)
@@ -13,6 +13,7 @@
13#include "ui-log.h" 13#include "ui-log.h"
14#include "ui-refs.h" 14#include "ui-refs.h"
15#include "ui-blob.h" 15#include "ui-blob.h"
16#include <libgen.h>
16 17
17static void print_url(char *base, char *suffix) 18static void print_url(char *base, char *suffix)
18{ 19{
@@ -95,69 +96,57 @@ void cgit_print_summary()
95 html("</table>"); 96 html("</table>");
96} 97}
97 98
98/* The caller must free filename and ref after calling this. */ 99/* The caller must free the return value. */
99void cgit_parse_readme(const char *readme, const char *path, char **filename, char **ref, struct cgit_repo *repo) 100static char* append_readme_path(const char *filename, const char *ref, const char *path)
100{ 101{
101 const char *slash, *colon; 102 char *file, *base_dir, *full_path, *resolved_base = NULL, *resolved_full = NULL;
102 char *resolved_base, *resolved_full;
103
104 *filename = NULL;
105 *ref = NULL;
106
107 if (!readme || !(*readme))
108 return;
109
110 /* Check if the readme is tracked in the git repo. */
111 colon = strchr(readme, ':');
112 if (colon && strlen(colon) > 1) {
113 /* If it starts with a colon, we want to use
114 * the default branch */
115 if (colon == readme && repo->defbranch)
116 *ref = xstrdup(repo->defbranch);
117 else
118 *ref = xstrndup(readme, colon - readme);
119 readme = colon + 1;
120 }
121
122 /* Prepend repo path to relative readme path unless tracked. */
123 if (!(*ref) && *readme != '/')
124 readme = fmtalloc("%s/%s", repo->path, readme);
125
126 /* If a subpath is specified for the about page, make it relative 103 /* If a subpath is specified for the about page, make it relative
127 * to the directory containing the configured readme. */ 104 * to the directory containing the configured readme. */
128 if (path) { 105
129 slash = strrchr(readme, '/'); 106 file = xstrdup(filename);
130 if (!slash) { 107 base_dir = dirname(file);
131 if (!colon) 108 if (!strcmp(base_dir, ".") || !strcmp(base_dir, "..")) {
132 return; 109 if (!ref) {
133 slash = colon; 110 free(file);
134 } 111 return NULL;
135 *filename = xmalloc(slash - readme + 1 + strlen(path) + 1);
136 strncpy(*filename, readme, slash - readme + 1);
137 if (!(*ref))
138 resolved_base = realpath(*filename, NULL);
139 strcpy(*filename + (slash - readme + 1), path);
140 if (!(*ref))
141 resolved_full = realpath(*filename, NULL);
142 if (!(*ref) && (!resolved_base || !resolved_full || strstr(resolved_full, resolved_base) != resolved_full)) {
143 free(*filename);
144 *filename = NULL;
145 }
146 if (!(*ref)) {
147 free(resolved_base);
148 free(resolved_full);
149 } 112 }
113 full_path = xstrdup(path);
150 } else 114 } else
151 *filename = xstrdup(readme); 115 full_path = fmtalloc("%s/%s", base_dir, path);
116
117 if (!ref) {
118 resolved_base = realpath(base_dir, NULL);
119 resolved_full = realpath(full_path, NULL);
120 if (!resolved_base || !resolved_full || strncmp(resolved_base, resolved_full, strlen(resolved_base))) {
121 free(full_path);
122 full_path = NULL;
123 }
124 }
125
126 free(file);
127 free(resolved_base);
128 free(resolved_full);
129
130 return full_path;
152} 131}
153 132
154void cgit_print_repo_readme(char *path) 133void cgit_print_repo_readme(char *path)
155{ 134{
156 char *filename, *ref; 135 char *filename, *ref;
157 cgit_parse_readme(ctx.repo->readme, path, &filename, &ref, ctx.repo); 136 int free_filename = 0;
158 137
159 if (!filename) 138 if (ctx.repo->readme.nr == 0)
160 return; 139 return;
140
141 filename = ctx.repo->readme.items[0].string;
142 ref = ctx.repo->readme.items[0].util;
143
144 if (path) {
145 free_filename = 1;
146 filename = append_readme_path(filename, ref, path);
147 if (!filename)
148 return;
149 }
161 150
162 /* Print the calculated readme, either from the git repo or from the 151 /* Print the calculated readme, either from the git repo or from the
163 * filesystem, while applying the about-filter. 152 * filesystem, while applying the about-filter.
@@ -168,14 +157,15 @@ void cgit_print_repo_readme(char *path)
168 cgit_open_filter(ctx.repo->about_filter); 157 cgit_open_filter(ctx.repo->about_filter);
169 } 158 }
170 if (ref) 159 if (ref)
171 cgit_print_file(filename, ref); 160 cgit_print_file(filename, ref, 1);
172 else 161 else
173 html_include(filename); 162 html_include(filename);
174 if (ctx.repo->about_filter) { 163 if (ctx.repo->about_filter) {
175 cgit_close_filter(ctx.repo->about_filter); 164 cgit_close_filter(ctx.repo->about_filter);
176 ctx.repo->about_filter->argv[1] = NULL; 165 ctx.repo->about_filter->argv[1] = NULL;
166 free(ref);
177 } 167 }
178 html("</div>"); 168 html("</div>");
179 free(filename); 169 if (free_filename)
180 free(ref); 170 free(filename);
181} 171}