Почему необходимо использовать strncpy вместо strcpy?

C# и платформа.NET повредили совместимость между версиями 1.0 и 1.1, а также между 1,1 и 2.0. Запущенные приложения в различных версиях, требуемых, имея несколько версий времени выполнения.NET, установлены.

, По крайней мере, они действительно включали мастер обновления для обновления источника от одной версии до следующего (это работало на большую часть нашего кода).

77
задан Deduplicator 21 February 2015 в 17:36
поделиться

8 ответов

strncpy борется с переполнением буфера, требуя указать длину в нем. strcpy зависит от завершающего \ 0 , что может не всегда встречаться.

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

Все функции n используются как защитное кодирование от переполнения буфера. Используйте их вместо старых функций, таких как strcpy .

92
ответ дан 24 November 2019 в 10:41
поделиться

Хотя я знаю цель strncpy , это не совсем хорошая функция. Избегайте обоих. Раймонд Чен объясняет .

Лично я пришел к выводу, что просто избегайте strncpy и всех его друзей, если вы имеете дело со строками с завершающим нулем. Несмотря на "str" ​​в имени, эти функции не создают строки с завершающим нулем. Они преобразуют строку с завершающим нулем в буфер необработанных символов. Использование их там, где ожидается строка с завершающим нулем, поскольку второй буфер явно неверен. Мало того, что вы не можете получить правильное завершение нуля, если источник слишком длинный, но если источник короткий, вы получите ненужное заполнение нулем.

См. Также Почему strncpy небезопасен?

31
ответ дан 24 November 2019 в 10:41
поделиться

strncpy НЕ безопаснее, чем strcpy, он просто заменяет один тип ошибок другим. В C при работе со строками C вам нужно знать размер ваших буферов, нет никакого способа обойти это. strncpy был оправдан для элемента каталога, упомянутого другими, но в противном случае вы никогда не должны его использовать:

  • если вы знаете длину своей строки и буфера, зачем использовать strncpy? В лучшем случае это напрасная трата вычислительной мощности (добавление бесполезных 0)
  • , если вы не знаете длины, вы рискуете незаметно обрезать свои строки, что не намного лучше, чем переполнение буфера
27
ответ дан 24 November 2019 в 10:41
поделиться

Функция strncpy () была разработана с учетом очень конкретной проблемы: манипулирование сохраненными строками как оригинальные записи каталога UNIX. В них использовался массив фиксированного размера, а нулевой символ конца использовался только в том случае, если имя файла было короче, чем массив.

Вот что скрывается за двумя странностями strncpy () :

  • Это не значит ' t поставить нуль-терминатор на место назначения, если оно полностью заполнено; и
  • Он всегда полностью заполняет место назначения, при необходимости, с нулями.

Для «более безопасного strcpy () » лучше использовать strncat () вот так :

if (dest_size > 0)
{
    dest[0] = '\0';
    strncat(dest, source, dest_size - 1);
}

Результат всегда будет завершаться нулем и не будет копироваться больше, чем необходимо.

манипулирование строками, хранящимися в манере исходных записей каталога UNIX. В них использовался массив фиксированного размера, а нулевой символ конца использовался только в том случае, если имя файла было короче, чем массив.

Вот что скрывается за двумя странностями strncpy () :

  • Это не значит ' t поставить нуль-терминатор на место назначения, если оно полностью заполнено; и
  • Он всегда полностью заполняет место назначения, при необходимости, с нулями.

Для «более безопасного strcpy () » лучше использовать strncat () вот так :

if (dest_size > 0)
{
    dest[0] = '\0';
    strncat(dest, source, dest_size - 1);
}

Результат всегда будет завершаться нулем и не будет копироваться больше, чем необходимо.

манипулирование строками, хранящимися в манере исходных записей каталога UNIX. Они использовали массив фиксированного размера, а нулевой символ конца использовался только в том случае, если имя файла было короче, чем массив.

Вот что скрывается за двумя странностями strncpy () :

  • Не t поставить нуль-терминатор на место назначения, если оно полностью заполнено; и
  • Он всегда полностью заполняет место назначения, при необходимости, с нулями.

Для «более безопасного strcpy () » лучше использовать strncat () вот так :

if (dest_size > 0)
{
    dest[0] = '\0';
    strncat(dest, source, dest_size - 1);
}

Результат всегда будет завершаться нулем и не будет копироваться больше, чем необходимо.

s что скрывается за двумя странностями strncpy () :

  • Он не помещает нулевой символ конца в место назначения, если оно полностью заполнено; и
  • Он всегда полностью заполняет место назначения, при необходимости, с нулями.

Для «более безопасного strcpy () » лучше использовать strncat () вот так :

if (dest_size > 0)
{
    dest[0] = '\0';
    strncat(dest, source, dest_size - 1);
}

Результат всегда будет завершаться нулем и не будет копироваться больше, чем необходимо.

s что скрывается за двумя странностями strncpy () :

  • Он не помещает нулевой символ конца в место назначения, если оно полностью заполнено; и
  • Он всегда полностью заполняет место назначения, при необходимости, с нулями.

Для «более безопасного strcpy () » лучше использовать strncat () вот так :

if (dest_size > 0)
{
    dest[0] = '\0';
    strncat(dest, source, dest_size - 1);
}

Результат всегда будет завершаться нулем и не будет копироваться больше, чем необходимо.

164
ответ дан 24 November 2019 в 10:41
поделиться

То, что вы ищете, - это функция strlcpy () , которая всегда завершает строку нулем и инициализирует буфер. Он также может обнаруживать переполнения. Единственная проблема, он (действительно) не переносимый и присутствует только в некоторых системах (BSD, Solaris). Проблема с этой функцией заключается в том, что она открывает еще одну банку червей, как видно из обсуждений на http://en.wikipedia.org/wiki/Strlcpy

Лично я считаю, что он намного полезнее, чем strncpy () и strcpy () . Он имеет лучшую производительность и является хорошим дополнением к snprintf () . Для платформ, на которых его нет, это относительно легко реализовать. (на этапе разработки приложения я заменяю эти две функции ( snprintf () и strlcpy () ) версией с захватом, которая грубо прерывает программу при переполнении или усечении буфера. позволяет быстро вылавливать худших нарушителей. Особенно, если вы работаете с кодовой базой от кого-то другого.

РЕДАКТИРОВАТЬ: strlcpy () может быть легко реализован:

size_t strlcpy(char *dst, const char *src, size_t dstsize)
{
  size_t len = strlen(src);
  if(dstsize) {
    size_t bl = (len < dstsize-1 ? len : dstsize-1);
    ((char*)memcpy(dst, src, bl))[bl] = 0;
  }
  return len;
}
21
ответ дан 24 November 2019 в 10:41
поделиться

Функция strncpy () является более безопасной: вы должны передать максимальную длину, которую может принять целевой буфер. В противном случае может случиться так, что исходная строка неправильно завершена 0, и в этом случае функция strcpy () может записать больше символов в место назначения, повредив все, что находится в памяти после буфера назначения. Это проблема переполнения буфера, используемая во многих эксплойтах

Также для функций API POSIX, таких как read () , которые не помещают завершающий 0 в буфер, но возвращают количество прочитанных байтов, вы будете либо вручную введите 0, либо скопируйте его с помощью strncpy () .

В вашем примере кода index фактически не является индексом, но счетчик - он сообщает, сколько символов не более копировать из источника в место назначения. Если среди первых n байтов источника нет нулевого байта, строка, помещенная в пункт назначения, не будет завершаться нулем

3
ответ дан 24 November 2019 в 10:41
поделиться

Это может использоваться во многих других сценариях, когда вам нужно скопировать только часть исходной строки в место назначения. Используя strncpy (), вы можете скопировать ограниченную часть исходной строки, в отличие от strcpy (). Я вижу, что вы разместили код с publib.boulder.ibm.com .

0
ответ дан 24 November 2019 в 10:41
поделиться

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

-8
ответ дан 24 November 2019 в 10:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: