commit - 33dc7bd2ce65f30f3efefdb4aad6ff16f1dca774
commit + 070fee2709b6be28d90fc074b9c575282d73a142
blob - 8e9a86d49518f0cd0a86f7c333116111749023fc
blob + f6662471730375b3f9548114ec067c572baf7f70
--- gotweb/gotweb.c
+++ gotweb/gotweb.c
static const struct got_error *gw_get_clone_url(char **, struct gw_trans *, char *);
static char *gw_get_got_link(struct gw_trans *);
static char *gw_get_site_link(struct gw_trans *);
-static char *gw_html_escape(const char *);
+static const struct got_error *gw_html_escape(char **, const char *);
static char *gw_colordiff_line(char *);
static char *gw_gen_commit_header(char *, char*);
const struct got_error *error = NULL;
struct gw_header *header = NULL;
char *blame = NULL, *blame_html = NULL, *blame_html_disp = NULL;
- char *age = NULL, *age_html = NULL;
+ char *age = NULL, *age_html = NULL, *escaped_commit_msg = NULL;
enum kcgi_err kerr;
if (pledge("stdio rpath wpath cpath proc exec sendfd unveil",
goto done;
}
+ error = gw_html_escape(&escaped_commit_msg, header->commit_msg);
+ if (error)
+ goto done;
if (asprintf(&blame_html_disp, blame_header, age_html,
- gw_gen_commit_msg_header(gw_html_escape(header->commit_msg)),
- blame_html) == -1) {
+ escaped_commit_msg, blame_html) == -1) {
error = got_error_from_errno("asprintf");
goto done;
}
free(blame_html_disp);
free(blame_html);
free(blame);
+ free(escaped_commit_msg);
return error;
}
const struct got_error *error = NULL;
struct gw_header *header = NULL;
char *diff = NULL, *diff_html = NULL, *diff_html_disp = NULL;
- char *age = NULL, *age_html = NULL;
+ char *age = NULL, *age_html = NULL, *escaped_commit_msg = NULL;
enum kcgi_err kerr;
if (pledge("stdio rpath wpath cpath proc exec sendfd unveil",
error = got_error_from_errno("asprintf");
goto done;
}
+ error = gw_html_escape(&escaped_commit_msg, header->commit_msg);
+ if (error)
+ goto done;
if (asprintf(&diff_html_disp, diff_header,
gw_gen_diff_header(header->parent_id, header->commit_id),
gw_gen_commit_header(header->commit_id, header->refs_str),
gw_gen_tree_header(header->tree_id),
gw_gen_author_header(header->author),
gw_gen_committer_header(header->committer), age_html,
- gw_gen_commit_msg_header(gw_html_escape(header->commit_msg)),
+ gw_gen_commit_msg_header(escaped_commit_msg),
diff_html) == -1) {
error = got_error_from_errno("asprintf");
goto done;
free(diff);
free(age);
free(age_html);
+ free(escaped_commit_msg);
return error;
}
const struct got_error *error = NULL;
char *commits_html, *commits_navs_html;
struct gw_header *header = NULL, *n_header = NULL;
- char *age = NULL, *age_html = NULL;
+ char *age = NULL, *age_html = NULL, *escaped_commit_msg = NULL;
enum kcgi_err kerr;
if ((header = gw_init_header()) == NULL)
TM_LONG);
if (error)
goto done;
- if (asprintf(&age_html, header_age_html, age ? age : "") == -1) {
+ if (asprintf(&age_html, header_age_html, age ? age : "")
+ == -1) {
error = got_error_from_errno("asprintf");
goto done;
}
+ error = gw_html_escape(&escaped_commit_msg,
+ n_header->commit_msg);
+ if (error)
+ goto done;
if (asprintf(&commits_html, commits_line,
gw_gen_commit_header(n_header->commit_id,
n_header->refs_str),
gw_gen_author_header(n_header->author),
gw_gen_committer_header(n_header->committer),
- age_html,
- gw_html_escape(n_header->commit_msg),
+ age_html, escaped_commit_msg,
commits_navs_html) == -1) {
error = got_error_from_errno("asprintf");
goto done;
age = NULL;
free(age_html);
age_html = NULL;
+ free(escaped_commit_msg);
+ escaped_commit_msg = NULL;
kerr = khttp_puts(gw_trans->gw_req, commits_html);
if (kerr != KCGI_OK) {
error = gw_kcgi_error(kerr);
gw_free_headers(n_header);
free(age);
free(age_html);
+ free(escaped_commit_msg);
return error;
}
const struct got_error *error = NULL;
char *briefs_html = NULL, *briefs_navs_html = NULL, *newline;
struct gw_header *header = NULL, *n_header = NULL;
- char *age = NULL, *age_html = NULL;
+ char *age = NULL, *age_html = NULL, *escaped_commit_msg = NULL;
enum kcgi_err kerr;
if ((header = gw_init_header()) == NULL)
error = got_error_from_errno("asprintf");
goto done;
}
+ error = gw_html_escape(&escaped_commit_msg,
+ n_header->commit_msg);
+ if (error)
+ goto done;
if (asprintf(&briefs_html, briefs_line, age_html,
- n_header->author, gw_html_escape(n_header->commit_msg),
+ n_header->author, escaped_commit_msg,
briefs_navs_html) == -1) {
error = got_error_from_errno("asprintf");
goto done;
age = NULL;
free(age_html);
age_html = NULL;
+ free(escaped_commit_msg);
+ escaped_commit_msg = NULL;
kerr = khttp_puts(gw_trans->gw_req, briefs_html);
if (kerr != KCGI_OK) {
error = gw_kcgi_error(kerr);
gw_free_headers(n_header);
free(age);
free(age_html);
+ free(escaped_commit_msg);
return error;
}
const struct got_error *error = NULL;
struct gw_header *header = NULL;
char *tree = NULL, *tree_html = NULL, *tree_html_disp = NULL;
- char *age = NULL, *age_html = NULL;
+ char *age = NULL, *age_html = NULL, *escaped_commit_msg = NULL;
enum kcgi_err kerr;
if (pledge("stdio rpath proc exec sendfd unveil", NULL) == -1)
error = got_error_from_errno("asprintf");
goto done;
}
+ error = gw_html_escape(&escaped_commit_msg, header->commit_msg);
+ if (error)
+ goto done;
if (asprintf(&tree_html_disp, tree_header, age_html,
- gw_gen_commit_msg_header(gw_html_escape(header->commit_msg)),
+ gw_gen_commit_msg_header(escaped_commit_msg),
tree_html) == -1) {
error = got_error_from_errno("asprintf");
goto done;
free(tree);
free(age);
free(age_html);
+ free(escaped_commit_msg);
return error;
}
const struct got_error *error = NULL;
struct gw_header *header = NULL;
char *tag = NULL, *tag_html = NULL, *tag_html_disp = NULL;
+ char *escaped_commit_msg = NULL;
enum kcgi_err kerr;
if (pledge("stdio rpath proc exec sendfd unveil", NULL) == -1)
}
}
+ error = gw_html_escape(&escaped_commit_msg, header->commit_msg);
+ if (error)
+ goto done;
if (asprintf(&tag_html_disp, tag_header,
gw_gen_commit_header(header->commit_id, header->refs_str),
- gw_gen_commit_msg_header(gw_html_escape(header->commit_msg)),
+ gw_gen_commit_msg_header(escaped_commit_msg),
tag_html) == -1) {
error = got_error_from_errno("asprintf");
goto done;
free(tag_html_disp);
free(tag_html);
free(tag);
+ free(escaped_commit_msg);
return error;
}
case(TEMPL_SITEOWNER):
if (gw_trans->gw_conf->got_site_owner != NULL &&
gw_trans->gw_conf->got_show_site_owner) {
- site_owner_name =
- gw_html_escape(gw_trans->gw_conf->got_site_owner);
+ error = gw_html_escape(&site_owner_name,
+ gw_trans->gw_conf->got_site_owner);
+ if (error)
+ return 0;
if (asprintf(&site_owner_name_h, site_owner,
- site_owner_name) == -1)
+ site_owner_name) == -1) {
+ free(site_owner_name);
return 0;
-
+ }
khttp_puts(gw_trans->gw_req, site_owner_name_h);
free(site_owner_name);
free(site_owner_name_h);
goto done;
while ((fgets(buf, 2048, f)) != NULL) {
+ char *escaped_buf;
if (ferror(f))
goto done;
n_buf = buf;
if (newline)
*newline = ' ';
- buf_color = gw_colordiff_line(gw_html_escape(n_buf));
+ error = gw_html_escape(&escaped_buf, n_buf);
+ if (error)
+ goto done;
+ buf_color = gw_colordiff_line(escaped_buf);
if (buf_color == NULL)
continue;
struct got_reflist_entry *re;
char *tags = NULL, *tag_row = NULL, *tags_navs_disp = NULL;
char *age = NULL, *age_html = NULL, *newline, *time_str = NULL;
+ char *escaped_tagger = NULL, *escaped_tag_commit = NULL;
struct buf *diffbuf = NULL;
size_t newsize;
error = gw_get_time_str(&age, tagger_time, TM_LONG);
if (error)
goto done;
+ error = gw_html_escape(&escaped_tagger, tagger);
+ if (error)
+ goto done;
+ error = gw_html_escape(&escaped_tag_commit, tag_commit);
+ if (error)
+ goto done;
if (asprintf(&tag_row, tag_info, age ? age : "",
- gw_html_escape(tagger),
- gw_html_escape(tag_commit)) == -1) {
+ escaped_tagger, escaped_tag_commit) == -1) {
error = got_error_from_errno("asprintf");
goto done;
}
age = NULL;
free(age_html);
age_html = NULL;
+ free(escaped_tagger);
+ escaped_tagger = NULL;
+ free(escaped_tag_commit);
+ escaped_tag_commit = NULL;
free(tag_commit0);
free(tag_row);
got_repo_close(repo);
free(age);
free(age_html);
+ free(escaped_tagger);
+ free(escaped_tag_commit);
if (error)
return NULL;
else
header->committer_time =
got_object_commit_get_committer_time(header->commit);
- if (gw_trans->action != GW_BRIEFS && gw_trans->action != GW_SUMMARY) {
- header->author = strdup(
- gw_html_escape(got_object_commit_get_author(header->commit))
- );
- } else {
- header->author = strdup(
- got_object_commit_get_author(header->commit)
- );
- }
+ error = gw_html_escape(&header->author,
+ got_object_commit_get_author(header->commit));
+ if (error)
+ return error;
+ error = gw_html_escape(&header->committer,
+ got_object_commit_get_committer(header->commit));
+ if (error)
+ return error;
- header->committer = strdup(
- gw_html_escape(got_object_commit_get_committer(header->commit))
- );
-
+ /* XXX Doesn't the log message require escaping? */
error = got_object_commit_get_logmsg(&commit_msg0, header->commit);
if (error)
return error;
if (nl)
*nl = '\0';
- if (strcmp(line, "") != 0)
- line_escape = strdup(gw_html_escape(line));
- else
- line_escape = strdup("");
+ err = gw_html_escape(&line_escape, line);
+ if (err)
+ goto err;
if (a->gw_trans->repo_folder == NULL)
a->gw_trans->repo_folder = strdup("");
return colorized_line;
}
-static char *
-gw_html_escape(const char *html)
+/*
+ * XXX This function should not exist.
+ * We should let khtml_puts(3) handle HTML escaping.
+ */
+static const struct got_error *
+gw_html_escape(char **escaped_html, const char *orig_html)
{
- char *escaped_str = NULL, *buf;
- char c[1];
- size_t sz, i, buff_sz = 2048;
-
- if ((buf = calloc(buff_sz, sizeof(char *))) == NULL)
- return NULL;
+ const struct got_error *error = NULL;
+ struct escape_pair {
+ char c;
+ const char *s;
+ } esc[] = {
+ { '>', ">" },
+ { '<', "<" },
+ { '&', "&" },
+ { '"', """ },
+ { '\'', "'" },
+ { '\n', "<br />" },
+ };
+ size_t orig_len, len;
+ int i, j, x;
- if (html == NULL)
- return NULL;
- else
- if ((sz = strlen(html)) == 0)
- return NULL;
+ orig_len = strlen(orig_html);
+ len = orig_len;
+ for (i = 0; i < orig_len; i++) {
+ for (j = 0; j < nitems(esc); j++) {
+ if (orig_html[i] != esc[j].c)
+ continue;
+ len += strlen(esc[j].s) - 1 /* escaped char */;
+ }
+ }
- /* only work with buff_sz */
- if (buff_sz < sz)
- sz = buff_sz;
+ *escaped_html = calloc(len + 1 /* NUL */, sizeof(**escaped_html));
+ if (*escaped_html == NULL)
+ return got_error_from_errno("calloc");
+
+ x = 0;
+ for (i = 0; i < orig_len; i++) {
+ int escaped = 0;
+ for (j = 0; j < nitems(esc); j++) {
+ if (orig_html[i] != esc[j].c)
+ continue;
- for (i = 0; i < sz; i++) {
- c[0] = html[i];
- switch (c[0]) {
- case ('>'):
- strcat(buf, ">");
+ if (strlcat(*escaped_html, esc[j].s, len + 1)
+ >= len + 1) {
+ error = got_error(GOT_ERR_NO_SPACE);
+ goto done;
+ }
+ x += strlen(esc[j].s);
+ escaped = 1;
break;
- case ('&'):
- strcat(buf, "&");
- break;
- case ('<'):
- strcat(buf, "<");
- break;
- case ('"'):
- strcat(buf, """);
- break;
- case ('\''):
- strcat(buf, "'");
- break;
- case ('\n'):
- strcat(buf, "<br />");
- default:
- strcat(buf, &c[0]);
- break;
}
+ if (!escaped) {
+ (*escaped_html)[x] = orig_html[i];
+ x++;
+ }
}
- asprintf(&escaped_str, "%s", buf);
- free(buf);
- return escaped_str;
+done:
+ if (error) {
+ free(*escaped_html);
+ *escaped_html = NULL;
+ } else {
+ (*escaped_html)[x] = '\0';
+ }
+ return error;
}
int