gets
読み:ゲット-エス
外語:gets
Cで、標準入力から1行分を読み取り、文字配列に書き込む関数。
この関数は文字配列の大きさを指定できず、バッファーオーバーフローを防ぐ手段がないという致命的な脆弱性を持っていたため、結果C11にて仕様から削除された。
書式
#include <stdio.h>
char *gets(char *s);
概要
標準入力から改行('\n')が現れるまで入力を読み取り、結果をバッファーに書く。
その際、末端の改行は削除され、代わりにNULL文字('\0')をバッファーに格納する。
特徴
脆弱性
この関数は、結果を格納するバッファーの大きさを与えることができない。そのため、バッファーオーバーフローを防ぐ手立てがない。
char buf[10];
gets(buf);
この場合、バッファーは10バイトしかないため、終端を除くと9バイトしか余裕が無い。結果として、9文字を超えて入力してしまうと、簡単にバッファーオーバーフローが発生する。
警告類
GCCの場合、getsを使うと次のようなワーニングを出力していた。
warning: the `gets' function is dangerous and should not be used.
Cの標準関数で、「危険なので使うべきではない」(dangerous and should not be used)とまで言われるものは他にはない。
Linuxのmanpageに至っては「gets() は絶対に使用してはならない。」とまで書かれている。ここまで言われる標準関数も、他にはない。
代替関数
代替方法はいくつか存在する。
- fgets関数
- この関数はバッファーの大きさを与えることができるため、初期から存在するCの標準関数の中ではセキュアである。
但し、改行文字を削除せずそのまま残すため、単純にgetsをfgetsで置き換えることができない。
- gets_s関数
- C11から追加されたgetsのセキュア版だが、実装は任意であり、必ず使えるとは限らない。
char *gets_s(char *, size_t);として定義されており、バッファーの長さを指定することができる。
- getline関数
- GCC拡張で、後にPOSIXでも採用されたgetsのセキュア版。
ssize_t getline(char **, size_t *, FILE *);として定義されており、バッファーの長さを指定することができる。
但し、改行文字を削除せずそのまま残すため、単純にgetsをgetlineで置き換えることができない。
再検索