Безопасно звоня strftime с недоверяемой строкой формата

У нас есть C++ / приложение MFC, которое позволяет пользователям настраивать форматирование даты через конфигурационные файлы. Не желая изобрести велосипед, я передаю строку формата CTime:: Формат (" <строка формата>"), чтобы сделать фактическое форматирование. Под покрытиями Формат называет вариант стандарта C функцией strftime ().

Естественно, пользователь может случайно ввести строку недопустимого формата. (Например, "%s" вместо "%S".), Когда это происходит, Время выполнения C называет Обработчик Недействительных аргументов, который, по умолчанию, выходит из приложения. (Никакие исключения для ловли - просто выход приложения.)

Мой вопрос состоит в том, как корректно обработать этот недоверяемый вход. В теории я мог записать свой собственный синтаксический анализатор/блок проверки допустимости для строки формата, но это походило на пустую трату времени. Вместо этого лучшее, которое я мог придумать, должно было установить мой собственный (глобальный) обработчик недействительных аргументов, который, вместо выхода, выдает исключение Недействительного аргумента:

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

Это, действительно кажется, работает и позволяет моему явно ловить (и корректно обрабатывать) исключения недействительного аргумента в случаях, где я "ожидаю", что они произойдут. Я обеспокоен, однако, что переопределяю глобальную, установку во время выполнения в крупном приложении для решения относительно "локальной" проблемы - я не хотел бы в эту фиксацию вызвать дополнительные проблемы в другом месте.

Действительно ли этот подход разумен? Или есть ли более чистый подход, решая эту проблему?

5
задан Eric Pi 24 February 2010 в 14:08
поделиться

1 ответ

Если вас интересует только эта ошибка в определенное время вы можете временно заменить обработчик недопустимого параметра, а затем вернуть его обратно после вызова Format.

_invalid_parameter_handler oldHandler = _set_invalid_parameter_handler(MyInvalidParameterHandler);

// Your try/Format/catch code here

_set_invalid_parameter_handler(oldHandler);

Конечно, я полагаю, что если у вас есть несколько потоков в вашей программе, другой поток может в конечном итоге вызвать ваш обработчик недопустимых параметров, пока он установлен. Вам нужно будет определить, насколько это вероятно.

Я не знаю, как еще можно это сделать, кроме написания собственной функции проверки.

3
ответ дан 15 December 2019 в 06:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: