Является ли sscanf считающимся безопасным для использования?

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

Ответы

Ответ 1

Я думаю, это зависит от того, как вы его используете: если вы сканируете что-то вроде int, это нормально. Если вы сканируете строку, это не (если не было поля ширины, которое я забыл?).


Edit

Это не всегда безопасно для сканирования строк.

Если ваш размер буфера является константой, вы можете указать его как нечто вроде %20s. Но если это не константа, вам нужно указать ее в строке формата, и вам нужно будет сделать:

char format[80]; //Make sure this is big enough... kinda painful
sprintf(format, "%%%ds", cchBuffer - 1); //Don't miss the percent signs and - 1!
sscanf(format, input); //Good luck

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

Ответ 2

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

Ответ 3

Да, это... если вы укажете ширину строки, так что проблемы с переполнением буфера не связаны.

В любом случае, как показал нам @Mehrdad, будут проблемы, если размер буфера не будет установлен во время компиляции. Я полагаю, что ограничение на длину строки, которая может быть передана в sscanf, может устранить проблему.

Ответ 4

Обратите внимание, что до тех пор, пока ваши буферы не меньше, чем strlen(input_string)+1, нет возможности переполнения спецификаторов %s или %[. Вы также можете использовать ширину поля в спецификаторах, если вы хотите применять более строгие ограничения, или вы можете использовать %*s и %*[ для подавления назначения и вместо этого использовать %n до и после, чтобы получить смещения в исходной строке, и затем используйте их, чтобы прочитать полученную подстроку на месте из входной строки.

Ответ 5

Есть 2 пункта, чтобы заботиться.

Выходной буфер [s].

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

Входной буфер.

Здесь вы должны убедиться, что это строка с нулевым завершением или что вы не будете читать больше, чем размер входного буфера.

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