Signed-off-by: Gijs Vermeulen <gijsvrm(a)gmail.com>
---
dlls/msvcrt/wcs.c | 318 +++++++++++++++++++++++-------------------------------
1 file changed, 132 insertions(+), 186 deletions(-)
diff --git a/dlls/msvcrt/wcs.c b/dlls/msvcrt/wcs.c
index 098e0d5ba8..fb1173c859 100644
--- a/dlls/msvcrt/wcs.c
+++ b/dlls/msvcrt/wcs.c
@@ -720,20 +720,117 @@ printf_arg arg_clbk_positional(void *ctx, int pos, int type, __ms_va_list *valis
return args[pos];
}
+static int vsprintf_helper(DWORD options, char *str, MSVCRT_size_t sizeOfBuffer, MSVCRT_size_t count,
+ const char *format, MSVCRT__locale_t locale, __ms_va_list valist)
+{
+ static const char nullbyte = '\0';
+ printf_arg args_ctx[MSVCRT__ARGMAX+1];
+ struct _str_ctx_a puts_ctx;
+ int len, ret;
+ BOOL postional, secure, initially_positional;
+
+ len = sizeOfBuffer;
+ postional = options & MSVCRT_PRINTF_POSITIONAL_PARAMS;
+ initially_positional = postional;
+ secure = options & MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER;
+
+ if(secure && !postional)
+ if(sizeOfBuffer>count+1 && count!=-1) len = count+1;
+
+ puts_ctx.len = len;
+ puts_ctx.buf = str;
+
+ if(postional) {
+ memset(args_ctx, 0, sizeof(args_ctx));
+
+ ret = create_positional_ctx_a(args_ctx, format, valist);
+ if(ret < 0) {
+ MSVCRT__invalid_parameter(NULL, NULL, NULL, 0, 0);
+ *MSVCRT__errno() = MSVCRT_EINVAL;
+ return ret;
+ } else if(!ret)
+ postional = FALSE;
+ }
+
+ ret = pf_printf_a(puts_clbk_str_a,
+ &puts_ctx, format, locale, options,
+ postional ? arg_clbk_positional : arg_clbk_valist,
+ postional ? args_ctx : NULL,
+ postional ? NULL : &valist);
+ puts_clbk_str_a(&puts_ctx, 1, &nullbyte);
+
+ if((secure && !initially_positional) && (ret<0 || ret==len)) {
+ if(count!=MSVCRT__TRUNCATE && count>sizeOfBuffer) {
+ MSVCRT_INVALID_PMT("str[sizeOfBuffer] is too small", MSVCRT_ERANGE);
+ memset(str, 0, sizeOfBuffer);
+ } else
+ str[len-1] = '\0';
+
+ return -1;
+ }
+
+ return ret;
+}
+
+static int vswprintf_helper(DWORD options, MSVCRT_wchar_t *str, MSVCRT_size_t sizeOfBuffer, MSVCRT_size_t count,
+ const MSVCRT_wchar_t *format, MSVCRT__locale_t locale, __ms_va_list valist)
+{
+ static const MSVCRT_wchar_t nullbyte = '\0';
+ printf_arg args_ctx[MSVCRT__ARGMAX+1];
+ struct _str_ctx_w puts_ctx;
+ int len, ret;
+ BOOL postional, secure, initially_positional;
+
+ len = sizeOfBuffer;
+ postional = options & MSVCRT_PRINTF_POSITIONAL_PARAMS;
+ initially_positional = postional;
+ secure = options & MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER;
+
+ if(secure && !postional)
+ if(sizeOfBuffer>count+1 && count!=-1) len = count+1;
+
+ puts_ctx.len = len;
+ puts_ctx.buf = str;
+
+ if(postional) {
+ memset(args_ctx, 0, sizeof(args_ctx));
+
+ ret = create_positional_ctx_w(args_ctx, format, valist);
+ if(ret < 0) {
+ MSVCRT__invalid_parameter(NULL, NULL, NULL, 0, 0);
+ *MSVCRT__errno() = MSVCRT_EINVAL;
+ return ret;
+ } else if(!ret)
+ postional = FALSE;
+ }
+
+ ret = pf_printf_w(puts_clbk_str_w,
+ &puts_ctx, format, locale, options,
+ postional ? arg_clbk_positional : arg_clbk_valist,
+ postional ? args_ctx : NULL,
+ postional ? NULL : &valist);
+ puts_clbk_str_w(&puts_ctx, 1, &nullbyte);
+
+ if((secure && !initially_positional) && (ret<0 || ret==len)) {
+ if(count!=MSVCRT__TRUNCATE && count>sizeOfBuffer) {
+ MSVCRT_INVALID_PMT("str[sizeOfBuffer] is too small", MSVCRT_ERANGE);
+ memset(str, 0, sizeOfBuffer*sizeof(MSVCRT_wchar_t));
+ } else
+ str[len-1] = '\0';
+
+ return -1;
+ }
+
+ return ret;
+}
+
/*********************************************************************
* _vsnprintf (MSVCRT.@)
*/
int CDECL MSVCRT_vsnprintf( char *str, MSVCRT_size_t len,
const char *format, __ms_va_list valist )
{
- static const char nullbyte = '\0';
- struct _str_ctx_a ctx = {len, str};
- int ret;
-
- ret = pf_printf_a(puts_clbk_str_a, &ctx, format, NULL, 0,
- arg_clbk_valist, NULL, &valist);
- puts_clbk_str_a(&ctx, 1, &nullbyte);
- return ret;
+ return vsprintf_helper(0, str, len, 0, format, NULL, valist);
}
#if _MSVCR_VER>=140
@@ -793,14 +890,7 @@ int CDECL MSVCRT__stdio_common_vsprintf( unsigned __int64 options, char *str, MS
int CDECL MSVCRT_vsnprintf_l( char *str, MSVCRT_size_t len, const char *format,
MSVCRT__locale_t locale, __ms_va_list valist )
{
- static const char nullbyte = '\0';
- struct _str_ctx_a ctx = {len, str};
- int ret;
-
- ret = pf_printf_a(puts_clbk_str_a, &ctx, format, locale, 0,
- arg_clbk_valist, NULL, &valist);
- puts_clbk_str_a(&ctx, 1, &nullbyte);
- return ret;
+ return vsprintf_helper(0, str, len, 0, format, locale, valist);
}
/*********************************************************************
@@ -826,69 +916,6 @@ int WINAPIV MSVCRT_sprintf_l(char *str, const char *format,
return retval;
}
-static int CDECL MSVCRT_vsnprintf_s_l_opt( char *str, MSVCRT_size_t sizeOfBuffer,
- MSVCRT_size_t count, const char *format, DWORD options,
- MSVCRT__locale_t locale, __ms_va_list valist )
-{
- static const char nullbyte = '\0';
- struct _str_ctx_a ctx;
- int len, ret;
-
- if(sizeOfBuffer<count+1 || count==-1)
- len = sizeOfBuffer;
- else
- len = count+1;
-
- ctx.len = len;
- ctx.buf = str;
- ret = pf_printf_a(puts_clbk_str_a, &ctx, format, locale, MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER | options,
- arg_clbk_valist, NULL, &valist);
- puts_clbk_str_a(&ctx, 1, &nullbyte);
-
- if(ret<0 || ret==len) {
- if(count!=MSVCRT__TRUNCATE && count>sizeOfBuffer) {
- MSVCRT_INVALID_PMT("str[sizeOfBuffer] is too small", MSVCRT_ERANGE);
- memset(str, 0, sizeOfBuffer);
- } else
- str[len-1] = '\0';
-
- return -1;
- }
-
- return ret;
-}
-
-static int MSVCRT_vsnwprintf_s_l_opt( MSVCRT_wchar_t *str, MSVCRT_size_t sizeOfBuffer,
- MSVCRT_size_t count, const MSVCRT_wchar_t *format, DWORD options,
- MSVCRT__locale_t locale, __ms_va_list valist)
-{
- static const MSVCRT_wchar_t nullbyte = '\0';
- struct _str_ctx_w ctx;
- int len, ret;
-
- len = sizeOfBuffer;
- if(count!=-1 && len>count+1)
- len = count+1;
-
- ctx.len = len;
- ctx.buf = str;
- ret = pf_printf_w(puts_clbk_str_w, &ctx, format, locale, MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER | options,
- arg_clbk_valist, NULL, &valist);
- puts_clbk_str_w(&ctx, 1, &nullbyte);
-
- if(ret<0 || ret==len) {
- if(count!=MSVCRT__TRUNCATE && count>sizeOfBuffer) {
- MSVCRT_INVALID_PMT("str[sizeOfBuffer] is too small", MSVCRT_ERANGE);
- memset(str, 0, sizeOfBuffer*sizeof(MSVCRT_wchar_t));
- } else
- str[len-1] = '\0';
-
- return -1;
- }
-
- return ret;
-}
-
/*********************************************************************
* _vsnprintf_s_l (MSVCRT.@)
*/
@@ -896,7 +923,8 @@ int CDECL MSVCRT_vsnprintf_s_l( char *str, MSVCRT_size_t sizeOfBuffer,
MSVCRT_size_t count, const char *format,
MSVCRT__locale_t locale, __ms_va_list valist )
{
- return MSVCRT_vsnprintf_s_l_opt(str, sizeOfBuffer, count, format, 0, locale, valist);
+ return vsprintf_helper(MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER, str, sizeOfBuffer, count, format,
+ locale, valist);
}
/*********************************************************************
@@ -942,7 +970,8 @@ int CDECL MSVCRT__stdio_common_vsnprintf_s( unsigned __int64 options,
{
if (options & ~UCRTBASE_PRINTF_MASK)
FIXME("options %s not handled\n", wine_dbgstr_longlong(options));
- return MSVCRT_vsnprintf_s_l_opt(str, sizeOfBuffer, count, format, options & UCRTBASE_PRINTF_MASK, locale, valist);
+ return vsprintf_helper((options & UCRTBASE_PRINTF_MASK) | MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER, str,
+ sizeOfBuffer, count, format, locale, valist);
}
/*********************************************************************
@@ -954,7 +983,8 @@ int CDECL MSVCRT__stdio_common_vsnwprintf_s( unsigned __int64 options,
{
if (options & ~UCRTBASE_PRINTF_MASK)
FIXME("options %s not handled\n", wine_dbgstr_longlong(options));
- return MSVCRT_vsnwprintf_s_l_opt(str, sizeOfBuffer, count, format, options & UCRTBASE_PRINTF_MASK, locale, valist);
+ return vswprintf_helper((options & UCRTBASE_PRINTF_MASK) | MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER, str,
+ sizeOfBuffer, count, format, locale, valist);
}
/*********************************************************************
@@ -974,9 +1004,7 @@ int CDECL MSVCRT__stdio_common_vsprintf_s( unsigned __int64 options,
char *str, MSVCRT_size_t count, const char *format,
MSVCRT__locale_t locale, __ms_va_list valist )
{
- if (options & ~UCRTBASE_PRINTF_MASK)
- FIXME("options %s not handled\n", wine_dbgstr_longlong(options));
- return MSVCRT_vsnprintf_s_l_opt(str, INT_MAX, count, format, options & UCRTBASE_PRINTF_MASK, locale, valist);
+ return MSVCRT__stdio_common_vsnprintf_s(options, str, INT_MAX, count, format, locale, valist);
}
#endif /* _MSVCR_VER>=140 */
@@ -1011,28 +1039,8 @@ int CDECL MSVCRT__vscprintf( const char *format, __ms_va_list valist )
int CDECL MSVCRT__vscprintf_p_l(const char *format,
MSVCRT__locale_t locale, __ms_va_list args)
{
- printf_arg args_ctx[MSVCRT__ARGMAX+1];
- struct _str_ctx_a puts_ctx = {INT_MAX, NULL};
- int ret;
-
- memset(args_ctx, 0, sizeof(args_ctx));
-
- ret = create_positional_ctx_a(args_ctx, format, args);
- if(ret < 0) {
- MSVCRT__invalid_parameter(NULL, NULL, NULL, 0, 0);
- *MSVCRT__errno() = MSVCRT_EINVAL;
- return ret;
- } else if(ret == 0) {
- ret = pf_printf_a(puts_clbk_str_a, &puts_ctx, format, locale,
- MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER,
- arg_clbk_valist, NULL, &args);
- } else {
- ret = pf_printf_a(puts_clbk_str_a, &puts_ctx, format, locale,
- MSVCRT_PRINTF_POSITIONAL_PARAMS | MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER,
- arg_clbk_positional, args_ctx, NULL);
- }
-
- return ret;
+ return vsprintf_helper(MSVCRT_PRINTF_POSITIONAL_PARAMS | MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER,
+ NULL, INT_MAX, 0, format, locale, args);
}
/*********************************************************************
@@ -1103,14 +1111,7 @@ int WINAPIV MSVCRT__scprintf(const char *format, ...)
int CDECL MSVCRT_vsnwprintf(MSVCRT_wchar_t *str, MSVCRT_size_t len,
const MSVCRT_wchar_t *format, __ms_va_list valist)
{
- static const MSVCRT_wchar_t nullbyte = '\0';
- struct _str_ctx_w ctx = {len, str};
- int ret;
-
- ret = pf_printf_w(puts_clbk_str_w, &ctx, format, NULL, 0,
- arg_clbk_valist, NULL, &valist);
- puts_clbk_str_w(&ctx, 1, &nullbyte);
- return ret;
+ return vswprintf_helper(0, str, len, 0, format, NULL, valist);
}
/*********************************************************************
@@ -1120,41 +1121,7 @@ int CDECL MSVCRT_vsnwprintf_l(MSVCRT_wchar_t *str, MSVCRT_size_t len,
const MSVCRT_wchar_t *format, MSVCRT__locale_t locale,
__ms_va_list valist)
{
- static const MSVCRT_wchar_t nullbyte = '\0';
- struct _str_ctx_w ctx = {len, str};
- int ret;
-
- ret = pf_printf_w(puts_clbk_str_w, &ctx, format, locale, 0,
- arg_clbk_valist, NULL, &valist);
- puts_clbk_str_w(&ctx, 1, &nullbyte);
- return ret;
-}
-
-static int MSVCRT_vswprintf_p_l_opt(MSVCRT_wchar_t *buffer, MSVCRT_size_t length,
- const MSVCRT_wchar_t *format, DWORD options, MSVCRT__locale_t locale, __ms_va_list args)
-{
- static const MSVCRT_wchar_t nullbyte = '\0';
- printf_arg args_ctx[MSVCRT__ARGMAX+1];
- struct _str_ctx_w puts_ctx = {length, buffer};
- int ret;
-
- memset(args_ctx, 0, sizeof(args_ctx));
-
- ret = create_positional_ctx_w(args_ctx, format, args);
- if(ret < 0) {
- MSVCRT__invalid_parameter(NULL, NULL, NULL, 0, 0);
- *MSVCRT__errno() = MSVCRT_EINVAL;
- return ret;
- } else if(ret == 0)
- ret = pf_printf_w(puts_clbk_str_w, &puts_ctx, format, locale, MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER | options,
- arg_clbk_valist, NULL, &args);
- else
- ret = pf_printf_w(puts_clbk_str_w, &puts_ctx, format, locale,
- MSVCRT_PRINTF_POSITIONAL_PARAMS | MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER | options,
- arg_clbk_positional, args_ctx, NULL);
-
- puts_clbk_str_w(&puts_ctx, 1, &nullbyte);
- return ret;
+ return vswprintf_helper(0, str, len, 0, format, locale, valist);
}
/*********************************************************************
@@ -1163,7 +1130,8 @@ static int MSVCRT_vswprintf_p_l_opt(MSVCRT_wchar_t *buffer, MSVCRT_size_t length
int CDECL MSVCRT_vswprintf_p_l(MSVCRT_wchar_t *buffer, MSVCRT_size_t length,
const MSVCRT_wchar_t *format, MSVCRT__locale_t locale, __ms_va_list args)
{
- return MSVCRT_vswprintf_p_l_opt(buffer, length, format, 0, locale, args);
+ return vswprintf_helper(MSVCRT_PRINTF_POSITIONAL_PARAMS | MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER,
+ buffer, length, 0, format, locale, args);
}
#if _MSVCR_VER>=80
@@ -1173,7 +1141,7 @@ int CDECL MSVCRT_vswprintf_p_l(MSVCRT_wchar_t *buffer, MSVCRT_size_t length,
int CDECL MSVCRT__vswprintf_p(MSVCRT_wchar_t *buffer, MSVCRT_size_t length,
const MSVCRT_wchar_t *format, __ms_va_list args)
{
- return MSVCRT_vswprintf_p_l_opt(buffer, length, format, 0, NULL, args);
+ return MSVCRT_vswprintf_p_l(buffer, length, format, NULL, args);
}
#endif
@@ -1187,7 +1155,8 @@ int CDECL MSVCRT__stdio_common_vswprintf_p( unsigned __int64 options,
{
if (options & ~UCRTBASE_PRINTF_MASK)
FIXME("options %s not handled\n", wine_dbgstr_longlong(options));
- return MSVCRT_vswprintf_p_l_opt(str, count, format, options & UCRTBASE_PRINTF_MASK, locale, valist);
+ return vswprintf_helper((options & UCRTBASE_PRINTF_MASK) | (MSVCRT_PRINTF_POSITIONAL_PARAMS |
+ MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER), str, count, 0, format, locale, valist);
}
#endif
@@ -1198,7 +1167,8 @@ int CDECL MSVCRT_vsnwprintf_s_l( MSVCRT_wchar_t *str, MSVCRT_size_t sizeOfBuffer
MSVCRT_size_t count, const MSVCRT_wchar_t *format,
MSVCRT__locale_t locale, __ms_va_list valist)
{
- return MSVCRT_vsnwprintf_s_l_opt(str, sizeOfBuffer, count, format, 0, locale, valist);
+ return vswprintf_helper(MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER, str, sizeOfBuffer, count, format,
+ locale, valist);
}
/*********************************************************************
@@ -1444,7 +1414,8 @@ int CDECL MSVCRT__vscwprintf_l( const MSVCRT_wchar_t *format, MSVCRT__locale_t l
*/
int CDECL MSVCRT__vscwprintf_p_l( const MSVCRT_wchar_t *format, MSVCRT__locale_t locale, __ms_va_list args )
{
- return MSVCRT_vswprintf_p_l_opt( NULL, INT_MAX, format, 0, locale, args );
+ return vswprintf_helper(MSVCRT_PRINTF_POSITIONAL_PARAMS | MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER, NULL, INT_MAX,
+ 0, format, locale, args);
}
#if _MSVCR_VER>=80
@@ -1453,7 +1424,7 @@ int CDECL MSVCRT__vscwprintf_p_l( const MSVCRT_wchar_t *format, MSVCRT__locale_t
*/
int CDECL MSVCRT__vscwprintf_p(const MSVCRT_wchar_t *format, __ms_va_list args)
{
- return MSVCRT_vswprintf_p_l_opt(NULL, INT_MAX, format, 0, NULL, args);
+ return MSVCRT__vscwprintf_p_l(format, NULL, args);
}
#endif
@@ -1476,40 +1447,14 @@ int CDECL MSVCRT_vswprintf_s_l(MSVCRT_wchar_t* str, MSVCRT_size_t numberOfElemen
format, locale, args );
}
-static int MSVCRT_vsprintf_p_l_opt(char *buffer, MSVCRT_size_t length, const char *format,
- DWORD options, MSVCRT__locale_t locale, __ms_va_list args)
-{
- static const char nullbyte = '\0';
- printf_arg args_ctx[MSVCRT__ARGMAX+1];
- struct _str_ctx_a puts_ctx = {length, buffer};
- int ret;
-
- memset(args_ctx, 0, sizeof(args_ctx));
-
- ret = create_positional_ctx_a(args_ctx, format, args);
- if(ret < 0) {
- MSVCRT__invalid_parameter(NULL, NULL, NULL, 0, 0);
- *MSVCRT__errno() = MSVCRT_EINVAL;
- return ret;
- } else if(ret == 0)
- ret = pf_printf_a(puts_clbk_str_a, &puts_ctx, format, locale,
- MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER | options, arg_clbk_valist, NULL, &args);
- else
- ret = pf_printf_a(puts_clbk_str_a, &puts_ctx, format, locale,
- MSVCRT_PRINTF_POSITIONAL_PARAMS | MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER | options,
- arg_clbk_positional, args_ctx, NULL);
-
- puts_clbk_str_a(&puts_ctx, 1, &nullbyte);
- return ret;
-}
-
/*********************************************************************
* _vsprintf_p_l (MSVCRT.@)
*/
int CDECL MSVCRT_vsprintf_p_l(char *buffer, MSVCRT_size_t length, const char *format,
MSVCRT__locale_t locale, __ms_va_list args)
{
- return MSVCRT_vsprintf_p_l_opt(buffer, length, format, 0, locale, args);
+ return vsprintf_helper(MSVCRT_PRINTF_POSITIONAL_PARAMS | MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER, buffer, length,
+ 0, format, locale, args);
}
/*********************************************************************
@@ -1530,7 +1475,8 @@ int CDECL MSVCRT__stdio_common_vsprintf_p(unsigned __int64 options, char *buffer
{
if (options & ~UCRTBASE_PRINTF_MASK)
FIXME("options %s not handled\n", wine_dbgstr_longlong(options));
- return MSVCRT_vsprintf_p_l_opt(buffer, length, format, options & UCRTBASE_PRINTF_MASK, locale, args);
+ return vsprintf_helper((options & UCRTBASE_PRINTF_MASK) | (MSVCRT_PRINTF_POSITIONAL_PARAMS |
+ MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER), buffer, length, 0, format, locale, args);
}
#endif
@@ -1591,7 +1537,7 @@ int WINAPIV MSVCRT_swprintf_p_l(MSVCRT_wchar_t *buffer, MSVCRT_size_t length,
int r;
__ms_va_start(valist, locale);
- r = MSVCRT_vswprintf_p_l_opt(buffer, length, format, 0, locale, valist);
+ r = MSVCRT_vswprintf_p_l(buffer, length, format, locale, valist);
__ms_va_end(valist);
return r;
--
2.15.1