- struct commit *commit;
- struct commitinfo *info;
- char *name = (char *)ref->refname;
-
- commit = lookup_commit(ref->object->sha1);
- // object is not really parsed at this point, because of some fallout
- // from previous calls to git functions in cgit_print_log()
- commit->object.parsed = 0;
- if (commit && !parse_commit(commit)){
- info = cgit_parse_commit(commit);
- html("<tr><td>");
- cgit_log_link(name, NULL, NULL, name, NULL, NULL, 0);
- html("</td><td>");
- cgit_print_age(commit->date, -1, NULL);
- html("</td><td>");
- html_txt(info->author);
- html("</td><td>");
- cgit_commit_link(info->subject, NULL, NULL, name, NULL);
- html("</td></tr>\n");
- cgit_free_commitinfo(info);
- } else {
- html("<tr><td>");
- html_txt(name);
- html("</td><td colspan='3'>");
- htmlf("*** bad ref %s ***", sha1_to_hex(ref->object->sha1));
- html("</td></tr>\n");
+ char *file, *base_dir, *full_path, *resolved_base = NULL, *resolved_full = NULL;
+ /* If a subpath is specified for the about page, make it relative
+ * to the directory containing the configured readme. */
+
+ file = xstrdup(filename);
+ base_dir = dirname(file);
+ if (!strcmp(base_dir, ".") || !strcmp(base_dir, "..")) {
+ if (!ref) {
+ free(file);
+ return NULL;
+ }
+ full_path = xstrdup(path);
+ } else
+ full_path = fmtalloc("%s/%s", base_dir, path);
+
+ if (!ref) {
+ resolved_base = realpath(base_dir, NULL);
+ resolved_full = realpath(full_path, NULL);
+ if (!resolved_base || !resolved_full || !starts_with(resolved_full, resolved_base)) {
+ free(full_path);
+ full_path = NULL;
+ }