Альтернативы MS strncpy_s - PullRequest
4 голосов
/ 13 мая 2009

Какие есть альтернативы расширенным функциям безопасности Microsoft, таким как strncpy_s или _itoa_s? При разработке в среде MS цель состоит в том, чтобы написать код, который можно легко перенести на другие платформы.

Ответы [ 10 ]

3 голосов
/ 13 мая 2009

Если вы действительно хотите программировать на C:

Используйте простой старый стандарт strncpy.

Если вы программируете на C ++:

Использовать обычную старую стандартную строку класса std::string.

(подсказка: вы, вероятно, хотите последнее. Строки C - это просто ошибки, ожидающие выполнения, даже если вы используете «безопасные» функции *_s. C ++ добавил класс строки по причине)

3 голосов
/ 13 мая 2009
std::string s(Cstring, n);
2 голосов
/ 13 мая 2009

Попробуйте strlcpy . Хотя это и не стандарт C, он существует на нескольких платформах, и вы можете скачать реализации, так как исходный код доступен бесплатно. Смотри http://www.gratisoft.us/todd/papers/strlcpy.html

1 голос
/ 04 февраля 2016

Я думаю, что @codeLizard спрашивает о том, как написать совместимый код для обработки всех функций, которые Microsoft устарела в пользу их защищенных версий, а не только строковых функций.

Функции, основанные на безопасных функциях Microsoft, включены в Приложение K стандарта C11, но приложение широко не поддерживается за пределами MSVS.

Вы можете написать макросы и встроенные функции во включаемом файле для сопоставления между некоторыми традиционных и безопасных версий. Я разместил набор макросов преобразования здесь , если вы хотите скопировать их, получите их с понравившейся страницы; более полные, лучшие комментарии, чем ниже.

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

Я рекомендую использовать защищенные функции в новом коде, если вы можете, использовать решение для функции «плюс», если это необходимо, для переносимости в компиляторы не-MS, а также в качестве моста для повторного использования устаревшего кода, пока у вас не будет времени обновить его с помощью безопасные функции.

Вот сокращенная версия вышеуказанного связанного подхода макроса / встроенной функции:

#pragma once
#if !defined(FCN_S_MACROS_H)
   #define   FCN_S_MACROS_H
   #include <cstdio>
   #include <string> // Need this for _stricmp
   using namespace std;

   #if (defined(_MSC_VER) && (_MSC_VER >= 1400) ) // _MSC_VER==MSVC 2005 

      // The function plus macro strategy could be used to maintain
      // consistent exception behaviors and return values. 
      inline extern
      FILE*   fcnSMacro_fopen_s(char *fname, char *mode)
      {  FILE *fptr;
         fopen_s(&fptr, fname, mode);
         return fptr;
      }
      #define fopen(fname, mode)               fcnSMacro_fopen_s((fname), mode))

      #define fprintf(fptr, ...)               fprintf_s((fptr), __VA_ARGS__)
      #define fscanf                           fscanf_s
      #define strncpy(dest, source, count)     strcpy_s((dest), (count), (source))
      // Can't map sprinf to sprintf_s (size argument unavailable). 
      //    #define sprintf                    ???


      ...
    #else
      #define fopen_s(fp, fmt, mode)          *(fp)=fopen( (fmt), (mode))
      #define fprintf_s                        fprintf
      #define fscanf_s                         fscanf
      #define strcpy_s(dest, count, source)    strncpy( (dest), (source), (count) )
      ...
    #endif //_MSC_VER
#endif // FCN_S_MACROS_H
1 голос
/ 13 мая 2009

Вас может заинтересовать проект Apache Portable Runtime :

Задача проекта Apache Portable Runtime (APR) - создавать и поддерживать библиотеки программного обеспечения, которые обеспечивают предсказуемый и согласованный интерфейс для базовых реализаций, специфичных для платформы.

autoconf также может позаботиться о некоторых из этих специфических для платформы различий (установив #defines и т. Д.), Хотя мой опыт работы с ним под Windows оставляет желать лучшего.

1 голос
/ 13 мая 2009

Rageous - это правильно, за этим нет сложной логики.

Я бы просто использовал версию Microsoft на данный момент, и если вы решите портировать на другую ОС позже, ТО затем внедрите ее самостоятельно для целевой платформы и используйте команды препроцессора, чтобы указать вашу реализацию на платформах (не) Windows. *

1 голос
/ 13 мая 2009

Насколько я понимаю, strncpy_s не имеет сложной логики: достаточно взять минимум длины строки, размера данных источника и назначения и скопировать полученное количество символов в место назначения. Если вам это так нужно, почему бы не реализовать это самостоятельно?

1 голос
/ 13 мая 2009

Просто используйте strncpy и отключите предупреждение в VC ++.

0 голосов
/ 15 января 2018

Да, попробуйте https://rurban.github.io/safeclib/.

Это независимая от платформы реализация Приложения K C11 поверх всех libc. Он в основном совместим с Windows sec_api. Windows немного отличается от спецификации некоторыми функциями.

strncpy_s - один из самых сложных API в sec_api. Windows не обнаруживает переполнение двух длин, а не совпадение двух строк. И что делать, когда 4-й аргумент count = 0 тоже сомнительный. Спецификация http://en.cppreference.com/w/c/string/byte/strncpy говорит Нулевое возвращаемое значение подразумевает ... что результат в s1 завершается нулем , но в Windows это неправильно Это просто прерывается слишком рано. Смотрите, например Винная реализация: https://github.com/mirror/reactos/blob/master/reactos/lib/sdk/crt/wine/heap.c#L577

А для безопасного суффикса _s следует предположить, что неправильно скопированные байты в буфер назначения очищаются от посторонних глаз при возникновении ошибки времени выполнения. Не так на винде с их sec_api. Они просто устанавливают самый первый байт на 0.

https://github.com/rurban/safeclib/releases

0 голосов
/ 13 мая 2009

Вы можете предоставить собственную реализацию для платформ, которые не имеют этой функции. Или используйте макрос для уменьшения аргументов на единицу и сопоставления со стандартной строковой функцией.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...