Mercurial > hg > nginx
comparison src/http/modules/ngx_http_autoindex_module.c @ 4192:61e4af19df9f
Autoindex: escape '?' in file names.
For files with '?' in their names autoindex generated links with '?' not
escaped. This resulted in effectively truncated links as '?' indicates
query string start.
This is an updated version of the patch originally posted at [1]. It
introduces generic NGX_ESCAPE_URI_COMPONENT which escapes everything but
unreserved characters as per RFC 3986. This approach also renders unneeded
special colon processing (as colon is percent-encoded now), it's dropped
accordingly.
[1] http://nginx.org/pipermail/nginx-devel/2010-February/000112.html
Reported by Konstantin Leonov.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Tue, 11 Oct 2011 17:56:51 +0000 |
parents | 84905c7b2aa7 |
children | 63aa6ab94630 |
comparison
equal
deleted
inserted
replaced
4191:08d8af70760c | 4192:61e4af19df9f |
---|---|
26 ngx_str_t name; | 26 ngx_str_t name; |
27 size_t utf_len; | 27 size_t utf_len; |
28 size_t escape; | 28 size_t escape; |
29 | 29 |
30 unsigned dir:1; | 30 unsigned dir:1; |
31 unsigned colon:1; | |
32 | 31 |
33 time_t mtime; | 32 time_t mtime; |
34 off_t size; | 33 off_t size; |
35 } ngx_http_autoindex_entry_t; | 34 } ngx_http_autoindex_entry_t; |
36 | 35 |
336 } | 335 } |
337 | 336 |
338 ngx_cpystrn(entry->name.data, ngx_de_name(&dir), len + 1); | 337 ngx_cpystrn(entry->name.data, ngx_de_name(&dir), len + 1); |
339 | 338 |
340 entry->escape = 2 * ngx_escape_uri(NULL, ngx_de_name(&dir), len, | 339 entry->escape = 2 * ngx_escape_uri(NULL, ngx_de_name(&dir), len, |
341 NGX_ESCAPE_HTML); | 340 NGX_ESCAPE_URI_COMPONENT); |
342 | 341 |
343 if (utf8) { | 342 if (utf8) { |
344 entry->utf_len = ngx_utf8_length(entry->name.data, entry->name.len); | 343 entry->utf_len = ngx_utf8_length(entry->name.data, entry->name.len); |
345 } else { | 344 } else { |
346 entry->utf_len = len; | 345 entry->utf_len = len; |
347 } | 346 } |
348 | |
349 entry->colon = (ngx_strchr(entry->name.data, ':') != NULL); | |
350 | 347 |
351 entry->dir = ngx_de_is_dir(&dir); | 348 entry->dir = ngx_de_is_dir(&dir); |
352 entry->mtime = ngx_de_mtime(&dir); | 349 entry->mtime = ngx_de_mtime(&dir); |
353 entry->size = ngx_de_size(&dir); | 350 entry->size = ngx_de_size(&dir); |
354 } | 351 } |
371 for (i = 0; i < entries.nelts; i++) { | 368 for (i = 0; i < entries.nelts; i++) { |
372 len += sizeof("<a href=\"") - 1 | 369 len += sizeof("<a href=\"") - 1 |
373 + entry[i].name.len + entry[i].escape | 370 + entry[i].name.len + entry[i].escape |
374 + 1 /* 1 is for "/" */ | 371 + 1 /* 1 is for "/" */ |
375 + sizeof("\">") - 1 | 372 + sizeof("\">") - 1 |
376 + entry[i].name.len - entry[i].utf_len + entry[i].colon * 2 | 373 + entry[i].name.len - entry[i].utf_len |
377 + NGX_HTTP_AUTOINDEX_NAME_LEN + sizeof(">") - 2 | 374 + NGX_HTTP_AUTOINDEX_NAME_LEN + sizeof(">") - 2 |
378 + sizeof("</a>") - 1 | 375 + sizeof("</a>") - 1 |
379 + sizeof(" 28-Sep-1970 12:00 ") - 1 | 376 + sizeof(" 28-Sep-1970 12:00 ") - 1 |
380 + 20 /* the file size */ | 377 + 20 /* the file size */ |
381 + 2; | 378 + 2; |
404 tp = ngx_timeofday(); | 401 tp = ngx_timeofday(); |
405 | 402 |
406 for (i = 0; i < entries.nelts; i++) { | 403 for (i = 0; i < entries.nelts; i++) { |
407 b->last = ngx_cpymem(b->last, "<a href=\"", sizeof("<a href=\"") - 1); | 404 b->last = ngx_cpymem(b->last, "<a href=\"", sizeof("<a href=\"") - 1); |
408 | 405 |
409 if (entry[i].colon) { | |
410 *b->last++ = '.'; | |
411 *b->last++ = '/'; | |
412 } | |
413 | |
414 if (entry[i].escape) { | 406 if (entry[i].escape) { |
415 ngx_escape_uri(b->last, entry[i].name.data, entry[i].name.len, | 407 ngx_escape_uri(b->last, entry[i].name.data, entry[i].name.len, |
416 NGX_ESCAPE_HTML); | 408 NGX_ESCAPE_URI_COMPONENT); |
417 | 409 |
418 b->last += entry[i].name.len + entry[i].escape; | 410 b->last += entry[i].name.len + entry[i].escape; |
419 | 411 |
420 } else { | 412 } else { |
421 b->last = ngx_cpymem(b->last, entry[i].name.data, | 413 b->last = ngx_cpymem(b->last, entry[i].name.data, |