Насколько мы должны защищаться?

11

Мы запустили Pex поверх некоторого кода, и он показывал некоторые хорошие вещи (хорошо плохие, но показывал их, прежде чем приступить к работе!).

Тем не менее, одна из приятных сторон Pex заключается в том, что он не обязательно прекращает попытки найти проблемы.

Мы обнаружили, что при передаче строки мы не проверяем наличие пустых строк.

Итак, мы изменились:

if (inputString == null)

в

if (string.IsNullOrEmpty(inputString)) // ***

Это исправило первоначальные проблемы. Но потом, когда мы снова запустили Pex, он решил, что:

inputString = "\0";

вызывал проблемы. А потом

inputString = "\u0001";

Мы решили, что по умолчанию можно использовать, если мы встретимся, // ***и что мы рады видеть исключение, вызванное любым другим нечетным вводом (и иметь дело с ним).

Этого достаточно?

Питер К.
источник
Вы проверили, можете ли вы отключить некоторые предупреждения? Я знаю, что JTest тоже это сделает, но у него была возможность отключить некоторые из его рекомендаций. Потребовалось некоторое время для настройки параметров, чтобы получить профиль тестирования кода, который нам понравился.
FrustratedWithFormsDesigner
@ Разочарованный: Да, есть определенные изменения в профиле, которые мы можем сделать и делаем. Кстати, Pex - отличный инструмент. Результаты, которые он показал, только что вызвали вопрос.
Питер К.
У меня нет ответа для вас, но я хотел сказать спасибо за эту ссылку на эту вещь Пекса; это выглядит довольно аккуратно, если это то, что я думаю, и автоматически (?) создает модульные тесты для существующего кода. Код, над которым я работаю, огромен, не имеет тестов и очень тесно связанного кода, поэтому невозможно что-либо реорганизовать.
Уэйн Молина
@WayneM: Да, это довольно хорошо, хотя мне нужно было пройти несколько примеров, чтобы понять, что он делает. Для устаревшего кода это здорово. Еще лучше для нового кода!
Питер К.

Ответы:

9

Три вопроса должны помочь вам определить, насколько защищен ваш код.

Первый - Каковы последствия неудачного прохождения ввода? Если это сообщение об ошибке на одном из ПК вашего разработчика, возможно, не так критично, чтобы защищаться. Может ли это привести к финансовым сбоям у клиентов, нарушению бухгалтерской информации в IE? Это система реального времени, где жизнь подвергается риску? В сценарии «жизнь / смерть» должно быть больше кода проверки и обработки ошибок, чем фактического кода функции.

Во-вторых, сколько людей будут повторно использовать эту функцию или фрагмент кода? Только ты? Ваш отдел? Твоя компания? Ваши клиенты? Чем шире использование кода, тем больше защиты.

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

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

Борк Блатт
источник
6

Пользователи злые, и все, что они вводят, должно быть проверено со всей строгостью.

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

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

Satanicpuppy
источник
2

Я буду защищаться так, как вам нужно. Я думаю, что это немного двусмысленно, но я постараюсь объяснить.

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

Если метод является открытым API, то же самое. Вы не можете контролировать то, что входит, поэтому вы должны попытаться охватить все аспекты и программы соответственно.

Для методов, которые производятся в ядре вашего проекта, здесь вы должны принять решение. Предполагаю ли я, что поступающие данные предварительно проверены и проверены до их поступления, или я должен поставить необходимые проверки. Я предполагаю, что это зависит от концептуального уровня метода и приемлемого места для проверки. Итак, что я мог бы рассмотреть это:

1) Это единственное место, где мне нужно будет сделать эту проверку? Нужно ли проверять эту переменную во множестве разных мест для этого условия. Если да, могу ли я сделать проверку один раз выше по цепочке, а затем принять законность

2) Ожидаются ли другие компоненты системы для работы с методами и интерфейсами, которые я пишу. Если да, то можете ли вы контролировать с помощью операторов отладки assert, исключений отладки, комментирования методов и общей архитектуры системы требуемый результат, или же потребуется проверка данных на месте.

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

4) Есть ли смысл ставить здесь чек? Иногда проверка части возможных поврежденных данных, хотя и помогает решить проблему в этот момент, а не исключает ошибки, может помочь скрыть это. В этот момент вы могли бы часами искать другую проблему только для того, чтобы найти фактическую проблему из-за правильной проверки данных в цепочке событий, которая каскадно совпадает с той, о которой сообщили пользователь / разработчик.

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

dreza
источник
1

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

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

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

Карл Билефельдт
источник