Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Нужен совет по написанию функции на pl/perl
|
|||
|---|---|---|---|
|
#18+
Задался целью проверять данные, вводимые в базу через веб-форму на предмет отсутствия в полях данных недопустимых символов. Например, есть поля для хранения имени и фамилии, в них, соответственно, не должно быть ничего, кроме русских букв, пробелов и дефиса. Для этого написал такую вот монстроподобную функцию на pl/perl и триггер к ней: create function check_users() returns trigger as $$ my $errstr = ""; if ( !($_TD->{new}{lastname} =~ /^[^A-Za-z0-9\!\@\#\$\%\^\&\*\(\)\_\+\=\\\/\?\,\.\<\>\~\`\"\'\;\:\{\}\[\]]+$/) ) { $errstr.= "<br>\nCHECK_USERS: Недопустимый символ в поле ФАМИЛИЯ"; } if ( !($_TD->{new}{firstname} =~ /^[^A-Za-z0-9\!\@\#\$\%\^\&\*\(\)\_\+\=\\\/\?\,\.\<\>\~\`\"\'\;\:\{\}\[\]]+$/) ) { $errstr.= "<br>\nCHECK_USERS: Недопустимый символ в поле ИМЯ"; } if ( $errstr ne '' ) { elog(ERROR, $errstr); return "SKIP"; } else { return; } $$ language 'plperl'; create trigger tg_check_users before insert or update on users for each row execute procedure check_users(); Проблема в том, что используемые регэкспы не желают отлавливать одинарные кавычки, слеши и некоторые другие спецсимволы при выполнении этой функции - хотя будучи использованы в приложении на perl, эти регэкспы отрабатывают как надо и не пропускают ничего, кроме руских буковок. Вот собственно и вопрос - что предпринять для того, чтобы данная функция заработала как надо, или каким еще способом можно осуществлять такого рода проверки? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.10.2006, 07:43 |
|
||
|
Нужен совет по написанию функции на pl/perl
|
|||
|---|---|---|---|
|
#18+
Ответа на поставленный вопрос я не знаю, но происходит изобретение велосипеда. CHECK constraint http://www.postgresql.org/files/documentation/books/aw_pgsql/node132.html в сочетании с SIMILAR TO легко решит поставленную задачу безо всяких перлов и триггеров. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.10.2006, 10:50 |
|
||
|
Нужен совет по написанию функции на pl/perl
|
|||
|---|---|---|---|
|
#18+
ilejnОтвета на поставленный вопрос я не знаю, но происходит изобретение велосипеда. Мда, действительно. Спасибо за наводку. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.10.2006, 11:13 |
|
||
|
Нужен совет по написанию функции на pl/perl
|
|||
|---|---|---|---|
|
#18+
ilejnв сочетании с SIMILAR TO легко решит поставленную задачу безо всяких перлов и триггеров. Оно конечно проще, но своей цели я не добился - спецсимволы по-прежнему просачиваются: Создал тестовую табличку createtestbase.sql: create table test ( uid serial8 primary key, lastname varchar(64) not null, firstname varchar(64) not null, constraint empty_field check ( lastname <> '' and firstname <> ''), constraint valid_chars check ( lastname not similar to '^[A-Za-z0-9\\\']+$') ); insert into test (lastname, firstname) values ('Smith', 'Jonh'); insert into test (lastname, firstname) values ('Петров', 'Иван'); insert into test (lastname, firstname) values ('Пе\тров', 'Ив\'ан'); Проверяем: # su -l pgsql -c "exec /usr/local/bin/psql testbase < createtestbase.sql" CREATE DATABASE NOTICE: CREATE TABLE will create implicit sequence "test_uid_seq" for serial column "test.uid" NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "test_pkey" for table "test" CREATE TABLE ERROR: new row for relation "test" violates check constraint "valid_chars" INSERT 0 1 INSERT 0 1 Вставились две записи вместо одной :( # su -l pgsql -c "exec /usr/local/bin/psql testbase" Welcome to psql 8.1.4, the PostgreSQL interactive terminal. Type: \copyright for distribution terms \h for help with SQL commands \? for help with psql commands \g or terminate with semicolon to execute query \q to quit testbase=# select * from test; uid | lastname | firstname -----+----------+----------- 2 | Петров | Иван 3 | Петров | Ив'ан (записей: 2) testbase=# \q Вопрос по-прежнему открыт - можно ли заблокировать ввод пользователем слешей, кавычек и прочих служебных символов и каким образом это делать, кроме как в самом приложении-клиенте? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.10.2006, 12:09 |
|
||
|
Нужен совет по написанию функции на pl/perl
|
|||
|---|---|---|---|
|
#18+
Такой вариант create table const_check ( f text check (f similar to '[А-Яа-я -]+') ) не рассматривался? Если используется UNICODE, все будет работать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.10.2006, 13:00 |
|
||
|
Нужен совет по написанию функции на pl/perl
|
|||
|---|---|---|---|
|
#18+
ilejnТакой вариант create table const_check ( f text check (f similar to '[А-Яа-я -]+') ) не рассматривался? Если используется UNICODE, все будет работать. Рассматривался, но используется KOI8-R, и в ближайшее воемя перейти на юникод не получится ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.10.2006, 13:13 |
|
||
|
Нужен совет по написанию функции на pl/perl
|
|||
|---|---|---|---|
|
#18+
shrdlu ilejnТакой вариант create table const_check ( f text check (f similar to '[А-Яа-я -]+') ) не рассматривался? Если используется UNICODE, все будет работать. Рассматривался, но используется KOI8-R, и в ближайшее воемя перейти на юникод не получится А может тогда попробовать вначале приводить к UTF8, специально для проверки. Примерно так create table const_check ( f text check (convert(f , 'koi8', 'utf8') similar to '[А-Яа-я -]+') ) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.10.2006, 15:17 |
|
||
|
Нужен совет по написанию функции на pl/perl
|
|||
|---|---|---|---|
|
#18+
Да и почему на уникод не получиться перейти? Клиета то можно оставить как и было, в КОИ8, а базу переделать под уникод. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.10.2006, 15:19 |
|
||
|
Нужен совет по написанию функции на pl/perl
|
|||
|---|---|---|---|
|
#18+
JelisДа и почему на уникод не получиться перейти? Клиета то можно оставить как и было, в КОИ8, а базу переделать под уникод. Конвертацию в проверке я обязательно попробую, а перейти не получится по причине моих ограниченных знаний и прав для работы с БД. Да и если бы были права, не хотелось бы невзначай убить неосторожным движением рабочие базы, я с Postgresql очень недавно дело имею. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.10.2006, 15:27 |
|
||
|
Нужен совет по написанию функции на pl/perl
|
|||
|---|---|---|---|
|
#18+
Jelis А может тогда попробовать вначале приводить к UTF8, специально для проверки. Примерно так Сделал по твоему совету: create table test ( uid serial8 primary key, lastname varchar(64) not null, firstname varchar(64) not null, constraint empty_field check ( lastname <> '' and firstname <> ''), constraint valid_chars check (convert(lastname , 'koi8', 'utf8') similar to '[А-Яа-я -]+') ); insert into test (lastname, firstname) values ('Smith', 'Jonh'); insert into test (lastname, firstname) values ('Петров', 'Иван'); insert into test (lastname, firstname) values ('Пе\тров', 'Ив\'ан'); увы, не работает CREATE DATABASE NOTICE: CREATE TABLE will create implicit sequence "test_uid_seq" for serial column "test.uid" NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "test_pkey" for table "test" CREATE TABLE ERROR: new row for relation "test" violates check constraint "valid_chars" ERROR: new row for relation "test" violates check constraint "valid_chars" ERROR: new row for relation "test" violates check constraint "valid_chars" ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.10.2006, 15:43 |
|
||
|
Нужен совет по написанию функции на pl/perl
|
|||
|---|---|---|---|
|
#18+
shrdlu увы, не работает Нет ничего удивительного: cтрока в UTF, а паттерн в KOI-8. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.10.2006, 20:28 |
|
||
|
Нужен совет по написанию функции на pl/perl
|
|||
|---|---|---|---|
|
#18+
Что-то вас не в ту степь понесло. При чём тут юникод? \w должен давать совпадение с буквами в любой однобайтной кодировке (а вот в юникоде - наоборот не работает). Код: plaintext 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.10.2006, 03:39 |
|
||
|
Нужен совет по написанию функции на pl/perl
|
|||
|---|---|---|---|
|
#18+
ilejnНет ничего удивительного: cтрока в UTF, а паттерн в KOI-8. Блин. В общем, как я понял, пока база в кодировке KOI, решения не существует? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.10.2006, 07:09 |
|
||
|
Нужен совет по написанию функции на pl/perl
|
|||
|---|---|---|---|
|
#18+
ффффЧто-то вас не в ту степь понесло. При чём тут юникод? \w должен давать совпадение с буквами в любой однобайтной кодировке (а вот в юникоде - наоборот не работает). Код: plaintext 1. в поле lastname по моему замыслу допустимы только РУССКИЕ буквы, пробел и дефис, так что \w никак не поможет ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.10.2006, 09:05 |
|
||
|
Нужен совет по написанию функции на pl/perl
|
|||
|---|---|---|---|
|
#18+
shrdlu В общем, как я понял, пока база в кодировке KOI, решения не существует? Что мешает сконвертировать в UTF и pattern тоже? Вообще-то, мне непонятно, почему это не работает в KOI-8 само по себе. Казалось бы, кодировка официально поддерживается, сортировка по ней есть, а вот сделать regexp поленились, получается? Странно это. Что возвращает show lc_collate на Вашей базе? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.10.2006, 09:14 |
|
||
|
Нужен совет по написанию функции на pl/perl
|
|||
|---|---|---|---|
|
#18+
ilejnЧто мешает сконвертировать в UTF и pattern тоже? Либо мои кривые руки, либо BSD не дружит с юникодом. На FreeBSD 6.1 пробую так: # iconv -f koi8-r -t utf8 1.txt iconv: conversion to utf8 unsupported ilejnВообще-то, мне непонятно, почему это не работает в KOI-8 само по себе. Казалось бы, кодировка официально поддерживается, сортировка по ней есть, а вот сделать regexp поленились, получается? Странно это. Очень странно, действительно ilejnЧто возвращает show lc_collate на Вашей базе? testbase=# show lc_collate; lc_collate -------------- ru_RU.KOI8-R (1 запись) testbase=# ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.10.2006, 09:35 |
|
||
|
Нужен совет по написанию функции на pl/perl
|
|||
|---|---|---|---|
|
#18+
shrdlu фффф в поле lastname по моему замыслу допустимы только РУССКИЕ буквы, пробел и дефис, так что \w никак не поможет Условия на проверку одним регэкспом тоже нет Код: plaintext 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.10.2006, 09:59 |
|
||
|
Нужен совет по написанию функции на pl/perl
|
|||
|---|---|---|---|
|
#18+
ффффУсловия на проверку одним регэкспом тоже нет Код: plaintext 1. Кавычки и слеши по-прежнему проскакивают сквозь этот регэксп. Начинаю подозревать, что запретить их на уровне сервера БД вообще невозможно ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.10.2006, 10:09 |
|
||
|
Нужен совет по написанию функции на pl/perl
|
|||
|---|---|---|---|
|
#18+
shrdlu На FreeBSD 6.1 пробую так: # iconv -f koi8-r -t utf8 1.txt iconv: conversion to utf8 unsupported Вы же используете PostgreSQL'ный convert для строки. Используйте его же для образца. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.10.2006, 11:01 |
|
||
|
Нужен совет по написанию функции на pl/perl
|
|||
|---|---|---|---|
|
#18+
ilejnВы же используете PostgreSQL'ный convert для строки. Используйте его же для образца. Это я уже пробовал, резуультат тот же. Пишу check (convert(lastname , 'koi8', 'utf8') similar to convert('[А-Яа-я -]+', 'koi8', 'utf8')) в ответ на insert into test (lastname, firstname) values ('Smith', 'Jonh'); insert into test (lastname, firstname) values ('Петров', 'Иван'); insert into test (lastname, firstname) values ('Пе\тров', 'Ив\'ан'); получал ERROR: new row for relation "test" violates check constraint "valid_chars" ERROR: new row for relation "test" violates check constraint "valid_chars" ERROR: new row for relation "test" violates check constraint "valid_chars" ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.10.2006, 11:15 |
|
||
|
Нужен совет по написанию функции на pl/perl
|
|||
|---|---|---|---|
|
#18+
Не нужно никуда ничего конвертировать. Всё в KOI8-R работает (FreeBSD 6.0, 6.1, Postgresql 8.1.4). Могу предположить, что: 1. наверняка проблемы с кодировкой у клиента 2. несмотря на то, что кодировка БД koi8-r, сами данные там хранятся в другой кодировке (что возможно по причине п. 1, сам с таким сталкивался) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.10.2006, 12:47 |
|
||
|
Нужен совет по написанию функции на pl/perl
|
|||
|---|---|---|---|
|
#18+
Согласен с glebofff. С кодировками полная беда. Кроме культурного решения - разобраться с кодировками, существует еще очевидное и некультурное - отказаться от диапазонов и перечислить все русские буковки one by one в квадратных скобках. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.10.2006, 12:57 |
|
||
|
Нужен совет по написанию функции на pl/perl
|
|||
|---|---|---|---|
|
#18+
glebofff1. наверняка проблемы с кодировкой у клиента А если клиент - штатный psql? С утра на виртуалке поднял PostgreSQL и в нем ковыряюсь. Сортировки/поиск/upper/lower работают. Работают, в общем-то и рэгэкспы, одно НО - они пропускают символы "\" и "'" (обратный слэш и одинарная кавычка) Слушайте, может, я зря вообще парюсь? Может не так уж и опасно допускать ввод этих символов? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.10.2006, 13:02 |
|
||
|
Нужен совет по написанию функции на pl/perl
|
|||
|---|---|---|---|
|
#18+
ilejnнекультурное - отказаться от диапазонов и перечислить все русские буковки one by one в квадратных скобках. Есть и третье решение - делать эти проверки в клиенте, благо в перловой CGIшке все это работает на ура. Но вот в целях повышения самообразованности задался целью все проверки/правила организовать именно на сервере... хотя может и зря :-\ ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.10.2006, 13:05 |
|
||
|
Нужен совет по написанию функции на pl/perl
|
|||
|---|---|---|---|
|
#18+
shrdlu glebofff1. наверняка проблемы с кодировкой у клиента А если клиент - штатный psql? С утра на виртуалке поднял PostgreSQL и в нем ковыряюсь. Сортировки/поиск/upper/lower работают. Работают, в общем-то и рэгэкспы, одно НО - они пропускают символы "\" и "'" (обратный слэш и одинарная кавычка) Слушайте, может, я зря вообще парюсь? Может не так уж и опасно допускать ввод этих символов? PostgreSQL: Documentation: Manuals: PostgreSQL 8.1: Pattern Matching Читаем там: Note : Remember that the backslash (\) already has a special meaning in PostgreSQL string literals. To write a pattern constant that contains a backslash, you must write two backslashes in the statement. Там же можно найти про \B - альяс для \. Код: plaintext Код: plaintext (и пусть вся подсветка сойдёт с ума! ) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.10.2006, 15:02 |
|
||
|
|

start [/forum/topic.php?fid=53&msg=34085921&tid=2006004]: |
0ms |
get settings: |
5ms |
get forum list: |
8ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
49ms |
get topic data: |
5ms |
get forum data: |
1ms |
get page messages: |
33ms |
get tp. blocked users: |
1ms |
| others: | 221ms |
| total: | 327ms |

| 0 / 0 |
