tag.rb: validate tag names.
Makes these tag names invalid when tagging posts: * Blank names (e.g. ___). * Non-ASCII characters (Japanese text). * Non-printable characters (e.g. control characters < 0x20). * Leading or trailing underscores, or consecutive underscores. Reason: `_foo__bar_` and `foo_bar` both render as `foo bar` in the tag list. * Leading `-` or `~`, or '*' (-foo, ~foo, foo*bar). Previously these were silently stripped, but that meant tagging a post with e.g. `*-foo` tagged the post with the invalid tag `-foo`. * Tag type prefixes (e.g. `character:character:hatsune_miku` no longer creates the literal tag `character:hatsune_miku`). * Metatags (order:score, user:evazion, etc).
This commit is contained in:
30
app/logical/tag_name_validator.rb
Normal file
30
app/logical/tag_name_validator.rb
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
class TagNameValidator < ActiveModel::EachValidator
|
||||||
|
def validate_each(record, attribute, value)
|
||||||
|
case Tag.normalize_name(value)
|
||||||
|
when /\A_*\z/
|
||||||
|
record.errors[attribute] << "'#{value}' cannot be blank"
|
||||||
|
when /\*/
|
||||||
|
record.errors[attribute] << "'#{value}' cannot contain asterisks ('*')"
|
||||||
|
when /,/
|
||||||
|
record.errors[attribute] << "'#{value}' cannot contain commas (',')"
|
||||||
|
when /\A~/
|
||||||
|
record.errors[attribute] << "'#{value}' cannot begin with a tilde ('~')"
|
||||||
|
when /\A-/
|
||||||
|
record.errors[attribute] << "'#{value}' cannot begin with a dash ('-')"
|
||||||
|
when /\A_/
|
||||||
|
record.errors[attribute] << "'#{value}' cannot begin with an underscore"
|
||||||
|
when /_\z/
|
||||||
|
record.errors[attribute] << "'#{value}' cannot end with an underscore"
|
||||||
|
when /__/
|
||||||
|
record.errors[attribute] << "'#{value}' cannot contain consecutive underscores"
|
||||||
|
when /[^[[:graph:]]]/
|
||||||
|
record.errors[attribute] << "'#{value}' cannot contain non-printable characters"
|
||||||
|
when /[^[[:ascii:]]]/
|
||||||
|
record.errors[attribute] << "'#{value}' must consist of only ASCII characters"
|
||||||
|
when /\A(#{Tag::METATAGS}|#{Tag::SUBQUERY_METATAGS}):(.+)\z/i
|
||||||
|
record.errors[attribute] << "'#{value}' cannot begin with '#{$1}:'"
|
||||||
|
when /\A(#{Tag.categories.regexp}):(.+)\z/i
|
||||||
|
record.errors[attribute] << "'#{value}' cannot begin with '#{$1}:'"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -6,6 +6,8 @@ class Tag < ActiveRecord::Base
|
|||||||
attr_accessible :is_locked, :as => [:moderator, :admin]
|
attr_accessible :is_locked, :as => [:moderator, :admin]
|
||||||
has_one :wiki_page, :foreign_key => "title", :primary_key => "name"
|
has_one :wiki_page, :foreign_key => "title", :primary_key => "name"
|
||||||
|
|
||||||
|
validates :name, uniqueness: true, tag_name: true, on: :create
|
||||||
|
|
||||||
module ApiMethods
|
module ApiMethods
|
||||||
def to_legacy_json
|
def to_legacy_json
|
||||||
return {
|
return {
|
||||||
@@ -179,7 +181,7 @@ class Tag < ActiveRecord::Base
|
|||||||
|
|
||||||
module NameMethods
|
module NameMethods
|
||||||
def normalize_name(name)
|
def normalize_name(name)
|
||||||
name.mb_chars.downcase.tr(" ", "_").gsub(/\A[-~]+/, "").gsub(/\*/, "").to_s
|
name.to_s.mb_chars.downcase.strip.tr(" ", "_").to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_or_create_by_name(name, options = {})
|
def find_or_create_by_name(name, options = {})
|
||||||
|
|||||||
Reference in New Issue
Block a user