email_address_validator 1.0.0 → 2.0.0

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
2
  SHA1:
3
- metadata.gz: 40a7903f966cc1c88ea370e25ef041484c4d1fa6
4
- data.tar.gz: d1f7aeafad963a543d4ad128e2a3b1108ea7cc67
3
+ metadata.gz: 2cc3e2b1d36178731391c09de74d8ee9c378f5f6
4
+ data.tar.gz: 30b987b6aed56e55292fea9240f272613d63fc8a
5
5
  SHA512:
6
- metadata.gz: 6f9aa6e4b76be4595fff9ee5c04776bdf7fc6f77bc32ebed9f11167059559252807877c2d32cd6e4f03f87ddcea78a755fa373fd35894f07a424a245ab9fc8c6
7
- data.tar.gz: b9092df595f541c160d68558f4f44b41fc48dfe92763a61bce501e5722a9faeb8df8ac31f2b226a5408306995e5de9787aefb750c1c90c73f37def73b846b0ba
6
+ metadata.gz: 8dd649a91a55f24208cffdfd3f681b80e8b31759c728b2ef8ca355a0a398697d70cd022de075ab61d346e0918255bd8071930ef2f5210dbc7110e63b53f8a162
7
+ data.tar.gz: 8620453673d42a5e172e4afe70af4c84f271780c875a8e1a6f61c71ebf5ef12511af9c74e915493294355df7eaec629fef9238bfe9fefe36a4b3be0e6140eae6
data/Gemfile CHANGED
@@ -2,5 +2,5 @@
2
2
  source "https://rubygems.org"
3
3
 
4
4
  gem "rake"
5
- gem "rspec"
5
+ gem "rspec", "~> 2.0"
6
6
  # gem "rails"
@@ -3,22 +3,18 @@ GEM
3
3
  specs:
4
4
  diff-lcs (1.2.5)
5
5
  rake (10.3.2)
6
- rspec (3.1.0)
7
- rspec-core (~> 3.1.0)
8
- rspec-expectations (~> 3.1.0)
9
- rspec-mocks (~> 3.1.0)
10
- rspec-core (3.1.7)
11
- rspec-support (~> 3.1.0)
12
- rspec-expectations (3.1.2)
13
- diff-lcs (>= 1.2.0, < 2.0)
14
- rspec-support (~> 3.1.0)
15
- rspec-mocks (3.1.3)
16
- rspec-support (~> 3.1.0)
17
- rspec-support (3.1.2)
6
+ rspec (2.99.0)
7
+ rspec-core (~> 2.99.0)
8
+ rspec-expectations (~> 2.99.0)
9
+ rspec-mocks (~> 2.99.0)
10
+ rspec-core (2.99.2)
11
+ rspec-expectations (2.99.2)
12
+ diff-lcs (>= 1.1.3, < 2.0)
13
+ rspec-mocks (2.99.3)
18
14
 
19
15
  PLATFORMS
20
16
  ruby
21
17
 
22
18
  DEPENDENCIES
23
19
  rake
24
- rspec
20
+ rspec (~> 2.0)
@@ -3,7 +3,7 @@
3
3
  %% { attr_accessor :validate_domain }
4
4
 
5
5
  d(num) = <.> &{ text[0] == num }
6
- d_btw(start,fin) = <.> &{ t = text[0]; t >= start && t <= fin }
6
+ d_btw(start,fin) = <.> &{ t = text[0].ord; t >= start && t <= fin }
7
7
 
8
8
  WSP = " " | d(9)
9
9
 
@@ -19,16 +19,16 @@ CRLF = CR LF
19
19
 
20
20
  linear_white_space = (CRLF? LWSP_char)+
21
21
 
22
- atom = /[^\]\x00-\x20 \x7F\x80-\xFF()<>@,;:\\".\[]+/
22
+ atom = /[^\]\x00-\x20 \x7F\x80-\xFF()<>@,;:\\".\[]+/n
23
23
 
24
- ctext = /[^)\\\x0D\x80-\xFF(]+/
24
+ ctext = /[^)\\\x0D\x80-\xFF(]+/n
25
25
  | linear_white_space
26
26
 
27
27
 
28
- dtext = /[^\]\\\x0D\x80-\xFF\[]+/
28
+ dtext = /[^\]\\\x0D\x80-\xFF\[]+/n
29
29
  | linear_white_space
30
30
 
31
- qtext = /[^"\\\x0D\x80-\xFF]+/
31
+ qtext = /[^"\\\x0D\x80-\xFF]+/n
32
32
  | linear_white_space
33
33
 
34
34
 
@@ -52,7 +52,9 @@ module EmailAddressValidator
52
52
  end
53
53
 
54
54
  # Shorthand for +EmailAddressParser.validate_2822_addr
55
- def self.validate_addr(addr, validate_domain=false); self.validate_2822; end
55
+ def self.validate_addr(addr, validate_domain=false)
56
+ validate_2822_addr addr, validate_domain
57
+ end
56
58
 
57
59
  # Validates +addr+ against the addr_spec portion of RFC 2822.
58
60
  # This is what most people actually want out of an email validator
@@ -65,7 +67,9 @@ module EmailAddressValidator
65
67
  end
66
68
 
67
69
  # Shorthand for +EmailAddressParser.validate_2822
68
- def self.validate(addr, validate_domain=false); self.validate_2822; end
70
+ def self.validate(addr, validate_domain=false)
71
+ validate_2822 addr, validate_domain
72
+ end
69
73
 
70
74
  # Validates an email address according to RFC 2822
71
75
  # This validates addresses against the full spec, which
@@ -1,8 +1,19 @@
1
1
  class EmailAddressValidator::DomainParser
2
- # STANDALONE START
2
+ # :stopdoc:
3
+
4
+ # This is distinct from setup_parser so that a standalone parser
5
+ # can redefine #initialize and still have access to the proper
6
+ # parser setup code.
7
+ def initialize(str, debug=false)
8
+ setup_parser(str, debug)
9
+ end
10
+
11
+
12
+
13
+ # Prepares for parsing +str+. If you define a custom initialize you must
14
+ # call this method before #parse
3
15
  def setup_parser(str, debug=false)
4
- @string = str
5
- @pos = 0
16
+ set_string str, 0
6
17
  @memoizations = Hash.new { |h,k| h[k] = {} }
7
18
  @result = nil
8
19
  @failed_rule = nil
@@ -11,22 +22,10 @@ class EmailAddressValidator::DomainParser
11
22
  setup_foreign_grammar
12
23
  end
13
24
 
14
- def setup_foreign_grammar
15
- end
16
-
17
- # This is distinct from setup_parser so that a standalone parser
18
- # can redefine #initialize and still have access to the proper
19
- # parser setup code.
20
- #
21
- def initialize(str, debug=false)
22
- setup_parser(str, debug)
23
- end
24
-
25
25
  attr_reader :string
26
- attr_reader :result, :failing_rule_offset
27
- attr_accessor :pos
26
+ attr_reader :failing_rule_offset
27
+ attr_accessor :result, :pos
28
28
 
29
- # STANDALONE START
30
29
  def current_column(target=pos)
31
30
  if c = string.rindex("\n", target-1)
32
31
  return target - c - 1
@@ -54,12 +53,19 @@ class EmailAddressValidator::DomainParser
54
53
  lines
55
54
  end
56
55
 
57
- #
56
+
58
57
 
59
58
  def get_text(start)
60
59
  @string[start..@pos-1]
61
60
  end
62
61
 
62
+ # Sets the string and current parsing position for the parser.
63
+ def set_string string, pos
64
+ @string = string
65
+ @string_size = string ? string.size : 0
66
+ @pos = pos
67
+ end
68
+
63
69
  def show_pos
64
70
  width = 10
65
71
  if @pos < width
@@ -166,19 +172,19 @@ class EmailAddressValidator::DomainParser
166
172
  return nil
167
173
  end
168
174
 
169
- if "".respond_to? :getbyte
175
+ if "".respond_to? :ord
170
176
  def get_byte
171
- if @pos >= @string.size
177
+ if @pos >= @string_size
172
178
  return nil
173
179
  end
174
180
 
175
- s = @string.getbyte @pos
181
+ s = @string[@pos].ord
176
182
  @pos += 1
177
183
  s
178
184
  end
179
185
  else
180
186
  def get_byte
181
- if @pos >= @string.size
187
+ if @pos >= @string_size
182
188
  return nil
183
189
  end
184
190
 
@@ -189,41 +195,37 @@ class EmailAddressValidator::DomainParser
189
195
  end
190
196
 
191
197
  def parse(rule=nil)
198
+ # We invoke the rules indirectly via apply
199
+ # instead of by just calling them as methods because
200
+ # if the rules use left recursion, apply needs to
201
+ # manage that.
202
+
192
203
  if !rule
193
- _root ? true : false
204
+ apply(:_root)
194
205
  else
195
- # This is not shared with code_generator.rb so this can be standalone
196
206
  method = rule.gsub("-","_hyphen_")
197
- __send__("_#{method}") ? true : false
207
+ apply :"_#{method}"
198
208
  end
199
209
  end
200
210
 
201
- class LeftRecursive
202
- def initialize(detected=false)
203
- @detected = detected
204
- end
205
-
206
- attr_accessor :detected
207
- end
208
-
209
211
  class MemoEntry
210
212
  def initialize(ans, pos)
211
213
  @ans = ans
212
214
  @pos = pos
213
- @uses = 1
214
215
  @result = nil
216
+ @set = false
217
+ @left_rec = false
215
218
  end
216
219
 
217
- attr_reader :ans, :pos, :uses, :result
218
-
219
- def inc!
220
- @uses += 1
221
- end
220
+ attr_reader :ans, :pos, :result, :set
221
+ attr_accessor :left_rec
222
222
 
223
223
  def move!(ans, pos, result)
224
224
  @ans = ans
225
225
  @pos = pos
226
226
  @result = result
227
+ @set = true
228
+ @left_rec = false
227
229
  end
228
230
  end
229
231
 
@@ -231,30 +233,61 @@ class EmailAddressValidator::DomainParser
231
233
  old_pos = @pos
232
234
  old_string = @string
233
235
 
234
- @pos = other.pos
235
- @string = other.string
236
+ set_string other.string, other.pos
236
237
 
237
238
  begin
238
239
  if val = __send__(rule, *args)
239
240
  other.pos = @pos
241
+ other.result = @result
240
242
  else
241
243
  other.set_failed_rule "#{self.class}##{rule}"
242
244
  end
243
245
  val
244
246
  ensure
245
- @pos = old_pos
246
- @string = old_string
247
+ set_string old_string, old_pos
248
+ end
249
+ end
250
+
251
+ def apply_with_args(rule, *args)
252
+ memo_key = [rule, args]
253
+ if m = @memoizations[memo_key][@pos]
254
+ @pos = m.pos
255
+ if !m.set
256
+ m.left_rec = true
257
+ return nil
258
+ end
259
+
260
+ @result = m.result
261
+
262
+ return m.ans
263
+ else
264
+ m = MemoEntry.new(nil, @pos)
265
+ @memoizations[memo_key][@pos] = m
266
+ start_pos = @pos
267
+
268
+ ans = __send__ rule, *args
269
+
270
+ lr = m.left_rec
271
+
272
+ m.move! ans, @pos, @result
273
+
274
+ # Don't bother trying to grow the left recursion
275
+ # if it's failing straight away (thus there is no seed)
276
+ if ans and lr
277
+ return grow_lr(rule, args, start_pos, m)
278
+ else
279
+ return ans
280
+ end
281
+
282
+ return ans
247
283
  end
248
284
  end
249
285
 
250
286
  def apply(rule)
251
287
  if m = @memoizations[rule][@pos]
252
- m.inc!
253
-
254
- prev = @pos
255
288
  @pos = m.pos
256
- if m.ans.kind_of? LeftRecursive
257
- m.ans.detected = true
289
+ if !m.set
290
+ m.left_rec = true
258
291
  return nil
259
292
  end
260
293
 
@@ -262,19 +295,20 @@ class EmailAddressValidator::DomainParser
262
295
 
263
296
  return m.ans
264
297
  else
265
- lr = LeftRecursive.new(false)
266
- m = MemoEntry.new(lr, @pos)
298
+ m = MemoEntry.new(nil, @pos)
267
299
  @memoizations[rule][@pos] = m
268
300
  start_pos = @pos
269
301
 
270
302
  ans = __send__ rule
271
303
 
304
+ lr = m.left_rec
305
+
272
306
  m.move! ans, @pos, @result
273
307
 
274
308
  # Don't bother trying to grow the left recursion
275
309
  # if it's failing straight away (thus there is no seed)
276
- if ans and lr.detected
277
- return grow_lr(rule, start_pos, m)
310
+ if ans and lr
311
+ return grow_lr(rule, nil, start_pos, m)
278
312
  else
279
313
  return ans
280
314
  end
@@ -283,12 +317,16 @@ class EmailAddressValidator::DomainParser
283
317
  end
284
318
  end
285
319
 
286
- def grow_lr(rule, start_pos, m)
320
+ def grow_lr(rule, args, start_pos, m)
287
321
  while true
288
322
  @pos = start_pos
289
323
  @result = m.result
290
324
 
291
- ans = __send__ rule
325
+ if args
326
+ ans = __send__ rule, *args
327
+ else
328
+ ans = __send__ rule
329
+ end
292
330
  return nil unless ans
293
331
 
294
332
  break if @pos <= m.pos
@@ -314,7 +352,9 @@ class EmailAddressValidator::DomainParser
314
352
  RuleInfo.new(name, rendered)
315
353
  end
316
354
 
317
- #
355
+
356
+ # :startdoc:
357
+ # :stopdoc:
318
358
  def setup_foreign_grammar; end
319
359
 
320
360
  # domain = < subdomain > &{ text.size < 255 }
@@ -322,22 +362,22 @@ class EmailAddressValidator::DomainParser
322
362
 
323
363
  _save = self.pos
324
364
  while true # sequence
325
- _text_start = self.pos
326
- _tmp = apply(:_subdomain)
327
- if _tmp
328
- text = get_text(_text_start)
329
- end
330
- unless _tmp
331
- self.pos = _save
365
+ _text_start = self.pos
366
+ _tmp = apply(:_subdomain)
367
+ if _tmp
368
+ text = get_text(_text_start)
369
+ end
370
+ unless _tmp
371
+ self.pos = _save
372
+ break
373
+ end
374
+ _save1 = self.pos
375
+ _tmp = begin; text.size < 255 ; end
376
+ self.pos = _save1
377
+ unless _tmp
378
+ self.pos = _save
379
+ end
332
380
  break
333
- end
334
- _save1 = self.pos
335
- _tmp = begin; text.size < 255 ; end
336
- self.pos = _save1
337
- unless _tmp
338
- self.pos = _save
339
- end
340
- break
341
381
  end # end sequence
342
382
 
343
383
  set_failed_rule :_domain unless _tmp
@@ -350,31 +390,31 @@ class EmailAddressValidator::DomainParser
350
390
  _save = self.pos
351
391
  while true # choice
352
392
 
353
- _save1 = self.pos
354
- while true # sequence
355
- _tmp = apply(:_subdomain)
356
- unless _tmp
357
- self.pos = _save1
358
- break
359
- end
360
- _tmp = match_string(".")
361
- unless _tmp
362
- self.pos = _save1
363
- break
364
- end
365
- _tmp = apply(:_label)
366
- unless _tmp
367
- self.pos = _save1
368
- end
369
- break
370
- end # end sequence
393
+ _save1 = self.pos
394
+ while true # sequence
395
+ _tmp = apply(:_subdomain)
396
+ unless _tmp
397
+ self.pos = _save1
398
+ break
399
+ end
400
+ _tmp = match_string(".")
401
+ unless _tmp
402
+ self.pos = _save1
403
+ break
404
+ end
405
+ _tmp = apply(:_label)
406
+ unless _tmp
407
+ self.pos = _save1
408
+ end
409
+ break
410
+ end # end sequence
371
411
 
372
- break if _tmp
373
- self.pos = _save
374
- _tmp = apply(:_label)
375
- break if _tmp
376
- self.pos = _save
377
- break
412
+ break if _tmp
413
+ self.pos = _save
414
+ _tmp = apply(:_label)
415
+ break if _tmp
416
+ self.pos = _save
417
+ break
378
418
  end # end choice
379
419
 
380
420
  set_failed_rule :_subdomain unless _tmp
@@ -386,31 +426,31 @@ class EmailAddressValidator::DomainParser
386
426
 
387
427
  _save = self.pos
388
428
  while true # sequence
389
- _tmp = apply(:_let_hyphen_dig)
390
- unless _tmp
391
- self.pos = _save
392
- break
393
- end
394
- _text_start = self.pos
395
- while true
396
- _tmp = apply(:_let_hyphen_dig_hyphen_hyp)
397
- break unless _tmp
398
- end
399
- _tmp = true
400
- if _tmp
401
- text = get_text(_text_start)
402
- end
403
- unless _tmp
404
- self.pos = _save
429
+ _tmp = apply(:_let_hyphen_dig)
430
+ unless _tmp
431
+ self.pos = _save
432
+ break
433
+ end
434
+ _text_start = self.pos
435
+ while true
436
+ _tmp = apply(:_let_hyphen_dig_hyphen_hyp)
437
+ break unless _tmp
438
+ end
439
+ _tmp = true
440
+ if _tmp
441
+ text = get_text(_text_start)
442
+ end
443
+ unless _tmp
444
+ self.pos = _save
445
+ break
446
+ end
447
+ _save2 = self.pos
448
+ _tmp = begin; text.size < 63 && (text.size == 0 || text[-1] != ?-) ; end
449
+ self.pos = _save2
450
+ unless _tmp
451
+ self.pos = _save
452
+ end
405
453
  break
406
- end
407
- _save2 = self.pos
408
- _tmp = begin; text.size < 63 && (text.size == 0 || text[-1] != ?-) ; end
409
- self.pos = _save2
410
- unless _tmp
411
- self.pos = _save
412
- end
413
- break
414
454
  end # end sequence
415
455
 
416
456
  set_failed_rule :_label unless _tmp
@@ -422,13 +462,13 @@ class EmailAddressValidator::DomainParser
422
462
 
423
463
  _save = self.pos
424
464
  while true # choice
425
- _tmp = apply(:_let_hyphen_dig)
426
- break if _tmp
427
- self.pos = _save
428
- _tmp = match_string("-")
429
- break if _tmp
430
- self.pos = _save
431
- break
465
+ _tmp = apply(:_let_hyphen_dig)
466
+ break if _tmp
467
+ self.pos = _save
468
+ _tmp = match_string("-")
469
+ break if _tmp
470
+ self.pos = _save
471
+ break
432
472
  end # end choice
433
473
 
434
474
  set_failed_rule :_let_hyphen_dig_hyphen_hyp unless _tmp
@@ -440,13 +480,13 @@ class EmailAddressValidator::DomainParser
440
480
 
441
481
  _save = self.pos
442
482
  while true # choice
443
- _tmp = apply(:_letter)
444
- break if _tmp
445
- self.pos = _save
446
- _tmp = apply(:_digit)
447
- break if _tmp
448
- self.pos = _save
449
- break
483
+ _tmp = apply(:_letter)
484
+ break if _tmp
485
+ self.pos = _save
486
+ _tmp = apply(:_digit)
487
+ break if _tmp
488
+ self.pos = _save
489
+ break
450
490
  end # end choice
451
491
 
452
492
  set_failed_rule :_let_hyphen_dig unless _tmp
@@ -472,19 +512,19 @@ class EmailAddressValidator::DomainParser
472
512
 
473
513
  _save = self.pos
474
514
  while true # sequence
475
- _tmp = apply(:_domain)
476
- unless _tmp
477
- self.pos = _save
515
+ _tmp = apply(:_domain)
516
+ unless _tmp
517
+ self.pos = _save
518
+ break
519
+ end
520
+ _save1 = self.pos
521
+ _tmp = get_byte
522
+ _tmp = _tmp ? nil : true
523
+ self.pos = _save1
524
+ unless _tmp
525
+ self.pos = _save
526
+ end
478
527
  break
479
- end
480
- _save1 = self.pos
481
- _tmp = get_byte
482
- _tmp = _tmp ? nil : true
483
- self.pos = _save1
484
- unless _tmp
485
- self.pos = _save
486
- end
487
- break
488
528
  end # end sequence
489
529
 
490
530
  set_failed_rule :_root unless _tmp
@@ -500,4 +540,5 @@ class EmailAddressValidator::DomainParser
500
540
  Rules[:_letter] = rule_info("letter", "/[A-Za-z]/")
501
541
  Rules[:_digit] = rule_info("digit", "/[0-9]/")
502
542
  Rules[:_root] = rule_info("root", "domain !.")
543
+ # :startdoc:
503
544
  end