Merge character validators

This commit is contained in:
Tom Hughes 2018-11-05 18:54:19 +00:00
parent b4ef61a9f3
commit d73a5d4bc0
26 changed files with 102 additions and 111 deletions

View file

@ -28,7 +28,7 @@ class ChangesetComment < ActiveRecord::Base
validates :changeset, :presence => true, :associated => true validates :changeset, :presence => true, :associated => true
validates :author, :presence => true, :associated => true validates :author, :presence => true, :associated => true
validates :visible, :inclusion => [true, false] validates :visible, :inclusion => [true, false]
validates :body, :invalid_chars => true validates :body, :characters => true
# Return the comment text # Return the comment text
def body def body

View file

@ -21,6 +21,6 @@ class ChangesetTag < ActiveRecord::Base
belongs_to :changeset belongs_to :changeset
validates :changeset, :presence => true, :associated => true validates :changeset, :presence => true, :associated => true
validates :k, :v, :allow_blank => true, :length => { :maximum => 255 }, :invalid_chars => true validates :k, :v, :allow_blank => true, :length => { :maximum => 255 }, :characters => true
validates :k, :uniqueness => { :scope => :changeset_id } validates :k, :uniqueness => { :scope => :changeset_id }
end end

View file

@ -28,7 +28,7 @@ class DiaryComment < ActiveRecord::Base
scope :visible, -> { where(:visible => true) } scope :visible, -> { where(:visible => true) }
validates :body, :presence => true, :invalid_chars => true validates :body, :presence => true, :characters => true
validates :diary_entry, :user, :associated => true validates :diary_entry, :user, :associated => true
after_save :spam_check after_save :spam_check

View file

@ -37,8 +37,8 @@ class DiaryEntry < ActiveRecord::Base
scope :visible, -> { where(:visible => true) } scope :visible, -> { where(:visible => true) }
validates :title, :presence => true, :length => 1..255, :invalid_chars => true validates :title, :presence => true, :length => 1..255, :characters => true
validates :body, :presence => true, :invalid_chars => true validates :body, :presence => true, :characters => true
validates :latitude, :allow_nil => true, validates :latitude, :allow_nil => true,
:numericality => { :greater_than_or_equal_to => -90, :numericality => { :greater_than_or_equal_to => -90,
:less_than_or_equal_to => 90 } :less_than_or_equal_to => 90 }

View file

@ -24,7 +24,7 @@ class IssueComment < ActiveRecord::Base
belongs_to :issue belongs_to :issue
belongs_to :user belongs_to :user
validates :body, :presence => true, :invalid_chars => true validates :body, :presence => true, :characters => true
validates :user, :presence => true validates :user, :presence => true
validates :issue, :presence => true validates :issue, :presence => true
end end

View file

@ -32,7 +32,7 @@ class Message < ActiveRecord::Base
validates :title, :presence => true, :utf8 => true, :length => 1..255 validates :title, :presence => true, :utf8 => true, :length => 1..255
validates :body, :sent_on, :sender, :recipient, :presence => true validates :body, :sent_on, :sender, :recipient, :presence => true
validates :title, :body, :invalid_chars => true validates :title, :body, :characters => true
def self.from_mail(mail, from, to) def self.from_mail(mail, from, to)
if mail.multipart? if mail.multipart?

View file

@ -18,6 +18,6 @@ class NodeTag < ActiveRecord::Base
belongs_to :node belongs_to :node
validates :node, :presence => true, :associated => true validates :node, :presence => true, :associated => true
validates :k, :v, :allow_blank => true, :length => { :maximum => 255 }, :invalid_chars => true validates :k, :v, :allow_blank => true, :length => { :maximum => 255 }, :characters => true
validates :k, :uniqueness => { :scope => :node_id } validates :k, :uniqueness => { :scope => :node_id }
end end

View file

@ -33,7 +33,7 @@ class NoteComment < ActiveRecord::Base
validates :visible, :inclusion => [true, false] validates :visible, :inclusion => [true, false]
validates :author, :associated => true validates :author, :associated => true
validates :event, :inclusion => %w[opened closed reopened commented hidden] validates :event, :inclusion => %w[opened closed reopened commented hidden]
validates :body, :length => { :maximum => 2000 }, :invalid_chars => true validates :body, :length => { :maximum => 2000 }, :characters => true
# Return the comment text # Return the comment text
def body def body

View file

@ -19,6 +19,6 @@ class OldNodeTag < ActiveRecord::Base
belongs_to :old_node, :foreign_key => [:node_id, :version] belongs_to :old_node, :foreign_key => [:node_id, :version]
validates :old_node, :presence => true, :associated => true validates :old_node, :presence => true, :associated => true
validates :k, :v, :allow_blank => true, :length => { :maximum => 255 }, :invalid_chars => true validates :k, :v, :allow_blank => true, :length => { :maximum => 255 }, :characters => true
validates :k, :uniqueness => { :scope => [:node_id, :version] } validates :k, :uniqueness => { :scope => [:node_id, :version] }
end end

View file

@ -19,6 +19,6 @@ class OldRelationTag < ActiveRecord::Base
belongs_to :old_relation, :foreign_key => [:relation_id, :version] belongs_to :old_relation, :foreign_key => [:relation_id, :version]
validates :old_relation, :presence => true, :associated => true validates :old_relation, :presence => true, :associated => true
validates :k, :v, :allow_blank => true, :length => { :maximum => 255 }, :invalid_chars => true validates :k, :v, :allow_blank => true, :length => { :maximum => 255 }, :characters => true
validates :k, :uniqueness => { :scope => [:relation_id, :version] } validates :k, :uniqueness => { :scope => [:relation_id, :version] }
end end

View file

@ -19,6 +19,6 @@ class OldWayTag < ActiveRecord::Base
belongs_to :old_way, :foreign_key => [:way_id, :version] belongs_to :old_way, :foreign_key => [:way_id, :version]
validates :old_way, :presence => true, :associated => true validates :old_way, :presence => true, :associated => true
validates :k, :v, :allow_blank => true, :length => { :maximum => 255 }, :invalid_chars => true validates :k, :v, :allow_blank => true, :length => { :maximum => 255 }, :characters => true
validates :k, :uniqueness => { :scope => [:way_id, :version] } validates :k, :uniqueness => { :scope => [:way_id, :version] }
end end

View file

@ -31,8 +31,8 @@ class Redaction < ActiveRecord::Base
has_many :old_ways has_many :old_ways
has_many :old_relations has_many :old_relations
validates :title, :presence => true, :invalid_chars => true validates :title, :presence => true, :characters => true
validates :description, :presence => true, :invalid_chars => true validates :description, :presence => true, :characters => true
validates :description_format, :inclusion => { :in => %w[text html markdown] } validates :description_format, :inclusion => { :in => %w[text html markdown] }
# this method overrides the AR default to provide the rich # this method overrides the AR default to provide the rich

View file

@ -18,6 +18,6 @@ class RelationTag < ActiveRecord::Base
belongs_to :relation belongs_to :relation
validates :relation, :presence => true, :associated => true validates :relation, :presence => true, :associated => true
validates :k, :v, :allow_blank => true, :length => { :maximum => 255 }, :invalid_chars => true validates :k, :v, :allow_blank => true, :length => { :maximum => 255 }, :characters => true
validates :k, :uniqueness => { :scope => :relation_id } validates :k, :uniqueness => { :scope => :relation_id }
end end

View file

@ -27,7 +27,7 @@ class Report < ActiveRecord::Base
validates :issue, :presence => true validates :issue, :presence => true
validates :user, :presence => true validates :user, :presence => true
validates :details, :presence => true, :invalid_chars => true validates :details, :presence => true, :characters => true
validates :category, :presence => true validates :category, :presence => true
def self.categories_for(reportable) def self.categories_for(reportable)

View file

@ -38,8 +38,8 @@ class Trace < ActiveRecord::Base
scope :tagged, ->(t) { joins(:tags).where(:gpx_file_tags => { :tag => t }) } scope :tagged, ->(t) { joins(:tags).where(:gpx_file_tags => { :tag => t }) }
validates :user, :presence => true, :associated => true validates :user, :presence => true, :associated => true
validates :name, :presence => true, :length => 1..255, :invalid_chars => true validates :name, :presence => true, :length => 1..255, :characters => true
validates :description, :presence => { :on => :create }, :length => 1..255, :invalid_chars => true validates :description, :presence => { :on => :create }, :length => 1..255, :characters => true
validates :timestamp, :presence => true validates :timestamp, :presence => true
validates :visibility, :inclusion => %w[private public trackable identifiable] validates :visibility, :inclusion => %w[private public trackable identifiable]

View file

@ -22,5 +22,5 @@ class Tracetag < ActiveRecord::Base
belongs_to :trace, :foreign_key => "gpx_id" belongs_to :trace, :foreign_key => "gpx_id"
validates :trace, :associated => true validates :trace, :associated => true
validates :tag, :length => 1..255, :format => %r{\A[^/;.,?]*\z}, :invalid_chars => true validates :tag, :length => 1..255, :format => %r{\A[^/;.,?]*\z}, :characters => true
end end

View file

@ -93,10 +93,9 @@ class User < ActiveRecord::Base
validates :display_name, :if => proc { |u| u.display_name_changed? }, validates :display_name, :if => proc { |u| u.display_name_changed? },
:uniqueness => { :case_sensitive => false } :uniqueness => { :case_sensitive => false }
validates :display_name, :if => proc { |u| u.display_name_changed? }, validates :display_name, :if => proc { |u| u.display_name_changed? },
:invalid_chars => true, :characters => { :url_safe => true },
:invalid_url_chars => true,
:whitespace => { :leading => false, :trailing => false } :whitespace => { :leading => false, :trailing => false }
validates :email, :presence => true, :confirmation => true, :invalid_chars => true validates :email, :presence => true, :confirmation => true, :characters => true
validates :email, :if => proc { |u| u.email_changed? }, validates :email, :if => proc { |u| u.email_changed? },
:uniqueness => { :case_sensitive => false } :uniqueness => { :case_sensitive => false }
validates :pass_crypt, :confirmation => true, :length => 8..255 validates :pass_crypt, :confirmation => true, :length => 8..255

View file

@ -26,7 +26,7 @@
class UserBlock < ActiveRecord::Base class UserBlock < ActiveRecord::Base
validate :moderator_permissions validate :moderator_permissions
validates :reason, :invalid_chars => true validates :reason, :characters => true
belongs_to :user, :class_name => "User", :foreign_key => :user_id belongs_to :user, :class_name => "User", :foreign_key => :user_id
belongs_to :creator, :class_name => "User", :foreign_key => :creator_id belongs_to :creator, :class_name => "User", :foreign_key => :creator_id

View file

@ -17,7 +17,7 @@ class UserPreference < ActiveRecord::Base
belongs_to :user belongs_to :user
validates :user, :presence => true, :associated => true validates :user, :presence => true, :associated => true
validates :k, :v, :length => 1..255, :invalid_chars => true validates :k, :v, :length => 1..255, :characters => true
# Turn this Node in to an XML Node without the <osm> wrapper. # Turn this Node in to an XML Node without the <osm> wrapper.
def to_xml_node def to_xml_node

View file

@ -18,6 +18,6 @@ class WayTag < ActiveRecord::Base
belongs_to :way belongs_to :way
validates :way, :presence => true, :associated => true validates :way, :presence => true, :associated => true
validates :k, :v, :allow_blank => true, :length => { :maximum => 255 }, :invalid_chars => true validates :k, :v, :allow_blank => true, :length => { :maximum => 255 }, :characters => true
validates :k, :uniqueness => { :scope => :way_id } validates :k, :uniqueness => { :scope => :way_id }
end end

View file

@ -0,0 +1,12 @@
class CharactersValidator < ActiveModel::EachValidator
INVALID_CHARS = "\x00-\x08\x0b-\x0c\x0e-\x1f\x7f\ufffe\uffff".freeze
INVALID_URL_CHARS = "/;.,?%#".freeze
def validate_each(record, attribute, value)
record.errors[attribute] << (options[:message] || I18n.t("validations.invalid_chars")) if value =~ /[#{INVALID_CHARS}]/
if options[:url_safe]
record.errors[attribute] << (options[:message] || I18n.t("validations.invalid_url_chars", :invalid_url_chars => INVALID_URL_CHARS)) if value =~ /[#{INVALID_URL_CHARS}]/
end
end
end

View file

@ -1,7 +0,0 @@
class InvalidCharsValidator < ActiveModel::EachValidator
INVALID_CHARS = "\x00-\x08\x0b-\x0c\x0e-\x1f\x7f\ufffe\uffff".freeze
def validate_each(record, attribute, value)
record.errors[attribute] << (options[:message] || I18n.t("validations.invalid_chars")) if value =~ /[#{INVALID_CHARS}]/
end
end

View file

@ -1,7 +0,0 @@
class InvalidUrlCharsValidator < ActiveModel::EachValidator
INVALID_URL_CHARS = "/;.,?%#".freeze
def validate_each(record, attribute, value)
record.errors[attribute] << (options[:message] || I18n.t("validations.invalid_url_chars", :invalid_url_chars => INVALID_URL_CHARS)) if value =~ /[#{INVALID_URL_CHARS}]/
end
end

View file

@ -0,0 +1,66 @@
require "test_helper"
class InvalidCharsValidatable
include ActiveModel::Validations
validates :chars, :characters => true
attr_accessor :chars
end
class InvalidUrlCharsValidatable
include ActiveModel::Validations
validates :chars, :characters => { :url_safe => true }
attr_accessor :chars
end
class CharactersValidatorTest < ActiveSupport::TestCase
include Rails::Dom::Testing::Assertions::SelectorAssertions
def test_with_valid_chars
c = InvalidCharsValidatable.new
valid = ["Name.", "'me", "he\"", "<hr>", "*ho", "\"help\"@",
"vergrößern", "ルシステムにも対応します", "輕觸搖晃的遊戲", "/;.,?%#"]
valid.each do |v|
c.chars = v
assert c.valid?, "'#{v}' should be valid"
end
end
def test_with_invalid_chars
c = InvalidCharsValidatable.new
invalid = ["\x7f<hr/>", "test@example.com\x0e-", "s/\x1ff", "aa/\ufffe",
"aa\x0b-,", "aa?\x08", "/;\uffff.,?", "\x00-も対応します/", "\x0c#ping",
"foo\x1fbar", "foo\x7fbar", "foo\ufffebar", "foo\uffffbar"]
invalid.each do |v|
c.chars = v
assert_not c.valid?, "'#{v}' should not be valid"
end
end
def test_with_valid_url_chars
c = InvalidUrlCharsValidatable.new
valid = ["Name", "'me", "he\"", "<hr>", "*ho", "\"help\"@",
"vergrößern", "ルシステムにも対応します", "輕觸搖晃的遊戲"]
valid.each do |v|
c.chars = v
assert c.valid?, "'#{v}' should be valid"
end
end
def test_with_invalid_url_chars
c = InvalidUrlCharsValidatable.new
invalid = ["Name.", "you;me", "he\"#", "<hr/>", "50%", "good?",
"vergrößern,deutsche", "ルシステムに;.も対応します", "輕觸搖/晃的遊戲", "/;.,?%#"]
invalid.each do |v|
c.chars = v
assert_not c.valid?, "'#{v}' should not be valid"
end
end
end

View file

@ -1,36 +0,0 @@
require "test_helper"
class InvalidCharsValidatable
include ActiveModel::Validations
validates :chars, :invalid_chars => true
attr_accessor :chars
end
class InvalidCharsValidatorTest < ActiveSupport::TestCase
include Rails::Dom::Testing::Assertions::SelectorAssertions
def test_with_valid_chars
c = InvalidCharsValidatable.new
valid = ["Name.", "'me", "he\"", "<hr>", "*ho", "\"help\"@",
"vergrößern", "ルシステムにも対応します", "輕觸搖晃的遊戲", "/;.,?%#"]
valid.each do |v|
c.chars = v
assert c.valid?, "'#{v}' should be valid"
end
end
def test_with_invalid_chars
c = InvalidCharsValidatable.new
invalid = ["\x7f<hr/>", "test@example.com\x0e-", "s/\x1ff", "aa/\ufffe",
"aa\x0b-,", "aa?\x08", "/;\uffff.,?", "\x00-も対応します/", "\x0c#ping",
"foo\x1fbar", "foo\x7fbar", "foo\ufffebar", "foo\uffffbar"]
invalid.each do |v|
c.chars = v
assert_not c.valid?, "'#{v}' should not be valid"
end
end
end

View file

@ -1,36 +0,0 @@
require "test_helper"
class InvalidUrlCharsValidatable
include ActiveModel::Validations
validates :chars, :invalid_url_chars => true
attr_accessor :chars
end
class InvalidUrlCharsValidatorTest < ActiveSupport::TestCase
include Rails::Dom::Testing::Assertions::SelectorAssertions
def test_with_valid_url_chars
c = InvalidUrlCharsValidatable.new
valid = ["\x7f<hr>", "test@examplecom\x0e-", "s\x1ff", "aa\ufffe",
"aa\x0b-", "aa\x08", "\uffff::", "\x00-も対応します", "\x0c*ping",
"foo\x1fbar", "foo\x7fbar", "foo\ufffebar", "foo\uffffbar"]
valid.each do |v|
c.chars = v
assert c.valid?, "'#{v}' should be valid"
end
end
def test_with_invalid_url_chars
c = InvalidUrlCharsValidatable.new
invalid = ["Name.", "you;me", "he\"#", "<hr/>", "50%", "good?",
"vergrößern,deutsche", "ルシステムに;.も対応します", "輕觸搖/晃的遊戲", "/;.,?%#"]
invalid.each do |v|
c.chars = v
assert_not c.valid?, "'#{v}' should not be valid"
end
end
end