Я пытаюсь обновить некоторый «устаревший» код, чтобы соответствовать последним обновлениям безопасности для MSVC, и столкнулся с некоторыми проблемами миграции от _vsnprintf
до _vsnprintf_s
.Получение необходимой длины буфера с помощью защищенного _vsnprintf_s
В частности, я звонил _vsnprintf
с нулевым буфером и ноль для подсчета/длины, получение результата, выделяя буфер нужного размера (return value + 1
), а затем вызвать _vsnprintf
снова с недавно выделенным буфером и известно, правильный размер:
size_t length = _vsntprintf(nullptr, 0, mask, params);
TCHAR *final = new TCHAR [length + 1];
_vsntprintf(final, length + 1, mask, params);
Такое поведение является documented on MSDN:
Если размер буфера задается кол не является достаточно большим, чтобы содержать выход, определенный формат и argptr, тем возвращаемое значение vsnprintf - это количество символов, которое было бы записано, если количество было достаточно большим. Если возвращаемое значение больше, чем count - 1, выход был усечен.
Я пытаюсь сделать то же самое с _vsnprintf_s
, но its documentation does not contain the same. Вместо этого он говорит
Если хранилище требуется для хранения данных и нуль-терминатор превышает sizeOfBuffer, инвалиду обработчик параметров вызывается, как описано в параметре санкционирования, если счетчик не _TRUNCATE, в этом случае, как большая часть строки как вписывается в буфер, записывается и возвращается -1.
Попытка это в любом случае со следующим:
size_t length = _vsntprintf_s(nullptr, 0, 0, mask, params);
Это приводит к "длине" нуля. Если вы передаете в _TRUNCATE
(-1), как граф вместо этого, следующее утверждение не:
Expression: буфер = nullptr & & buffer_count> 0
Я полагаю, что можно переопределить _set_invalid_parameter_handler
и как-то узнать, какая длина должна быть, но должен быть более простой способ?
Это не код C. – Olaf
@Olaf Извините, это должно было быть C++. Я беспокоился о теге «security-enhance-crt», который я пропустил опечатку. Вы действительно думаете, что это стоило бы вниз, хотя? –
В строке 'size_t length = _vsntprintf (nullptr, 0, 0, mask, params);', вы имели в виду '_vsntprintf_s'? – TriskalJM