diff options
Diffstat (limited to 'ui-summary.c')
-rw-r--r-- | ui-summary.c | 100 |
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 | ||
17 | static void print_url(char *base, char *suffix) | 18 | static 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. */ |
99 | void cgit_parse_readme(const char *readme, const char *path, char **filename, char **ref, struct cgit_repo *repo) | 100 | static 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 | ||
154 | void cgit_print_repo_readme(char *path) | 133 | void 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 | } |