X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2FRecord.pm;h=9eb1c9aebfad64599dbfb983068a03e4100c6b5b;hb=368ed08e24400e9d1faf401a1e4e23ea54d2c969;hp=cf8ec4d73ea6ae59eea083c6d134a15c0e9c9aeb;hpb=2a9d2460814b37e07d7cb83392723146a60d34c7;p=freeside.git diff --git a/FS/FS/Record.pm b/FS/FS/Record.pm index cf8ec4d73..9eb1c9aeb 100644 --- a/FS/FS/Record.pm +++ b/FS/FS/Record.pm @@ -286,6 +286,11 @@ the individual PARAMS_HASHREF queries #regular FS::TABLE methods #on it. +C<$FS::Record::qsearch_qualify_columns> package global is enabled by default. +When enabled, the WHERE clause generated from the 'hashref' parameter has +the table name prepended to each column name. WHERE column = 'value' becomes +WHERE table.coumn = 'value' + =cut my %TYPE = (); #for debugging @@ -2911,18 +2916,9 @@ Check/untaint IPv4 or IPv6 address. sub ut_ip46 { my( $self, $field ) = @_; - my $ip_addr = $self->getfield( $field ); - - # strip user-entered leading 0's from IPv4 addresses - # Parsers like NetAddr::IP interpret them as octal instead of decimal - $ip_addr = join( '.', ( - map{ int($_) } - split( /\./, $ip_addr ) - ) - ) if $ip_addr =~ /\./ && $ip_addr =~ /[\.^]0/; - - my $ip = NetAddr::IP->new( $ip_addr ) - or return "Illegal (IP address) $field: ".$self->getfield($field); + my $ip = NetAddr::IP->new( + $self->_ut_ip_strip_leading_zeros( $self->getfield( $field ) ) + ) or return "Illegal (IP address) $field: ".$self->getfield($field); $self->setfield($field, lc($ip->addr)); return ''; } @@ -2942,6 +2938,21 @@ sub ut_ip46n { $self->ut_ip46($field); } +sub _ut_ip_strip_leading_zeros { + # strip user-entered leading 0's from IP addresses + # so parsers like NetAddr::IP don't mangle the address + # e.g. NetAddr::IP converts 10.0.022.220 into 10.0.18.220 + + my ( $self, $ip ) = @_; + + return join '.', map int, split /\./, $ip + if $ip + && $ip =~ /\./ + && $ip =~ /[\.^]0/; + $ip; +} + + =item ut_coord COLUMN [ LOWER [ UPPER ] ] Check/untaint coordinates. @@ -3219,6 +3230,60 @@ sub ut_enumn { : ''; } +=item ut_date COLUMN + +Check/untaint a column containing a date string. + +Date will be normalized to YYYY-MM-DD format + +=cut + +sub ut_date { + my ( $self, $field ) = @_; + my $value = $self->getfield( $field ); + + my @date = split /[\-\/]/, $value; + if ( scalar(@date) == 3 ) { + @date = @date[2,0,1] if $date[2] >= 1900; + + local $@; + my $ymd; + eval { + # DateTime will die given invalid date + $ymd = DateTime->new( + year => $date[0], + month => $date[1], + day => $date[2], + )->ymd('-'); + }; + + unless( $@ ) { + $self->setfield( $field, $ymd ) unless $value eq $ymd; + return ''; + } + + } + return "Illegal (date) field $field: $value"; +} + +=item ut_daten COLUMN + +Check/untaint a column containing a date string. + +Column may be null. + +Date will be normalized to YYYY-MM-DD format + +=cut + +sub ut_daten { + my ( $self, $field ) = @_; + + $self->getfield( $field ) =~ /^()$/ + ? $self->setfield( $field, '' ) + : $self->ut_date( $field ); +} + =item ut_flag COLUMN Check/untaint a column if it contains either an empty string or 'Y'. This @@ -3587,7 +3652,19 @@ sub _quote { && driver_name eq 'Pg' ) { - dbh->quote($value, { pg_type => PG_BYTEA() }); + local $@; + + eval { $value = dbh->quote($value, { pg_type => PG_BYTEA() }); }; + + if ( $@ && $@ =~ /Wide character/i ) { + warn 'Correcting malformed UTF-8 string for binary quote()' + if $DEBUG; + utf8::decode($value); + utf8::encode($value); + $value = dbh->quote($value, { pg_type => PG_BYTEA() }); + } + + $value; } else { dbh->quote($value); }