email_validator 1.6.0 → 2.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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