Вопрос основан на «загруженной» предпосылке, которая делает сам вопрос недействительным.
Суть в том, что strncpy
не считается небезопасным и никогда не считалось небезопасным. Единственные утверждения о «небезопасности», которые могут быть присоединены к этой функции, - это широкие требования общей небезопасности модели памяти C и самого языка C. (Но это, очевидно, совершенно другая тема).
В области языка Си ошибочное убеждение о некой «небезопасности», присущей strncpy
, вытекает из широко распространенной сомнительной схемы использования strncpy
для «безопасного копирования строк», то есть чего-то, чего эта функция не делает и никогда не был предназначен для. Такое использование действительно очень подвержено ошибкам. Но даже если вы поставите знак равенства между «очень подверженным ошибкам» и «небезопасным», это все равно проблема использования (то есть проблема отсутствия образования), а не проблема strncpy
.
По сути, можно сказать, что единственная проблема с strncpy
- неудачное именование, из-за которого начинающие программисты предполагают, что они понимают, что делает эта функция, вместо того, чтобы фактически читать спецификацию. Глядя на название функции, некомпетентный программист предполагает, что strncpy
является «безопасной версией» strcpy
, тогда как на самом деле эти две функции совершенно не связаны.
Точно такая же претензия может быть предъявлена оператору деления, например. Как большинство из вас знает, один из наиболее часто задаваемых вопросов о языке Си звучит так: «Я предполагал, что 1/2
оценивается как 0.5
, но вместо этого я получил 0
. Почему?» Тем не менее, мы не утверждаем, что оператор деления небезопасен только потому, что начинающие языки склонны неверно истолковывать его поведение.
В другом примере мы не называем функции генератора псевдослучайных чисел «небезопасными» только потому, что некомпетентных программистов часто неприятно удивляет тот факт, что их выходные данные не являются действительно случайными.
Именно так и работает с strncpy
функцией. Точно так же, как начинающим программистам требуется время, чтобы понять, что на самом деле делают генераторы псевдослучайных чисел, так и им нужно время, чтобы узнать, что на самом деле делает strncpy
. Требуется время, чтобы понять, что strncpy
- это функция преобразования , предназначенная для преобразования строк с нулевым окончанием в строки фиксированной ширины . Требуется время, чтобы понять, что strncpy
не имеет абсолютно никакого отношения к «безопасному копированию строк» и не может быть осмысленно использовано для этой цели.
Конечно, студенту, изучающему язык, обычно требуется намного больше времени для изучения цели strncpy
, чем разбираться с оператором деления. Тем не менее, это является основанием для любых претензий "небезопасности" против strncpy
.
P.S. Документ CERT, ссылка на который содержится в принятом ответе, посвящен именно этому: продемонстрировать отсутствие безопасности типичного некомпетентного злоупотребления функцией strncpy
как «безопасной» версией strcpy
. Он никоим образом не претендует на то, что strncpy
сам по себе небезопасен.