diff --git a/qse/cmd/http/httpd.c b/qse/cmd/http/httpd.c index 564bf898..d1363a2a 100644 --- a/qse/cmd/http/httpd.c +++ b/qse/cmd/http/httpd.c @@ -14,7 +14,6 @@ #include #include -#include #if defined(_WIN32) # include diff --git a/qse/cmd/http/ursd.c b/qse/cmd/http/ursd.c index 0439f547..e53ca634 100644 --- a/qse/cmd/http/ursd.c +++ b/qse/cmd/http/ursd.c @@ -17,7 +17,6 @@ #include #include -#include #if defined(_WIN32) # include diff --git a/qse/include/qse/cmn/str.h b/qse/include/qse/cmn/str.h index 985b72a3..605cfb8e 100644 --- a/qse/include/qse/cmn/str.h +++ b/qse/include/qse/cmn/str.h @@ -706,7 +706,7 @@ QSE_EXPORT qse_size_t qse_mbsvfmt ( * terminating null. When \a buf is #QSE_NULL, it returns the number of * characters that would have been written excluding the terminating null * if \a buf has not been #QSE_NULL. If conversion from a wide-character - * string failure, it returns (qse_size_t)-1. + * string fails, it returns (qse_size_t)-1. */ QSE_EXPORT qse_size_t qse_mbsxfmt ( qse_mchar_t* buf, @@ -722,6 +722,36 @@ QSE_EXPORT qse_size_t qse_mbsxvfmt ( va_list ap ); +QSE_EXPORT qse_size_t qse_mbsfmts ( + qse_mchar_t* buf, + const qse_mchar_t* fmt, + ... +); + +QSE_EXPORT qse_size_t qse_mbsvfmts ( + qse_mchar_t* buf, + const qse_mchar_t* fmt, + va_list ap +); + +/** + * The qse_mbsxfmt() function behaves the same as qse_mbsxfmt() except + * that it returns (qse_size_t)-1 if the buffer is not large enough. + */ +QSE_EXPORT qse_size_t qse_mbsxfmts ( + qse_mchar_t* buf, + qse_size_t bsz, + const qse_mchar_t* fmt, + ... +); + +QSE_EXPORT qse_size_t qse_mbsxvfmts ( + qse_mchar_t* buf, + qse_size_t bsz, + const qse_mchar_t* fmt, + va_list ap +); + QSE_EXPORT qse_size_t qse_wcsfmt ( qse_wchar_t* buf, const qse_wchar_t* fmt, @@ -763,17 +793,56 @@ QSE_EXPORT qse_size_t qse_wcsxvfmt ( va_list ap ); +QSE_EXPORT qse_size_t qse_wcsfmts ( + qse_wchar_t* buf, + const qse_wchar_t* fmt, + ... +); + +QSE_EXPORT qse_size_t qse_wcsvfmts ( + qse_wchar_t* buf, + const qse_wchar_t* fmt, + va_list ap +); + +/** + * The qse_wcsxfmts() function behaves the same as qse_wcsxfmt() except + * that it returns (qse_size_t)-1 if the buffer is not large enough. + */ +QSE_EXPORT qse_size_t qse_wcsxfmts ( + qse_wchar_t* buf, + qse_size_t bsz, + const qse_wchar_t* fmt, + ... +); + +QSE_EXPORT qse_size_t qse_wcsxvfmts ( + qse_wchar_t* buf, + qse_size_t bsz, + const qse_wchar_t* fmt, + va_list ap +); #if defined(QSE_CHAR_IS_MCHAR) # define qse_strfmt qse_mbsfmt # define qse_strvfmt qse_mbsvfmt # define qse_strxfmt qse_mbsxfmt # define qse_strxvfmt qse_mbsxvfmt + +# define qse_strfmts qse_mbsfmts +# define qse_strvfmts qse_mbsvfmts +# define qse_strxfmts qse_mbsxfmts +# define qse_strxvfmts qse_mbsxvfmts #else # define qse_strfmt qse_wcsfmt # define qse_strvfmt qse_wcsvfmt # define qse_strxfmt qse_wcsxfmt # define qse_strxvfmt qse_wcsxvfmt + +# define qse_strfmts qse_wcsfmts +# define qse_strvfmts qse_wcsvfmts +# define qse_strxfmts qse_wcsxfmts +# define qse_strxvfmts qse_wcsxvfmts #endif /** diff --git a/qse/lib/cmn/str-fmt.c b/qse/lib/cmn/str-fmt.c index 9ef754a2..fb4c679c 100644 --- a/qse/lib/cmn/str-fmt.c +++ b/qse/lib/cmn/str-fmt.c @@ -77,6 +77,35 @@ static int put_wchar (qse_wchar_t c, void* ctx) return 0; } +static int put_mchar_strict (qse_mchar_t c, void* ctx) +{ + mbuf_t* buf = (mbuf_t*)ctx; + + if (buf->len < buf->capa) + { + buf->ptr[buf->len++] = c; + return 1; + } + + /* buffer is full stop. return error */ + return -1; +} + +static int put_wchar_strict (qse_wchar_t c, void* ctx) +{ + wbuf_t* buf = (wbuf_t*)ctx; + + if (buf->len < buf->capa) + { + buf->ptr[buf->len++] = c; + return 1; + } + + /* buffer is full stop. return error */ + return -1; +} + + static int wcs_to_mbs ( const qse_wchar_t* wcs, qse_size_t* wcslen, qse_mchar_t* mbs, qse_size_t* mbslen, void* ctx) @@ -135,6 +164,35 @@ static int mbs_to_wcs ( #undef strvfmt #undef strxvfmt +#define T(x) QSE_MT(x) +#define char_t qse_mchar_t +#define buf_t mbuf_t +#define fmtout_t qse_mfmtout_t +#define fmtout qse_mfmtout +#define put_char_null put_mchar_null +#define put_char put_mchar_strict +#define conv_char wcs_to_mbs +#define strfmt qse_mbsfmts +#define strxfmt qse_mbsxfmts +#define strvfmt qse_mbsvfmts +#define strxvfmt qse_mbsxvfmts +#include "str-fmt.h" + +/* ----------------------------------- */ + +#undef T +#undef char_t +#undef buf_t +#undef fmtout_t +#undef fmtout +#undef put_char_null +#undef put_char +#undef conv_char +#undef strfmt +#undef strxfmt +#undef strvfmt +#undef strxvfmt + #define T(x) QSE_WT(x) #define char_t qse_wchar_t #define buf_t wbuf_t @@ -149,3 +207,31 @@ static int mbs_to_wcs ( #define strxvfmt qse_wcsxvfmt #include "str-fmt.h" +/* ----------------------------------- */ + +#undef T +#undef char_t +#undef buf_t +#undef fmtout_t +#undef fmtout +#undef put_char_null +#undef put_char +#undef conv_char +#undef strfmt +#undef strxfmt +#undef strvfmt +#undef strxvfmt + +#define T(x) QSE_WT(x) +#define char_t qse_wchar_t +#define buf_t wbuf_t +#define fmtout_t qse_wfmtout_t +#define fmtout qse_wfmtout +#define put_char_null put_wchar_null +#define put_char put_wchar_strict +#define conv_char mbs_to_wcs +#define strfmt qse_wcsfmts +#define strxfmt qse_wcsxfmts +#define strvfmt qse_wcsvfmts +#define strxvfmt qse_wcsxvfmts +#include "str-fmt.h" diff --git a/qse/lib/http/http.c b/qse/lib/http/http.c index e476c1d1..02cd1f4c 100644 --- a/qse/lib/http/http.c +++ b/qse/lib/http/http.c @@ -24,11 +24,6 @@ #include #include "../cmn/mem.h" -#include /* for snprintf. TODO: remove this. */ -#if defined(_MSC_VER) || defined(__BORLANDC__) || (defined(__WATCOMC__) && (__WATCOMC__ < 1200)) -# define snprintf _snprintf -#endif - int qse_comparehttpversions ( const qse_http_version_t* v1, const qse_http_version_t* v2) @@ -378,9 +373,7 @@ qse_mchar_t* qse_fmthttptime ( qse_gmtime (nt, &bt); -/* TODO: avoid using snprintf () */ - - snprintf ( + qse_mbsxfmt ( buf, bufsz, QSE_MT("%s, %d %s %d %02d:%02d:%02d GMT"), wday_name[bt.wday].s, diff --git a/qse/lib/http/httpd-cgi.c b/qse/lib/http/httpd-cgi.c index 11c497fa..7db6f23d 100644 --- a/qse/lib/http/httpd-cgi.c +++ b/qse/lib/http/httpd-cgi.c @@ -35,11 +35,6 @@ # include "../cmn/syscall.h" #endif -#include /* TODO: remove this */ -#if defined(_MSC_VER) || defined(__BORLANDC__) || (defined(__WATCOMC__) && (__WATCOMC__ < 1200)) -# define snprintf _snprintf -#endif - typedef struct task_cgi_arg_t task_cgi_arg_t; struct task_cgi_arg_t { @@ -238,27 +233,19 @@ static int cgi_htrd_peek_script_output (qse_htrd_t* htrd, qse_htre_t* req) if (req->attr.status) { - qse_mchar_t buf[128]; int nstatus; qse_mchar_t* endptr; /* TODO: check the syntax of status value??? if not numeric??? */ QSE_MBSTONUM (nstatus, req->attr.status, &endptr, 10); - snprintf (buf, QSE_COUNTOF(buf), - QSE_MT("HTTP/%d.%d %d "), - cgi->version.major, - cgi->version.minor, - nstatus - ); - /* Would it need this kind of extra work? while (QSE_ISMSPACE(*endptr)) endptr++; if (*endptr == QSE_MT('\0')) .... */ - if (qse_mbs_cat (cgi->res, buf) == (qse_size_t)-1 || + if (qse_mbs_fcat (cgi->res, QSE_MT("HTTP/%d.%d %d "), cgi->version.major, cgi->version.minor, nstatus) == (qse_size_t)-1 || qse_mbs_cat (cgi->res, endptr) == (qse_size_t)-1 || qse_mbs_cat (cgi->res, QSE_MT("\r\n")) == (qse_size_t)-1) { @@ -269,16 +256,12 @@ static int cgi_htrd_peek_script_output (qse_htrd_t* htrd, qse_htre_t* req) else { const qse_htre_hdrval_t* location; - qse_mchar_t buf[128]; location = qse_htre_getheaderval (req, QSE_MT("Location")); if (location) { - snprintf (buf, QSE_COUNTOF(buf), - QSE_MT("HTTP/%d.%d 301 Moved Permanently\r\n"), - cgi->version.major, cgi->version.minor - ); - if (qse_mbs_cat (cgi->res, buf) == (qse_size_t)-1) + if (qse_mbs_fcat (cgi->res, QSE_MT("HTTP/%d.%d 301 Moved Permanently\r\n"), + cgi->version.major, cgi->version.minor) == (qse_size_t)-1) { cgi->httpd->errnum = QSE_HTTPD_ENOMEM; return -1; @@ -289,11 +272,8 @@ static int cgi_htrd_peek_script_output (qse_htrd_t* htrd, qse_htre_t* req) } else { - snprintf (buf, QSE_COUNTOF(buf), - QSE_MT("HTTP/%d.%d 200 OK\r\n"), - cgi->version.major, cgi->version.minor - ); - if (qse_mbs_cat (cgi->res, buf) == (qse_size_t)-1) + if (qse_mbs_fcat (cgi->res, QSE_MT("HTTP/%d.%d 200 OK\r\n"), + cgi->version.major, cgi->version.minor) == (qse_size_t)-1) { cgi->httpd->errnum = QSE_HTTPD_ENOMEM; return -1; @@ -467,7 +447,7 @@ static int cgi_add_env ( #endif qse_env_insertmbs (env, QSE_MT("GATEWAY_INTERFACE"), QSE_MT("CGI/1.1")); - snprintf (buf, QSE_COUNTOF(buf), QSE_MT("HTTP/%d.%d"), (int)v->major, (int)v->minor); + qse_mbsxfmt (buf, QSE_COUNTOF(buf), QSE_MT("HTTP/%d.%d"), (int)v->major, (int)v->minor); qse_env_insertmbs (env, QSE_MT("SERVER_PROTOCOL"), buf); qse_env_insertmbs (env, QSE_MT("SCRIPT_FILENAME"), path); diff --git a/qse/lib/http/httpd-dir.c b/qse/lib/http/httpd-dir.c index 7f7f9264..ee4c3265 100644 --- a/qse/lib/http/httpd-dir.c +++ b/qse/lib/http/httpd-dir.c @@ -23,11 +23,6 @@ #include #include -#include /* TODO: remove this */ -#if defined(_MSC_VER) || defined(__BORLANDC__) || (defined(__WATCOMC__) && (__WATCOMC__ < 1200)) -# define snprintf _snprintf -#endif - typedef struct task_dir_t task_dir_t; struct task_dir_t { @@ -141,14 +136,14 @@ static void fill_chunk_length (task_dseg_t* ctx) while (ctx->buf[ctx->bufpos] == QSE_MT(' ')) ctx->bufpos++; } -static int format_dirent ( +static qse_size_t format_dirent ( qse_httpd_t* httpd, qse_httpd_client_t* client, const qse_httpd_dirent_t* dirent, qse_mchar_t* buf, int bufsz) { /* TODO: page encoding?? utf-8??? or derive name from cmgr or current locale??? */ - int n; + qse_size_t x; qse_mchar_t* encname; qse_mchar_t* escname; @@ -176,9 +171,9 @@ static int format_dirent ( } qse_localtime (&dirent->stat.mtime, &bt); - snprintf (tmbuf, QSE_COUNTOF(tmbuf), + qse_mbsxfmt (tmbuf, QSE_COUNTOF(tmbuf), QSE_MT("%04d-%02d-%02d %02d:%02d:%02d"), - bt.year + QSE_BTIME_YEAR_BASE, bt.mon + 1, bt.mday, + bt.year + QSE_BTIME_YEAR_BASE, bt.mon + 1, bt.mday, bt.hour, bt.min, bt.sec); if (dirent->stat.isdir) @@ -193,7 +188,7 @@ static int format_dirent ( ); } - n = snprintf ( + x = qse_mbsxfmts ( buf, bufsz, QSE_MT("%s%s%s%s\n"), encname, @@ -207,28 +202,24 @@ static int format_dirent ( if (escname != dirent->name) qse_httpd_freemem (httpd, escname); if (encname != dirent->name) QSE_MMGR_FREE (httpd->mmgr, encname); - if (n <= -1 || n >= bufsz) - { - httpd->errnum = QSE_HTTPD_ENOBUF; - return -1; - } - - return n; + if (x == (qse_size_t)-1) httpd->errnum = QSE_HTTPD_ENOBUF; + return x; } static int add_footer (qse_httpd_t* httpd, qse_httpd_client_t* client, task_dseg_t* ctx) { - int x, rem; + qse_size_t x; + int rem; - rem = ctx->chunked? (ctx->buflen - 5): ctx->buflen; + rem = ctx->chunked? (ctx->bufrem - 5): ctx->bufrem; if (rem < 1) { httpd->errnum = QSE_HTTPD_ENOBUF; return -1; } - x = snprintf (&ctx->buf[ctx->buflen], rem, QSE_MT("\n\n"), ctx->foot.ptr); - if (x <= -1 || x >= rem) + x = qse_mbsxfmts (&ctx->buf[ctx->buflen], rem, QSE_MT("\n\n"), ctx->foot.ptr); + if (x == (qse_size_t)-1) { httpd->errnum = QSE_HTTPD_ENOBUF; return -1; @@ -257,7 +248,7 @@ static int task_main_dseg ( { task_dseg_t* ctx = (task_dseg_t*)task->ctx; qse_ssize_t n; - int x; + qse_size_t x; if (ctx->bufpos < ctx->buflen) { @@ -335,17 +326,14 @@ static int task_main_dseg ( qpath_esc = qse_httpd_escapehtml (httpd, ctx->qpath.ptr); if (qpath_esc == QSE_NULL) return -1; - x = snprintf (&ctx->buf[ctx->buflen], ctx->bufrem, + x = qse_mbsxfmts (&ctx->buf[ctx->buflen], ctx->bufrem, QSE_MT("%s\n\n
%s
\n
%s"), ctx->head.ptr, qpath_esc, (is_root? QSE_MT(""): QSE_MT("\n")) ); if (qpath_esc != ctx->qpath.ptr) qse_httpd_freemem (httpd, qpath_esc); -#if 0 - if (x <= -1) -#endif - if (x <= -1 || x >= ctx->bufrem) + if (x == (qse_size_t)-1) { /* return an error if the buffer is too small to * hold the header(httpd->errnum == QSE_HTTPD_ENOBUF). @@ -371,7 +359,7 @@ static int task_main_dseg ( else { if (httpd->opt.scb.dir.read (httpd, ctx->handle, &ctx->dent) <= 0) - ctx->state |= DIRENT_NOMORE; + ctx->state |= DIRENT_NOMORE; } do @@ -391,15 +379,14 @@ static int task_main_dseg ( ctx->state |= FOOTER_PENDING; } else if (ctx->chunked) fill_chunk_length (ctx); - break; + break; } - if (qse_mbscmp (ctx->dent.name, QSE_MT(".")) != 0 && qse_mbscmp (ctx->dent.name, QSE_MT("..")) != 0) { x = format_dirent (httpd, client, &ctx->dent, &ctx->buf[ctx->buflen], ctx->bufrem); - if (x <= -1) + if (x == (qse_size_t)-1) { /* buffer not large enough to hold this entry */ if (ctx->dcount <= 0) @@ -445,7 +432,7 @@ send_dirlist: if (n <= -1) return -1; /* NOTE if (n == 0), it will enter an infinite loop */ - + ctx->bufpos += n; return (ctx->bufpos < ctx->buflen || (ctx->state & FOOTER_PENDING) || !(ctx->state & DIRENT_NOMORE))? 1: 0; } @@ -669,7 +656,7 @@ qse_httpd_task_t* qse_httpd_entaskdir ( status = (httpd->errnum == QSE_HTTPD_ENOENT)? 404: (httpd->errnum == QSE_HTTPD_EACCES)? 403: 500; } - + return qse_httpd_entaskerr (httpd, client, pred, status, req); } diff --git a/qse/lib/http/httpd-std.c b/qse/lib/http/httpd-std.c index fad9b6a6..d8d78976 100644 --- a/qse/lib/http/httpd-std.c +++ b/qse/lib/http/httpd-std.c @@ -107,11 +107,6 @@ # include #endif -#include /* TODO: remove this */ -#if defined(_MSC_VER) || defined(__BORLANDC__) || (defined(__WATCOMC__) && (__WATCOMC__ < 1200)) -# define snprintf _snprintf -#endif - typedef struct server_xtn_t server_xtn_t; struct server_xtn_t { @@ -2142,8 +2137,6 @@ if (qse_htre_getcontentlen(req) > 0) * * NOTE: CONNECT is implemented to ignore many headers like * 'Expect: 100-continue' and 'Connection: keep-alive'. */ - -/* TODO: CHECK if CONNECT is allowed ... */ qse_httpd_discardcontent (httpd, req); } else @@ -2272,7 +2265,7 @@ static int poke_request ( static int format_error ( qse_httpd_t* httpd, qse_httpd_client_t* client, int code, qse_mchar_t* buf, int bufsz) { - int n; + qse_size_t n; server_xtn_t* server_xtn; const qse_mchar_t* head, * foot, * msg; @@ -2286,17 +2279,16 @@ static int format_error ( msg = qse_httpstatustombs(code); -/* TODO: use my own version of snprintf replacement */ - n = snprintf (buf, bufsz, + n = qse_mbsxfmts (buf, bufsz, QSE_MT("%s%s
HTTP ERROR
%d %s
"), head, msg, code, msg, foot); - if (n < 0 || n >= bufsz) + if (n == (qse_size_t)-1) { httpd->errnum = QSE_HTTPD_ENOBUF; return -1; } - return n; + return 0; } static void impede_httpd (qse_httpd_t* httpd) diff --git a/qse/lib/http/httpd-task.c b/qse/lib/http/httpd-task.c index 21f67aae..a0be0fe8 100644 --- a/qse/lib/http/httpd-task.c +++ b/qse/lib/http/httpd-task.c @@ -199,7 +199,7 @@ qse_httpd_task_t* qse_httpd_entask_status ( case 205: case 206: /* nothing to do */ - break; + break; default: if (method != QSE_HTTP_HEAD &&
..