From bce7e2f8c16c5d8a310b436c3b74e7a3f46ad6e3 Mon Sep 17 00:00:00 2001
From: Adam Niedzielski <adamsunday@gmail.com>
Date: Thu, 25 Jul 2024 16:24:19 +0200
Subject: [PATCH] =?UTF-8?q?Fix=20=C3=9F=20bug=20in=20regexp=20for=20mentio?=
 =?UTF-8?q?ns=20and=20tags=20(#31122)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/models/account.rb       | 2 +-
 app/models/tag.rb           | 2 +-
 spec/models/account_spec.rb | 8 ++++++++
 spec/models/tag_spec.rb     | 8 ++++++++
 4 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/app/models/account.rb b/app/models/account.rb
index d9713dbb42..215a7b3df6 100644
--- a/app/models/account.rb
+++ b/app/models/account.rb
@@ -72,7 +72,7 @@ class Account < ApplicationRecord
   INSTANCE_ACTOR_ID = -99
 
   USERNAME_RE   = /[a-z0-9_]+([a-z0-9_.-]+[a-z0-9_]+)?/i
-  MENTION_RE    = %r{(?<![=/[:word:]])@((#{USERNAME_RE})(?:@[[:word:].-]+[[:word:]]+)?)}i
+  MENTION_RE    = %r{(?<![=/[:word:]])@((#{USERNAME_RE})(?:@[[:word:].-]+[[:word:]]+)?)}
   URL_PREFIX_RE = %r{\Ahttp(s?)://[^/]+}
   USERNAME_ONLY_RE = /\A#{USERNAME_RE}\z/i
   USERNAME_LENGTH_LIMIT = 30
diff --git a/app/models/tag.rb b/app/models/tag.rb
index 9ea710f3b8..b9e0edc176 100644
--- a/app/models/tag.rb
+++ b/app/models/tag.rb
@@ -39,7 +39,7 @@ class Tag < ApplicationRecord
   HASHTAG_LAST_SEQUENCE = '([[:word:]_]*[[:alpha:]][[:word:]_]*)'
   HASHTAG_NAME_PAT = "#{HASHTAG_FIRST_SEQUENCE}|#{HASHTAG_LAST_SEQUENCE}"
 
-  HASHTAG_RE = %r{(?<![=/)\p{Alnum}])#(#{HASHTAG_NAME_PAT})}i
+  HASHTAG_RE = %r{(?<![=/)\p{Alnum}])#(#{HASHTAG_NAME_PAT})}
   HASHTAG_NAME_RE = /\A(#{HASHTAG_NAME_PAT})\z/i
   HASHTAG_INVALID_CHARS_RE = /[^[:alnum:]\u0E47-\u0E4E#{HASHTAG_SEPARATORS}]/
 
diff --git a/spec/models/account_spec.rb b/spec/models/account_spec.rb
index 2851bbe83c..b91cbe915e 100644
--- a/spec/models/account_spec.rb
+++ b/spec/models/account_spec.rb
@@ -934,6 +934,14 @@ RSpec.describe Account do
     it 'does not match URL query string' do
       expect(subject.match('https://example.com/?x=@alice')).to be_nil
     end
+
+    it 'matches usernames immediately following the letter ß' do
+      expect(subject.match('Hello toß @alice from me')[1]).to eq 'alice'
+    end
+
+    it 'matches usernames containing uppercase characters' do
+      expect(subject.match('Hello to @aLice@Example.com from me')[1]).to eq 'aLice@Example.com'
+    end
   end
 
   describe 'validations' do
diff --git a/spec/models/tag_spec.rb b/spec/models/tag_spec.rb
index 7799afe44b..a3cae4a339 100644
--- a/spec/models/tag_spec.rb
+++ b/spec/models/tag_spec.rb
@@ -95,6 +95,14 @@ RSpec.describe Tag do
     it 'does not match purely-numeric hashtags' do
       expect(subject.match('hello #0123456')).to be_nil
     end
+
+    it 'matches hashtags immediately following the letter ß' do
+      expect(subject.match('Hello toß #ruby').to_s).to eq '#ruby'
+    end
+
+    it 'matches hashtags containing uppercase characters' do
+      expect(subject.match('Hello #rubyOnRails').to_s).to eq '#rubyOnRails'
+    end
   end
 
   describe '#to_param' do