星期二, 12月 16, 2008

危險的gets()

今天在寫測試程式的時候,發現compiler給了各warning:
the `gets' function is dangerous and should not be used.

去google了一下,原來是因為它沒有做長度check,如果餵長一點的字串,就會overflow:
*** stack smashing detected ***: ./getstdin terminated
Aborted (core dumped)


除了自己check字串長度做保護外(但很麻煩),可以用fgets代替:
char *fgets(char *restrict s, int n, FILE *restrict stream);

說起來,由於歷史因素,許多好用的standard C functions到了現在這個越來越『先進』的時代,都變得dangerous,像是buffer的allocate和檢驗、是否可以reentrant、變數是否是library內static宣告...等。所以,使用一些有參數是pointer或是沒有限制buffer size的function,應該要提高警覺心,像是sprintf。有一些function有reentrant的版本,會命名為同名加上『_r』的方式。

sprintf --> snprintf
gets --> fgets
time系列functions(ex: asctime --> asctime_r)
search user DB系列functions(ex: getpwnam --> getpwnam_r)
string functions(ex: strerror --> strerror_r、strtok --> strtok)
...

沒有留言: