簡體   English   中英

如何防范未終止的字符串

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM