首页 > 解决方案 > VS 2017 _vsnprintf 改变了行为

问题描述

我有一个用于记录目的的带有可变参数的函数。在使用传递的缓冲区进行一些自定义操作后,它会调用 _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,但结果是,它最终调用了相同的方法。我非常愿意接受建议。

标签: visual-studio-2017printfc++17msvcrt

解决方案


推荐阅读