comparison src/http/modules/ngx_http_autoindex_module.c @ 4193:63aa6ab94630

Autoindex: escape html in file names.
author Maxim Dounin <mdounin@mdounin.ru>
date Tue, 11 Oct 2011 17:57:41 +0000
parents 61e4af19df9f
children d620f497c50f
comparison
equal deleted inserted replaced
4192:61e4af19df9f 4193:63aa6ab94630
24 24
25 typedef struct { 25 typedef struct {
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 size_t escape_html;
29 30
30 unsigned dir:1; 31 unsigned dir:1;
31 32
32 time_t mtime; 33 time_t mtime;
33 off_t size; 34 off_t size;
135 static ngx_int_t 136 static ngx_int_t
136 ngx_http_autoindex_handler(ngx_http_request_t *r) 137 ngx_http_autoindex_handler(ngx_http_request_t *r)
137 { 138 {
138 u_char *last, *filename, scale; 139 u_char *last, *filename, scale;
139 off_t length; 140 off_t length;
140 size_t len, utf_len, allocated, root; 141 size_t len, char_len, escape_html, allocated, root;
141 ngx_tm_t tm; 142 ngx_tm_t tm;
142 ngx_err_t err; 143 ngx_err_t err;
143 ngx_buf_t *b; 144 ngx_buf_t *b;
144 ngx_int_t rc, size; 145 ngx_int_t rc, size;
145 ngx_str_t path; 146 ngx_str_t path;
337 ngx_cpystrn(entry->name.data, ngx_de_name(&dir), len + 1); 338 ngx_cpystrn(entry->name.data, ngx_de_name(&dir), len + 1);
338 339
339 entry->escape = 2 * ngx_escape_uri(NULL, ngx_de_name(&dir), len, 340 entry->escape = 2 * ngx_escape_uri(NULL, ngx_de_name(&dir), len,
340 NGX_ESCAPE_URI_COMPONENT); 341 NGX_ESCAPE_URI_COMPONENT);
341 342
343 entry->escape_html = ngx_escape_html(NULL, entry->name.data,
344 entry->name.len);
345
342 if (utf8) { 346 if (utf8) {
343 entry->utf_len = ngx_utf8_length(entry->name.data, entry->name.len); 347 entry->utf_len = ngx_utf8_length(entry->name.data, entry->name.len);
344 } else { 348 } else {
345 entry->utf_len = len; 349 entry->utf_len = len;
346 } 350 }
353 if (ngx_close_dir(&dir) == NGX_ERROR) { 357 if (ngx_close_dir(&dir) == NGX_ERROR) {
354 ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno, 358 ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno,
355 ngx_close_dir_n " \"%s\" failed", &path); 359 ngx_close_dir_n " \"%s\" failed", &path);
356 } 360 }
357 361
362 escape_html = ngx_escape_html(NULL, r->uri.data, r->uri.len);
363
358 len = sizeof(title) - 1 364 len = sizeof(title) - 1
359 + r->uri.len 365 + r->uri.len + escape_html
360 + sizeof(header) - 1 366 + sizeof(header) - 1
361 + r->uri.len 367 + r->uri.len + escape_html
362 + sizeof("</h1>") - 1 368 + sizeof("</h1>") - 1
363 + sizeof("<hr><pre><a href=\"../\">../</a>" CRLF) - 1 369 + sizeof("<hr><pre><a href=\"../\">../</a>" CRLF) - 1
364 + sizeof("</pre><hr>") - 1 370 + sizeof("</pre><hr>") - 1
365 + sizeof(tail) - 1; 371 + sizeof(tail) - 1;
366 372
369 len += sizeof("<a href=\"") - 1 375 len += sizeof("<a href=\"") - 1
370 + entry[i].name.len + entry[i].escape 376 + entry[i].name.len + entry[i].escape
371 + 1 /* 1 is for "/" */ 377 + 1 /* 1 is for "/" */
372 + sizeof("\">") - 1 378 + sizeof("\">") - 1
373 + entry[i].name.len - entry[i].utf_len 379 + entry[i].name.len - entry[i].utf_len
380 + entry[i].escape_html
374 + NGX_HTTP_AUTOINDEX_NAME_LEN + sizeof("&gt;") - 2 381 + NGX_HTTP_AUTOINDEX_NAME_LEN + sizeof("&gt;") - 2
375 + sizeof("</a>") - 1 382 + sizeof("</a>") - 1
376 + sizeof(" 28-Sep-1970 12:00 ") - 1 383 + sizeof(" 28-Sep-1970 12:00 ") - 1
377 + 20 /* the file size */ 384 + 20 /* the file size */
378 + 2; 385 + 2;
388 sizeof(ngx_http_autoindex_entry_t), 395 sizeof(ngx_http_autoindex_entry_t),
389 ngx_http_autoindex_cmp_entries); 396 ngx_http_autoindex_cmp_entries);
390 } 397 }
391 398
392 b->last = ngx_cpymem(b->last, title, sizeof(title) - 1); 399 b->last = ngx_cpymem(b->last, title, sizeof(title) - 1);
393 b->last = ngx_cpymem(b->last, r->uri.data, r->uri.len); 400
394 b->last = ngx_cpymem(b->last, header, sizeof(header) - 1); 401 if (escape_html) {
395 b->last = ngx_cpymem(b->last, r->uri.data, r->uri.len); 402 b->last = (u_char *) ngx_escape_html(b->last, r->uri.data, r->uri.len);
403 b->last = ngx_cpymem(b->last, header, sizeof(header) - 1);
404 b->last = (u_char *) ngx_escape_html(b->last, r->uri.data, r->uri.len);
405
406 } else {
407 b->last = ngx_cpymem(b->last, r->uri.data, r->uri.len);
408 b->last = ngx_cpymem(b->last, header, sizeof(header) - 1);
409 b->last = ngx_cpymem(b->last, r->uri.data, r->uri.len);
410 }
411
396 b->last = ngx_cpymem(b->last, "</h1>", sizeof("</h1>") - 1); 412 b->last = ngx_cpymem(b->last, "</h1>", sizeof("</h1>") - 1);
397 413
398 b->last = ngx_cpymem(b->last, "<hr><pre><a href=\"../\">../</a>" CRLF, 414 b->last = ngx_cpymem(b->last, "<hr><pre><a href=\"../\">../</a>" CRLF,
399 sizeof("<hr><pre><a href=\"../\">../</a>" CRLF) - 1); 415 sizeof("<hr><pre><a href=\"../\">../</a>" CRLF) - 1);
400 416
423 439
424 len = entry[i].utf_len; 440 len = entry[i].utf_len;
425 441
426 if (entry[i].name.len != len) { 442 if (entry[i].name.len != len) {
427 if (len > NGX_HTTP_AUTOINDEX_NAME_LEN) { 443 if (len > NGX_HTTP_AUTOINDEX_NAME_LEN) {
428 utf_len = NGX_HTTP_AUTOINDEX_NAME_LEN - 3 + 1; 444 char_len = NGX_HTTP_AUTOINDEX_NAME_LEN - 3 + 1;
429 445
430 } else { 446 } else {
431 utf_len = NGX_HTTP_AUTOINDEX_NAME_LEN + 1; 447 char_len = NGX_HTTP_AUTOINDEX_NAME_LEN + 1;
432 } 448 }
433 449
450 last = b->last;
434 b->last = ngx_utf8_cpystrn(b->last, entry[i].name.data, 451 b->last = ngx_utf8_cpystrn(b->last, entry[i].name.data,
435 utf_len, entry[i].name.len + 1); 452 char_len, entry[i].name.len + 1);
453
454 if (entry[i].escape_html) {
455 b->last = (u_char *) ngx_escape_html(last, entry[i].name.data,
456 b->last - last);
457 }
458
436 last = b->last; 459 last = b->last;
437 460
438 } else { 461 } else {
439 b->last = ngx_cpystrn(b->last, entry[i].name.data, 462 if (entry[i].escape_html) {
440 NGX_HTTP_AUTOINDEX_NAME_LEN + 1); 463 if (len > NGX_HTTP_AUTOINDEX_NAME_LEN) {
441 last = b->last - 3; 464 char_len = NGX_HTTP_AUTOINDEX_NAME_LEN - 3;
465
466 } else {
467 char_len = len;
468 }
469
470 b->last = (u_char *) ngx_escape_html(b->last,
471 entry[i].name.data, char_len);
472 last = b->last;
473
474 } else {
475 b->last = ngx_cpystrn(b->last, entry[i].name.data,
476 NGX_HTTP_AUTOINDEX_NAME_LEN + 1);
477 last = b->last - 3;
478 }
442 } 479 }
443 480
444 if (len > NGX_HTTP_AUTOINDEX_NAME_LEN) { 481 if (len > NGX_HTTP_AUTOINDEX_NAME_LEN) {
445 b->last = ngx_cpymem(last, "..&gt;</a>", sizeof("..&gt;</a>") - 1); 482 b->last = ngx_cpymem(last, "..&gt;</a>", sizeof("..&gt;</a>") - 1);
446 483