diff --git a/app/models/case_log.rb b/app/models/case_log.rb index 0ec02b529..2c09bd650 100644 --- a/app/models/case_log.rb +++ b/app/models/case_log.rb @@ -561,12 +561,12 @@ private end def process_postcode_changes! - self.postcode_full = postcode_full.present? ? postcode_full.upcase.gsub(/\s+/, "") : postcode_full + self.postcode_full = upcase_and_remove_whitespace(postcode_full) process_postcode(postcode_full, "postcode_known", "is_la_inferred", "la") end def process_previous_postcode_changes! - self.ppostcode_full = ppostcode_full.present? ? ppostcode_full.upcase.gsub(/\s+/, "") : ppostcode_full + self.ppostcode_full = upcase_and_remove_whitespace(ppostcode_full) process_postcode(ppostcode_full, "previous_postcode_known", "is_previous_la_inferred", "prevloc") end @@ -621,9 +621,14 @@ private end def get_inferred_la(postcode) + # Avoid network calls when postcode is invalid + return unless postcode.match(Validations::PropertyValidations::POSTCODE_REGEXP) + postcode_lookup = nil begin - Timeout.timeout(5) { postcode_lookup = PIO.lookup(postcode) } + # URI encoding only supports ASCII characters + ascii_postcode = postcode.encode("ASCII", "UTF-8", invalid: :replace, undef: :replace, replace: "") + Timeout.timeout(5) { postcode_lookup = PIO.lookup(ascii_postcode) } rescue Timeout::Error Rails.logger.warn("Postcodes.io lookup timed out") end @@ -718,4 +723,8 @@ private (value * 52 / num_of_weeks).round(2) end + + def upcase_and_remove_whitespace(string) + string.present? ? string.upcase.gsub(/\s+/, "") : string + end end diff --git a/spec/models/case_log_spec.rb b/spec/models/case_log_spec.rb index 10056506b..33389c28d 100644 --- a/spec/models/case_log_spec.rb +++ b/spec/models/case_log_spec.rb @@ -1996,5 +1996,13 @@ RSpec.describe CaseLog do expect(case_log.plural_gender_for_person_3).to be_nil end end + + context "when a postcode contains unicode characters" do + let(:case_log) { FactoryBot.build(:case_log, postcode_full: "SR81LS\u00A0") } + + it "triggers a validation error" do + expect { case_log.save! }.to raise_error(ActiveRecord::RecordInvalid, /Enter a postcode in the correct format/) + end + end end end