aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/ngx_string.c22
-rw-r--r--src/core/ngx_string.h13
-rw-r--r--src/http/modules/ngx_http_autoindex_module.c75
3 files changed, 80 insertions, 30 deletions
diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c
index 75bc6578d..8f29e9070 100644
--- a/src/core/ngx_string.c
+++ b/src/core/ngx_string.c
@@ -1380,6 +1380,26 @@ ngx_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
};
+ /* not ALPHA, DIGIT, "-", ".", "_", "~" */
+
+ static uint32_t uri_component[] = {
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+
+ /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
+ 0xfc009fff, /* 1111 1100 0000 0000 1001 1111 1111 1111 */
+
+ /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
+ 0x78000001, /* 0111 1000 0000 0000 0000 0000 0000 0001 */
+
+ /* ~}| {zyx wvut srqp onml kjih gfed cba` */
+ 0xb8000001, /* 1011 1000 0000 0000 0000 0000 0000 0001 */
+
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ 0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ };
+
/* " ", "#", """, "%", "'", %00-%1F, %7F-%FF */
static uint32_t html[] = {
@@ -1443,7 +1463,7 @@ ngx_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
/* mail_auth is the same as memcached */
static uint32_t *map[] =
- { uri, args, html, refresh, memcached, memcached };
+ { uri, args, uri_component, html, refresh, memcached, memcached };
escape = map[type];
diff --git a/src/core/ngx_string.h b/src/core/ngx_string.h
index 2030988d8..2b9c59a5e 100644
--- a/src/core/ngx_string.h
+++ b/src/core/ngx_string.h
@@ -189,12 +189,13 @@ size_t ngx_utf8_length(u_char *p, size_t n);
u_char *ngx_utf8_cpystrn(u_char *dst, u_char *src, size_t n, size_t len);
-#define NGX_ESCAPE_URI 0
-#define NGX_ESCAPE_ARGS 1
-#define NGX_ESCAPE_HTML 2
-#define NGX_ESCAPE_REFRESH 3
-#define NGX_ESCAPE_MEMCACHED 4
-#define NGX_ESCAPE_MAIL_AUTH 5
+#define NGX_ESCAPE_URI 0
+#define NGX_ESCAPE_ARGS 1
+#define NGX_ESCAPE_URI_COMPONENT 2
+#define NGX_ESCAPE_HTML 3
+#define NGX_ESCAPE_REFRESH 4
+#define NGX_ESCAPE_MEMCACHED 5
+#define NGX_ESCAPE_MAIL_AUTH 6
#define NGX_UNESCAPE_URI 1
#define NGX_UNESCAPE_REDIRECT 2
diff --git a/src/http/modules/ngx_http_autoindex_module.c b/src/http/modules/ngx_http_autoindex_module.c
index b67931806..bd7388126 100644
--- a/src/http/modules/ngx_http_autoindex_module.c
+++ b/src/http/modules/ngx_http_autoindex_module.c
@@ -26,9 +26,9 @@ typedef struct {
ngx_str_t name;
size_t utf_len;
size_t escape;
+ size_t escape_html;
unsigned dir:1;
- unsigned colon:1;
time_t mtime;
off_t size;
@@ -138,7 +138,7 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
{
u_char *last, *filename, scale;
off_t length;
- size_t len, utf_len, allocated, root;
+ size_t len, char_len, escape_html, allocated, root;
ngx_tm_t tm;
ngx_err_t err;
ngx_buf_t *b;
@@ -338,7 +338,10 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
ngx_cpystrn(entry->name.data, ngx_de_name(&dir), len + 1);
entry->escape = 2 * ngx_escape_uri(NULL, ngx_de_name(&dir), len,
- NGX_ESCAPE_HTML);
+ NGX_ESCAPE_URI_COMPONENT);
+
+ entry->escape_html = ngx_escape_html(NULL, entry->name.data,
+ entry->name.len);
if (utf8) {
entry->utf_len = ngx_utf8_length(entry->name.data, entry->name.len);
@@ -346,8 +349,6 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
entry->utf_len = len;
}
- entry->colon = (ngx_strchr(entry->name.data, ':') != NULL);
-
entry->dir = ngx_de_is_dir(&dir);
entry->mtime = ngx_de_mtime(&dir);
entry->size = ngx_de_size(&dir);
@@ -358,10 +359,12 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
ngx_close_dir_n " \"%s\" failed", &path);
}
+ escape_html = ngx_escape_html(NULL, r->uri.data, r->uri.len);
+
len = sizeof(title) - 1
- + r->uri.len
+ + r->uri.len + escape_html
+ sizeof(header) - 1
- + r->uri.len
+ + r->uri.len + escape_html
+ sizeof("</h1>") - 1
+ sizeof("<hr><pre><a href=\"../\">../</a>" CRLF) - 1
+ sizeof("</pre><hr>") - 1
@@ -373,7 +376,8 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
+ entry[i].name.len + entry[i].escape
+ 1 /* 1 is for "/" */
+ sizeof("\">") - 1
- + entry[i].name.len - entry[i].utf_len + entry[i].colon * 2
+ + entry[i].name.len - entry[i].utf_len
+ + entry[i].escape_html
+ NGX_HTTP_AUTOINDEX_NAME_LEN + sizeof("&gt;") - 2
+ sizeof("</a>") - 1
+ sizeof(" 28-Sep-1970 12:00 ") - 1
@@ -393,9 +397,18 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
}
b->last = ngx_cpymem(b->last, title, sizeof(title) - 1);
- b->last = ngx_cpymem(b->last, r->uri.data, r->uri.len);
- b->last = ngx_cpymem(b->last, header, sizeof(header) - 1);
- b->last = ngx_cpymem(b->last, r->uri.data, r->uri.len);
+
+ if (escape_html) {
+ b->last = (u_char *) ngx_escape_html(b->last, r->uri.data, r->uri.len);
+ b->last = ngx_cpymem(b->last, header, sizeof(header) - 1);
+ b->last = (u_char *) ngx_escape_html(b->last, r->uri.data, r->uri.len);
+
+ } else {
+ b->last = ngx_cpymem(b->last, r->uri.data, r->uri.len);
+ b->last = ngx_cpymem(b->last, header, sizeof(header) - 1);
+ b->last = ngx_cpymem(b->last, r->uri.data, r->uri.len);
+ }
+
b->last = ngx_cpymem(b->last, "</h1>", sizeof("</h1>") - 1);
b->last = ngx_cpymem(b->last, "<hr><pre><a href=\"../\">../</a>" CRLF,
@@ -406,14 +419,9 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
for (i = 0; i < entries.nelts; i++) {
b->last = ngx_cpymem(b->last, "<a href=\"", sizeof("<a href=\"") - 1);
- if (entry[i].colon) {
- *b->last++ = '.';
- *b->last++ = '/';
- }
-
if (entry[i].escape) {
ngx_escape_uri(b->last, entry[i].name.data, entry[i].name.len,
- NGX_ESCAPE_HTML);
+ NGX_ESCAPE_URI_COMPONENT);
b->last += entry[i].name.len + entry[i].escape;
@@ -433,20 +441,41 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
if (entry[i].name.len != len) {
if (len > NGX_HTTP_AUTOINDEX_NAME_LEN) {
- utf_len = NGX_HTTP_AUTOINDEX_NAME_LEN - 3 + 1;
+ char_len = NGX_HTTP_AUTOINDEX_NAME_LEN - 3 + 1;
} else {
- utf_len = NGX_HTTP_AUTOINDEX_NAME_LEN + 1;
+ char_len = NGX_HTTP_AUTOINDEX_NAME_LEN + 1;
}
+ last = b->last;
b->last = ngx_utf8_cpystrn(b->last, entry[i].name.data,
- utf_len, entry[i].name.len + 1);
+ char_len, entry[i].name.len + 1);
+
+ if (entry[i].escape_html) {
+ b->last = (u_char *) ngx_escape_html(last, entry[i].name.data,
+ b->last - last);
+ }
+
last = b->last;
} else {
- b->last = ngx_cpystrn(b->last, entry[i].name.data,
- NGX_HTTP_AUTOINDEX_NAME_LEN + 1);
- last = b->last - 3;
+ if (entry[i].escape_html) {
+ if (len > NGX_HTTP_AUTOINDEX_NAME_LEN) {
+ char_len = NGX_HTTP_AUTOINDEX_NAME_LEN - 3;
+
+ } else {
+ char_len = len;
+ }
+
+ b->last = (u_char *) ngx_escape_html(b->last,
+ entry[i].name.data, char_len);
+ last = b->last;
+
+ } else {
+ b->last = ngx_cpystrn(b->last, entry[i].name.data,
+ NGX_HTTP_AUTOINDEX_NAME_LEN + 1);
+ last = b->last - 3;
+ }
}
if (len > NGX_HTTP_AUTOINDEX_NAME_LEN) {