enhanced the directory listing handler in bin/webs.c
This commit is contained in:
		
							
								
								
									
										143
									
								
								bin/webs.c
									
									
									
									
									
								
							
							
						
						
									
										143
									
								
								bin/webs.c
									
									
									
									
									
								
							| @ -27,8 +27,16 @@ struct htts_ext_t | |||||||
| }; | }; | ||||||
| typedef struct htts_ext_t htts_ext_t; | typedef struct htts_ext_t htts_ext_t; | ||||||
|  |  | ||||||
|  | struct buff_t | ||||||
|  | { | ||||||
|  | 	hio_uint8_t buf[4096]; | ||||||
|  | 	hio_oow_t len; | ||||||
|  | }; | ||||||
|  | typedef struct buff_t buff_t; | ||||||
|  |  | ||||||
| void untar (hio_t* hio, hio_dev_thr_iopair_t* iop, hio_svc_htts_thr_func_info_t* tfi, void* ctx) | /* ------------------------------------------------------------------------- */ | ||||||
|  |  | ||||||
|  | static void untar (hio_t* hio, hio_dev_thr_iopair_t* iop, hio_svc_htts_thr_func_info_t* tfi, void* ctx) | ||||||
| { | { | ||||||
| 	FILE* wfp = HIO_NULL; | 	FILE* wfp = HIO_NULL; | ||||||
| 	htts_ext_t* ext; | 	htts_ext_t* ext; | ||||||
| @ -82,6 +90,70 @@ done: | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /* ------------------------------------------------------------------------- */ | ||||||
|  |  | ||||||
|  | static hio_oow_t write_all_to_fd (int fd, const hio_uint8_t* ptr, hio_oow_t len) | ||||||
|  | { | ||||||
|  | 	hio_oow_t rem = len; | ||||||
|  |  | ||||||
|  | 	while (rem > 0) | ||||||
|  | 	{ | ||||||
|  | 		hio_ooi_t n; | ||||||
|  | 		n = write(fd, ptr, rem); | ||||||
|  | 		if (n <= -1) break; | ||||||
|  | 		rem -= n; | ||||||
|  | 		ptr += n; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return len - rem; /* return the number of bytes written */ | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static HIO_INLINE void init_buff (buff_t* buf) | ||||||
|  | { | ||||||
|  | 	buf->len = 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int flush_buff_to_fd (int fd, buff_t* buf) | ||||||
|  | { | ||||||
|  | 	if (buf->len > 0) | ||||||
|  | 	{ | ||||||
|  | 		hio_oow_t n; | ||||||
|  | 		n = write_all_to_fd(fd, buf->buf, buf->len); | ||||||
|  | 		buf->len -= n; | ||||||
|  | 		if (buf->len > 0) return -1; | ||||||
|  | 	} | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int write_buff_to_fd (int fd, buff_t* buf, const void* ptr, hio_oow_t len) | ||||||
|  | { | ||||||
|  | 	hio_oow_t rcapa; | ||||||
|  |  | ||||||
|  | 	rcapa = HIO_COUNTOF(buf->buf) - buf->len; | ||||||
|  | 	if (len >= HIO_COUNTOF(buf->buf) + rcapa) | ||||||
|  | 	{ | ||||||
|  | 		if (flush_buff_to_fd(fd, buf) <= -1) return -1; | ||||||
|  | 		if (write_all_to_fd(fd, (const hio_uint8_t*)ptr, len) != len) return -1; | ||||||
|  | 	} | ||||||
|  | 	else if (len >= rcapa) | ||||||
|  | 	{ | ||||||
|  | 		HIO_MEMCPY (&buf->buf[buf->len], ptr, rcapa); | ||||||
|  | 		buf->len += rcapa; | ||||||
|  | 		if (flush_buff_to_fd(fd, buf) <= -1) return -1; | ||||||
|  | 		HIO_MEMCPY (buf->buf, (const hio_uint8_t*)ptr + rcapa, len - rcapa); | ||||||
|  | 		buf->len = len - rcapa; | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		HIO_MEMCPY (&buf->buf[buf->len], ptr, len); | ||||||
|  | 		buf->len += len; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* ------------------------------------------------------------------------- */ | ||||||
|  |  | ||||||
| static const hio_bch_t* file_get_mime_type (hio_svc_htts_t* htts, const hio_bch_t* qpath, const hio_bch_t* file_path, void* ctx) | static const hio_bch_t* file_get_mime_type (hio_svc_htts_t* htts, const hio_bch_t* qpath, const hio_bch_t* file_path, void* ctx) | ||||||
| { | { | ||||||
| 	const hio_bch_t* mt = HIO_NULL; | 	const hio_bch_t* mt = HIO_NULL; | ||||||
| @ -99,6 +171,7 @@ static int file_open_dir_list (hio_svc_htts_t* htts, const hio_bch_t* qpath, con | |||||||
| 	hio_bch_t file_path[] = "/tmp/.XXXXXX"; | 	hio_bch_t file_path[] = "/tmp/.XXXXXX"; | ||||||
| 	int fd = -1; | 	int fd = -1; | ||||||
| 	struct dirent* de; | 	struct dirent* de; | ||||||
|  | 	buff_t buf; | ||||||
|  |  | ||||||
| 	if (ext->ai->file_load_index_page) | 	if (ext->ai->file_load_index_page) | ||||||
| 	{ | 	{ | ||||||
| @ -134,42 +207,66 @@ static int file_open_dir_list (hio_svc_htts_t* htts, const hio_bch_t* qpath, con | |||||||
|  |  | ||||||
| 	unlink (file_path); | 	unlink (file_path); | ||||||
|  |  | ||||||
| 	write (fd, "<html><body>", 12); | 	buf.len = 0; | ||||||
| 	if (!(qpath[0] == '\0' || (qpath[0] == '/' && qpath[1] == '\0'))) | 	init_buff (&buf); | ||||||
| 		write (fd, "<li><a href=\"..\">..</a>", 23); |  | ||||||
|  | 	if (write_buff_to_fd(fd, &buf, "<html><body>", 12) <= -1) goto oops; | ||||||
|  | 	if (!(qpath[0] == '\0' || (qpath[0] == '/' && qpath[1] == '\0')) && | ||||||
|  | 	    write_buff_to_fd(fd, &buf,"<li><a href=\"..\">..</a>", 23) <= -1) goto oops; | ||||||
|  |  | ||||||
| /* TODO: sorting, other informatino like size, */ |  | ||||||
| /* TODO: error handling of write() error */ |  | ||||||
| 	while ((de = readdir(dp))) | 	while ((de = readdir(dp))) | ||||||
| 	{ | 	{ | ||||||
| 		struct stat st; | 		struct stat st; | ||||||
| 		hio_bch_t* tmp_path; | 		hio_bch_t* tptr, * dend; | ||||||
|  | 		hio_bch_t tmp[1024]; /* this must be at least 5 characters large for html escaping */ | ||||||
|  | 		hio_oow_t tml; | ||||||
| 		int n; | 		int n; | ||||||
|  |  | ||||||
| 		if ((de->d_name[0] == '.' && de->d_name[1] == '\0') || | 		if ((de->d_name[0] == '.' && de->d_name[1] == '\0') || | ||||||
| 			(de->d_name[0] == '.' && de->d_name[1] == '.' && de->d_name[2] == '\0')) continue; | 			(de->d_name[0] == '.' && de->d_name[1] == '.' && de->d_name[2] == '\0')) continue; | ||||||
|  |  | ||||||
| 		tmp_path = hio_svc_htts_dupmergepaths(htts, dir_path, de->d_name); | 		tptr = hio_svc_htts_dupmergepaths(htts, dir_path, de->d_name); | ||||||
| 		if (HIO_UNLIKELY(!tmp_path)) continue; | 		if (HIO_UNLIKELY(!tptr)) continue; | ||||||
| 		n = stat(tmp_path, &st); | 		n = stat(tptr, &st); | ||||||
| 		hio_freemem (hio, tmp_path); | 		hio_freemem (hio, tptr); | ||||||
| 		if (HIO_UNLIKELY(n <= -1)) continue; | 		if (HIO_UNLIKELY(n <= -1)) continue; | ||||||
|  |  | ||||||
| 		write (fd, "<li><a href=\"", 13); | 		dend = de->d_name + strlen(de->d_name); | ||||||
|  |  | ||||||
|  | 		if (write_buff_to_fd(fd, &buf, "<li><a href=\"", 13) <= -1) goto oops; | ||||||
|  |  | ||||||
|  | 		for (tptr = de->d_name; tptr < dend; ) | ||||||
| 		{ | 		{ | ||||||
| 		char tmp[1000]; /* TODO:use dynamic buffer?? */ | 			hio_oow_t dlen = dend - tptr; | ||||||
| 		hio_perenc_http_bcstr(0, de->d_name, tmp, HIO_NULL); /* url encoding */ | 			if (dlen > HIO_COUNTOF(tmp) / 3) dlen = HIO_COUNTOF(tmp) / 3; /* it can grow upto 3 folds */ | ||||||
| 		//write (fd, de->d_name, strlen(de->d_name)); | 			HIO_ASSERT (hio, dlen >= 1); | ||||||
| 		write (fd, tmp, strlen(tmp)); | 			tml = hio_perenc_http_bchars(tptr, dlen, tmp, HIO_COUNTOF(tmp), 0); /* feed a chunk that won't overflow the buffer */ | ||||||
| 		} | 			HIO_ASSERT (hio, tml <= HIO_COUNTOF(tmp)); /* the buffer 'tmp' must be large enough */ | ||||||
| 		if (S_ISDIR(st.st_mode)) write (fd, "/", 1); | 			if (write_buff_to_fd(fd, &buf, tmp, tml) <= -1) goto oops; | ||||||
| 		write (fd, "\">", 2); | 			tptr += dlen; | ||||||
| 		write (fd, de->d_name, strlen(de->d_name)); /* TODO: html entity encoding */ |  | ||||||
| 		if (S_ISDIR(st.st_mode)) write (fd, "/", 1); |  | ||||||
| 		write (fd, "</a>", 4); |  | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 	write (fd, "</body></html>\n", 15); | 		if (S_ISDIR(st.st_mode) && write_buff_to_fd(fd, &buf, "/", 1) <= -1) goto oops; | ||||||
|  | 		if (write_buff_to_fd(fd, &buf, "\">", 2) <= -1) goto oops; | ||||||
|  |  | ||||||
|  | 		dend = de->d_name + strlen(de->d_name); | ||||||
|  | 		for (tptr = de->d_name; tptr < dend; ) | ||||||
|  | 		{ | ||||||
|  | 			hio_oow_t dlen = dend - tptr; | ||||||
|  | 			if (dlen > HIO_COUNTOF(tmp) / 5) dlen = HIO_COUNTOF(tmp) / 5; /* it can grow upto 5 folds */ | ||||||
|  | 			HIO_ASSERT (hio, dlen >= 1); | ||||||
|  | 			tml = hio_escape_html_bchars(tptr, dlen, tmp, HIO_COUNTOF(tmp)); /* feed a chunk that won't overflow the buffer */ | ||||||
|  | 			HIO_ASSERT (hio, tml <= HIO_COUNTOF(tmp)); /* the buffer 'tmp' must be large enough */ | ||||||
|  | 			if (write_buff_to_fd(fd, &buf, tmp, tml) <= -1) goto oops; | ||||||
|  | 			tptr += dlen; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if (S_ISDIR(st.st_mode) && write_buff_to_fd(fd, &buf, "/", 1) <= -1) goto oops; | ||||||
|  | 		if (write_buff_to_fd(fd, &buf, "</a>", 4) <= -1) goto oops; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (write_buff_to_fd(fd, &buf, "</body></html>\n", 15) <= -1) goto oops; | ||||||
|  | 	if (flush_buff_to_fd(fd, &buf) <= -1) goto oops; | ||||||
|  |  | ||||||
| 	closedir (dp); | 	closedir (dp); | ||||||
| 	lseek (fd, SEEK_SET, 0); | 	lseek (fd, SEEK_SET, 0); | ||||||
|  | |||||||
| @ -257,26 +257,32 @@ HIO_EXPORT hio_oow_t hio_perdec_http_bcs ( | |||||||
|  |  | ||||||
| /** | /** | ||||||
|  * The hio_perenc_http_bcstr() function performs percent-encoding over a string. |  * The hio_perenc_http_bcstr() function performs percent-encoding over a string. | ||||||
|  * The caller must ensure that the output buffer \a buf is large enough. |  * It returns the length of the encoded string if \a len is long enough to hold | ||||||
|  * If \a nencs is not #HIO_NULL, it is set to the number of characters |  * the resulting string and the terminating null. If the return value is equal to | ||||||
|  * encoded. 0 means no characters in the input string required encoding. |  * or greater than \a len, the buffer pointed to by \a buf of the length \a len | ||||||
|  * \return the length of the output string. |  * is not large enough. | ||||||
|  |  * \return the length of the output string encoded on success or the number of encoded | ||||||
|  |  *         string that would have been written if the buffer has been large enough. | ||||||
|  */ |  */ | ||||||
| HIO_EXPORT hio_oow_t hio_perenc_http_bcstr ( | HIO_EXPORT hio_oow_t hio_perenc_http_bcstr ( | ||||||
| 	int              opt, /**< 0 or bitwise-OR'ed of #hio_perenc_http_bcstr_opt_t */ |  | ||||||
| 	const hio_bch_t* str,  | 	const hio_bch_t* str,  | ||||||
| 	hio_bch_t*       buf, | 	hio_bch_t*       buf, | ||||||
| 	hio_oow_t*       nencs | 	hio_oow_t        len, | ||||||
|  | 	int              opt /**< 0 or bitwise-OR'ed of #hio_perenc_http_bcstr_opt_t */ | ||||||
| ); | ); | ||||||
|  |  | ||||||
| #if 0 | /** | ||||||
| /* TODO: rename this function according to the naming convension */ |  * The hio_perenc_http_bchars() function performs percent-ending over a length-bound string. | ||||||
| HIO_EXPORT hio_bch_t* hio_perenc_http_bcstrdup ( |  * It doesn't null-terminate the result. The buffer requirement is less than hio_perenc_http_bcstr() | ||||||
| 	int                opt, /**< 0 or bitwise-OR'ed of #hio_perenc_http_bcstr_opt_t */ |  * by 1. | ||||||
|  |  */ | ||||||
|  | HIO_EXPORT hio_oow_t hio_perenc_http_bchars ( | ||||||
| 	const hio_bch_t* str, | 	const hio_bch_t* str, | ||||||
| 	hio_mmgr_t*        mmgr | 	hio_oow_t        sln, | ||||||
|  | 	hio_bch_t*       buf, | ||||||
|  | 	hio_oow_t        len, | ||||||
|  | 	int              opt /**< 0 or bitwise-OR'ed of #hio_perenc_http_bcstr_opt_t */ | ||||||
| ); | ); | ||||||
| #endif |  | ||||||
|  |  | ||||||
| HIO_EXPORT int hio_scan_http_qparam ( | HIO_EXPORT int hio_scan_http_qparam ( | ||||||
| 	hio_bch_t*      qparam, | 	hio_bch_t*      qparam, | ||||||
| @ -284,6 +290,18 @@ HIO_EXPORT int hio_scan_http_qparam ( | |||||||
| 	void*           ctx | 	void*           ctx | ||||||
| ); | ); | ||||||
|  |  | ||||||
|  | HIO_EXPORT hio_oow_t hio_escape_html_bchars ( | ||||||
|  | 	const hio_bch_t* str, | ||||||
|  | 	hio_oow_t        sln, | ||||||
|  | 	hio_bch_t*       buf, | ||||||
|  | 	hio_oow_t        len | ||||||
|  | ); | ||||||
|  |  | ||||||
|  | HIO_EXPORT hio_oow_t hio_escape_html_bcstr ( | ||||||
|  | 	const hio_bch_t* str, | ||||||
|  | 	hio_bch_t*       buf, | ||||||
|  | 	hio_oow_t        len | ||||||
|  | ); | ||||||
| /* ------------------------------------------------------------------------- */ | /* ------------------------------------------------------------------------- */ | ||||||
| /* HTTP SERVER SERVICE                                                       */ | /* HTTP SERVER SERVICE                                                       */ | ||||||
| /* ------------------------------------------------------------------------- */ | /* ------------------------------------------------------------------------- */ | ||||||
|  | |||||||
							
								
								
									
										215
									
								
								lib/http.c
									
									
									
									
									
								
							
							
						
						
									
										215
									
								
								lib/http.c
									
									
									
									
									
								
							| @ -499,87 +499,73 @@ hio_oow_t hio_perdec_http_bcs (const hio_bcs_t* str, hio_bch_t* buf, hio_oow_t* | |||||||
|  |  | ||||||
| #define TO_HEX(v) ("0123456789ABCDEF"[(v) & 15]) | #define TO_HEX(v) ("0123456789ABCDEF"[(v) & 15]) | ||||||
|  |  | ||||||
| hio_oow_t hio_perenc_http_bcstr (int opt, const hio_bch_t* str, hio_bch_t* buf, hio_oow_t* nencs) | hio_oow_t hio_perenc_http_bchars (const hio_bch_t* str, hio_oow_t sln, hio_bch_t* buf, hio_oow_t len, int opt) | ||||||
| { | { | ||||||
| 	const hio_bch_t* p = str; | 	const hio_bch_t* ptr, * end = str + sln; | ||||||
| 	hio_bch_t* out = buf; | 	hio_bch_t* out = buf; | ||||||
| 	hio_oow_t enc_count = 0; | 	hio_bch_t slash; | ||||||
|  | 	hio_oow_t reqlen = 0; | ||||||
|  |  | ||||||
| 	/* this function doesn't accept the size of the buffer. the caller must  | 	slash = (opt & HIO_PERENC_HTTP_KEEP_SLASH)? '/': '\0'; | ||||||
| 	 * ensure that the buffer is large enough */ |  | ||||||
|  |  | ||||||
| 	if (opt & HIO_PERENC_HTTP_KEEP_SLASH) | 	for (ptr = str; ptr < end; ptr++) | ||||||
| 	{ | 	{ | ||||||
| 		while (*p != '\0') | 		reqlen += (IS_UNRESERVED(*ptr) || *ptr == slash)? 1: 3; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (len >= reqlen) | ||||||
| 	{ | 	{ | ||||||
| 			if (IS_UNRESERVED(*p) || *p == '/') *out++ = *p; | 		ptr = str; | ||||||
|  | 		while (ptr < end) | ||||||
|  | 		{ | ||||||
|  | 			if (IS_UNRESERVED(*ptr) || *ptr == slash) *out++ = *ptr; | ||||||
| 			else | 			else | ||||||
| 			{ | 			{ | ||||||
| 				*out++ = '%'; | 				*out++ = '%'; | ||||||
| 				*out++ = TO_HEX (*p >> 4); | 				*out++ = TO_HEX(*ptr >> 4); | ||||||
| 				*out++ = TO_HEX (*p & 15); | 				*out++ = TO_HEX(*ptr & 15); | ||||||
| 				enc_count++; |  | ||||||
| 			} | 			} | ||||||
| 			p++; | 			ptr++; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	else |  | ||||||
|  | 	return reqlen; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | hio_oow_t hio_perenc_http_bcstr (const hio_bch_t* str, hio_bch_t* buf, hio_oow_t len, int opt) | ||||||
| { | { | ||||||
| 		while (*p != '\0') | 	const hio_bch_t* ptr = str; | ||||||
|  | 	hio_bch_t* out = buf; | ||||||
|  | 	hio_bch_t slash; | ||||||
|  | 	hio_oow_t reqlen = 0; | ||||||
|  |  | ||||||
|  | 	slash = (opt & HIO_PERENC_HTTP_KEEP_SLASH)? '/': '\0'; | ||||||
|  |  | ||||||
|  | 	for (ptr = str; *ptr != '\0'; ptr++) | ||||||
| 	{ | 	{ | ||||||
| 			if (IS_UNRESERVED(*p)) *out++ = *p; | 		reqlen += (IS_UNRESERVED(*ptr) || *ptr == slash)? 1: 3; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (len > reqlen) | ||||||
|  | 	{ | ||||||
|  | 		ptr = str; | ||||||
|  | 		while (*ptr != '\0') | ||||||
|  | 		{ | ||||||
|  | 			if (IS_UNRESERVED(*ptr) || *ptr == slash) *out++ = *ptr; | ||||||
| 			else | 			else | ||||||
| 			{ | 			{ | ||||||
| 				*out++ = '%'; | 				*out++ = '%'; | ||||||
| 				*out++ = TO_HEX (*p >> 4); | 				*out++ = TO_HEX(*ptr >> 4); | ||||||
| 				*out++ = TO_HEX (*p & 15); | 				*out++ = TO_HEX(*ptr & 15); | ||||||
| 				enc_count++; |  | ||||||
| 			} |  | ||||||
| 			p++; |  | ||||||
| 			} | 			} | ||||||
|  | 			ptr++; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		*out = '\0'; | 		*out = '\0'; | ||||||
| 	if (nencs) *nencs = enc_count; |  | ||||||
| 	return out - buf; |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| #if 0 | 	return reqlen; | ||||||
| hio_bch_t* hio_perenc_http_bcstrdup (int opt, const hio_bch_t* str, hio_mmgr_t* mmgr) |  | ||||||
| { |  | ||||||
| 	hio_bch_t* buf; |  | ||||||
| 	hio_oow_t len = 0; |  | ||||||
| 	hio_oow_t count = 0; |  | ||||||
| 	 |  | ||||||
| 	/* count the number of characters that should be encoded */ |  | ||||||
| 	if (opt & HIO_PERENC_HTTP_KEEP_SLASH) |  | ||||||
| 	{ |  | ||||||
| 		for (len = 0; str[len] != '\0'; len++) |  | ||||||
| 		{ |  | ||||||
| 			if (!IS_UNRESERVED(str[len]) && str[len] != '/') count++; |  | ||||||
| } | } | ||||||
| 	} |  | ||||||
| 	else |  | ||||||
| 	{ |  | ||||||
| 		for (len = 0; str[len] != '\0'; len++) |  | ||||||
| 		{ |  | ||||||
| 			if (!IS_UNRESERVED(str[len])) count++; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	/* if there are no characters to escape, just return the original string */ |  | ||||||
| 	if (count <= 0) return (hio_bch_t*)str; |  | ||||||
|  |  | ||||||
| 	/* allocate a buffer of an optimal size for escaping, otherwise */ |  | ||||||
| 	buf = HIO_MMGR_ALLOC(mmgr, (len  + (count * 2) + 1)  * HIO_SIZEOF(*buf)); |  | ||||||
| 	if (!buf) return HIO_NULL; |  | ||||||
|  |  | ||||||
| 	/* perform actual escaping */ |  | ||||||
| 	hio_perenc_http_bcstr (opt, str, buf, HIO_NULL); |  | ||||||
|  |  | ||||||
| 	return buf; |  | ||||||
| } |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|  |  | ||||||
| int hio_scan_http_qparam (hio_bch_t* qparam, int (*qparamcb) (hio_bcs_t* key, hio_bcs_t* val, void* ctx), void* ctx) | int hio_scan_http_qparam (hio_bch_t* qparam, int (*qparamcb) (hio_bcs_t* key, hio_bcs_t* val, void* ctx), void* ctx) | ||||||
| { | { | ||||||
| @ -638,3 +624,116 @@ int hio_scan_http_qparam (hio_bch_t* qparam, int (*qparamcb) (hio_bcs_t* key, hi | |||||||
|  |  | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | hio_oow_t hio_escape_html_bchars (const hio_bch_t* str, hio_oow_t sln, hio_bch_t* buf, hio_oow_t len) | ||||||
|  | { | ||||||
|  | 	hio_bch_t* ptr, * end = str + sln; | ||||||
|  | 	hio_oow_t reqlen = 0; | ||||||
|  |  | ||||||
|  | 	for (ptr = (hio_bch_t*)str; ptr < end; ptr++) | ||||||
|  | 	{ | ||||||
|  | 		switch (*ptr) | ||||||
|  | 		{ | ||||||
|  | 			case '<': | ||||||
|  | 			case '>': | ||||||
|  | 				reqlen += 4; | ||||||
|  | 				break; | ||||||
|  |  | ||||||
|  | 			case '&': | ||||||
|  | 				reqlen += 5; | ||||||
|  | 				break; | ||||||
|  |  | ||||||
|  | 			default: | ||||||
|  | 				reqlen++; | ||||||
|  | 				break; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (len >= reqlen) | ||||||
|  | 	{ | ||||||
|  | 		/* the buffer is large enough */ | ||||||
|  | 		ptr = buf; | ||||||
|  | 		while (str < end) | ||||||
|  | 		{ | ||||||
|  | 			switch (*str) | ||||||
|  | 			{ | ||||||
|  | 				case '<': | ||||||
|  | 					*ptr++ = '&'; *ptr++ = 'l';	*ptr++ = 't'; *ptr++ = ';'; | ||||||
|  | 					break; | ||||||
|  |  | ||||||
|  | 				case '>': | ||||||
|  | 					*ptr++ = '&'; *ptr++ = 'g'; *ptr++ = 't'; *ptr++ = ';'; | ||||||
|  | 					break; | ||||||
|  |  | ||||||
|  | 				case '&': | ||||||
|  | 					*ptr++ = '&'; *ptr++ = 'a'; *ptr++ = 'm'; *ptr++ = 'p'; *ptr++ = ';'; | ||||||
|  | 					break; | ||||||
|  |  | ||||||
|  | 				default: | ||||||
|  | 					*ptr++ = *str; | ||||||
|  | 					break; | ||||||
|  | 			} | ||||||
|  | 			str++; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/* NOTE no null termination */ | ||||||
|  | 	return reqlen; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | hio_oow_t hio_escape_html_bcstr (const hio_bch_t* str, hio_bch_t* buf, hio_oow_t len) | ||||||
|  | { | ||||||
|  | 	hio_bch_t* ptr; | ||||||
|  | 	hio_oow_t reqlen = 0; | ||||||
|  |  | ||||||
|  | 	for (ptr = (hio_bch_t*)str; *ptr != '\0'; ptr++) | ||||||
|  | 	{ | ||||||
|  | 		switch (*ptr) | ||||||
|  | 		{ | ||||||
|  | 			case '<': | ||||||
|  | 			case '>': | ||||||
|  | 				reqlen += 4; | ||||||
|  | 				break; | ||||||
|  |  | ||||||
|  | 			case '&': | ||||||
|  | 				reqlen += 5; | ||||||
|  | 				break; | ||||||
|  |  | ||||||
|  | 			default: | ||||||
|  | 				reqlen++; | ||||||
|  | 				break; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (len > reqlen) | ||||||
|  | 	{ | ||||||
|  | 		/* the buffer is large enough */ | ||||||
|  | 		ptr = buf; | ||||||
|  | 		while (*str != '\0') | ||||||
|  | 		{ | ||||||
|  | 			switch (*str) | ||||||
|  | 			{ | ||||||
|  | 				case '<': | ||||||
|  | 					*ptr++ = '&'; *ptr++ = 'l';	*ptr++ = 't'; *ptr++ = ';'; | ||||||
|  | 					break; | ||||||
|  |  | ||||||
|  | 				case '>': | ||||||
|  | 					*ptr++ = '&'; *ptr++ = 'g'; *ptr++ = 't'; *ptr++ = ';'; | ||||||
|  | 					break; | ||||||
|  |  | ||||||
|  | 				case '&': | ||||||
|  | 					*ptr++ = '&'; *ptr++ = 'a'; *ptr++ = 'm'; *ptr++ = 'p'; *ptr++ = ';'; | ||||||
|  | 					break; | ||||||
|  |  | ||||||
|  | 				default: | ||||||
|  | 					*ptr++ = *str; | ||||||
|  | 					break; | ||||||
|  | 			} | ||||||
|  | 			str++; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		*ptr = '\0'; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return reqlen; | ||||||
|  | } | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user