Подтвердить что ты не робот

Ложное чувство безопасности с `snprintf_s`

MSVC "secure" sprintf funcions имеет версию шаблона, которая "знает" размер целевого буфера. Тем не менее, этот код счастливо рисует 567890 над стекем после окончания bytes...

char bytes[5];
_snprintf_s( bytes, _TRUNCATE, "%s", "1234567890" );

Любая идея, что я делаю неправильно, или это известная ошибка?

(я работаю в VS2005 - не тестировал в 2008 или 2010 году)

4b9b3361

Ответ 1

Кажется, что ошибка в Visual С++ 2005 (у меня возникли проблемы с получением этой ссылки; Google также кэширует).

Я смог воспроизвести проблему в Visual С++ 2005. В Visual С++ 2008 и 2010 строка правильно усечена (bytes содержит 1234\0) и -1 возвращается как ожидалось.

Ответ 2

Пример действительно правильный. Начиная с версии -

Microsoft Visual Studio 2005
Version 8.0.50727.867 (vsvista.050727-8600)
...
Visual C++ 77626-009-0000007-41722

- который включает в себя SP1, исправление vista и несколько исправлений в библиотеке - вышеупомянутая функция

template <size_t size>
int _snprintf_s(
   char (&buffer)[size],
   size_t count,
   const char *format [,
      argument] ... 
);

по-прежнему глючит. Однако, что действительно интересно, так это то, что только эта функция из 4-х вариантных функций

  • ОК: int _snprintf_s(char *buffer, size_t sizeOfBuffer, size_t count, :::
  • Багги: template <size_t size> int _snprintf_s(char (&buffer)[size], size_t count, :::
  • ОК: int _snwprintf_s (версия с широким символом)
  • ОК: template <size_t size> int _snwprintf_s (да, версия с широким символом в порядке)

является ошибкой, то есть если вы используете версию без шаблона, это нормально, и если вы используете одну из широкоформатных версий, это тоже ОК. Удивительно.

Ответ 3

Пример неправильный.

Код должен быть:

char bytes[5];
_snprintf_s( bytes, 5, _TRUNCATE, "%s", "1234567890" );

В случае неправильного кода может возникнуть ошибка, из-за которой компилятор не выдавал никаких предупреждений, но это была бы слабая проверка для snprintf.