diff --git a/stagit-index.c b/stagit-index.c
index 84785a9..8a53463 100644
--- a/stagit-index.c
+++ b/stagit-index.c
@@ -28,6 +28,28 @@ joinpath(char *buf, size_t bufsiz, const char *path, const char *path2)
path, path[0] && path[strlen(path) - 1] != '/' ? "/" : "", path2);
}
+/* Percent-encode, see RFC3986 section 2.1. */
+void
+percentencode(FILE *fp, const char *s, size_t len)
+{
+ static char tab[] = "0123456789ABCDEF";
+ unsigned char uc;
+ size_t i;
+
+ for (i = 0; *s && i < len; s++, i++) {
+ uc = *s;
+ /* NOTE: do not encode '/' for paths */
+ if (uc < '/' || uc >= 127 || (uc >= ':' && uc <= '@') ||
+ uc == '[' || uc == ']') {
+ putc('%', fp);
+ putc(tab[(uc >> 4) & 0x0f], fp);
+ putc(tab[uc & 0x0f], fp);
+ } else {
+ putc(uc, fp);
+ }
+ }
+}
+
/* Escape characters below as HTML 2.0 / XML 1.0. */
void
xmlencode(FILE *fp, const char *s, size_t len)
@@ -118,7 +140,7 @@ writelog(FILE *fp)
*p = '\0';
fputs("
", fp);
xmlencode(fp, stripped_name, strlen(stripped_name));
fputs(" | ", fp);
diff --git a/stagit.c b/stagit.c
index d637691..07d7929 100644
--- a/stagit.c
+++ b/stagit.c
@@ -359,6 +359,28 @@ efopen(const char *filename, const char *flags)
return fp;
}
+/* Percent-encode, see RFC3986 section 2.1. */
+void
+percentencode(FILE *fp, const char *s, size_t len)
+{
+ static char tab[] = "0123456789ABCDEF";
+ unsigned char uc;
+ size_t i;
+
+ for (i = 0; *s && i < len; s++, i++) {
+ uc = *s;
+ /* NOTE: do not encode '/' for paths */
+ if (uc < '/' || uc >= 127 || (uc >= ':' && uc <= '@') ||
+ uc == '[' || uc == ']') {
+ putc('%', fp);
+ putc(tab[(uc >> 4) & 0x0f], fp);
+ putc(tab[uc & 0x0f], fp);
+ } else {
+ putc(uc, fp);
+ }
+ }
+}
+
/* Escape characters below as HTML 2.0 / XML 1.0. */
void
xmlencode(FILE *fp, const char *s, size_t len)
@@ -497,7 +519,7 @@ writeheader(FILE *fp, const char *title)
fputs(" |
", fp);
if (cloneurl[0]) {
fputs(" | git clone ", fp);
xmlencode(fp, cloneurl, strlen(cloneurl));
fputs(" |
", fp);
@@ -570,7 +592,7 @@ printcommit(FILE *fp, struct commitinfo *ci)
fputs("Author: ", fp);
xmlencode(fp, ci->author->name, strlen(ci->author->name));
fputs(" <author->email, strlen(ci->author->email));
+ xmlencode(fp, ci->author->email, strlen(ci->author->email)); /* not percent-encoded */
fputs("\">", fp);
xmlencode(fp, ci->author->email, strlen(ci->author->email));
fputs(">\nDate: ", fp);
@@ -665,11 +687,11 @@ printshowfile(FILE *fp, struct commitinfo *ci)
patch = ci->deltas[i]->patch;
delta = git_patch_get_delta(patch);
fprintf(fp, "diff --git a/old_file.path, strlen(delta->old_file.path));
+ percentencode(fp, delta->old_file.path, strlen(delta->old_file.path));
fputs(".html\">", fp);
xmlencode(fp, delta->old_file.path, strlen(delta->old_file.path));
fprintf(fp, " b/new_file.path, strlen(delta->new_file.path));
+ percentencode(fp, delta->new_file.path, strlen(delta->new_file.path));
fprintf(fp, ".html\">");
xmlencode(fp, delta->new_file.path, strlen(delta->new_file.path));
fprintf(fp, "\n");
@@ -1037,7 +1059,7 @@ writefilestree(FILE *fp, git_tree *tree, const char *path)
fputs("", fp);
fputs(filemode(git_tree_entry_filemode(entry)), fp);
fprintf(fp, " | ", fp);
xmlencode(fp, entrypath, strlen(entrypath));
fputs(" | ", fp);
|