[英]How guard against unterminated strings
在C程序中,我有一個將消息寫入日志文件的函數
LogResult writeLog(const char* format, ...)
該函數將其參數傳遞給'vfprintf()'作為'format'字符串和'va_list'。 我剛剛想到,如果有人傳遞未終結的字符串,我無法控制會發生什么
const char unterminatedString[5] = {'h', 'e', 'l', 'l', 'o'};
writeLog("Log message: %s", unterminatedString);
有沒有辦法防范這個?
傳遞非法字符串還有很多其他方法(在你提到的方法之上)。
幾個例子:
char* unterminatedString;
writeLog("Log message: %s", unterminatedString);
char* unterminatedString = (char*)0xA5A5A5A5;
writeLog("Log message: %s", unterminatedString);
char unterminatedString[] = "abc";
unterminatedString[3] = 'd';
writeLog("Log message: %s", unterminatedString);
int x = -1;
char* unterminatedString = (char*)&x;
writeLog("Log message: %s", unterminatedString);
合法字符串必須從有效的內存地址開始,並以有效的內存地址結束(帶0字符)。 沒有明確的方法斷言,除了迭代字符串本身,直到達到0字符或執行內存訪問沖突(這正是vfprintf
函數所做的)。
const char*
不知道數組的長度,它只是一個地址。 所以這不是簡單的可能。
如果你想保持純C,你可以傳遞字符串的長度int len
作為額外的參數,並檢查format[len]==0
。 我不認為這有用,但在我看來更糟糕。
既然你用C ++標記了這個問題,你可以(並且應該)使用std::string
:
LogResult writeLog(const std::string& format, ...)
始終正確終止std::string
,您可以使用std::string::c_str()
訪問其底層C樣式字符串。
請注意, std::string
可以存儲\\0
-Characters,因此使用C樣式字符串的函數將停在第一個\\0
,而不是在std::string
。
我假設你的日志功能有自己的內部緩沖區,你知道它的大小。
然后,您可以使用指定緩沖區大小的vsprintf()函數。 請參閱可能的緩沖區溢出漏
不,沒有辦法可移植。
你可以做的是使用像valgrind
這樣的工具來尋找這類錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.