From d0aa47d345afed5e5d2b0eb9ebd214e7fde75431 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20G=C3=BCnther?= Date: Mon, 23 Mar 2026 08:54:41 +0100 Subject: [PATCH] Correctly evaluate parse number string in =n operator --- modules/reporting/lib/report/operator.rb | 2 +- .../spec/models/cost_query/operator_spec.rb | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/modules/reporting/lib/report/operator.rb b/modules/reporting/lib/report/operator.rb index e3fc153ff65..a54cb1afdfb 100644 --- a/modules/reporting/lib/report/operator.rb +++ b/modules/reporting/lib/report/operator.rb @@ -174,7 +174,7 @@ class Report::Operator new "=n", label: :label_equals do def modify(query, field, value) - query.where "#{field} = #{parse_number_string(value)}" + query.where ["#{field} = ?", parse_number_string_to_number(value)] query end end diff --git a/modules/reporting/spec/models/cost_query/operator_spec.rb b/modules/reporting/spec/models/cost_query/operator_spec.rb index 1cc232352ed..1c90e2ccc77 100644 --- a/modules/reporting/spec/models/cost_query/operator_spec.rb +++ b/modules/reporting/spec/models/cost_query/operator_spec.rb @@ -333,6 +333,24 @@ RSpec.describe CostQuery::Operator, :reporting_query_helper do expect(query_on_entries("costs", "=n", 13.37).pluck("id")).to contain_exactly(ce1.id, ce2.id) end + describe "=n value escaping" do + let(:rate) { create(:cost_rate, rate: 10.0) } + + before do + create(:cost_entry, units: 1, rate:, cost_type: rate.cost_type) + create(:cost_entry, units: 1, rate:, cost_type: rate.cost_type) + end + + it "tries to convert invalid values" do + expect(query_on_entries("costs", "=n", "0/**/OR/**/1=1")).to be_empty + end + + it "returns the correct rows for a legitimate numeric value" do + expect(query_on_entries("costs", "=n", "10.0").size).to eq(2) + expect(query_on_entries("costs", "=n", "20.0").size).to eq(0) + end + end + it "does 0" do expect(query_on_entries("costs", "0").size).to eq(Entry.all.count { |e| e.costs == 0 }) end