diff options
Diffstat (limited to 'ui-clone.c')
-rw-r--r-- | ui-clone.c | 23 |
1 files changed, 19 insertions, 4 deletions
@@ -92,17 +92,32 @@ void cgit_clone_info(void) | |||
92 | 92 | ||
93 | void cgit_clone_objects(void) | 93 | void cgit_clone_objects(void) |
94 | { | 94 | { |
95 | if (!ctx.qry.path) { | 95 | char *p; |
96 | cgit_print_error_page(400, "Bad request", "Bad request"); | 96 | |
97 | return; | 97 | if (!ctx.qry.path) |
98 | } | 98 | goto err; |
99 | 99 | ||
100 | if (!strcmp(ctx.qry.path, "info/packs")) { | 100 | if (!strcmp(ctx.qry.path, "info/packs")) { |
101 | print_pack_info(); | 101 | print_pack_info(); |
102 | return; | 102 | return; |
103 | } | 103 | } |
104 | 104 | ||
105 | /* Avoid directory traversal by forbidding "..", but also work around | ||
106 | * other funny business by just specifying a fairly strict format. For | ||
107 | * example, now we don't have to stress out about the Cygwin port. | ||
108 | */ | ||
109 | for (p = ctx.qry.path; *p; ++p) { | ||
110 | if (*p == '.' && *(p + 1) == '.') | ||
111 | goto err; | ||
112 | if (!isalnum(*p) && *p != '/' && *p != '.' && *p != '-') | ||
113 | goto err; | ||
114 | } | ||
115 | |||
105 | send_file(git_path("objects/%s", ctx.qry.path)); | 116 | send_file(git_path("objects/%s", ctx.qry.path)); |
117 | return; | ||
118 | |||
119 | err: | ||
120 | cgit_print_error_page(400, "Bad request", "Bad request"); | ||
106 | } | 121 | } |
107 | 122 | ||
108 | void cgit_clone_head(void) | 123 | void cgit_clone_head(void) |