Является ли 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
может читать границу буфера и сбой, если память не выделена.