Question

We have a C++/MFC application which allows users to customize date formatting via configuration files. Not wanting to reinvent the wheel, I pass the format string to CTime::Format("< format string >") to do the actual formatting. Under the covers, Format calls a variant of the standard C function strftime().

Naturally, the user can accidentally enter an invalid format string. (For example, "%s" instead of "%S".) When this happens, the C Run-Time calls the Invalid Argument Handler which, by default, exits the app. (No exceptions to catch-- just app exit.)

My question is how to gracefully handle this untrusted input. In theory, I could write my own parser/validator for the format string, but this sounded like a waste of time. Instead, the best I could come up with was to set my own (global) invalid argument handler which, instead of exiting, throws an Invalid Argument exception:

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

This does seem to work, and allows my to explicitly catch (and gracefully handle) the invalid argument exceptions in the cases where I "expect" them to occur. I am concerned, however, that I am overriding a global, run-time setting in a large application in order to solve a relatively "local" problem-- I would hate for this fix to cause additional problems elsewhere.

Is this approach sensible? Or is there a cleaner approach solving this problem?

Was it helpful?

Solution

If you are only interested in catching this error at certain times, you could temporarily replace the invalid parameter handler and then set it back once you have called Format.

_invalid_parameter_handler oldHandler = _set_invalid_parameter_handler(MyInvalidParameterHandler);

// Your try/Format/catch code here

_set_invalid_parameter_handler(oldHandler);

Of course, I suppose it is possible that if you have multiple threads in your program, another thread could end up calling your invalid parameter handler while it's set. You would have to determine how likely that is.

Other than writing your own validation function, I'm not sure how else you could do this.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top