activevalidators 2.0.0 → 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/activevalidators.gemspec +1 -1
- data/lib/active_model/validations/postal_code_validator.rb +1 -1
- data/lib/active_model/validations/tracking_number_validator.rb +4 -4
- data/lib/active_model/validations/twitter_validator.rb +18 -5
- data/lib/active_model/validations/url_validator.rb +1 -1
- data/test/validations/postal_code_test.rb +6 -0
- data/test/validations/tracking_number_test.rb +8 -0
- data/test/validations/twitter_test.rb +21 -0
- data/test/validations/url_test.rb +7 -0
- metadata +18 -18
data/activevalidators.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
Gem::Specification.new do |s|
|
3
3
|
s.name = 'activevalidators'
|
4
|
-
s.version = '2.0.
|
4
|
+
s.version = '2.0.1'
|
5
5
|
s.platform = Gem::Platform::RUBY
|
6
6
|
s.authors = ['Franck Verrot', 'Paco Guzmán', 'Oriol Gual', 'Garrett Bjerkhoel', 'Renato Riccieri Santos Zannon', 'Brian Moseley']
|
7
7
|
s.email = ['franck@verrot.fr']
|
@@ -84,7 +84,7 @@ module ActiveModel
|
|
84
84
|
private
|
85
85
|
|
86
86
|
def self.regexp_from(format)
|
87
|
-
Regexp.new
|
87
|
+
Regexp.new '\A' + (Regexp.escape format).gsub(/[@#]/, '@' => '[[:alpha:]]', '#' => 'd') + '\z'
|
88
88
|
end
|
89
89
|
end
|
90
90
|
end
|
@@ -6,13 +6,13 @@ module ActiveModel
|
|
6
6
|
raise "Carrier option required" unless carrier
|
7
7
|
method = "valid_#{carrier.to_s}?"
|
8
8
|
raise "Tracking number validation not supported for carrier #{carrier}" unless self.respond_to?(method)
|
9
|
-
record.errors.add(attribute) if value.blank? || !self.send(method, value)
|
9
|
+
record.errors.add(attribute) if value.blank? || !self.send(method, value)
|
10
10
|
end
|
11
11
|
|
12
12
|
# UPS:
|
13
13
|
# ups tracking codes are validated solely on their format
|
14
14
|
# see https://www.ups.com/content/us/en/tracking/help/tracking/tnh.html
|
15
|
-
UPS_REGEXES = [
|
15
|
+
UPS_REGEXES = [ /\A1Z[a-zA-Z0-9]{16}\z/, /\A[a-zA-Z0-9]{12}\z/, /\A[a-zA-Z0-9]{9}\z/, /\AT[a-zA-Z0-9]{10}\z/ ]
|
16
16
|
def valid_ups?(value)
|
17
17
|
!!UPS_REGEXES.detect { |fmt| value.match(fmt) }
|
18
18
|
end
|
@@ -28,13 +28,13 @@ module ActiveModel
|
|
28
28
|
uss228?(value) || uss39?(value)
|
29
29
|
end
|
30
30
|
|
31
|
-
USS128_REGEX =
|
31
|
+
USS128_REGEX = /\A(\d{19,21})(\d)\z/
|
32
32
|
def uss228?(value)
|
33
33
|
m = value.match(USS128_REGEX)
|
34
34
|
m.present? && (m[2].to_i == usps_mod10(m[1]))
|
35
35
|
end
|
36
36
|
|
37
|
-
USS39_REGEX =
|
37
|
+
USS39_REGEX = /\A[a-zA-Z0-9]{2}(\d{8})(\d)US\z/
|
38
38
|
def uss39?(value)
|
39
39
|
m = value.match(USS39_REGEX)
|
40
40
|
# it appears to be valid for a USS39 barcode's checkdigit to be calculated with either the usps mod 10
|
@@ -2,18 +2,31 @@ module ActiveModel
|
|
2
2
|
module Validations
|
3
3
|
|
4
4
|
class TwitterValidator < EachValidator
|
5
|
+
|
6
|
+
# Basic username regexp
|
7
|
+
TWITTER_USERNAME_REGEXP = /([A-Za-z0-9_]{1,15})/i
|
8
|
+
|
9
|
+
# Regexp used to detect twitter username within the URL.
|
10
|
+
TWITTER_URL_REGEXP = %r{\Ahttps?://(?:www\.)?twitter.com/#{TWITTER_USERNAME_REGEXP}\z}i
|
11
|
+
|
12
|
+
# Regexp to test using twitter username as @sign.
|
13
|
+
TWITTER_ATSIGN_REGEXP = /\A@#{TWITTER_USERNAME_REGEXP}\z/i
|
14
|
+
|
15
|
+
# Regexp to test against usernames without the @sign
|
16
|
+
TWITTER_NOATSIGN_REGEXP = /\A#{TWITTER_USERNAME_REGEXP}\z/i
|
17
|
+
|
5
18
|
def validate_each(record, attribute, value)
|
6
19
|
format = options[:format].to_sym if options[:format]
|
7
|
-
|
20
|
+
|
8
21
|
if value.nil?
|
9
22
|
record.errors.add_on_blank(attribute)
|
10
23
|
elsif format == :url
|
11
|
-
match = value.match(
|
12
|
-
record.errors.add(attribute) unless match && !match[
|
24
|
+
match = value.match(TWITTER_URL_REGEXP)
|
25
|
+
record.errors.add(attribute) unless match && !match[1].nil?
|
13
26
|
elsif format == :username_with_at
|
14
|
-
record.errors.add(attribute) unless value
|
27
|
+
record.errors.add(attribute) unless value =~ TWITTER_ATSIGN_REGEXP
|
15
28
|
else
|
16
|
-
record.errors.add(attribute) unless value
|
29
|
+
record.errors.add(attribute) unless value =~ TWITTER_NOATSIGN_REGEXP
|
17
30
|
end
|
18
31
|
end
|
19
32
|
end
|
@@ -49,5 +49,11 @@ describe "Postal Code Validation" do
|
|
49
49
|
subject.valid?.must_equal false
|
50
50
|
subject.errors[:postal_code].include?(subject.errors.generate_message(:postal_code, :invalid)).must_equal true
|
51
51
|
end
|
52
|
+
|
53
|
+
it "rejects injected content" do
|
54
|
+
subject = build_postal_code_record true, :postal_code => "injected\n11211"
|
55
|
+
subject.valid?.must_equal false
|
56
|
+
subject.errors.size.must_equal 1
|
57
|
+
end
|
52
58
|
end
|
53
59
|
end
|
@@ -51,6 +51,10 @@ describe "Tracking Number Validation" do
|
|
51
51
|
it "rejects invalid formats and generates an error message of type invalid" do
|
52
52
|
assert_invalid_tracking_number({:carrier => :ups}, '1Z12345E020_271688')
|
53
53
|
end
|
54
|
+
|
55
|
+
it "rejects injected content" do
|
56
|
+
assert_invalid_tracking_number({:carrier => :ups}, "injected\n1Z12345E0205271688")
|
57
|
+
end
|
54
58
|
end
|
55
59
|
end
|
56
60
|
|
@@ -109,6 +113,10 @@ describe "Tracking Number Validation" do
|
|
109
113
|
it 'USS128 tracking number with invalid chars' do
|
110
114
|
assert_invalid_tracking_number({:carrier => :usps}, 'U11234567891234567879')
|
111
115
|
end
|
116
|
+
|
117
|
+
it 'rejects injected chars in USS39 and others' do
|
118
|
+
assert_invalid_tracking_number({:carrier => :usps}, "injected\nEA123456784US")
|
119
|
+
end
|
112
120
|
end
|
113
121
|
end
|
114
122
|
|
@@ -80,6 +80,13 @@ describe "Twitter Validation" do
|
|
80
80
|
subject.valid?.must_equal false
|
81
81
|
subject.errors.size.must_equal 1
|
82
82
|
end
|
83
|
+
|
84
|
+
it "generates error with injected content" do
|
85
|
+
subject = build_twitter_record :format => :url
|
86
|
+
subject.twitter_username = "javascript:alert('xss');\nhttp://twitter.com/garrettbjerkhoelwashere"
|
87
|
+
subject.valid?.must_equal false
|
88
|
+
subject.errors.size.must_equal 1
|
89
|
+
end
|
83
90
|
end
|
84
91
|
|
85
92
|
describe "for twitter at sign validator" do
|
@@ -115,6 +122,13 @@ describe "Twitter Validation" do
|
|
115
122
|
subject.valid?.must_equal false
|
116
123
|
subject.errors.size.must_equal 1
|
117
124
|
end
|
125
|
+
|
126
|
+
it "generate error with injected content" do
|
127
|
+
subject = build_twitter_record :format => :username_with_at
|
128
|
+
subject.twitter_username = "injected\n@erik"
|
129
|
+
subject.valid?.must_equal false
|
130
|
+
subject.errors.size.must_equal 1
|
131
|
+
end
|
118
132
|
end
|
119
133
|
|
120
134
|
describe "for twitter without at sign validator" do
|
@@ -157,5 +171,12 @@ describe "Twitter Validation" do
|
|
157
171
|
subject.valid?.must_equal false
|
158
172
|
subject.errors.size.must_equal 1
|
159
173
|
end
|
174
|
+
|
175
|
+
it "generate error with at injected data" do
|
176
|
+
subject = build_twitter_record true
|
177
|
+
subject.twitter_username = "something\ngarrettb\nelse"
|
178
|
+
subject.valid?.must_equal false
|
179
|
+
subject.errors.size.must_equal 1
|
180
|
+
end
|
160
181
|
end
|
161
182
|
end
|
@@ -58,6 +58,13 @@ describe "Url Validation" do
|
|
58
58
|
subject.errors.size.must_equal 1
|
59
59
|
end
|
60
60
|
|
61
|
+
it "rejects injected urls" do
|
62
|
+
subject = build_url_record
|
63
|
+
subject.url = "javascript:alert('xss');\nhttp://google.com"
|
64
|
+
subject.valid?.must_equal false
|
65
|
+
subject.errors.size.must_equal 1
|
66
|
+
end
|
67
|
+
|
61
68
|
it "generates an error message of type invalid" do
|
62
69
|
subject = build_url_record
|
63
70
|
subject.url = 'http://^^^^.fr'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activevalidators
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -14,11 +14,11 @@ authors:
|
|
14
14
|
autorequire:
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
|
-
date: 2012-
|
17
|
+
date: 2012-09-15 00:00:00.000000000 Z
|
18
18
|
dependencies:
|
19
19
|
- !ruby/object:Gem::Dependency
|
20
20
|
name: bundler
|
21
|
-
requirement: &
|
21
|
+
requirement: &70131187685580 !ruby/object:Gem::Requirement
|
22
22
|
none: false
|
23
23
|
requirements:
|
24
24
|
- - ! '>='
|
@@ -26,10 +26,10 @@ dependencies:
|
|
26
26
|
version: '0'
|
27
27
|
type: :development
|
28
28
|
prerelease: false
|
29
|
-
version_requirements: *
|
29
|
+
version_requirements: *70131187685580
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
31
|
name: minitest
|
32
|
-
requirement: &
|
32
|
+
requirement: &70131187684280 !ruby/object:Gem::Requirement
|
33
33
|
none: false
|
34
34
|
requirements:
|
35
35
|
- - ! '>='
|
@@ -37,10 +37,10 @@ dependencies:
|
|
37
37
|
version: '0'
|
38
38
|
type: :development
|
39
39
|
prerelease: false
|
40
|
-
version_requirements: *
|
40
|
+
version_requirements: *70131187684280
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rake
|
43
|
-
requirement: &
|
43
|
+
requirement: &70131187683500 !ruby/object:Gem::Requirement
|
44
44
|
none: false
|
45
45
|
requirements:
|
46
46
|
- - ! '>='
|
@@ -48,10 +48,10 @@ dependencies:
|
|
48
48
|
version: 0.8.7
|
49
49
|
type: :runtime
|
50
50
|
prerelease: false
|
51
|
-
version_requirements: *
|
51
|
+
version_requirements: *70131187683500
|
52
52
|
- !ruby/object:Gem::Dependency
|
53
53
|
name: activemodel
|
54
|
-
requirement: &
|
54
|
+
requirement: &70131187682840 !ruby/object:Gem::Requirement
|
55
55
|
none: false
|
56
56
|
requirements:
|
57
57
|
- - ! '>='
|
@@ -59,10 +59,10 @@ dependencies:
|
|
59
59
|
version: 3.0.0
|
60
60
|
type: :runtime
|
61
61
|
prerelease: false
|
62
|
-
version_requirements: *
|
62
|
+
version_requirements: *70131187682840
|
63
63
|
- !ruby/object:Gem::Dependency
|
64
64
|
name: phony
|
65
|
-
requirement: &
|
65
|
+
requirement: &70131187682280 !ruby/object:Gem::Requirement
|
66
66
|
none: false
|
67
67
|
requirements:
|
68
68
|
- - ~>
|
@@ -70,10 +70,10 @@ dependencies:
|
|
70
70
|
version: 1.7.4
|
71
71
|
type: :runtime
|
72
72
|
prerelease: false
|
73
|
-
version_requirements: *
|
73
|
+
version_requirements: *70131187682280
|
74
74
|
- !ruby/object:Gem::Dependency
|
75
75
|
name: countries
|
76
|
-
requirement: &
|
76
|
+
requirement: &70131187681620 !ruby/object:Gem::Requirement
|
77
77
|
none: false
|
78
78
|
requirements:
|
79
79
|
- - ~>
|
@@ -81,10 +81,10 @@ dependencies:
|
|
81
81
|
version: 0.8.2
|
82
82
|
type: :runtime
|
83
83
|
prerelease: false
|
84
|
-
version_requirements: *
|
84
|
+
version_requirements: *70131187681620
|
85
85
|
- !ruby/object:Gem::Dependency
|
86
86
|
name: mail
|
87
|
-
requirement: &
|
87
|
+
requirement: &70131187681060 !ruby/object:Gem::Requirement
|
88
88
|
none: false
|
89
89
|
requirements:
|
90
90
|
- - ! '>='
|
@@ -92,10 +92,10 @@ dependencies:
|
|
92
92
|
version: '0'
|
93
93
|
type: :runtime
|
94
94
|
prerelease: false
|
95
|
-
version_requirements: *
|
95
|
+
version_requirements: *70131187681060
|
96
96
|
- !ruby/object:Gem::Dependency
|
97
97
|
name: date_validator
|
98
|
-
requirement: &
|
98
|
+
requirement: &70131187680120 !ruby/object:Gem::Requirement
|
99
99
|
none: false
|
100
100
|
requirements:
|
101
101
|
- - ! '>='
|
@@ -103,7 +103,7 @@ dependencies:
|
|
103
103
|
version: '0'
|
104
104
|
type: :runtime
|
105
105
|
prerelease: false
|
106
|
-
version_requirements: *
|
106
|
+
version_requirements: *70131187680120
|
107
107
|
description: ActiveValidators is a collection of ActiveModel/ActiveRecord validations
|
108
108
|
email:
|
109
109
|
- franck@verrot.fr
|