Skip to content

Commit f6eb0f2

Browse files
Gargronhiyuki2578
authored andcommitted
Change note length validation to ignore mention domains and URLs (mastodon#9717)
Fix mastodon#4419
1 parent 5ca016b commit f6eb0f2

3 files changed

Lines changed: 25 additions & 3 deletions

File tree

app/models/account.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ class Account < ApplicationRecord
7676
validates_with UniqueUsernameValidator, if: -> { local? && will_save_change_to_username? }
7777
validates_with UnreservedUsernameValidator, if: -> { local? && will_save_change_to_username? }
7878
validates :display_name, length: { maximum: 30 }, if: -> { local? && will_save_change_to_display_name? }
79-
validates :note, length: { maximum: 160 }, if: -> { local? && will_save_change_to_note? }
79+
validates :note, note_length: { maximum: 160 }, if: -> { local? && will_save_change_to_note? }
8080
validates :fields, length: { maximum: 4 }, if: -> { local? && will_save_change_to_fields? }
8181

8282
scope :remote, -> { where.not(domain: nil) }
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# frozen_string_literal: true
2+
3+
class NoteLengthValidator < ActiveModel::EachValidator
4+
def validate_each(record, attribute, value)
5+
record.errors.add(attribute, I18n.t('statuses.over_character_limit', max: options[:maximum])) if too_long?(value)
6+
end
7+
8+
private
9+
10+
def too_long?(value)
11+
countable_text(value).mb_chars.grapheme_length > options[:maximum]
12+
end
13+
14+
def countable_text(value)
15+
return '' if value.nil?
16+
17+
value.dup.tap do |new_text|
18+
new_text.gsub!(FetchLinkCardService::URL_PATTERN, 'x' * 23)
19+
new_text.gsub!(Account::MENTION_RE, '@\2')
20+
end
21+
end
22+
end

app/validators/url_validator.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ def validate_each(record, attribute, value)
88
private
99

1010
def compliant?(url)
11-
parsed_url = Addressable::URI.parse(url).normalize
12-
!parsed_url.nil? && %w(http https).include?(parsed_url.scheme) && parsed_url.host
11+
parsed_url = Addressable::URI.parse(url)
12+
parsed_url && %w(http https).include?(parsed_url.scheme) && parsed_url.host
1313
end
1414
end

0 commit comments

Comments
 (0)