escaped path names when listing a directory.

added qse_httpd_escapehtml()
This commit is contained in:
hyung-hwan 2013-03-31 15:19:24 +00:00
parent 28119c7289
commit 8363f28e47
4 changed files with 93 additions and 5 deletions

View File

@ -901,6 +901,11 @@ QSE_EXPORT qse_mchar_t* qse_httpd_strntombsdup (
qse_size_t len qse_size_t len
); );
QSE_EXPORT qse_mchar_t* qse_httpd_escapehtml (
qse_httpd_t* httpd,
const qse_mchar_t* str
);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -55,7 +55,7 @@ struct task_dseg_t
qse_size_t tcount; /* total directory entries */ qse_size_t tcount; /* total directory entries */
qse_size_t dcount; /* the number of items in the buffer */ qse_size_t dcount; /* the number of items in the buffer */
qse_mchar_t buf[4096*2]; qse_mchar_t buf[4096*2]; /* is this large enough? */
int bufpos; int bufpos;
int buflen; int buflen;
int bufrem; int bufrem;

View File

@ -2143,16 +2143,23 @@ static int format_dir (
{ {
/* header */ /* header */
const qse_mchar_t* css; const qse_mchar_t* css;
int is_root = (qse_mbscmp (qpath, QSE_MT("/")) == 0); int is_root;
qse_mchar_t* qpath_esc;
is_root = (qse_mbscmp (qpath, QSE_MT("/")) == 0);
if (server_xtn->query (httpd, client->server, QSE_NULL, QSE_NULL, QSE_HTTPD_SERVERSTD_DIRCSS, &css) <= -1) css = QSE_NULL; if (server_xtn->query (httpd, client->server, QSE_NULL, QSE_NULL, QSE_HTTPD_SERVERSTD_DIRCSS, &css) <= -1) css = QSE_NULL;
if (css == QSE_NULL) css = QSE_MT(""); if (css == QSE_NULL) css = QSE_MT("");
/* TODO: html escaping of qpath */ qpath_esc = qse_httpd_escapehtml (httpd, qpath);
if (qpath_esc == QSE_NULL) return -1;
n = snprintf (buf, bufsz, n = snprintf (buf, bufsz,
QSE_MT("<html><head>%s</head><body><div class='header'>%s</div><div class='body'><table>%s"), css, qpath, QSE_MT("<html><head>%s</head><body><div class='header'>%s</div><div class='body'><table>%s"), css, qpath_esc,
(is_root? QSE_MT(""): QSE_MT("<tr><td class='name'><a href='../'>..</a></td><td class='time'></td><td class='size'></td></tr>")) (is_root? QSE_MT(""): QSE_MT("<tr><td class='name'><a href='../'>..</a></td><td class='time'></td><td class='size'></td></tr>"))
); );
if (qpath_esc != qpath) qse_httpd_freemem (httpd, qpath_esc);
} }
else else
{ {
@ -2169,12 +2176,15 @@ static int format_dir (
{ {
/* main entry */ /* main entry */
qse_mchar_t* encname; qse_mchar_t* encname;
qse_mchar_t* escname;
qse_btime_t bt; qse_btime_t bt;
qse_mchar_t tmbuf[32]; qse_mchar_t tmbuf[32];
qse_mchar_t fszbuf[64]; qse_mchar_t fszbuf[64];
/* TODO: better buffer management in case there are /* TODO: better buffer management in case there are
* a lot of file names to escape. */ * a lot of file names to escape. */
/* perform percent-encoding for the anchor */
encname = qse_perenchttpstrdup (dirent->name, httpd->mmgr); encname = qse_perenchttpstrdup (dirent->name, httpd->mmgr);
if (encname == QSE_NULL) if (encname == QSE_NULL)
{ {
@ -2182,6 +2192,14 @@ static int format_dir (
return -1; return -1;
} }
/* perform html escaping for the text */
escname = qse_httpd_escapehtml (httpd, dirent->name);
if (escname == QSE_NULL)
{
if (encname != dirent->name) QSE_MMGR_FREE (httpd->mmgr, encname);
return -1;
}
qse_localtime (&dirent->stat.mtime, &bt); qse_localtime (&dirent->stat.mtime, &bt);
snprintf (tmbuf, QSE_COUNTOF(tmbuf), snprintf (tmbuf, QSE_COUNTOF(tmbuf),
QSE_MT("%04d-%02d-%02d %02d:%02d:%02d"), QSE_MT("%04d-%02d-%02d %02d:%02d:%02d"),
@ -2205,11 +2223,12 @@ static int format_dir (
QSE_MT("<tr><td class='name'><a href='%s%s'>%s%s</a></td><td class='time'>%s</td><td class='size'>%s</td></tr>"), QSE_MT("<tr><td class='name'><a href='%s%s'>%s%s</a></td><td class='time'>%s</td><td class='size'>%s</td></tr>"),
encname, encname,
(dirent->stat.isdir? QSE_MT("/"): QSE_MT("")), (dirent->stat.isdir? QSE_MT("/"): QSE_MT("")),
dirent->name, /* TODO: html escaping for entry name */ escname,
(dirent->stat.isdir? QSE_MT("/"): QSE_MT("")), (dirent->stat.isdir? QSE_MT("/"): QSE_MT("")),
tmbuf, fszbuf tmbuf, fszbuf
); );
if (escname != dirent->name) qse_httpd_freemem (httpd, escname);
if (encname != dirent->name) QSE_MMGR_FREE (httpd->mmgr, encname); if (encname != dirent->name) QSE_MMGR_FREE (httpd->mmgr, encname);
} }

View File

@ -1359,4 +1359,68 @@ const qse_mchar_t* qse_httpd_fmtgmtimetobb (
/* --------------------------------------------------- */ /* --------------------------------------------------- */
qse_mchar_t* qse_httpd_escapehtml (qse_httpd_t* httpd, const qse_mchar_t* str)
{
qse_mchar_t* ptr, * buf;
qse_size_t reqlen = 0;
for (ptr = str; *ptr != QSE_MT('\0'); ptr++)
{
switch (*ptr)
{
case QSE_MT('<'):
case QSE_MT('>'):
reqlen += 4;
break;
case QSE_MT('&'):
reqlen += 5;
break;
default:
reqlen++;
break;
}
}
if (ptr - str == reqlen) return str; /* no escaping is needed */
buf = qse_httpd_allocmem (httpd, QSE_SIZEOF(*buf) * (reqlen + 1));
if (buf == QSE_NULL) return QSE_NULL;
ptr = buf;
while (*str != QSE_MT('\0'))
{
switch (*str)
{
case QSE_MT('<'):
*ptr++ = QSE_MT('&');
*ptr++ = QSE_MT('l');
*ptr++ = QSE_MT('t');
*ptr++ = QSE_MT(';');
break;
case QSE_MT('>'):
*ptr++ = QSE_MT('&');
*ptr++ = QSE_MT('g');
*ptr++ = QSE_MT('t');
*ptr++ = QSE_MT(';');
break;
case QSE_MT('&'):
*ptr++ = QSE_MT('&');
*ptr++ = QSE_MT('a');
*ptr++ = QSE_MT('m');
*ptr++ = QSE_MT('p');
*ptr++ = QSE_MT(';');
break;
default:
*ptr++ = *str;
break;
}
str++;
}
*ptr = QSE_MT('\0');
return buf;
}