使用不受信任的格式字符串安全地调用strftime

时间:2010-02-24 14:08:20

标签: mfc validation strftime

我们有一个C ++ / MFC应用程序,允许用户通过配置文件自定义日期格式。我不想重新发明轮子,我将格式字符串传递给CTime :: Format(“< format string>”)来进行实际的格式化。在封面下,Format调用标准C函数strftime()的变体。

当然,用户可能会意外输入无效的格式字符串。 (例如,“%s”而不是“%S”。)发生这种情况时,C运行时调用Invalid Argument Handler,默认情况下退出应用程序。 (没有例外可以捕获 - 只需退出app。)

我的问题是如何优雅地处理这种不受信任的输入。从理论上讲,我可以为格式字符串编写自己的解析器/验证器,但这听起来像是浪费时间。相反,我能想到的最好的方法是设置我自己的(全局)无效参数处理程序,它不会退出,而是抛出一个无效的参数异常:

void MyInvalidParameterHandler(
    const wchar_t* expression,
    const wchar_t* function, 
    const wchar_t* file, 
    unsigned int line, 
    uintptr_t pReserved)
{
    ::AfxThrowInvalidArgException();
}

这似乎有效,并且允许我在“期望”它们发生的情况下显式捕获(并且优雅地处理)无效的参数异常。但是,我担心我在大型应用程序中覆盖全局的运行时设置以解决相对“本地”的问题 - 我不愿意这个修复在其他地方引起其他问题。

这种方法是否合理?或者是否有更清洁的方法来解决这个问题?

1 个答案:

答案 0 :(得分:3)

如果您只对某些时候捕获此错误感兴趣,可以暂时替换无效参数处理程序,然后在调用Format后将其设置回来。

_invalid_parameter_handler oldHandler = _set_invalid_parameter_handler(MyInvalidParameterHandler);

// Your try/Format/catch code here

_set_invalid_parameter_handler(oldHandler);

当然,我想如果你的程序中有多个线程,那么另一个线程可能会在设置时调用你的无效参数处理程序。你必须确定它的可能性。

除了编写自己的验证功能外,我不确定你还能做到这一点。