email_validator 1.6.0 → 2.2.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 3a61b5f5394d7e3995cb72b8020ed8877539658f
4
- data.tar.gz: e1781250b91b5b62faf766b6120c0e91ae2cbd0e
2
+ SHA256:
3
+ metadata.gz: c6952edf85fc0eafbe159b4a3b812731c81361ee0a15f22927e270a3eb885c9d
4
+ data.tar.gz: 8b5a56e059f652f1822c93cbcec0be9da23842433e9c7e5f97478496ba888ff9
5
5
  SHA512:
6
- metadata.gz: 7c0d25c20be026d62ef9bda3a775efe42e21f87be95323f3fbd5be16df2ed761d31066c0d54a3578ef1b7f22562e09df80152de910dd6a6517de936efce70279
7
- data.tar.gz: 2c6bd876e48aa9f27ac6d2ce53942961b52207cfe508d80dad93cd9df2ed0b0d1bc346ca3fc1ff8c218463b499b7d2fa5630af5374c3df013aec9cce183d93b7
6
+ metadata.gz: 158307d4196989b8d73872fa91c302ee9eab174b25f0686f3d61fe395796fa0b8e6c1c08185a4accf6c9581e23ba66bbebb8e3e8dc46b7ded935ed80a2484b53
7
+ data.tar.gz: 7f9ccf405a9bcf08d809fa58819d9e6d8489871a52020115802f3c755eddc3962b3533928f8f7c40e8122b055ad185c6f72cf1878ad6c920ba1b86872c0362a8
data/CHANGELOG.md ADDED
@@ -0,0 +1,131 @@
1
+ # CHANGELOG
2
+
3
+ This file is used to list changes made in `email_validator`.
4
+
5
+ All notable changes to this project will be documented in this file.
6
+ This project adheres to [Semantic Versioning](http://semver.org/).
7
+
8
+ ## 2.2.4 (2022-11-09)
9
+
10
+ * [karlwilbur] - Remove Ruby 2.4 from tested versions; add Ruby 3.0 and 3.1 to tested versions
11
+ * [karlwilbur] - Fix issue where `domain: ''` wasn't requiring empty domain
12
+ * [karlwilbur] - Remove checks for double hyphens (fixes [#87](https://github.com/K-and-R/email_validator/issues/87))
13
+ * [dependabot] - Security updates
14
+ - [#89](https://github.com/K-and-R/email_validator/pull/89)
15
+ + Bump `minimist` from `1.2.5` to `1.2.7`
16
+ - [#86](https://github.com/K-and-R/email_validator/pull/86)
17
+ + Bump `node-fetch` from `2.6.1` to `2.6.7`
18
+ + Add `whatwg-url` at `5.0.0`
19
+ + Add `tr46` at `0.0.3`
20
+ + Add `webidl-conversions` at `3.0.0`
21
+ - [#80](https://github.com/K-and-R/email_validator/pull/80)
22
+ + Bump `tar` from `6.0.5` to `6.1.11`
23
+ + Bump `minipass` from `3.1.3` to `3.1.5`
24
+ - [#79](https://github.com/K-and-R/email_validator/pull/79)
25
+ + Bump `path-parse` from `1.0.6` to `1.0.7`
26
+ - [#76](https://github.com/K-and-R/email_validator/pull/76)
27
+ + Bump `lodash` from `4.17.20` to `4.17.21`
28
+ - [#75](https://github.com/K-and-R/email_validator/pull/75)
29
+ + Bump `hosted-git-info` from `2.8.8` to `2.8.9`
30
+ * [msands] - Fix URL in `README.md` [#81](https://github.com/K-and-R/email_validator/pull/81)
31
+ * [kerolloz] - Fix typo in `README.md` [#73](https://github.com/K-and-R/email_validator/pull/73)
32
+
33
+ ## 2.2.3 (2021-04-05)
34
+
35
+ * [karlwilbur] - Fix regexp for numeric domains (fixes [#72](https://github.com/K-and-R/email_validator/issues/72))
36
+ - [delphaber] - Add checks for numeric-only domains in tests (should be considered valid)
37
+ - [karlwilbur] - Fix specs for numeric-only domains labels (should be considered valid)
38
+ - [karlwilbur] - Add checks for numeric-only TLDs in tests (should be considered invalid)
39
+ - [karlwilbur] - Add tests to ensure that `regexp` returns expected value
40
+ * [karlwilbur] - Add checks for double dash in domain (should be considered invalid)
41
+ * [karlwilbur] - Add `EmailValidator::Error` class, raise `EmailValidator::Error` when invalid `mode`
42
+
43
+ ## 2.2.2 (2020-12-10)
44
+
45
+ * [karlwilbur] - Fix includes for `:rfc` and `:strict` modes from `Gemfile`
46
+
47
+ ## 2.2.1 (2020-12-10)
48
+
49
+ * [karlwilbur] - Modify regexp to:
50
+ - allow numeric-only hosts [#68]
51
+ - allow mailbox-only addresses in `:rfc` mode
52
+ - enforce the 255-char domain limit (not in `:loose` mode unless using `:domain`)
53
+
54
+ ## 2.2.0 (2020-12-09)
55
+
56
+ * [karlwilbur] - Rename `:strict` -> `:rfc`; `:moderate` -> `:strict`
57
+
58
+ ## 2.1.0 (2020-12-09)
59
+
60
+ * [karlwilbur] - Add linters and commit hooks to validate code prior to commits
61
+ * [karlwilbur] - Add `:mode` config option; values `:loose`, `:moderate`, `:strict`; default to `:loose`
62
+ * [karlwilbur] - Merge in changes from <https://github.com/karlwilbur/email_validator> fork
63
+
64
+ ## 1.9.0.pre (2020-10-14)
65
+
66
+ * [karlwilbur] - Add `require_fqdn` option, require FQDN by default
67
+ * [karlwilbur] - Add support for IPv4 and IPv6 address hosts
68
+ * [karlwilbur] - Add Rubocop, `.editorconfig`; code cleanup/linting
69
+
70
+ ## 1.8.0 (2019-06-14)
71
+
72
+ * [karlwilbur] - Refactor class methods for readability
73
+ * [karlwilbur] - `gemspec` meta updates
74
+ * [karlwilbur] - Use POSIX classes for better performance
75
+ * [karlwilbur] - Refactored tests to check specical characters one at a time
76
+ * [karlwilbur] - Refactored validation regex to be more techincally correct
77
+ * [karlwilbur] - Add this `CHANGELOG`
78
+
79
+ ## 1.7.0 (2019-04-20)
80
+
81
+ * [karlwilbur] - Added test coverage badge to README
82
+ * [karlwilbur] - Added I18n directive to remove warning message in testing
83
+ * [karlwilbur] - Added RFC-2822 reference
84
+ * [karlwilbur] - Ignore local rspec config file
85
+ * [karlwilbur] - Check for invalid double dots in strict mode
86
+ * [karlwilbur] - Updated spec_helper to remove Code Climate Test Reporter; it is to be run separately now
87
+ * [karlwilbur] - Allow leading/trailing whitespace in normal, not strict
88
+ * [karlwilbur] - Added `invalid?` as inverse of `valid?`
89
+ * [karlwilbur] - Add the ability to limit to a domain
90
+ * [karlwilbur] - Removed CodeShip badge
91
+ * [karlwilbur] - Make the dot in the domain part non-conditional
92
+ * [karlwilbur] - Fix domain label pattern to allow numbers per rfc5321
93
+
94
+ ## 1.6.0 (2015-06-14)
95
+
96
+ * [karlwilbur] - Fixed validation to be closer to RFC-5321
97
+ * [karlwilbur] - Updated specs to use Rspec 3 syntax
98
+ * [karlwilbur] - Added unicode suport to validation regexp
99
+ * [karlwilbur] - Added class access to regexp, and `valid?` calss method
100
+ * [karlwilbur] - Simplified code using new methods
101
+ * [karlwilbur] - Added CodeClimate and SimpleCov
102
+ * [karlwilbur] - Updated version and contact info
103
+
104
+ *** Forked from <https://github.com/balexand/email_validator>
105
+
106
+ ## 2.0.1 (2019-03-09)
107
+
108
+ * Add email value to error details [f1sherman #50]
109
+ * CI doesn't test Ruby versions that no longer receive updates [f1sherman #51]
110
+
111
+ ## 2.0.0 (2019-03-02)
112
+
113
+ * Looser validation [#49]
114
+
115
+ ## 1.6.0 (2015-05-12)
116
+
117
+ * Unicode characters support [i7an #24]
118
+
119
+ ## 1.5.0 (2014-12-08)
120
+
121
+ * Add a class method for simpler validation [TiteiKo and cluesque #19]
122
+ * RSpec 3.0 syntax [strivedi183 #17]
123
+ * Create Changes.md
124
+
125
+ ---
126
+
127
+ Check the [Markdown Syntax Guide](http://daringfireball.net/projects/markdown/syntax)
128
+ for help with Markdown.
129
+
130
+ The [Github Flavored Markdown page](http://github.github.com/github-flavored-markdown/)
131
+ describes the differences between markdown on github and standard markdown.
data/README.md CHANGED
@@ -1,6 +1,29 @@
1
- [![Build Status](https://secure.travis-ci.org/balexand/email_validator.png)](http://travis-ci.org/balexand/email_validator)
1
+ # EmailValidator
2
2
 
3
- ## Usage
3
+ [![Build Status](https://travis-ci.com/K-and-R/email_validator.svg?branch=master)](http://travis-ci.com/K-and-R/email_validator)
4
+ [![Code Climate](https://codeclimate.com/github/K-and-R/email_validator/badges/gpa.svg)](https://codeclimate.com/github/K-and-R/email_validator)
5
+ [![Test Coverage](https://codeclimate.com/github/K-and-R/email_validator/badges/coverage.svg)](https://codeclimate.com/github/K-and-R/email_validator/coverage)
6
+
7
+ An email validator for Rails 3+.
8
+
9
+ Supports RFC-2822-compliant and RFC-5321-compliant email validation using RFC-3696 validation.
10
+
11
+ Formerly found at: <https://github.com/balexand/email_validator>
12
+
13
+ ## Validation philosophy
14
+
15
+ The default validation provided by this gem (the `:loose` configuration option)
16
+ is extremely loose. It just checks that there's an `@` with something before and
17
+ after it without any whitespace. See [this article by David Gilbertson](https://medium.com/hackernoon/the-100-correct-way-to-validate-email-addresses-7c4818f24643)
18
+ for an explanation of why.
19
+
20
+ We understand that many use cases require an increased level of validation. This
21
+ is supported by using the `:strict` validation mode. Additionally, the `:rfc`
22
+ RFC-compliant mode will consider technically valid emails address as valid which
23
+ may not be wanted, such as the valid `user` or `user@somehost` addresses. These
24
+ would be valid in `:rfc` mode but not valid in `:loose` or `:strict`.
25
+
26
+ ## Installation
4
27
 
5
28
  Add to your Gemfile:
6
29
 
@@ -10,54 +33,185 @@ gem 'email_validator'
10
33
 
11
34
  Run:
12
35
 
13
- ```
36
+ ```bash
14
37
  bundle install
15
38
  ```
16
39
 
17
- Then add the following to your model:
40
+ ## Usage
41
+
42
+ Add the following to your model:
18
43
 
19
44
  ```ruby
20
- validates :my_email_attribute, :email => true
45
+ validates :my_email_attribute, email: true
21
46
  ```
22
47
 
23
- ## Strict mode
48
+ You may wish to allow domains without a FQDN, like `user@somehost`. While this
49
+ is technically a valid address, it is uncommon to consider such address valid.
50
+ We will consider them valid by default with the `:loose` checking. Disallowed
51
+ by setting `require_fqdn: true` or by enabling `:strict` checking:
52
+
53
+ ```ruby
54
+ validates :my_email_attribute, email: {mode: :strict, require_fqdn: true}
55
+ ```
24
56
 
25
- In order to have stricter validation (according to http://www.remote.org/jochen/mail/info/chars.html) enable strict mode. You can do this globally by adding the following to your Gemfile:
57
+ You can also limit to a single domain (e.g: you have separate `User` and
58
+ `AdminUser` models and want to ensure that `AdminUser` emails are on a specific
59
+ domain):
26
60
 
27
61
  ```ruby
28
- gem 'email_validator', :require => 'email_validator/strict'
62
+ validates :my_email_attribute, email: {domain: 'example.com'}
29
63
  ```
30
64
 
31
- Or you can do this in a specific `validates` call:
65
+ ## Configuration
66
+
67
+ Default configuration can be overridden by setting options in `config/initializers/email_validator.rb`:
32
68
 
33
69
  ```ruby
34
- validates :my_email_attribute, :email => {:strict_mode => true}
70
+ if defined?(EmailValidator)
71
+ # To completely override the defaults
72
+ EmailValidator.default_options = {
73
+ allow_nil: false,
74
+ domain: nil,
75
+ require_fqdn: nil,
76
+ mode: :loose
77
+ }
78
+
79
+ # or just a few options
80
+ EmailValidator.default_options.merge!({ domain: 'mydomain.com' })
81
+ end
35
82
  ```
36
83
 
84
+ ### Loose mode
85
+
86
+ This it the default validation mode of this gem. It is intentionally extremely
87
+ loose (see the [Validation Philosophy section](#validation_philosophy) above. It
88
+ just checks that there's an `@` with something before and after it without any
89
+ whitespace.
90
+
91
+ ### Strict mode
92
+
93
+ Enabling `:strict` checking will check for a "normal" email format that would
94
+ be expected in most common everyday usage. Strict mode basically checks for a
95
+ properly sized and formatted mailbox label, a single "@" symbol, and a properly
96
+ sized and formatted FQDN. Enabling `:strict` mode will also enable `:require_fqdn`
97
+ configuration option.
98
+
99
+ Strict mode can be enabled globally by requiring `email_validator/strict` in
100
+ your `Gemfile`, by setting the option in `config/initializers/email_validator.rb`,
101
+ or by specifying the option in a specific `validates` call.
102
+
103
+ * `Gemfile`:
104
+
105
+ ```ruby
106
+ gem 'email_validator', require: 'email_validator/strict'
107
+ ```
108
+
109
+ * `config/initializers/email_validator.rb`:
110
+
111
+ ```ruby
112
+ if defined?(EmailValidator)
113
+ EmailValidator.default_options[:mode] = :strict
114
+ end
115
+ ```
116
+
117
+ * `validates` call:
118
+
119
+ ```ruby
120
+ validates :my_email_attribute, email: {mode: :strict}
121
+ ```
122
+
123
+ ### RFC mode
124
+
125
+ In order to have RFC-compliant validation (according to [http://www.remote.org/jochen/mail/info/chars.html](https://web.archive.org/web/20150508102948/http://www.remote.org/jochen/mail/info/chars.html)),
126
+ enable `:rfc` mode.
127
+
128
+ You can do this globally by requiring `email_validator/rfc` in your `Gemfile`,
129
+ by setting the options in `config/initializers/email_validator.rb`, or you can do
130
+ this in a specific `validates` call.
131
+
132
+ * `Gemfile`:
133
+
134
+ ```ruby
135
+ gem 'email_validator', require: 'email_validator/rfc'
136
+ ```
137
+
138
+ * `config/initializers/email_validator.rb`:
139
+
140
+ ```ruby
141
+ if defined?(EmailValidator)
142
+ EmailValidator.default_options[:mode] = :rfc
143
+ end
144
+ ```
145
+
146
+ * `validates` call:
147
+
148
+ ```ruby
149
+ validates :my_email_attribute, email: {mode: :rfc}
150
+ ```
151
+
37
152
  ## Validation outside a model
38
153
 
39
- If you need to validate an email outside a model, you can get the regexp :
154
+ If you need to validate an email outside a model, you can get the regexp:
40
155
 
41
- ### Normal mode
156
+ ### Loose/default mode
42
157
 
43
158
  ```ruby
44
- EmailValidator.regexp # returns the regex
45
159
  EmailValidator.valid?('narf@example.com') # boolean
46
160
  ```
47
161
 
162
+ ### Requiring a FQDN
163
+
164
+ ```ruby
165
+ EmailValidator.valid?('narf@somehost') # boolean false
166
+ EmailValidator.invalid?('narf@somehost', require_fqdn: false) # boolean true
167
+ ```
168
+
169
+ _NB: Enabling strict mode (`mode: :strict`) enables `require_fqdn`
170
+ (`require_fqdn: true`), overridding any `require_fqdn: false` while
171
+ `mode: :strict` is set._
172
+
173
+ ### Requiring a specific domain
174
+
175
+ ```ruby
176
+ EmailValidator.valid?('narf@example.com', domain: 'foo.com') # boolean false
177
+ EmailValidator.invalid?('narf@example.com', domain: 'foo.com') # boolean true
178
+ ```
179
+
48
180
  ### Strict mode
49
181
 
50
182
  ```ruby
51
- EmailValidator.regexp(:strict_mode => true)
183
+ EmailValidator.regexp(mode: :strict) # returns the regex
184
+ EmailValidator.valid?('narf@example.com', mode: :strict) # boolean
185
+ ```
186
+
187
+ ### RFC mode
188
+
189
+ ```ruby
190
+ EmailValidator.regexp(mode: :rfc) # returns the regex
191
+ EmailValidator.valid?('narf@example.com', mode: :rfc) # boolean
52
192
  ```
53
193
 
54
194
  ## Thread safety
55
195
 
56
- This gem is thread safe, with one caveat: `EmailValidator.default_options` must be configured before use in a multi-threaded environment. If you configure `default_options` in a Rails initializer file, then you're good to go since initializers are run before worker threads are spawned.
196
+ This gem is thread safe, with one caveat: `EmailValidator.default_options` must
197
+ be configured before use in a multi-threaded environment. If you configure
198
+ `default_options` in a Rails initializer file, then you're good to go since
199
+ initializers are run before worker threads are spawned.
200
+
201
+ ## Alternative gems
202
+
203
+ Do you prefer a different email validation gem? If so, open an issue with a brief
204
+ explanation of how it differs from this gem. I'll add a link to it in this README.
205
+
206
+ * [`email_address`](https://github.com/afair/email_address) (<https://github.com/K-and-R/email_validator/issues/58>)
207
+ * [`email_verifier`](https://github.com/kamilc/email_verifier) (<https://github.com/K-and-R/email_validator/issues/65>)
57
208
 
58
- ## Credit
209
+ ## Maintainers
59
210
 
60
- Based on http://thelucid.com/2010/01/08/sexy-validation-in-edge-rails-rails-3
211
+ All thanks is given to [Brian Alexander (balexand)](https://github.com/balexand)
212
+ for is initial work on this gem.
61
213
 
62
- Regular Expression based on http://fightingforalostcause.net/misc/2006/compare-email-regex.php tests.
214
+ Currently maintained by:
63
215
 
216
+ * Karl Wilbur (<https://github.com/karlwilbur>)
217
+ * K&R Software (<https://github.com/K-and-R>)
@@ -0,0 +1,4 @@
1
+ # require this file to enable `:rfc` mode by default
2
+
3
+ require 'email_validator'
4
+ EmailValidator.default_options[:mode] = :rfc
@@ -1,5 +1,4 @@
1
- # require this file to enable :strict_mode by default
1
+ # require this file to enable `:strict` mode by default
2
2
 
3
3
  require 'email_validator'
4
-
5
- EmailValidator::default_options[:strict_mode] = true
4
+ EmailValidator.default_options[:mode] = :strict
@@ -1,29 +1,165 @@
1
- # encoding: UTF-8
2
1
  # Based on work from http://thelucid.com/2010/01/08/sexy-validation-in-edge-rails-rails-3/
2
+
3
+ # EmailValidator class
3
4
  class EmailValidator < ActiveModel::EachValidator
4
- @@default_options = {}
5
+ # rubocop:disable Style/ClassVars
6
+ @@default_options = {
7
+ :allow_nil => false,
8
+ :domain => nil,
9
+ :require_fqdn => nil,
10
+ :mode => :loose
11
+ }
12
+ # rubocop:enable Style/ClassVars
5
13
 
6
- def self.regexp(options = {})
7
- options = default_options.merge(options)
14
+ # EmailValidator::Error class
15
+ class Error < StandardError
16
+ def initialize(msg = 'EmailValidator error')
17
+ super
18
+ end
19
+ end
8
20
 
9
- name_validation = options[:strict_mode] ? "-\\p{L}\\d+._" : "^@\\s"
21
+ class << self
22
+ def default_options
23
+ @@default_options
24
+ end
10
25
 
11
- /\A\s*([#{name_validation}]{1,64})@((?:[-\p{L}\d]+\.)+\p{L}{2,})\s*\z/i
12
- end
26
+ def valid?(value, options = {})
27
+ options = parse_options(options)
28
+ return true if value.nil? && options[:allow_nil] == true
29
+ return false if value.nil?
30
+ # quickly fail if domain is required but doesn't match
31
+ return false unless options[:domain].nil? || value[/^.*@#{regexp_safe_domain(options)}$/]
32
+ !!(value =~ regexp(options))
33
+ end
13
34
 
14
- def self.valid?(value, options = {})
15
- !!(value =~ regexp(options))
16
- end
35
+ def invalid?(value, options = {})
36
+ !valid?(value, options)
37
+ end
38
+
39
+ # Refs:
40
+ # https://tools.ietf.org/html/rfc2822 : 3.2. Lexical Tokens, 3.4.1. Addr-spec specification
41
+ # https://tools.ietf.org/html/rfc5321 : 4.1.2. Command Argument Syntax
42
+ def regexp(options = {})
43
+ options = parse_options(options)
44
+ case options[:mode]
45
+ when :loose
46
+ loose_regexp(options)
47
+ when :rfc
48
+ rfc_regexp(options)
49
+ when :strict
50
+ options[:require_fqdn] = true
51
+ strict_regexp(options)
52
+ else
53
+ fail EmailValidator::Error, "Validation mode '#{options[:mode]}' is not supported by EmailValidator"
54
+ end
55
+ end
56
+
57
+ protected
58
+
59
+ def loose_regexp(options = {})
60
+ return /\A[^\s]+@[^\s]+\z/ if options[:domain].nil?
61
+ /\A[^\s]+@#{domain_part_pattern(options)}\z/
62
+ end
63
+
64
+ def strict_regexp(options = {})
65
+ /\A(?>#{local_part_pattern})@#{domain_part_pattern(options)}\z/i
66
+ end
67
+
68
+ def rfc_regexp(options = {})
69
+ /\A(?>#{local_part_pattern})(?:@#{domain_part_pattern(options)})?\z/i
70
+ end
71
+
72
+ def alpha
73
+ '[[:alpha:]]'
74
+ end
75
+
76
+ def alnum
77
+ '[[:alnum:]]'
78
+ end
79
+
80
+ def alnumhy
81
+ "(?:#{alnum}|-)"
82
+ end
83
+
84
+ def ipv4
85
+ '\d{1,3}(?:\.\d{1,3}){3}'
86
+ end
87
+
88
+ def ipv6
89
+ # only supporting full IPv6 addresses right now
90
+ 'IPv6:[[:xdigit:]]{1,4}(?::[[:xdigit:]]{1,4}){7}'
91
+ end
17
92
 
18
- def self.default_options
19
- @@default_options
93
+ def address_literal
94
+ "\\[(?:#{ipv4}|#{ipv6})\\]"
95
+ end
96
+
97
+ def host_label_pattern
98
+ "#{label_is_correct_length}" \
99
+ "#{alnum}(?:#{alnumhy}{,61}#{alnum})?"
100
+ end
101
+
102
+ # splitting this up into separate regex pattern for performance; let's not
103
+ # try the "contains" pattern unless we have to
104
+ def domain_label_pattern
105
+ "#{host_label_pattern}\\.#{tld_label_pattern}"
106
+ end
107
+
108
+ # While, techincally, TLDs can be numeric-only, this is not allowed by ICANN
109
+ # Ref: ICANN Application Guidebook for new TLDs (June 2012)
110
+ # says the following starting at page 64:
111
+ #
112
+ # > The ASCII label must consist entirely of letters (alphabetic characters a-z)
113
+ #
114
+ # -- https://newgtlds.icann.org/en/applicants/agb/guidebook-full-04jun12-en.pdf
115
+ def tld_label_pattern
116
+ "#{alpha}{1,64}"
117
+ end
118
+
119
+ def label_is_correct_length
120
+ '(?=[^.]{1,63}(?:\.|$))'
121
+ end
122
+
123
+ def domain_part_is_correct_length
124
+ '(?=.{1,255}$)'
125
+ end
126
+
127
+ def atom_char
128
+ # The `atext` spec
129
+ # We are looking at this without whitespace; no whitespace support here
130
+ "[-#{alpha}#{alnum}+_!\"'#$%^&*{}/=?`|~]"
131
+ end
132
+
133
+ def local_part_pattern
134
+ # the `dot-atom-text` spec, but with a 64 character limit
135
+ "#{atom_char}(?:\\.?#{atom_char}){,63}"
136
+ end
137
+
138
+ def domain_part_pattern(options)
139
+ return regexp_safe_domain(options) unless options[:domain].nil?
140
+ return fqdn_pattern if options[:require_fqdn]
141
+ "#{domain_part_is_correct_length}(?:#{address_literal}|(?:#{host_label_pattern}\\.)*#{tld_label_pattern})"
142
+ end
143
+
144
+ def fqdn_pattern
145
+ "(?=.{1,255}$)(?:#{host_label_pattern}\\.)*#{domain_label_pattern}"
146
+ end
147
+
148
+ private
149
+
150
+ def parse_options(options)
151
+ # `:strict` mode enables `:require_fqdn`, unless it is already explicitly disabled
152
+ options[:require_fqdn] = true if options[:require_fqdn].nil? && options[:mode] == :strict
153
+ default_options.merge(options)
154
+ end
155
+
156
+ def regexp_safe_domain(options)
157
+ options[:domain].sub(/\./, '\.')
158
+ end
20
159
  end
21
160
 
22
161
  def validate_each(record, attribute, value)
23
162
  options = @@default_options.merge(self.options)
24
-
25
- unless self.class.valid?(value, self.options)
26
- record.errors.add(attribute, options[:message] || :invalid)
27
- end
163
+ record.errors.add(attribute, options[:message] || :invalid) unless self.class.valid?(value, options)
28
164
  end
29
165
  end