Я пробежал fuzzying на Dcraw и нашел исключение с плавающей запятой.
Каковы опасности этого? Это читает некоторую длину plen
из поврежденного файла и вычисляет foo[i % plen]
, Если plen == 0
тогда это не определено по стандарту и gcc выдает исключение с плавающей запятой. РЕДАКТИРОВАТЬ: И исключение не перехватывается (это C), и программа завершается.
Должен ли я заботиться? Есть ли сценарий, где это может быть использовано или вызвать другие плохие вещи? Одним из возможных правильных действий кода было бы заметить, что файл поврежден и просто существует. Чем это отличается от броска FPE и затем выхода?
(Я удивлен, что не нашел вопрос по этому вопросу, потому что это кажется мне очень простым.)
Если
plen == 0
тогда это не определено стандартом …
Именно так. Это означает, что компилятор может предположить, что этого не происходит. Этот код, например
int foo(int m, int n) {
if(n == 0) return m % n;
return 0;
}
составлен в
foo: # @foo
xorl %eax, %eax
ret
от clang -std=c99 -S -O2
на моей машине (Intel x86). if
предполагается, что ветвь никогда не будет введена и foo
возвращает 0 безоговорочно. Без FPE, без сбоев. (Я не смог найти похожий маленький пример с gcc
, к несчастью.)
… и gcc выдает исключение с плавающей запятой.
Не совсем. Это ваш процессор, если код пытается разделить на ноль. Но, как сказано выше, нет никакой гарантии, что такой код будет сгенерирован вообще.
Я сомневаюсь, что GCC что-то здесь определяет (и не смог найти ничего, указывающего на это в документации).
Должен ли я заботиться? Есть ли сценарий, где это может быть использовано или вызвать другие плохие вещи? Одним из возможных правильных действий кода было бы заметить, что файл поврежден и просто существует. Чем это отличается от броска FPE и затем выхода?
Вы должны заботиться. В случае неудачи ваша программа может продолжить работу с неверным входным файлом, см. Выше.
И сообщение об ошибке «Неверный входной файл». на мой взгляд, гораздо приятнее, чем просто «исключение с плавающей точкой». Первый говорит мне (как конечному пользователю), что не так, а второй говорит мне, что в программном обеспечении есть ошибка (я бы посчитал ее такой).
Исключения выдают, чтобы вы могли восстановить систему в четко определенное состояние после непредвиденных событий.
Брошенные исключения не восстанавливают систему до четко определенного состояния. Это ваша ответственность. Любая эксплуатация происходит на основе того, как вы это делаете, а не на основе самого брошенного исключения.
Regarding "Is there any scenario where this could be exploited or
cause other bad things? "
Восстановление из исключения полностью зависит от контекста, в котором было сгенерировано исключение. Если в результате некоторых вычислений возникло исключение, результат которого необходим для продвижения вперед, лучше остановить систему.
Однако, если ваше исключение выдается для чего-то, что может быть проигнорировано ИЛИ для которого могут быть предоставлены другие параметры по умолчанию, тогда вы, безусловно, можете перейти от этого.
Например: —
Допустим, я читаю .ini, используя параметры программы повышения. Из-за некоторых пропущенных переменных в файле .ini возникло исключение. в этом случае я могу восстановиться после исключения, указав для этой переменной подходящее значение по умолчанию.