У меня есть функция с переменными аргументами, используемая для целей ведения журнала.После некоторых пользовательских манипуляций с переданным буфером он вызывает _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
Однако в режиме Release это происходило сбоем.Это говорит мне о том, что реализация CRT, вероятно, изменилась в отношении обработки неправильно используемого процента в строке формата.Решение состоит в том, чтобы сканировать всю строку формата до ее передачи - но я бы хотел этого избежать, потому что это значительно замедлило бы процесс.Я пытался использовать StringCchVPrintfEx, но оказалось, что он вызвал тот же метод.Я очень открыт для предложений.