diff --git a/app/controllers/concerns/prepared_params.rb b/app/controllers/concerns/prepared_params.rb index 41bbda3cf..cf7a65c83 100644 --- a/app/controllers/concerns/prepared_params.rb +++ b/app/controllers/concerns/prepared_params.rb @@ -53,7 +53,7 @@ def original_params def page result = params[:page]&.to_i || FIRST_PAGE - result.zero? ? FIRST_PAGE : result + result < 1 ? FIRST_PAGE : result end def search diff --git a/app/presenters/base_presenter.rb b/app/presenters/base_presenter.rb index ba4f3f345..7b208afd2 100644 --- a/app/presenters/base_presenter.rb +++ b/app/presenters/base_presenter.rb @@ -41,12 +41,12 @@ def genders def page result = params[:page]&.to_i || FIRST_PAGE - result.zero? ? FIRST_PAGE : result + result < 1 ? FIRST_PAGE : result end def per_page result = params[:per_page]&.to_i || DEFAULT_PER_PAGE - result.zero? ? DEFAULT_PER_PAGE : result + result < 1 ? DEFAULT_PER_PAGE : result end def search_text diff --git a/spec/controllers/concerns/prepared_params_spec.rb b/spec/controllers/concerns/prepared_params_spec.rb index 68ee83828..c0640e2ce 100644 --- a/spec/controllers/concerns/prepared_params_spec.rb +++ b/spec/controllers/concerns/prepared_params_spec.rb @@ -449,6 +449,21 @@ it { expect(result).to eq(1) } end + context "when page is a negative integer" do + let(:page) { -11 } + it { expect(result).to eq(1) } + end + + context "when page is a negative string" do + let(:page) { "-11" } + it { expect(result).to eq(1) } + end + + context "when page is a SQL injection probe" do + let(:page) { "-11' UNION ALL SELECT NULL,NULL--" } + it { expect(result).to eq(1) } + end + context "when page is integer 1" do let(:page) { 1 } it { expect(result).to eq(1) } diff --git a/spec/presenters/base_presenter_spec.rb b/spec/presenters/base_presenter_spec.rb new file mode 100644 index 000000000..c5000509b --- /dev/null +++ b/spec/presenters/base_presenter_spec.rb @@ -0,0 +1,72 @@ +require "rails_helper" + +RSpec.describe BasePresenter do + subject { presenter_class.new(prepared_params) } + + let(:presenter_class) do + Class.new(described_class) do + def initialize(params) # rubocop:disable Lint/MissingSuper -- the parent initializer raises NotImplementedError + @params = params + end + + private + + attr_reader :params + end + end + + let(:prepared_params) { PreparedParams.new(ActionController::Parameters.new(query_params), [], []) } + + describe "#page" do + let(:result) { subject.page } + + context "when page is not provided" do + let(:query_params) { {} } + it { expect(result).to eq(1) } + end + + context "when page is zero" do + let(:query_params) { { page: "0" } } + it { expect(result).to eq(1) } + end + + context "when page is positive" do + let(:query_params) { { page: "3" } } + it { expect(result).to eq(3) } + end + + context "when page is negative" do + let(:query_params) { { page: "-11" } } + it { expect(result).to eq(1) } + end + + context "when page is a SQL injection probe" do + let(:query_params) { { page: "-11' UNION ALL SELECT NULL,NULL--" } } + it { expect(result).to eq(1) } + end + end + + describe "#per_page" do + let(:result) { subject.per_page } + + context "when per_page is not provided" do + let(:query_params) { {} } + it { expect(result).to eq(described_class::DEFAULT_PER_PAGE) } + end + + context "when per_page is zero" do + let(:query_params) { { per_page: "0" } } + it { expect(result).to eq(described_class::DEFAULT_PER_PAGE) } + end + + context "when per_page is positive" do + let(:query_params) { { per_page: "25" } } + it { expect(result).to eq(25) } + end + + context "when per_page is negative" do + let(:query_params) { { per_page: "-5" } } + it { expect(result).to eq(described_class::DEFAULT_PER_PAGE) } + end + end +end