Некорректная обработка в IE форм с полями, содержащими экзотические символы
Дмитрий Леонов, http://bugtraq.ru/ Опубликовано: dl, 20.03.04 04:21 Началось все с того, что на ровном месте перестал работать скрипт редактирования анкеты ФРИ. Причем последний раз он правился за несколько месяцев до того, все эти месяцы успешно работал, да и на этот раз отказывалась нормально редактироваться только одна анкета. После непродолжительных танцев с бубном выяснилось, что в скрипт перестало попадать значение первого поля формы. Поле это было спрятанное, называлось type и играло ключевую роль, так что с дальнейшим отказом скрипта от работы стало все понятно. Осталось лишь понять, куда исчезает это значение. Первая рабочая гипотеза - в форме появилось слишком много полей (в ней редактируются все проекты, имена и т.п., причем по мере добавления новых значений форма разрастается, а сбой случился на одной из самых больших анкет), броузер от такого количества сходит с ума, пора перепроектировать скрипт, разбивать большую форму на страницы и т.п. Правда, о таком поведении броузеров я никогда не слышал, да и порча первого параметра выглядит не слишком понятно, но это было единственное более-менее разумное предположение, которое пришло в голову. В качестве последней попытки что-то сделать со скриптом без принципиальной переделки оставалось только добавить фиктивный первый параметр. В общем, вполне логичное решение, хотя и слабо стыкующееся с гипотезой о слишком большом количестве полей - если портится первый параметр, давайте воткнем туда что-нибудь ненужное. Как ни странно, это сработало. Старый первый параметр, ставший вторым, теперь прекрасно считывался скриптом. Новый первый параметр по-прежнему терялся, но раз уж хоть какое-то рабочее решение было найдено, желание тратить время на поиск корней происходящего резко поуменьшилось. Прошло несколько дней, и неожиданно аналогичная проблема выскочила в относительно новом скрипте Информационного бума при редактировании существующего выпуска. Однако ж хотя скрипт был новым, к тому моменту он уже проработал неделю с лишним без малейшего намека на подобную ошибку. Решение с фиктивным первым параметром опять сработало, но на сей раз любопытство уже взяло верх. Новая форма была значительно меньше ФРИшной, так что гипотеза о чрезмерном количестве полей отпала сразу. И тут прозвенел звоночек - у этих форм осталась одна общая черта, отличавшая их от других форм сервера: они обе позволяли заливать на сервер файлы, а, следовательно, имели тип кодирования multipart/form-data. Данные от таких форм передаются на сервер уже не в привычном до боли виде param1=value1¶m2=value2, а с разбивкой на секции, примерно так: -----------------------------7d42329f061cContent-Disposition: form-data; name="param1"value1-----------------------------7d42329f061cContent-Disposition: form-data; name="param2"value2-----------------------------7d42329f061cПервое естественное желание - посмотреть, в каком виде данные попадают в скрипт до обработки старым добрым модулем CGI.pm. Втыкаю отладочную печать всего, что пришло на STDIN, и вместо нормального первого параметра вижу нечто подобное: param1"value1-----------------------------7d4a430f061cContent-Disposition: form-data; name="param2"... Явный прогресс - теперь становится понятно, почему CGI.pm не смог вытащить из этого обрубка первый параметр. Сохраняю страницу, начинаю последовательно удалять из нее содержимое различных полей. После очистки одного textarea ситуация нормализуется, что само по себе забавно - получается, что значение поля, введенное пользователем, влияет на то, что скрипт получает напрочь испорченный первый параметр. Начинаю играть с содержимым textarea и вскоре выясняю, что проблема начинает проявляться только если в данной поле присутствуют так называемые entities - символы, закодированные в виде ô, õ ç и т.п. (ô, õ и ç соответственно), причем относится это только к достаточно экзотическим символам, используемым, например, в финском или французском алфавитах. Что любопытно, для возникновения данной проблемы годится не любая форма - эти символы должны быть введены именно в textarea, причем после этого textarea в форме должен присутствовать checkbox - это тот минимальный набор полей, до которого мне удалось дойти. Из подобной избирательности следует, что проблема связана с броузером, а не с сервером, до которого значения из textarea добираются в такой же форме, что и значения из text или hidden. И действительно, что Opera, что Mozilla совершенно спокойно справились с этим тестом. В принципе, на этом можно заканчивать. Не исключено, что описанная здесь проблема давно известна, но лично я с ней столкнулся впервые, легкая пробежка по поисковикам ничего не дала, так что буду надеяться, что ее описание вполне может пригодиться практикующим web-программистам. Почти наверняка на поведение IE влияет и системная кодовая страница. Для проверки своего броузера вы можете воспользоваться следующей далее формой. IE6/XP SP1 при ее отправке без изменения значения текстового поля выдает приведенную выше испорченную секцию с первым параметром, при очистке и вводе "нормального" текста - нечто похожее на первый пример. Enjoy. http://bugtraq.ru/library/www/multipart.html