about summary refs log tree commit
diff options
context:
space:
mode:
-rw-r--r--html.c26
-rw-r--r--html.h1
-rw-r--r--ui-shared.c8
3 files changed, 32 insertions, 3 deletions
diff --git a/html.c b/html.c
index 959148c..d89df3a 100644
--- a/html.c
+++ b/html.c
@@ -239,6 +239,32 @@ void html_url_arg(const char *txt)
                 html(txt);
 }
 
+void html_header_arg_in_quotes(const char *txt)
+{
+        const char *t = txt;
+        while (t && *t) {
+                unsigned char c = *t;
+                const char *e = NULL;
+                if (c == '\\')
+                        e = "\\\\";
+                else if (c == '\r')
+                        e = "\\r";
+                else if (c == '\n')
+                        e = "\\n";
+                else if (c == '"')
+                        e = "\\\"";
+                if (e) {
+                        html_raw(txt, t - txt);
+                        html(e);
+                        txt = t + 1;
+                }
+                t++;
+        }
+        if (t != txt)
+                html(txt);
+
+}
+
 void html_hidden(const char *name, const char *value)
 {
         html("<input type='hidden' name='");
diff --git a/html.h b/html.h
index c554763..c72e845 100644
--- a/html.h
+++ b/html.h
@@ -23,6 +23,7 @@ extern void html_ntxt(int len, const char *txt);
 extern void html_attr(const char *txt);
 extern void html_url_path(const char *txt);
 extern void html_url_arg(const char *txt);
+extern void html_header_arg_in_quotes(const char *txt);
 extern void html_hidden(const char *name, const char *value);
 extern void html_option(const char *value, const char *text, const char *selected_value);
 extern void html_intoption(int value, const char *text, int selected_value);
diff --git a/ui-shared.c b/ui-shared.c
index 21f581f..54bbde7 100644
--- a/ui-shared.c
+++ b/ui-shared.c
@@ -692,9 +692,11 @@ void cgit_print_http_headers(void)
                 htmlf("Content-Type: %s\n", ctx.page.mimetype);
         if (ctx.page.size)
                 htmlf("Content-Length: %zd\n", ctx.page.size);
-        if (ctx.page.filename)
-                htmlf("Content-Disposition: inline; filename=\"%s\"\n",
-                      ctx.page.filename);
+        if (ctx.page.filename) {
+                html("Content-Disposition: inline; filename=\"");
+                html_header_arg_in_quotes(ctx.page.filename);
+                html("\"\n");
+        }
         if (!ctx.env.authenticated)
                 html("Cache-Control: no-cache, no-store\n");
         htmlf("Last-Modified: %s\n", http_date(ctx.page.modified));