Signed-off-by: Gijs Vermeulen gijsvrm@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;
Hi Gijs,
It might be better to add some tests and fix error conditions first. It will be easier to see how to implement the helper/if one helper is suitable in this case). Some quick testing shows that there are 3 different behaviors when buffer is too small (sprintf, sprintf_p and sprintf_s).
On 01/14/18 03:45, Gijs Vermeulen wrote:
Signed-off-by: Gijs Vermeulen gijsvrm@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;
Please use MSVCRT__TRUNCATE instead of -1 here. The if condition can be also simplified if _sprintf_p behavior is fixed when too small buffer is passed.
You can see the incorrect behavior with following test: errno = 0xdeadbeef; memset(buf, 'a', sizeof(buf)); ret = _vsprintf_p_wrapper(buf, 2, "%d", 1234); ok(ret == -1, "ret = %d\n", ret); ok(errno == ERANGE, "errno = %d\n", errno); ok(!memcmp(buf, "1", 2), "buf = %s\n", buf);
- 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) {
You should probably check if count>=sizeOfBuffer.
Thanks, Piotr