I'm trying to update some "legacy" code to comply with the latest security updates to MSVC, and am facing some trouble migrating from _vsnprintf
to _vsnprintf_s
.
In particular, I was calling _vsnprintf
with a null buffer and zero for the count/length, getting the result, allocating a buffer of the needed size (return value + 1
), and then calling _vsnprintf
again with the newly-allocated buffer and known-correct size:
size_t length = _vsntprintf(nullptr, 0, mask, params);
TCHAR *final = new TCHAR [length + 1];
_vsntprintf(final, length + 1, mask, params);
This behavior is documented on MSDN:
If the buffer size specified by count is not sufficiently large to contain the output specified by format and argptr, the return value of vsnprintf is the number of characters that would be written if count were sufficiently large. If the return value is greater than count - 1, the output has been truncated.
I'm trying to do the same with _vsnprintf_s
, but its documentation does not contain the same. It instead says
If the storage required to store the data and a terminating null exceeds sizeOfBuffer, the invalid parameter handler is invoked, as described in Parameter Validation, unless count is _TRUNCATE, in which case as much of the string as will fit in buffer is written and -1 returned.
Trying it out anyway with the following:
size_t length = _vsntprintf_s(nullptr, 0, 0, mask, params);
This results in a "length" of zero. If you pass in _TRUNCATE
(-1) as the count instead, the following assertion fails:
Expression: buffer != nullptr && buffer_count > 0
I presume it is possible to override _set_invalid_parameter_handler
and somehow find out what the length should be, but there has to be an easier way?
security-enhanced-crt
tag that I missed that typo. Do you really think that was worth downvoting, though?? – Dynamismsize_t length = _vsntprintf(nullptr, 0, 0, mask, params);
, did you mean_vsntprintf_s
? – Aveburyvsnprintf(nullptr,0,...)
to get the size and then dovsnprintf_s(final,length + 1,...)
– Antitragus