From 8695449cfc5d26ef24bf08aa9f3e74879dc4dc1a Mon Sep 17 00:00:00 2001 From: Bianca Nenciu Date: Wed, 4 May 2022 14:33:06 +0300 Subject: [PATCH] FIX: Validate permalink_normalizations setting (#16604) When an admin enters a badly formed regular expression in the permalink_normalizations site setting, a RegexpError exception is generated everytime a URL is normalized (see Permalink.normalize_url). The new validator validates every regular expression present in the setting value (delimited by '|'). --- config/locales/server.en.yml | 1 + config/site_settings.yml | 1 + lib/validators/regexp_list_validator.rb | 22 +++++++++++++++++++ .../validators/regexp_list_validator_spec.rb | 16 ++++++++++++++ 4 files changed, 40 insertions(+) create mode 100644 lib/validators/regexp_list_validator.rb create mode 100644 spec/lib/validators/regexp_list_validator_spec.rb diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index 80c37af5b14..4793883c6a1 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -2387,6 +2387,7 @@ en: email_polling_disabled: "You must enable either manual or POP3 polling before enabling reply by email." user_locale_not_enabled: "You must first enable 'allow user locale' before enabling this setting." invalid_regex: "Regex is invalid or not allowed." + invalid_regex_with_message: "The regex '%{regex}' has an error: %{message}" email_editable_enabled: "You must disable 'email editable' before enabling this setting." staged_users_disabled: "You must first enable 'staged users' before enabling this setting." reply_by_email_disabled: "You must first enable 'reply by email' before enabling this setting." diff --git a/config/site_settings.yml b/config/site_settings.yml index 9f34f609d20..4d131504b17 100644 --- a/config/site_settings.yml +++ b/config/site_settings.yml @@ -2134,6 +2134,7 @@ uncategorized: default: "" type: list list_type: simple + validator: "RegexpListValidator" max_similar_results: 5 minimum_topics_similar: 50 diff --git a/lib/validators/regexp_list_validator.rb b/lib/validators/regexp_list_validator.rb new file mode 100644 index 00000000000..dd35f31e958 --- /dev/null +++ b/lib/validators/regexp_list_validator.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +class RegexpListValidator + def initialize(opts = {}) + end + + def valid_value?(value) + value.split("|").all? do |regexp| + begin + Regexp.new(regexp) + rescue RegexpError => e + @regexp = regexp + @error_message = e.message + false + end + end + end + + def error_message + I18n.t("site_settings.errors.invalid_regex_with_message", regex: @regexp, message: @error_message) + end +end diff --git a/spec/lib/validators/regexp_list_validator_spec.rb b/spec/lib/validators/regexp_list_validator_spec.rb new file mode 100644 index 00000000000..441668e43cb --- /dev/null +++ b/spec/lib/validators/regexp_list_validator_spec.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +describe RegexpListValidator do + subject { described_class.new } + + it "allows lists of valid regular expressions" do + expect(subject.valid_value?('\d+|[0-9]?|\w+')).to eq(true) + end + + it "does not allow lists of invalid regular expressions do" do + expect(subject.valid_value?('\d+|[0-9?|\w+')).to eq(false) + expect(subject.error_message).to eq( + I18n.t("site_settings.errors.invalid_regex_with_message", regex: '[0-9?', message: 'premature end of char-class: /[0-9?/') + ) + end +end