From: Peter Rabbitson Date: Tue, 3 Mar 2009 21:43:48 +0000 (+0000) Subject: Clarify sybase/nobindvars problem (should have never merged in the 1st place) X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=5432c6ae1a31569775574edd42cb3e3f6f79cfff;p=dbsrgits%2FDBIx-Class-Historic.git Clarify sybase/nobindvars problem (should have never merged in the 1st place) --- diff --git a/lib/DBIx/Class/Storage/DBI/NoBindVars.pm b/lib/DBIx/Class/Storage/DBI/NoBindVars.pm index 9f81caf..c74b9c0 100644 --- a/lib/DBIx/Class/Storage/DBI/NoBindVars.pm +++ b/lib/DBIx/Class/Storage/DBI/NoBindVars.pm @@ -50,12 +50,12 @@ sub _prep_for_execute { foreach my $bound (@$bind) { my $col = shift @$bound; - my $do_quote = $self->should_quote_data_type($col); + my $datatype = 'FIXME!!!'; foreach my $data (@$bound) { if(ref $data) { $data = ''.$data; } - $data = $self->_dbh->quote($data) if $do_quote; + $data = $self->_dbh->quote($data) if $self->should_quote_data_type($datatype, $data); $new_sql .= shift(@sql_part) . $data; } } @@ -67,13 +67,17 @@ sub _prep_for_execute { =head2 should_quote_data_type This method is called by L for every column in -order to determine if its value should be quoted or not. The sole -argument is the current column data type, and the return value is -interpreted as: true - do quote, false - do not quote. You should -override this in you Storage::DBI:: subclass, if your -RDBMS does not like quotes around certain datatypes (e.g. Sybase -and integer columns). The default method always returns true (do -quote). +order to determine if its value should be quoted or not. The arguments +are the current column data type and the actual bind value. The return +value is interpreted as: true - do quote, false - do not quote. You should +override this in you Storage::DBI:: subclass, if your RDBMS +does not like quotes around certain datatypes (e.g. Sybase and integer +columns). The default method always returns true (do quote). + + WARNING!!! + + Always validate that the bind-value is valid for the current datatype. + Otherwise you may very well open the door to SQL injection attacks. =cut diff --git a/lib/DBIx/Class/Storage/DBI/Sybase.pm b/lib/DBIx/Class/Storage/DBI/Sybase.pm index cb7408b..0a26173 100644 --- a/lib/DBIx/Class/Storage/DBI/Sybase.pm +++ b/lib/DBIx/Class/Storage/DBI/Sybase.pm @@ -5,12 +5,23 @@ use warnings; use base qw/DBIx::Class::Storage::DBI::NoBindVars/; -my %noquote = map { $_ => 1 } qw(int integer); +my $noquote = { + int => qr/^ \-? \d+ $/x, + integer => qr/^ \-? \d+ $/x, + + # TODO maybe need to add float/real/etc +}; sub should_quote_data_type { my $self = shift; - my ($type) = @_; - return 0 if $noquote{$type}; + my ($type, $value) = @_; + + return $self->next::method(@_) if not defined $value; + + if (my $re = $noquote->{$type}) { + return 0 if $value =~ $re; + } + return $self->next::method(@_); } diff --git a/t/74mssql.t b/t/74mssql.t index 238f27a..92b3103 100644 --- a/t/74mssql.t +++ b/t/74mssql.t @@ -40,7 +40,7 @@ ok($new->artistid, "Auto-PK worked"); # Test LIMIT for (1..6) { - $schema->resultset('Artist')->create( { name => 'Artist ' . $_ } ); + $schema->resultset('Artist')->create( { name => 'Artist ' . $_, rank => $_ } ); } my $it = $schema->resultset('Artist')->search( { },