VS 2017 _vsnprintf更改了行为

时间:2018-08-24 13:51:37

标签: visual-studio-2017 printf c++17 msvcrt

我有一个带有可变参数的函数,用于记录日志。在对传递的缓冲区进行一些自定义操作之后,它会调用_vsnprintf_s格式化缓冲区。我们的一位客户最近通过了内部带有单个百分比的格式字符串,并且使用VS 2017构建的应用程序(其中CRT驻留在ucrtbase.dll中)崩溃了,而仅使用VS 2013构建的同一应用程序中的相同功能能够处理该问题。格式字符串为:

"...10% text..."

尽管我同意格式字符串不正确,但让我担心的是,使用VS 2013构建的应用程序在某种程度上对其进行了处理,并且输出为:

"...10 ..."

因此在使用VS 2017构建的应用程序崩溃时不会冒犯%。我尝试在std14和std17之间切换-没什么区别。我目前正在使用std17。调试时,我注意到它在这里失败:

_Success_(return >= 0)
_Check_return_opt_ _CRT_INSECURE_DEPRECATE(_vsnprintf_s_l)
_CRT_STDIO_INLINE int __CRTDECL _vsnprintf_l(
    _Out_writes_opt_(_BufferCount) _Post_maybez_ char*       const _Buffer,
    _In_                                         size_t      const _BufferCount,
    _In_z_ _Printf_format_string_params_(2)      char const* const _Format,
    _In_opt_                                     _locale_t   const _Locale,
                                                 va_list           _ArgList
    )
#if defined _NO_CRT_STDIO_INLINE
;
#else
{
    int const _Result = __stdio_common_vsprintf(
        _CRT_INTERNAL_LOCAL_PRINTF_OPTIONS | _CRT_INTERNAL_PRINTF_LEGACY_VSPRINTF_NULL_TERMINATION,
        _Buffer, _BufferCount, _Format, _Locale, _ArgList);

    return _Result < 0 ? -1 : _Result;
}
#endif

有消息

Expression: _length == length_modifier::none

但是在发布模式下它崩溃了。这告诉我,在处理格式字符串中使用不正确的百分比方面,CRT实现可能发生了变化。解决方案是先扫描整个格式字符串,然后再传递它-但我想避免使用它,因为这样做会大大降低速度。我尝试使用StringCchVPrintfEx,但事实证明,它最终调用了相同的方法。我很乐意提出建议。

0 个答案:

没有答案