我們有一個C++/MFC應用程序,它允許用戶通過配置文件自定義日期格式。不想重新發明輪子,我將格式字符串傳遞給CTime :: Format(「< format string>」)以執行實際的格式化。在封面下,Format調用標準C函數strftime()的變體。用不可信的格式字符串安全地調用strftime
當然,用戶可能會無意中輸入無效的格式字符串。 (例如,「%s」而不是「%S」)。發生這種情況時,C運行時會調用默認情況下退出應用程序的Invalid Argument Handler。 (沒有例外 - 趕上 - 只是應用程序退出。)
我的問題是如何優雅地處理這個不受信任的輸入。理論上,我可以爲格式字符串編寫我自己的解析器/驗證器,但這聽起來像浪費時間。相反,我會拿出最好的就是把我自己的(全球)無效的參數處理程序,其中代替退出,拋出一個無效的參數異常:
void MyInvalidParameterHandler(
const wchar_t* expression,
const wchar_t* function,
const wchar_t* file,
unsigned int line,
uintptr_t pReserved)
{
::AfxThrowInvalidArgException();
}
這似乎工作,並允許我明確在我「期待」它們發生的情況下捕捉(並優雅地處理)無效參數異常。然而,我擔心爲了解決一個相對「本地」的問題,我在一個大型應用程序中重寫全局運行時環境 - 我恨這個修復會導致其他問題。
這種方法是否合理?還是有更清晰的方法來解決這個問題?
謝謝你的建議。不幸的是,我的應用程序確實是多線程的,所以我不認爲我可以安全地來回切換處理程序。 (無效的參數處理程序是全局的,而不是線程特定的。) – 2010-02-24 14:19:43
在這種情況下,我相信您需要創建自己的驗證功能。它不應該那麼難。如果您在CRT源代碼中查看strftime.c,您將看到一個名爲_expandtime的函數。它包含所有支持的格式說明符的case語句。你可以用它作爲你的函數的基礎。 – Dustin 2010-02-24 14:30:11
一種可能性是添加您自己的無效參數處理程序。該文檔聲明,如果控制權返回到調用函數,它將返回一個錯誤代碼。 – Dustin 2010-02-24 15:24:34