最近 ubuntu/debian 正在討論 sprintf/snprintf 的問題,我在這描述一遍。
sprintf 的原型爲:
int sprintf(char *restrict s, const char *restrict format, ...);
其中 char* restrict s 的含義爲經過s 指向的內存空間不得與其餘指針參數指向的內存的空間重疊。好比以下的語句就是錯誤的用法, 由於參數1與參數3指向的內存重疊了。但這種作法做爲加強版的 strcat 已被普遍使用。
sprintf(buf, "%s foo %d %d", buf, var1, var2);
在 ubuntu 8.10 所帶的 gcc 中,若是編譯時加入了優化選項(好比 -O1, -O2), 那麼sprinf 會首先將 s 清空,好比以下的程序會輸出 "fail", 而不是 "not fail"。
#include <stdio.h> char buf[80] = "not ";int main(){sprintf(buf, "%sfail", buf);puts(buf); return 0;}
做爲補救方案,能夠使用以下的語句來代替:
sprintf(buf+strlen(buf), " foo %d %d", var1, var2);
snprintf 有相似的 bug.
不少 Debian/Ubuntu 包都有此 bug,能夠參見以下兩個 thread 中的具體內容:
[1]
https://bugs.launchpad.net/ubuntu/+source/glibc/+bug/305901
[2]
http://groups.google.com/group/linux.debian.devel/browse_thread/thread/c5bbda39f1a01bd4
html