Вопрос

Как некоторые из вас, возможно, знают, Microsoft запрещена memcpy() из жизненного цикла их разработки в области безопасности, заменив его на memcpy_s().

void *memcpy(void *dest, const void *src, size_t n);

/* simplified signature */
errno_t memcpy_s(void *dst, size_t dstsize, const void *src, size_t n);

Итак, если ваш код раньше был:

if (in_len > dst_len) {
    /* error */
}
memcpy(dst, src, in_len);

это становится:

if (memcpy_s(dst, dst_len, src, src_len)) {
    /* error */
}

Или, с усечением,

memcpy(dst, src, min(in_len, dst_len));

против

(void)memcpy_s(dst, dst_len, src, src_len);

Этот вопрос:как дополнительный параметр длины делает код более безопасным?Для использования memcpy(), Я уже должен был бы знать все четыре параметра и передать соответствующую длину в качестве третьего аргумента.Что мешает мне совершить ту же ошибку, неправильно рассчитав размер буфера назначения и передав неправильное значение dst_size?Я не могу понять, почему это как-то отличается от memcpy() и почему он устарел.Есть ли какой-нибудь распространенный вариант использования, который я не вижу? Чего я здесь не понимаю?

Это было полезно?

Решение

Ничто не мешает вам также неправильно использовать параметры в "безопасной" версии.Microsoft, похоже, думает, что вы всегда будете использовать что-то вроде:

errno_t e = memcpy_s (&dstbuff, sizeof(dstbuff), &srcbuff, sizeof(srcbuff));

и проверьте ошибку.

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

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

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

Другие советы

Дублирование информации - это всегда плохой дизайн - это просто дает вам больше шансов сделать что-то неправильно.У Microsoft ужасающий послужной список, когда дело доходит до разработки API, и в прошлом ее спасало только превосходство их документации.Утешает то, что они не могут удалить исходную функцию memcpy() - это часть ANSI C.

Вы абсолютно правы.Если вы отслеживаете длины обоих буферов, memcpy безопасен в использовании.Если вы этого не сделаете, memcpy_s вас не спасет.

Вы ничего не упускаете, я думаю, что этот фрагмент из статьи, на которую вы ссылаетесь, в значительной степени охватывает это:

Как ничто другое, memcpy_s заставляет вас задуматься о размере целевого буфера.

По словам Microsoft, это немного упростит написание проверок качества кода - вы можете убедиться, что программист не передает одинаковое значение обоим параметрам size (что многие люди, вероятно, все равно сделали бы из-за лени).Другая вещь (на самом деле не связанная с безопасностью кода) заключается в том, что вы можете немного почистить свой код, используя этот метод, потому что в вашем коде меньше проверок - memcpy_s функция проверит за вас, достаточно ли места в целевом буфере, исключив одну из ваших проверок.

Самый важный из всех, memcpy_s возвращает код ошибки, указывающий, удалось ли выполнить всю копию, но с memcpy нет никакого способа быть уверенным в этом. Это это то, что, по мнению Microsoft, делает memcpy_s безопаснее , чем memcpy.

C like assembly предназначен для людей, которые знают, что они делают, я помню, что читал что-то подобное непосредственно из K & R

Иногда я действительно сомневаюсь, что в мире действительно осталось не так много настоящих программистов, которые видят машину такой, какая она есть, и любят перекладывать биты.Я знаю, это немного не по теме, но мне нравится точно знать, что происходит, и я определенно не хочу, чтобы какой-нибудь отстойный сборщик мусора бродил на заднем плане, отчаянно пытаясь разобраться в беспорядочных кучах неаккуратных программистов.Я имею в виду, насколько сложно сопоставить вызовы free() с вызовами malloc() / strdup(), насколько сложно убедиться, что вы выделили достаточно места в буфере, чтобы знать, что вы можете вызывать memcpy() автоматически?Ответ:Не очень, но 99,9% программистов действительно не заботятся о том, что они делают, потому что они занимаются этим только ради денег, а не из страсти написать красиво оформленный фрагмент кода.

Конец разглагольствования.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top