Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

10 359 Posts in 5 734 Topics- by 1 216 Members - Latest Member: santini862

20 September 2019, 18:33
Select Language English | Russian ru | German
Main PageIRC Client KVIrc forumRussian talksСкриптингВопросы по работе отдельных функций и командBinding operator
Pages: [1]
Print
Author Topic: Binding operator  (Read 13600 times)
0 Members and 1 Guest are viewing this topic.
Skull
Новичок
*

Репутация: 8
Posts: 42


View Profile
« on: 31 August 2008, 15:15 »

Строю подобие urldecode, решил воспользоваться оператором =~ :
Code:
%c = "<\%66\%31>"
%c =~ s/\%([a-f0-9]{2}|[a-f0-9]{4})/$hexToAscii(\\1)/gi
echo %c
Но в таком случае в функцию $hexToAscii посылается строка "\1", а не найденное число.
Возможно ли это как то обойти?
+
Экранирование символов:
Code:
%c = "!@#abc\$%^"
%c =~ s/([^\\d\\s\\w])/\\\\1/g
echo %c
По идее должно работать, но не работает. Символы, вместо того чтобы перед ними ставился обратный слеш, заменяются на "\\1"
При этом
Code:
%c =~ s/([^\\d\\s\\w])/\\\\\\1/g
работает, но ставится два обратных слеша (как и ожидалось)
$str.replace(%c,\\,\\\\) - плохой вариант.
Logged
Maximusya
Глобальный модератор
*****

Репутация: 49
Gender: Male
Posts: 343



View Profile
« Reply #1 on: 31 August 2008, 21:01 »

Однотипную операцию над перечисляемым множеством символов я делал вот так:
1. создавал массив искомых символов (в твоем случае - это экранируемые символы)
2. в цикле foreach по этому массиву делал $str.replace(%текст, $операция(%символ), %символ)
Конечно, нужно учитывать, что возможно наложение символов уже преобразованной строки на экранируемые символы. Ну и тп побочные эффекты.
А проделать это (как и вызов функции) с помощью =~ у меня так и не получилось.
« Last Edit: 31 August 2008, 21:03 by Maximusya » Logged
kns
Постоялец
***

Репутация: 38
Gender: Male
Posts: 232


View Profile WWW
« Reply #2 on: 31 August 2008, 21:05 »

Или, например, пробираясь по каждой букве смотреть $ascii() и заменять символы с кодом больше 127. %)
Logged
Skull
Новичок
*

Репутация: 8
Posts: 42


View Profile
« Reply #3 on: 31 August 2008, 22:24 »

Однотипную операцию над перечисляемым множеством символов я делал вот так:
1. создавал массив искомых символов (в твоем случае - это экранируемые символы)
2. в цикле foreach по этому массиву делал $str.replace(%текст, $операция(%символ), %символ)
Конечно, нужно учитывать, что возможно наложение символов уже преобразованной строки на экранируемые символы. Ну и тп побочные эффекты.
А проделать это (как и вызов функции) с помощью =~ у меня так и не получилось.
Да, был такой вариант, но: массив => лишняя память, foreach => многократный вызов функции. Вобщем, думаю не стоит оно того Smiley (легче в конце приписать $str.replace + меньше проблем с наложением)
Или, например, пробираясь по каждой букве смотреть $ascii() и заменять символы с кодом больше 127. %)
Об этом тоже думал - экранировать все что не в 48-57 65-90 97-22. но тоже накладно, хотелось в одну строчку Smiley

Ну ладно, всем спасибо Wink
Logged
Skull
Новичок
*

Репутация: 8
Posts: 42


View Profile
« Reply #4 on: 5 September 2008, 14:17 »

Сделал я все-таки urldecode, правда немного криво... не хотелось мне циклов Smiley
Code:
%var=~s/([^\\d\\s\\w])/\\\\\\1/g
%var=$str.replace(%var,\\,\\\\)
%var=~s/\\\\\%([a-f0-9]{2}|[a-f0-9]{4}|[a-f0-9]{6})/\$hexToAscii(\\1)/gi
eval\%var=%var
Интересно выслушать ваше мнение Smiley
Logged
Maximusya
Глобальный модератор
*****

Репутация: 49
Gender: Male
Posts: 343



View Profile
« Reply #5 on: 6 September 2008, 01:12 »

eval я хотел предложить сразу) для использования вызова функции в теле =~, но помня о своих экспериментах с eval, решил его не предлагать)
Тестируем приведенный код на строке "<\%66\%31>\nrun calc":
Code:
%var = "<\%66\%31>\nrun calc"
%var=~s/([^\\d\\s\\w])/\\\\\\1/g
%var=$str.replace(%var,\\,\\\\)
%var=~s/\\\\\%([a-f0-9]{2}|[a-f0-9]{4}|[a-f0-9]{6})/\$hexToAscii(\\1)/gi
eval\%var=%var
echo %var
И если у вас Windows, то получаем то, что задумывалось таким хаком)
Да, таким образом можно сделать инъекцию простейшего kvs-кода, не содержащего [^\\d\\s\\w], но тот же run... или даже вызов какого-нибудь алиаса... могут преподнести сюрприз)
А все потому, что
Quote
A script contains a list of instructions separated by newlines or ';' characters.
Кстати, можно было написать и так:
%var = "<\%66\%31>\\\\;run calc"


P.S. : ХАХАХАХА  Cheesy вот гораздо более интересный пример:
%var = "<\%66\%31>\nexit"
(asis, no warranty и все такое)
« Last Edit: 6 September 2008, 01:30 by Maximusya » Logged
Skull
Новичок
*

Репутация: 8
Posts: 42


View Profile
« Reply #6 on: 6 September 2008, 19:13 »

Тебе самому то это глупостью не кажется?)
Весь смысл в том что \n это Line feed, т.е. да, код исполняется, но только потому что, ты сам не ескейпнул lf.
Если кто не понял, то весь смысл в том, что переменную присваивают на месте (это было для тестов). При этом присваивают изначально две строки.
Попробуй сделай тоже самое, только например читая из конфига или Поле_ввода+кнопка
Низачот Smiley
Logged
Maximusya
Глобальный модератор
*****

Репутация: 49
Gender: Male
Posts: 343



View Profile
« Reply #7 on: 6 September 2008, 20:38 »

А что мешает ввести в строку ввода многострочное сообщение?

И вообще, если ты контролируешь содержимое обрабатываемых строк, то можно не бояться побочных эффектов. Если же ты обрабатываешь чей-то ввод, то искренне надеюсь, что тот человек будет твоим другом и не будет приколистом)
Logged
Skull
Новичок
*

Репутация: 8
Posts: 42


View Profile
« Reply #8 on: 6 September 2008, 21:19 »

Вообще не понял при чем тут сообщения, друзья и пр. Wink
Ибо это тулза для юзера, которая будет в его квирке.
Но понял в чем ошибся и не заметил этого: регулярка долна быть
Code:
%var=~s/([^\\d\\w])/\\\\\\1/g
Ескейпить пробельные символы полезно.
Logged
mechmind
Пользователь
**

Репутация: 8
Posts: 60


View Profile
« Reply #9 on: 7 October 2008, 01:18 »

Ещё вариант )
Code:
alias(urlencode){
%data=$0;
perl.begin;
   $str=KVIrc::getLocal("data");
   $str=~s/([^A-Za-z0-9])/sprintf("%%%02X", ord($1))/seg;
   KVIrc::setLocal("data", $str);
perl.end;
return %data;
}

alias(urldecode){
%data=$0;
perl.begin;
   $str=KVIrc::getLocal("data");
   $str=~s/\%([A-Fa-f0-9]{2})/pack('C', hex($1))/seg;
   KVIrc::setLocal("data", $str);
perl.end;
return %data;
}

Малость извращенно, но если эскейпить большоие строки, возможно даст прирост производительности - перл как никак заточен под такие операции.
« Last Edit: 7 October 2008, 10:56 by Maximusya » Logged

Тысячи лет поиска и все впустую, 001010011101011...
Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic