From 192f5d3030e3dd021a4f5e3a5b124b516207f493 Mon Sep 17 00:00:00 2001 From: Nicolas Rodriguez Date: Fri, 11 May 2018 01:12:40 +0200 Subject: [PATCH] Fix integer out of range --- .../datatable/column/search.rb | 26 +++++++++++++++++- .../orm/active_record_filter_records_spec.rb | 27 +++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/lib/ajax-datatables-rails/datatable/column/search.rb b/lib/ajax-datatables-rails/datatable/column/search.rb index e3371134..a6280892 100644 --- a/lib/ajax-datatables-rails/datatable/column/search.rb +++ b/lib/ajax-datatables-rails/datatable/column/search.rb @@ -5,6 +5,9 @@ module Datatable class Column module Search + SMALLEST_PQ_INTEGER = -2147483648 + LARGEST_PQ_INTEGER = 2147483647 + def searchable? @view_column.fetch(:searchable, true) end @@ -54,7 +57,7 @@ def non_regex_search when Proc filter when :eq, :not_eq, :lt, :gt, :lteq, :gteq, :in - numeric_search + is_searchable_integer? ? numeric_search : empty_search when :null_value null_value_search when :start_with @@ -82,6 +85,27 @@ def numeric_search end end + def empty_search + casted_column.matches('') + end + + def is_searchable_integer? + if search.value.is_a?(Array) + valids = search.value.map { |v| is_integer?(v) && !is_out_of_range?(v) } + !valids.include?(false) + else + is_integer?(search.value) && !is_out_of_range?(search.value) + end + end + + def is_out_of_range?(search_value) + Integer(search_value) > LARGEST_PQ_INTEGER || Integer(search_value) < SMALLEST_PQ_INTEGER + end + + def is_integer?(string) + true if Integer(string) rescue false + end + end end end diff --git a/spec/ajax-datatables-rails/orm/active_record_filter_records_spec.rb b/spec/ajax-datatables-rails/orm/active_record_filter_records_spec.rb index 32af9012..8f658521 100644 --- a/spec/ajax-datatables-rails/orm/active_record_filter_records_spec.rb +++ b/spec/ajax-datatables-rails/orm/active_record_filter_records_spec.rb @@ -492,5 +492,32 @@ expect(item[:first_name]).to eq 'john' end end + + describe 'Integer overflows' do + let(:datatable) { DatatableCondEq.new(view) } + let(:largest_postgresql_integer_value) { 2147483647 } + let(:smallest_postgresql_integer_value) { -2147483648 } + + before(:each) do + create(:user, first_name: 'john', post_id: 1) + create(:user, first_name: 'mary', post_id: 2) + create(:user, first_name: 'phil', post_id: largest_postgresql_integer_value) + end + + it 'Returns an empty result if input value is too large' do + datatable.params[:columns]['4'][:search][:value] = largest_postgresql_integer_value + 1 + expect(datatable.data.size).to eq 0 + end + + it 'Returns an empty result if input value is too small' do + datatable.params[:columns]['4'][:search][:value] = smallest_postgresql_integer_value - 1 + expect(datatable.data.size).to eq 0 + end + + it 'returns the matching user' do + datatable.params[:columns]['4'][:search][:value] = largest_postgresql_integer_value + expect(datatable.data.size).to eq 1 + end + end end end