From c71c1076499d5b86fe65e1bb28e01320bbeee0a8 Mon Sep 17 00:00:00 2001 From: megothss <1108771+megothss@users.noreply.github.com> Date: Wed, 16 Feb 2022 23:46:06 -0300 Subject: [PATCH] FIX: Don't accept accents in slug if generation_method == 'ascii' (#15702) * FIX: Don't accept accents in slug if generation_method == 'ascii' Fixes bug reported in: - https://meta.discourse.org/t/404-when-trying-to-edit-category-with-accent-in-slug/214762 - https://meta.discourse.org/t/formatting-and-accents-in-urls/215734/5 Assuming `SiteSetting.slug_generation_method == 'ascii'. If the user provides a slug containing non-ascii characters while creating the category, the user will receive a 404 error just after saving the category since the slug will be escaped anyway but Category.find_by_slug_path won't escape the category slug causing the Edit Page of the category to be inaccessible. This commit checks the provided slug and raises an error if the provided slugcontains non-ascii characters ensuring that the provided value is consistent with the site settings. It also changes Category.find_by_slug_path to always escape the slug, since if present, it is escaped anyway in Category.ensure_slug to prevent the 404 in the Edit Category Page in case the user already have some category with a non-ascii slug. * Removed trailing whitespace --- app/models/category.rb | 8 +++----- config/locales/server.en.yml | 1 + spec/models/category_spec.rb | 13 +++++++++++++ 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/app/models/category.rb b/app/models/category.rb index ad5a662a356..fc9d1377570 100644 --- a/app/models/category.rb +++ b/app/models/category.rb @@ -353,6 +353,8 @@ class Category < ActiveRecord::Base if self.slug.blank? errors.add(:slug, :invalid) + elsif SiteSetting.slug_generation_method == 'ascii' && !CGI.unescape(self.slug).ascii_only? + errors.add(:slug, I18n.t("category.errors.slug_contains_non_ascii_chars")) elsif duplicate_slug? errors.add(:slug, 'is already in use') end @@ -803,11 +805,7 @@ class Category < ActiveRecord::Base return nil if slug_path.size > SiteSetting.max_category_nesting slug_path.map! do |slug| - if SiteSetting.slug_generation_method == "encoded" - CGI.escape(slug.downcase) - else - slug.downcase - end + CGI.escape(slug.downcase) end query = diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index 24fe3a11b7f..18abca279ca 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -704,6 +704,7 @@ en: permission_conflict: "Any group that is allowed to access a subcategory must also be allowed to access the parent category. The following groups have access to one of the subcategories, but no access to parent category: %{group_names}." disallowed_topic_tags: "This topic has tags not allowed by this category: '%{tags}'" disallowed_tags_generic: "This topic has disallowed tags." + slug_contains_non_ascii_chars: "contains non-ascii characters" cannot_delete: uncategorized: "This category is special. It is intended as a holding area for topics that have no category; it cannot be deleted." has_subcategories: "Can't delete this category because it has sub-categories." diff --git a/spec/models/category_spec.rb b/spec/models/category_spec.rb index 85ba20b150c..d12aa8a66e6 100644 --- a/spec/models/category_spec.rb +++ b/spec/models/category_spec.rb @@ -362,6 +362,19 @@ describe Category do expect(@cat).to be_valid expect(@cat.errors[:slug]).not_to be_present end + + context 'if SiteSettings.slug_generation_method = ascii' do + before do + SiteSetting.slug_generation_method = 'ascii' + end + + it 'fails if slug contains non-ascii characters' do + c = Fabricate.build(:category, name: "Sem acentuação", slug: "sem-acentuação") + expect(c).not_to be_valid + + expect(c.errors[:slug]).to be_present + end + end end describe 'description_text' do