Protect DBIC as best we can from the failure mode in 7cb35852
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / ResultSet.pm
index 3d1a3a1..0a6c002 100644 (file)
@@ -8,6 +8,7 @@ use DBIx::Class::ResultSetColumn;
 use DBIx::Class::ResultClass::HashRefInflator;
 use Scalar::Util qw/blessed weaken reftype/;
 use DBIx::Class::_Util qw(
+  dbic_internal_try
   fail_on_internal_wantarray fail_on_internal_call UNRESOLVABLE_CONDITION
 );
 use Try::Tiny;
@@ -442,7 +443,7 @@ sub search_rs {
     $call_cond = shift;
   }
   # fish out attrs in the ($condref, $attr) case
-  elsif (@_ == 2 and ( ! defined $_[0] or (ref $_[0]) ne '') ) {
+  elsif (@_ == 2 and ( ! defined $_[0] or length ref $_[0] ) ) {
     ($call_cond, $call_attrs) = @_;
   }
   elsif (@_ % 2) {
@@ -456,7 +457,7 @@ sub search_rs {
     for my $i (0 .. $#_) {
       next if $i % 2;
       $self->throw_exception ('All keys in condition key/value pairs must be plain scalars')
-        if (! defined $_[$i] or ref $_[$i] ne '');
+        if (! defined $_[$i] or length ref $_[$i] );
     }
 
     $call_cond = { @_ };
@@ -878,7 +879,7 @@ sub find {
         join "\x00", sort $rsrc->unique_constraint_columns($c_name)
       }++;
 
-      try {
+      dbic_internal_try {
         push @unique_queries, $self->_qualify_cond_columns(
           $self->result_source->_minimal_valueset_satisfying_constraint(
             constraint_name => $c_name,
@@ -3531,6 +3532,19 @@ sub _resolved_attrs {
   $self->throw_exception("Specifying distinct => 1 in conjunction with collapse => 1 is unsupported")
     if $attrs->{collapse} and $attrs->{distinct};
 
+
+  # Sanity check the paging attributes
+  # SQLMaker does it too, but in case of a software_limit we'll never get there
+  if (defined $attrs->{offset}) {
+    $self->throw_exception('A supplied offset attribute must be a non-negative integer')
+      if ( $attrs->{offset} =~ /[^0-9]/ or $attrs->{offset} < 0 );
+  }
+  if (defined $attrs->{rows}) {
+    $self->throw_exception("The rows attribute must be a positive integer if present")
+      if ( $attrs->{rows} =~ /[^0-9]/ or $attrs->{rows} <= 0 );
+  }
+
+
   # default selection list
   $attrs->{columns} = [ $source->columns ]
     unless List::Util::first { exists $attrs->{$_} } qw/columns cols select as/;
@@ -4632,7 +4646,7 @@ revisit rows in your ResultSet:
     ... do stuff ...
   }
 
-  $rs->first; # without cache, this would issue a query
+  $resultset->first; # without cache, this would issue a query
 
 By default, searches are not cached.