parser

Написать ответ на текущее сообщение

 

 
   команды управления поиском

ах, это шаманство :-(

nolar 23.10.2002 12:49

Опять taint/untaint. В применении к уришкам.
Такой вот код:

^form:fields.foreach[k;v]{"$k" = "$v"}[<br>]<hr><pre>
1. $x[$request:uri] $y[^link[;?uri=$x]] <a href='$y'>$x // $y</a>
2. $x[$request:uri] $y[^link[;?uri=^taint[uri][$x]]] <a href='$y'>$x // $y</a>
3. $x[$request:uri] $y[^link[;^taint[uri][?uri=$x]]] <a href='$y'>$x // $y</a>
4. $x[$request:uri] $y[^taint[uri][^link[;?uri=$x]]] <a href='$y'>$x // $y</a>

Такая вот строка запроса:
http://localhost/lalala/m.pml?x=5&y=6&z=7

На выводе имеем:
"x" = "5" "y" = "6" "z" = "7"
1. ?uri=/lalala/m.pml?x=5&y=6&z=7
2. ?uri=/lalala/m.pml%3Fx%3D5&y=6&z=7
3. ?uri=/lalala/m.pml%3Fx%3D5&y=6&z=7
4. %3Furi%3D/lalala/m.pml%3Fx%3D5%26y%3D6%26z%3D7

Заметка: оператор link принимает вторым параметром строку запроса. Он ее разбирает на части (параметры). Перегруппирует. И соединяет вновь (смотрите в конце сообщения).

Начинаем думать.

Пункт первый. Обработка без taint'ов. Вывел ссылку как есть. Естественно, она воспринимается не как ?uri=(/lalala/m.pml?x=5&y=6&z=7), а как ?uri=(/lalala/m.pml?x=5)&y=6&z=7. То есть до первого амперсанда. Логично. Надо амперсанды и прочую нечисть заквотить.

Пункт второй. Пытаемся заквотить само значение параметра. Несмотря на то, что в taint передается вся строка $x, то есть все три аргумента запроса, квотятся только символы опять же до амперсанда. Странно конечно. Я ожидал окрашивания ВСЕЙ строки, то есть и всех прочих символов.

Пункт третий и четвертый. Ну это, как вы поняли, уже шаманство. Не помогло, увы :-( Заметьте: четвертый отквотил что нам было надо, но вместе с самим запросом.

Мне вот интересно, как это все на самом деле в таком коде работает и как получить запрос ?uri=/lalala/m.pml%3Fx%3D5%26y%3D6%26z%3D7

Это и есть вопрос.

PS: я знаю что я тупица :-) можете об этом мне не сообщать :-) но такие выкрутасы с красками - это шедевр человеческой мысли, ей богу %-)

Приложение: оператор link.
Ничего не меняю. Тут много кода, ненужного для понимания проблемы. Но я не сумею сократить оператор, ибо я сам не помню уже что тут что делает :-)
Задача оператора - заместить параметры в uri новыми значениями из nfields (задается в форме name1=val1&name2=val2&name3=val3, то есть как строка запроса). Но я заменами в вышеприведенном коде не пользуюсь. mode - режим замены. первый символ - "r" ил "l" - куда добавлять новые (не замещенные, а новые), параметры - справа или слева. второй символ "+" или "-" - нужно (+) или не нужно (-) сохранять позиции замещенных параметров. Если не нужно - они считаются как вновб добавленные. Вот такая мудрость :-)
#########################################################################################
@link[nfields;uri;mode][temp;temppos;tempfield;tempvalue;uripath;uriargs;qfields;rfields;modealign;modekeep]
# корректируем значения входных переменных и формируем вспомогательные структуры
^if(!def $uri){$uri[$request:uri]}
^if($nfields is 'string'){
$qfields[^table::create{field value}]
$temp[^nfields.lsplit[&]] ^temp.menu{
$temppos[^temp.piece.pos[=]]
$tempfield[^if($temppos >= 0){^temp.piece.mid(0;$temppos)}{$temp.piece}]
$tempvalue[^if($temppos >= 0){^temp.piece.mid($temppos+1)}{}]
^qfields.append{$tempfield $tempvalue}
} $nfields[$qfields]
}
^if(! $nfields is 'table'){$nfields[^table::create{field value}]}
^if(! def $nfields ){$nfields[^table::create{field value}]}
$qfields[^table::create{field value}]
$rfields[^table::create{field value}]
^switch[$mode]{
^case[r-]{$modealign[r] $modekeep[0]}
^case[l-]{$modealign[l] $modekeep[0]}
^case[r+]{$modealign[r] $modekeep[1]}
^case[l+]{$modealign[l] $modekeep[1]}
^case[DEFAULT]{$modealign[r] $modekeep[0]}}
# анализируем адрес, извлекая из него путь к файлу и строку аргументов
$temppos[^uri.pos[?]]
$uripath[^if($temppos >= 0){^uri.mid(0;$temppos)}{$uri}]
$uriargs[^if($temppos >= 0){^uri.mid($temppos+1)}{}]
# анализируем строку аргументов и преобразуем в таблицу
$temp[^uriargs.lsplit[&]] ^temp.menu{
$temppos[^temp.piece.pos[=]]
$tempfield[^if($temppos >= 0){^temp.piece.mid(0;$temppos)}{$temp.piece}]
$tempvalue[^if($temppos >= 0){^temp.piece.mid($temppos+1)}{}]
^qfields.append{$tempfield $tempvalue}
}
# переносим существующие аргументы, замещая старые значения новыми или сохраняя их
^if($modealign eq l){^rfields.join[^nfields.select((!^qfields.locate[field;$nfields.field] || !$modekeep) && def $nfields.value)]}
^qfields.menu{
^if(^nfields.locate[field;$qfields.field]){
^if(!$modekeep){$tempvalue[]}{
$tempvalue[$nfields.value]}
}{ $tempvalue[$qfields.value]
} $tempfield[$qfields.field]
^if(def $tempvalue){^rfields.append{$tempfield $tempvalue}}
}}
^if($modealign eq r){^rfields.join[^nfields.select((!^qfields.locate[field;$nfields.field] || !$modekeep) && def $nfields.value)]}
# формируем новый адрес и возвращаем его
#!!! $uriargs[^rfields.menu{^taint[uri][$rfields.field]=^taint[uri][$rfields.value]}[&]]
$uriargs[^rfields.menu{$rfields.field=$rfields.value}[&]]
$result[$uripath^if(def $uriargs){?}$uriargs]
#########################################################################################

ВСЕ.