fixed a bug in qse_mbs_ncpy() and qse_wcs_ncpy().
enhanced qse_mbs_ncat() and qse_wcs_ncat() to allocate a buffer if zero-length string is passed in when the current capacity is 0
This commit is contained in:
		| @ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * $Id: str_dynm.c 501 2011-07-05 15:45:00Z hyunghwan.chung $ | ||||
|  * $Id: str_dynm.c 502 2011-07-06 16:44:10Z hyunghwan.chung $ | ||||
|  * | ||||
|     Copyright 2006-2011 Chung, Hyung-Hwan. | ||||
|     This file is part of QSE. | ||||
| @ -235,22 +235,32 @@ qse_size_t qse_mbs_cpy (qse_mbs_t* str, const qse_mchar_t* s) | ||||
|  | ||||
| qse_size_t qse_mbs_ncpy (qse_mbs_t* str, const qse_mchar_t* s, qse_size_t len) | ||||
| { | ||||
| 	if (len > str->capa || str->val.ptr == QSE_NULL)  | ||||
| 	if (len > str->capa || str->capa <= 0) | ||||
| 	{ | ||||
| 		qse_mchar_t* buf; | ||||
| 		qse_size_t tmp; | ||||
|  | ||||
| 		buf = (qse_mchar_t*) QSE_MMGR_ALLOC ( | ||||
| 			str->mmgr, QSE_SIZEOF(qse_mchar_t) * (len + 1)); | ||||
| 		if (buf == QSE_NULL) return (qse_size_t)-1; | ||||
|  | ||||
| 		if (str->val.ptr != QSE_NULL) QSE_MMGR_FREE (str->mmgr, str->val.ptr); | ||||
| 		str->capa = len; | ||||
| 		str->val.ptr = buf; | ||||
| 		/* if the current capacity is 0 and the string len to copy is 0 | ||||
| 		 * we can't simply pass 'len' as the new capapcity. | ||||
| 		 * qse_mbs_setcapa() won't do anything the current capacity of 0 | ||||
| 		 * is the same as new capacity required. note that when str->capa  | ||||
| 		 * is 0, str->val.ptr is QSE_NULL. However, this is copying operation. | ||||
| 		 * Copying a zero-length string may indicate that str->val.ptr must | ||||
| 		 * not be QSE_NULL. so I simply pass 1 as the new capacity */ | ||||
| 		tmp = qse_mbs_setcapa ( | ||||
| 			str, ((str->capa <= 0 && len <= 0)? 1: len) | ||||
| 		); | ||||
| 		if (tmp == (qse_size_t)-1) return (qse_size_t)-1; | ||||
| 	} | ||||
|  | ||||
| 	QSE_MEMCPY (&str->val.ptr[0], s, len*QSE_SIZEOF(*s)); | ||||
| 	str->val.ptr[len] = QSE_MT('\0'); | ||||
| 	str->val.len = len; | ||||
| 	return len; | ||||
| #if 0 | ||||
| 	str->val.len = qse_mbsncpy (str->val.ptr, s, len); | ||||
| 	/*str->val.ptr[str->val.len] = QSE_MT('\0'); -> mbsncpy does this*/ | ||||
| 	return str->val.len; | ||||
| #endif | ||||
| } | ||||
|  | ||||
| qse_size_t qse_mbs_cat (qse_mbs_t* str, const qse_mchar_t* s) | ||||
| @ -295,6 +305,12 @@ qse_size_t qse_mbs_ncat (qse_mbs_t* str, const qse_mchar_t* s, qse_size_t len) | ||||
| 		} | ||||
| 		while (1); | ||||
| 	} | ||||
| 	else if (str->capa <= 0 && len <= 0) | ||||
| 	{ | ||||
| 		QSE_ASSERT (str->val.ptr == QSE_NULL); | ||||
| 		QSE_ASSERT (str->val.len <= 0); | ||||
| 		if (qse_mbs_setcapa (str, 1) == (qse_size_t)-1) return (qse_size_t)-1; | ||||
| 	} | ||||
|  | ||||
| 	if (len > str->capa - str->val.len)  | ||||
| 	{ | ||||
| @ -303,12 +319,16 @@ qse_size_t qse_mbs_ncat (qse_mbs_t* str, const qse_mchar_t* s, qse_size_t len) | ||||
| 		len = str->capa - str->val.len; | ||||
| 	} | ||||
|  | ||||
| #if 0 | ||||
| 	if (len > 0) | ||||
| 	{ | ||||
| #endif | ||||
| 		QSE_MEMCPY (&str->val.ptr[str->val.len], s, len*QSE_SIZEOF(*s)); | ||||
| 		str->val.len += len; | ||||
| 		str->val.ptr[str->val.len] = QSE_MT('\0'); | ||||
| #if 0 | ||||
| 	} | ||||
| #endif | ||||
|  | ||||
| 	return str->val.len; | ||||
| } | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * $Id: str_dynw.c 501 2011-07-05 15:45:00Z hyunghwan.chung $ | ||||
|  * $Id: str_dynw.c 502 2011-07-06 16:44:10Z hyunghwan.chung $ | ||||
|  * | ||||
|     Copyright 2006-2011 Chung, Hyung-Hwan. | ||||
|     This file is part of QSE. | ||||
| @ -235,22 +235,32 @@ qse_size_t qse_wcs_cpy (qse_wcs_t* str, const qse_wchar_t* s) | ||||
|  | ||||
| qse_size_t qse_wcs_ncpy (qse_wcs_t* str, const qse_wchar_t* s, qse_size_t len) | ||||
| { | ||||
| 	if (len > str->capa || str->val.ptr == QSE_NULL)  | ||||
| 	if (len > str->capa || str->capa <= 0) | ||||
| 	{ | ||||
| 		qse_wchar_t* buf; | ||||
| 		qse_size_t tmp; | ||||
|  | ||||
| 		buf = (qse_wchar_t*) QSE_MMGR_ALLOC ( | ||||
| 			str->mmgr, QSE_SIZEOF(qse_wchar_t) * (len + 1)); | ||||
| 		if (buf == QSE_NULL) return (qse_size_t)-1; | ||||
|  | ||||
| 		if (str->val.ptr != QSE_NULL) QSE_MMGR_FREE (str->mmgr, str->val.ptr); | ||||
| 		str->capa = len; | ||||
| 		str->val.ptr = buf; | ||||
| 		/* if the current capacity is 0 and the string len to copy is 0 | ||||
| 		 * we can't simply pass 'len' as the new capapcity. | ||||
| 		 * qse_wcs_setcapa() won't do anything the current capacity of 0 | ||||
| 		 * is the same as new capacity required. note that when str->capa  | ||||
| 		 * is 0, str->val.ptr is QSE_NULL. However, this is copying operation. | ||||
| 		 * Copying a zero-length string may indicate that str->val.ptr must | ||||
| 		 * not be QSE_NULL. so I simply pass 1 as the new capacity */ | ||||
| 		tmp = qse_wcs_setcapa ( | ||||
| 			str, ((str->capa <= 0 && len <= 0)? 1: len) | ||||
| 		); | ||||
| 		if (tmp == (qse_size_t)-1) return (qse_size_t)-1; | ||||
| 	} | ||||
|  | ||||
| 	QSE_MEMCPY (&str->val.ptr[0], s, len*QSE_SIZEOF(*s)); | ||||
| 	str->val.ptr[len] = QSE_WT('\0'); | ||||
| 	str->val.len = len; | ||||
| 	return len; | ||||
| #if 0 | ||||
| 	str->val.len = qse_wcsncpy (str->val.ptr, s, len); | ||||
| 	/* str->val.ptr[str->val.len] = QSE_WT('\0'); -> wcsncpy does this */ | ||||
| 	/*str->val.ptr[str->val.len] = QSE_WT('\0'); -> wcsncpy does this*/ | ||||
| 	return str->val.len; | ||||
| #endif | ||||
| } | ||||
|  | ||||
| qse_size_t qse_wcs_cat (qse_wcs_t* str, const qse_wchar_t* s) | ||||
| @ -295,6 +305,12 @@ qse_size_t qse_wcs_ncat (qse_wcs_t* str, const qse_wchar_t* s, qse_size_t len) | ||||
| 		} | ||||
| 		while (1); | ||||
| 	} | ||||
| 	else if (str->capa <= 0 && len <= 0) | ||||
| 	{ | ||||
| 		QSE_ASSERT (str->val.ptr == QSE_NULL); | ||||
| 		QSE_ASSERT (str->val.len <= 0); | ||||
| 		if (qse_wcs_setcapa (str, 1) == (qse_size_t)-1) return (qse_size_t)-1; | ||||
| 	} | ||||
|  | ||||
| 	if (len > str->capa - str->val.len)  | ||||
| 	{ | ||||
| @ -303,12 +319,16 @@ qse_size_t qse_wcs_ncat (qse_wcs_t* str, const qse_wchar_t* s, qse_size_t len) | ||||
| 		len = str->capa - str->val.len; | ||||
| 	} | ||||
|  | ||||
| #if 0 | ||||
| 	if (len > 0) | ||||
| 	{ | ||||
| #endif | ||||
| 		QSE_MEMCPY (&str->val.ptr[str->val.len], s, len*QSE_SIZEOF(*s)); | ||||
| 		str->val.len += len; | ||||
| 		str->val.ptr[str->val.len] = QSE_WT('\0'); | ||||
| #if 0 | ||||
| 	} | ||||
| #endif | ||||
|  | ||||
| 	return str->val.len; | ||||
| } | ||||
|  | ||||
| @ -198,7 +198,7 @@ static qse_htoc_t* parse_initial_line ( | ||||
| 	qse_htrd_t* http, qse_htoc_t* line) | ||||
| { | ||||
| 	qse_htoc_t* p = line; | ||||
| 	qse_htos_t tmp; | ||||
| 	qse_mcstr_t tmp; | ||||
| 	qse_http_method_t mtype; | ||||
|  | ||||
| #if 0 | ||||
| @ -285,7 +285,7 @@ static qse_htoc_t* parse_initial_line ( | ||||
| 	else | ||||
| 	{ | ||||
| 		qse_htoc_t* out; | ||||
| 		qse_htos_t param; | ||||
| 		qse_mcstr_t param; | ||||
|  | ||||
| 		/* method name must be followed by space */ | ||||
| 		if (!is_space_octet(*p)) goto badre; | ||||
| @ -344,7 +344,7 @@ static qse_htoc_t* parse_initial_line ( | ||||
| 		if (param.ptr) | ||||
| 		{ | ||||
| 			param.len = out - param.ptr; | ||||
| 			if (qse_htre_setqparamstr (&http->re, param.ptr) <= -1) goto outofmem; | ||||
| 			if (qse_htre_setqparamstr (&http->re, ¶m) <= -1) goto outofmem; | ||||
| 		} | ||||
| 		else tmp.len = out - tmp.ptr; | ||||
|  | ||||
|  | ||||
| @ -16,7 +16,6 @@ qse_htre_t* qse_htre_init (qse_htre_t* re, qse_mmgr_t* mmgr) | ||||
| 	} | ||||
|  | ||||
| 	qse_mbs_init (&re->content, mmgr, 0); | ||||
|  | ||||
| 	qse_mbs_init (&re->qpath_or_smesg, mmgr, 0); | ||||
| 	qse_mbs_init (&re->qparamstr, mmgr, 0); | ||||
|  | ||||
| @ -46,23 +45,21 @@ void qse_htre_clear (qse_htre_t* re) | ||||
| } | ||||
|  | ||||
| int qse_htre_setbuf ( | ||||
| 	qse_htre_t* re, qse_htob_t* buf, const qse_htos_t* str) | ||||
| 	qse_htre_t* re, qse_htob_t* buf, const qse_mcstr_t* str) | ||||
| { | ||||
| 	qse_mbs_clear (buf); | ||||
| 	return (qse_mbs_ncat (buf, str->ptr, str->len) == (qse_size_t)-1)? -1: 0; | ||||
| 	return (qse_mbs_ncpy (buf, str->ptr, str->len) == (qse_size_t)-1)? -1: 0; | ||||
| } | ||||
|  | ||||
| void qse_htre_getbuf ( | ||||
| 	qse_htre_t* re, const qse_htob_t* buf, qse_htos_t* str) | ||||
| 	qse_htre_t* re, const qse_htob_t* buf, qse_mcstr_t* str) | ||||
| { | ||||
| 	str->ptr = QSE_MBS_PTR(buf); | ||||
| 	str->len = QSE_MBS_LEN(buf); | ||||
| } | ||||
|  | ||||
| int qse_htre_setqparamstr (qse_htre_t* re, const qse_htoc_t* str) | ||||
|  | ||||
| int qse_htre_setqparamstr (qse_htre_t* re, const qse_mcstr_t* str) | ||||
| { | ||||
| 	return (qse_mbs_cpy (&re->qparamstr, str) == (qse_size_t)-1)? -1: 0; | ||||
| 	return (qse_mbs_ncpy (&re->qparamstr, str->ptr, str->len) == (qse_size_t)-1)? -1: 0; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -97,7 +97,7 @@ int qse_gethttpmethodtype ( | ||||
| } | ||||
|  | ||||
| int qse_gethttpmethodtypefromstr ( | ||||
| 	const qse_htos_t* name, | ||||
| 	const qse_mcstr_t* name, | ||||
| 	qse_http_method_t* type) | ||||
| { | ||||
| 	/* perform binary search */ | ||||
| @ -150,7 +150,11 @@ int qse_scanhttpparamstr ( | ||||
| 		if (*p == '&' || *p == ';' || *p == '\0') | ||||
| 		{ | ||||
| 			QSE_ASSERT (key.ptr != QSE_NULL); | ||||
| 			if (val.ptr == QSE_NULL) val.ptr = ""; | ||||
| 			if (val.ptr == QSE_NULL)  | ||||
| 			{ | ||||
| 				if (key.len == 0) break; | ||||
| 				val.ptr = ""; | ||||
| 			} | ||||
|  | ||||
| 			if (callback (ctx, &key, &val) <= -1) return -1; | ||||
|  | ||||
| @ -168,6 +172,7 @@ int qse_scanhttpparamstr ( | ||||
| 		{ | ||||
| 			if (val.ptr) val.len++; | ||||
| 			else key.len++; | ||||
| 			p++; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|  | ||||
| @ -2,6 +2,7 @@ | ||||
|  * $Id$ | ||||
|  */ | ||||
|  | ||||
| #if 0 | ||||
| #include "par.h" | ||||
| #include "../cmn/mem.h" | ||||
|  | ||||
| @ -1698,3 +1699,4 @@ static int __close_input (qse_stc_t* stc) | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| #endif | ||||
|  | ||||
		Reference in New Issue
	
	Block a user