Корректность и устойчивость программных систем. Проверка заполнения формы с использованием JavaScript


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

Если вы читали «Should I check the parameters to my function? » в блоге Larry Osterman, и являетесь сторонником второго подхода – можете дальше не читать. :-)

Когда то давно, функции IsBadReadPtr и IsBadWritePtr использовались для проверки валидности переданных указателей. Правда, со временем выяснилось, что от этих функций больше вреда, чем пользы. Во-первых, вместо обнаружения некорректных указателей (что по идее было целью их создателей), эти функции скорее скрывали ошибки. Во-вторых, даже успешное тестирование указателя с помощью одной из функций не гарантировало успешность следующей операции с этой памятью в многозадачной среде. В-третьих, IsBadWritePtr портит память по фактически случайному адресу – гарантия того, что приложение всё-таки упадёт позднее, но только с большими неприятностями. В-четвёртых, даже IsBadReadPtr может быть виновником в сбое приложения, если проверяемый адрес приходится на зашитную страницу (guard page) стека. В результате система потеряет возможность увеличивать стек, по мере надобности, и приложение с грохотом упадёт, если попытается это сделать.

Как же правильно проверять переданные указатели? Правило простое – любое значение указателя не равное 0 считается корректным. Если указатель на самом деле указывает «не туда», то приложение завершиться ошибкой доступа, что, в общем-то, плохо, но помогает найти и исправить ошибки быстрее.

Это правило не работает для специальных случаев, вроде точки входа в ядре операционной системы или RPC. Хотя в случае RPC каждая из сторон сама контролирует выделение буферов, так что функциональность IsBadXxxPtr все равно не требуется.

В случае ядерного вызова указатели должны проверяются на корректность, однако и в этом случае IsBadXxxPtr оказывается не у дел. NT ядро использует функции ProbeForRead и ProbeForWrite , которые во много похожи на IsBadXxxPtr. Не смотря на похожесть, ProbeForXxx главным образом проверяют, что переданный буфер целиком находится в пользовательском адресном пространстве, а не то, что буфер размещён в валидной памяти. Дальнейшие обращения к переданному буферу в любом случае окружаются блоком __try - __except. Иными словами такая проверка гарантирует, что пользовательский код не сможет заставить ядерный код обратится к какому-либо адресу в адресном пространстве ядра. Тем самым ситуация с порчей защитной страницы ядерного стека, как результат запроса из пользовательского кода, не возможна. Само собой, что защитная страница пользовательского стека по-прежнему может пострадать. Но тут уж само приложение виновато.

Данный урок описывает, как создать JavaScript форму, которая проверяет правильность заполнения посетителем полей перед отправкой данных на сервер. Сначала мы объясним, почему проверка заполнения формы является полезной методикой, а затем построим простой пример с объяснением, как все происходит.

Зачем нужна проверка заполнения формы?

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

Существует два основных метода для проверки заполнения формы: на стороне сервера (с использованием CGI скриптов, ASP и т.д.) и на стороне клиента (обычно используется JavaScript). Проверка на стороне сервера более безопасная, но в большинстве случаев требует более сложного кода, в то время как проверка на стороне клиента выполняется проще и быстрее (браузер не нуждается в соединении с сервером для проверки заполнения формы, таким образом, пользователь получает немедленный ответ в случае пропущенных полей, которые необходимо заполнить).

Проверка формы на стороне клиента. Обычно выполняется с помощью встроенного JavaScript скрипта.

Проверка формы на стороне сервера. Обычно выполняется с помощью CGI или ASP скрипта.

В данном уроке мы построим простую форму с проверкой на стороне клиента с помощью JavaScript. Вы сможете затем адаптировать ее под свои нужды.

Простая форма с проверкой.

Давайте построим простую форму с проверкой заполнения с помощью скрипта. Данная форма имеет одно текстовое поле "Ваше имя" и кнопку для отправки данных. Наш скрипт проверяет, что пользователь ввел свое имя перед тем, как отправить данные на сервер.

Откройте форму и посмотрите в действии. Попробуйте нажать кнопку "Отправить данные" ничего не вводя в поле "Ваше имя".

Страница содержит функцию JavaScript, которая называется validate_form(). Она выполняет проверку заполнения формы. давайте посмотрим сначала на форму.

Форма

Первая часть формы - тэг form

Форма имеет имя contact_form. С его помощью мы получим доступ к форме из JavaScript функции проверки.

Форма использует постметод для отправки данных в htm-файл заглушку, который просто выводит сообщение. В действительности Вы можете пересылать данные Вашему CGI скрипту, ASP странице и т.д. (например для отправки почты).

Также тэг form содержит onsubmit атрибут для вызова JavaScript функции проверки validate_form (), когда нажимается кнопка "Отправить данные". Функция возвращает логическое значение, для которого true означает "проверка прошла успешно", а false - "данные задержаны". Таким образом мы можем предотвратить отправку данных формы, если пользователь не заполнил ее правильно.

Остальной код формы добавляет поле ввода contact_name и кнопку "Отправить данные":

Пожалуйста введите Ваше имя.

Ваше имя:

Функция validate_form()

Функция проверки формы validate_form() встроена в секцию head вначале страницы:

Первая строчка () указывает браузеру, что далее идет код JavaScript, а коментарий HTML (