Каково лучшее "безопасное" решение библиотеки C с одним магазином остановки на Mac? Я использую кавычки на "безопасном" / "небезопасный", потому что существует много дебатов относительно преимуществ Библиотечных функций определенного стандарта или их предположительно улучшенных альтернатив.
Много традиционных функций Стандартной библиотеки для C (например, vfprintf
) считаются небезопасными из-за потенциала для переполнения буфера или других проблем безопасности.
В Windows Microsoft C/C ++ компиляторы обеспечивают функции "_s" (например, vfprintf_s
) как более безопасная альтернатива стандартным вызовам библиотеки. Эти функции не являются общедоступными заменами, так как у них есть различные подписи, необходимые для обеспечения дополнительной информации по технике безопасности (например, длина буфера). Они также обеспечивают другие функции, такие как строковое обнаружение недопустимого формата, другая защита файлов, и т.д. Насколько я знаю, эта реализация не доступна на Mac.
Apple (или третье лицо) обеспечивают что-либо подобное для использования с GCC на OSX?
В частности, я ищу "безопасные" реализации, по крайней мере, следующих функций:
fopen vfprintf vsprintf sprintf strncpy strcpy strcat
Отметьте: Этот вопрос о Mac. Я НЕ прошу Ваши мнения о реализации Microsoft (если это не доступно на Mac), Хотя некоторые из этих функций могли бы быть легки записать меня, не все. Я НЕ спрашиваю, как записать их сам. Я НЕ прошу подсказки относительно того, как использовать классы STL, чтобы сделать это. Я НЕ спрашиваю, как выключить предупреждения. Мои конкретные потребности очень конкретны. Я пытаюсь определить лучшую практику API Mac, который максимально подобен традиционным вызовам библиотеки C при добавлении безопасности. Конечно, портативная реализация, которая работает над Mac и Windows (и другие операционные системы) была бы еще лучше.
Резюме: На Mac есть несколько вариантов API и компилятора, которые обеспечивают более безопасные альтернативы стандартными функциями C стандартной библиотеки. Вот некоторые из них по сравнению с API Microsoft «Safe» API Microsoft :
C MSVC PROVIDERS MAC SOLUTION --------------------------------------------------------------------------------- fopen fopen_s C none, assume fopen is safe vfprintf vfprintf_s GCC GCC_WARN_TYPECHECK_CALLS_TO_PRINTF(1) vsprintf vsprintf_s GCC, C99 GCC_WARN_TYPECHECK_CALLS_TO_PRINTF, vsnprintf(2) sprintf sprintf_s GCC, C99 GCC_WARN_TYPECHECK_CALLS_TO_PRINTF, snprintf(3) strncpy strncpy_s BSD strlcpy(4) strcpy strcpy_s BSD strlcpy strcat strcat_s BSD strlcat(5)
(1) GCC_WARN_TYPECHECK_CALLS_TO_PRINTF
- опция конфигурации XCODE, которая соответствует варианту командной строки GCC - Wformat
. Эта опция производит компиляторы предупреждения о несогласии между типами аргументов и строки статического формата. Существует множество других вариантов управления лечением формата GCC. Вы можете даже использовать функциональный атрибут функции
, чтобы включить проверку строки формата на свои собственные функции.
(2) vsnprintf
и (3) SNPRINTF
находятся из версии C99 стандартной библиотеки C (доступной в GCC на Mac, но не в MSVC в Windows).
(4) STRLCPY
и (5) STRLCAT
являются функциями библиотеки BSD, доступные на Mac.
Поскольку пользовательское окружение OSX основано на FreeBSD, вы do имеете несколько более приятных функций, таких как strlcpy и strlcat.
вместо SprintF и VSPrintf, вы хотите использовать:
snprintf(buffer, buffer_size, fmt_string, args, ...);
vsnprintf(buffer, buffer_size, fmt_string, valist);
вместо strcpy, strncpy, strcat и STRNCAT Вы хотите нам:
strlcpy(dest, src, dest_size);
strlcat(dest, src, dest_size);
Существует один важный способ, которым функции strn не могут быть заменены функциями Strl. Если вы хотите скопировать un-0 Strected Strings, функции strn позволяют сделать это, установив длину в меньшее значение количества копии и размера буфера назначения. Функции Strl не делают этого и работают только тогда, когда исходная строка расторгнута.
Не уверен, как FOPEN или VFPRINTF считаются небезопасными.
Прежде всего, распечатайте документацию о "безопасных/небезопасных" функциях из MSDN и запишите ее!
fopen
так же безопасен, как и fopen_s.... Если вы не идиот и предполагаете, что возвращаемый указатель не NULL, или предоставляете NULL в качестве входного параметра.
vfprintf vsprintf sprintf
Только MS не поддерживает C99, используйте snprintf
семейство.
strncpy
Совершенно безопасно, если вы читаете инструкцию
strcpy strcat
Используйте strncpy
и strncat
и читаете спецификации. (т.е. strncpy может не закончиться нулем)
Так что... еще раз:
Распечатайте документацию о "безопасных/небезопасных" функциях из MSDN и запишите ее!
См. Также: SO 327980 .
Стандартный C Комитет создал технический отчет, TR 24731-1 , отчасти при поддержке Microsoft (я верю). Он стандартизирует интерфейсы различным функциям, таким как vsnprintf_s ()
. К сожалению, однако, интерфейс, определяемый стандартом, несовместим с интерфейсом, определенным Microsoft, что делает стандарт, в основном неактуальный.
Например, TR 24731-1 говорит интерфейс к vsnprintf_s ()
:
#define _ _STDC_WANT_LIB_EXT1_ _ 1
#include <stdarg.h>
#include <stdio.h>
int vsnprintf_s(char * restrict s, rsize_t n,
const char * restrict format, va_list arg);
К сожалению, MSDN говорит интерфейс к vsnprintf_s ()
:
int vsnprintf_s(
char *buffer,
size_t sizeOfBuffer,
size_t count,
const char *format,
va_list argptr
);
Параметры
Обратите внимание, что это не просто вопрос отображения типа: количество фиксированных аргументов отличается и, следовательно, непримиримо. Также неясно для меня (и, по-видимому, также к стандартам комитета), какую пользу есть как «SizeOfBuffer», так и «счетчик»; Он выглядит как та же информация дважды (или, по крайней мере, код обычно будет писать с тем же значением для обоих параметров).
Стандарт C уже имеет набор «безопасной» версии этих функций.
(Для определенного определения термина Safe)
SNPRINTF () (и FAMILY) предоставляет функции безопасности, которые вы ищете. Проверка переполнения буфера.
Компилятор GCC дополнительно делает валидацию строки форматирования (но лучше, чем MS, потому что валидация выполняется во время компиляции).
fopen() Not sure how you make that safer?
vfprintf -- These are low level functions
vsprintf -- These are low level functions
sprintf snprintf
strncpy Already the safe version
strcpy strncpy
strcat strncat
Google Summer of Code 2010: OpenAfs и Google спонсируют перенос библиотеки Microsoft String Safe. См. http://www.openafs.org/pages/gsoc.html .