]> git.cameronkatri.com Git - mandoc.git/commitdiff
Add missing URI encoding when writing HTTP redirects,
authorIngo Schwarze <schwarze@openbsd.org>
Mon, 1 Oct 2018 08:06:53 +0000 (08:06 +0000)
committerIngo Schwarze <schwarze@openbsd.org>
Mon, 1 Oct 2018 08:06:53 +0000 (08:06 +0000)
fixing a bug reported by <jungleboogie0 at gmail dot com> on bugs@.
While here, fully validate the arch name
such that we do not have to URI encode that one.

cgi.c

diff --git a/cgi.c b/cgi.c
index 8098352d614018a9702ef9e05b53eea6d2c8b499..3560f160a95b9a5f870fb27b6998efdbc6dc975f 100644 (file)
--- a/cgi.c
+++ b/cgi.c
@@ -1,4 +1,4 @@
-/*     $Id: cgi.c,v 1.158 2018/05/29 20:32:45 schwarze Exp $ */
+/*     $Id: cgi.c,v 1.159 2018/10/01 08:06:53 schwarze Exp $ */
 /*
  * Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze <schwarze@usta.de>
@@ -69,6 +69,7 @@ enum  focus {
 static void             html_print(const char *);
 static void             html_putchar(char);
 static int              http_decode(char *);
+static void             http_encode(const char *p);
 static void             parse_manpath_conf(struct req *);
 static void             parse_path_info(struct req *req, const char *path);
 static void             parse_query_string(struct req *, const char *);
@@ -90,6 +91,7 @@ static        void             resp_format(const struct req *, const char *);
 static void             resp_searchform(const struct req *, enum focus);
 static void             resp_show(const struct req *, const char *);
 static void             set_query_attr(char **, char **);
+static int              validate_arch(const char *);
 static int              validate_filename(const char *);
 static int              validate_manpath(const struct req *, const char *);
 static int              validate_urifrag(const char *);
@@ -315,6 +317,18 @@ http_decode(char *p)
        return 1;
 }
 
+static void
+http_encode(const char *p)
+{
+       for (; *p != '\0'; p++) {
+               if (isalnum((unsigned char)*p) == 0 &&
+                   strchr("-._~", *p) == NULL)
+                       printf("%%%02.2X", (unsigned char)*p);
+               else
+                       putchar(*p);
+       }
+}
+
 static void
 resp_begin_http(int code, const char *msg)
 {
@@ -489,6 +503,18 @@ validate_manpath(const struct req *req, const char* manpath)
        return 0;
 }
 
+static int
+validate_arch(const char *arch)
+{
+       int      i;
+
+       for (i = 0; i < arch_MAX; i++)
+               if (strcmp(arch, arch_names[i]) == 0)
+                       return 1;
+
+       return 0;
+}
+
 static int
 validate_filename(const char *file)
 {
@@ -562,9 +588,11 @@ pg_redirect(const struct req *req, const char *name)
                printf("%s/", req->q.manpath);
        if (req->q.arch != NULL)
                printf("%s/", req->q.arch);
-       printf("%s", name);
-       if (req->q.sec != NULL)
-               printf(".%s", req->q.sec);
+       http_encode(name);
+       if (req->q.sec != NULL) {
+               putchar('.');
+               http_encode(req->q.sec);
+       }
        printf("\r\nContent-Type: text/html; charset=utf-8\r\n\r\n");
 }
 
@@ -1089,7 +1117,7 @@ main(void)
                return EXIT_FAILURE;
        }
 
-       if ( ! (NULL == req.q.arch || validate_urifrag(req.q.arch))) {
+       if (req.q.arch != NULL && validate_arch(req.q.arch) == 0) {
                pg_error_badrequest(
                    "You specified an invalid architecture.");
                return EXIT_FAILURE;