Ru-Board.club
← Вернуться в раздел «Web-программирование»

» [perl] int DBI /^\d+$/

Автор: rtyug
Дата сообщения: 31.07.2009 12:13
хотел спросить на всякий случай:


Код:
my ( $self, $c, @args) = @_;

if ( !$args[0] || $args[0] !~ /^\d+$/ ) {
$c->response->redirect($c->uri_for('/'));
$c->detach();
}

my $sql_max = 'SELECT MAX(t1.id_co) AS prev
FROM content AS t1
WHERE t1.id_co > '.$args[0].'
LIMIT 1';

my $sth = $dbh->prepare($sql_max);
$sth->execute();
my $loop_data3 = $sth->fetchrow_hashref();
$sth->finish();
Автор: Oleg Tarusov
Дата сообщения: 31.07.2009 12:46
Защитит

Если у тебя оракл, делай так (хотя может и на других базах сработает):

Код:
my $sql_max = 'SELECT MAX(t1.id_co) AS prev
FROM content AS t1
WHERE t1.id_co > :arg_0
LIMIT 1';

my $sth = $dbh->prepare($sql_max);
$sth->bind_param(':arg_0', $arg[0]);
$sth->execute();
Автор: rtyug
Дата сообщения: 31.07.2009 15:03
а смысл ставить в bind_param?

если сюда поставить $sth->execute(); то заэкранирует
Автор: CheRt
Дата сообщения: 31.07.2009 17:36
А не проще?

Код:
my $sql_max = ($dbh->selectrow_array('SELECT MAX(t1.id_co) AS prev
FROM content AS t1
WHERE t1.id_co > ?
LIMIT 1', {}, $arg[0])[0];
Автор: rtyug
Дата сообщения: 31.07.2009 17:53
а в чем разница? тут одно значение вынимается... LIMIT 1

если много вынимается, то тогда можно selectrow или selectall или нет?

в данном случае $arg[0] не экранируется?

============

CheRt

если делать selectrow, т окак сделать массив хэшей?
Автор: CheRt
Дата сообщения: 31.07.2009 20:17
rtyug,

Цитата:
а в чем разница? тут одно значение вынимается... LIMIT 1

Чистка регуляркой в данном случае - танцы с бубном. Хотя можно использовать для сообщения об ошибке, не делая запрос.
Да и однострочка вместо нескольких.


Цитата:
если много вынимается, то тогда можно selectrow или selectall или нет?

В случае очень большого участка данных лучше пользоваться fetch-методами. Но параметрические запросы никто не отменял


Цитата:
в данном случае $arg[0] не экранируется?

А зачем, SQL-инъекция таким образом не получится.


Цитата:
если делать selectrow, то как сделать массив хэшей?

если я правильно понял ваш запрос, то выбирается только 1 значение, зачем массив хэшей?

А так - методов много и selectall_arrayref, и selectrow_hashref, и selectall_hashref - выбира
йте под задачу и используйте.
perldoc DBI в помощь
Автор: rtyug
Дата сообщения: 01.08.2009 20:18
1) где написано что при параметрических (selectrow) нужно маленькие вынимать? и почему fetch большие?
там написнао что selectrow (и аналогичные) самые быстрые потому что отсутствует защита от инъекий

2) а как опнять где SQL-инъекция будет? ну я вообще-то просто привел пример кода....

3) чтобы массих хэши сделать, я вот нашле Slice => {}


Код:
...
my $loop_data = $dbh->selectall_arrayref(
" SELECT id_se, name_se
FROM section",
{ Slice => {} }
);
$c->stash->{messages} = $loop_data;
...
}
Автор: CheRt
Дата сообщения: 02.08.2009 00:49

Цитата:
1) где написано что при параметрических (selectrow) нужно маленькие вынимать? и почему fetch большие?
там написнао что selectrow (и аналогичные) самые быстрые потому что отсутствует защита от инъекий

Параметрические не быстрее, наоборот, но не намного. Просто они удобнее и безопаснее, позволяют лишний раз не перестраховываться.

Параметрические/параметризованные - это не select*, а ? (или *) в запросе + бинд параметра. Т.е. когда динамические данные запроса (параметры) передаются не в самом SQL-запросе.

А вот select* может оказаться медленнее prepare/execute/fetch* и терять лишнюю память. Методы select*, по сути, и есть prepare/execute/fetch* (лучше посмотрите своими глазами либу DBI - понятнее будет), но заранее оформленные, потому проще запустить дублирование участка памяти или подобную утечку.


Цитата:
2) а как опнять где SQL-инъекция будет? ну я вообще-то просто привел пример кода....

Почитайте про SQL-инъекции, уязвимость очень простая.

А я пример приведу - есть у вас в форме textarea, содержимое которой надо as is записать в базу (без убивания кавычек и т.д.). Попробуйте организовать грамотную экранизацию, дабы не нарушить запрос (а там где он случайно нарушается, можно сделать и специально).


Цитата:
3) чтобы массих хэши сделать, я вот нашле Slice => {}

Можно предложенным вами методом, можно сделать выбор selectall_hashref, можно сделать преобразование "на лету" (лучше не делать при больших объемах данных).


Код:
my $arrayOfHashes = [
map {
bla => $_->[0],
...
} @{ $dbh->selectall_arrayref('bla-bla') || [[]] }
];
Автор: rtyug
Дата сообщения: 02.08.2009 09:06

Цитата:
А вот select* может оказаться медленнее prepare/execute/fetch* и терять лишнюю память. Методы select*, по сути, и есть prepare/execute/fetch* (лучше посмотрите своими глазами либу DBI - понятнее будет), но заранее оформленные, потому проще запустить дублирование участка памяти или подобную
утечку.



Код:
sub selectall_arrayref {
    my ($dbh, $stmt, $attr, @bind) = @_;
    my $sth = (ref $stmt) ? $stmt : $dbh->prepare($stmt, $attr)
     or return;
    $sth->execute(@bind) || return;
    my $slice = $attr->{Slice}; # typically undef, else hash or array ref
    if (!$slice and $slice=$attr->{Columns}) {
     if (ref $slice eq 'ARRAY') { # map col idx to perl array idx
        $slice = [ @{$attr->{Columns}} ];    # take a copy
        for (@$slice) { $_-- }
     }
    }
    my $rows = $sth->fetchall_arrayref($slice, my $MaxRows = $attr->{MaxRows});
    $sth->finish if defined $MaxRows;
    return $rows;
}

Автор: CheRt
Дата сообщения: 02.08.2009 11:53

Цитата:
почему? в чем разница?

#Знакомы с понятием "черный ящик"?
что такое, скажем, selectall_arrayref:
prepare
execute(@params)
Slice ? Slice : []
MaxRows ? { fetchall_arrayref; finish} : fetchall_arrayref

Теперь далее, знаем, что СуБД крупные ответы выдает не сразу, кусками в течении некоторого времени.

В случае с prepare/execute/while(bla=fetchrow_arrayref) мы разбираем также постепенно данный ответ, дополняя сразу необходимую структуру. Все конкатерации, все обработки в своих ф-циях и т.д. (т.е. операции, которые приводят к дублированию памяти, почитайте, про утечки в перле есть статьи даже на русском) дадут дублирование только для маленьких порций данных.
В случае с selectall_arryref, для обработки придет уже ссылка на весь блок данных, который уже и предстоит дозатачивать.


Цитата:
DBIx::Class Firebird не поддердживает, хотел на ней писать

дело в том что в моей программе есть много запросов которые там не сделать, это массивы SQL и т.д.

Хмм, однако, не знал про Файрбёрд, хотя все равно пользую только Оракл и Постгрес сейчас.

Динамическая генерация запроса + все та же параметризация (только динамическая же подготовка параметров). Я подобные вещи делал, в принципе, хоть и немного в другой ипостаси.
В любом случае, решать вам


Цитата:
я предпочитаю SQL::Abstract!
вот посмотрие как я написал класс CRUD для SQL::Abstract: http://www.lissyara.su/?id=1962 зеркало http://unixforum.org.ua/index.php?topic=26299

Не совсем то, что хотел увидеть, но авось интересные идеи и найду.

ЗЫ: судя по стилю сообщений и crud/catalyst могу предположить, что вы gcc/винград?
Автор: rtyug
Дата сообщения: 02.08.2009 18:50
да, я вас тоже нашел в гугле
Автор: Oleg Tarusov
Дата сообщения: 03.08.2009 18:20

Цитата:
если сюда поставить $sth->execute(); то заэкранирует


Э-э-э, не понял
Автор: rtyug
Дата сообщения: 04.08.2009 17:46
$sth->execute($df);

если вы поставите вот так, то оно заэкранирует...

=====
$sth->bind_param(':arg_0', $arg[0]);

в оркл можно написать какой стобец именно экранирует... если нужно несколько запросов сразу
Автор: CheRt
Дата сообщения: 04.08.2009 18:05
rtyug,

Цитата:
$sth->execute($df);

пример параметризации запроса. Не экранируется, идет отдельно от запроса, потому на кавычки вообще можно забить


Цитата:
да, я вас тоже нашел в гугле

Не в гугле, читаю/пишу на винграде изредка.


Цитата:
$sth->bind_param(':arg_0', $arg[0]);

в оркл можно написать какой стобец именно экранирует... если нужно несколько запросов сразу

Смена позиции аргумента, имхо, не такая уж и важная фича. Проще в перле правильно подготовить данные.

Автор: rtyug
Дата сообщения: 04.08.2009 20:14

Цитата:
пример параметризации запроса. Не экранируется, идет отдельно от запроса, потому на кавычки вообще можно забить


не понял, а кто его экранирует? инъекция будет? и что значит отдельно?





Автор: CheRt
Дата сообщения: 04.08.2009 21:04
rtyug,

Цитата:
не понял, а кто его экранирует? инъекция будет? и что значит отдельно?

Не переживайте, не будет.

Вот пример экранизации параметра в не параметризованном запросе

Код:
my $sth = $dbh->prepare(
sprintf("SELECT value FROM table WHERE value LIKE %s", $dbh->quote($value)) );
$sth->execute();
Автор: rtyug
Дата сообщения: 04.08.2009 21:23
говорили что в $sth->execute($value); и в do() в любом случае экранируется

короче вы имеете ввиду что инъекции не будет в любом случае $sth->execute($value);

Автор: CheRt
Дата сообщения: 04.08.2009 21:26
rtyug,

Цитата:
говорили что в $sth->execute($value); и в do() в любом случае экранируется

короче вы имеете ввиду что инъекции не будет в любом случае $sth->execute($value);

Угу, не будет.
Просто это называется параметрическим запросом, а не экранизацией (эскейпом) - вот и все

Не забивайте голову, понимание теории само придет со временем
Автор: rtyug
Дата сообщения: 04.08.2009 21:34
вот я написал несколько модулей из программы http://kiev.pm.org/node/354
требуется критика, кто хочет может посмотреть и найти ошибки в коде
Автор: Oleg Tarusov
Дата сообщения: 05.08.2009 11:37

Цитата:
Смена позиции аргумента, имхо, не такая уж и важная фича

Когда параметров много, так не кажется, по крайней мере, мне.

Страницы: 1

Предыдущая тема: Конвертация кодировки базы из cp1252 в cp1251


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.