whois-parser-next 0.4.4 → 0.4.6

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
  SHA256:
3
- metadata.gz: f4c96a0a74b64788109bc1bf2d100571089e9bbbd49668c8146e175567b0f08c
4
- data.tar.gz: e9e721292aaad948280edebea47d502ce309c1db903be8da692bfb50bf4e6e00
3
+ metadata.gz: 66e7767b738ae0cf7df9736dc9a6a7685f9ddf7d344506a3a4233accf905f0d2
4
+ data.tar.gz: c15b010e832b1e52cebdb02fd473e8c75176a0f232c777ba385e39b17676b327
5
5
  SHA512:
6
- metadata.gz: daf6ebf45111891d95f5c3bd6bc0bc57d5be7a0e641fd8054cdb359bf5bc64a2406db5cc4aeb9cf02e195e65a740abc15260b5f092f3c23b75a1c6927bc3a56a
7
- data.tar.gz: 87849973634827aa16cc8ecad6e78031cf348ee01351709217bcfc9580cf9603a7943824d87df9a0222d76bf7940db020b4dc5928f2141f225390dfffc07e639
6
+ metadata.gz: 587e231a29331459c3d14a9cd655ef2fa0230b819cbbcde397be5465500fd4a8eef4b5742407f402ed203d7104a9dc235553795427ec1b2daa1d08a34a24e82e
7
+ data.tar.gz: d4e01866484c46fcf88ef68889d677459ae34db5c0920dcabfc4bb2eaf390f16af8d5524436056a543154320742d51cc445dfb3553de4eb4386adc5c0ef511f1
data/CHANGELOG.md CHANGED
@@ -2,6 +2,70 @@
2
2
 
3
3
  This project uses [Semantic Versioning 2.0.0](http://semver.org/).
4
4
 
5
+ #### Release 0.4.6 (2026-10-19)
6
+
7
+ - ADDED: Added `.ga` parsing for ANINF's current French WHOIS response, requiring
8
+ one valid domain, `Statut: actif`, and a parseable creation date; absence
9
+ requires the exact `%% NOT FOUND` marker. Added `.jo` parsing for a single
10
+ valid domain with a creation date and `Domain Status: Active`; absence
11
+ requires the exact quoted-name `No match for domain` response and matching
12
+ echoed domain.
13
+ - UPDATED: `.sx` recognizes the current CIRA EPP statuses
14
+ `clientDeleteProhibited` and `clientTransferProhibited`, plus the exact
15
+ `Not found: <name>` absence response, while retaining its legacy format.
16
+ Duplicate, contradictory, malformed, or incomplete evidence remains
17
+ unknown; explicit denials and throttling remain blocked.
18
+ - SAFETY: `.il` no longer treats a missing status as absence. Production
19
+ registered and absent queries returned the same 790-byte disclaimer-only
20
+ reply without an absence marker. Absence now requires the exact
21
+ `% No data was found to match the request criteria.` marker; registration
22
+ requires one valid domain and one `Transfer Locked` or `Transfer Allowed`
23
+ status. Empty, denied, throttled, duplicate, mixed, or incomplete replies
24
+ remain unknown. This corrects false absence; `.il` coverage remains
25
+ unverified.
26
+ - EVIDENCE: Bounded production-host and managed-proxy checks on 2026-10-19 UTC
27
+ observed registered and absent replies for all three hosts. IANA lists
28
+ `whois.nic.net.jo` for [`.jo`](https://www.iana.org/domains/root/db/jo.html)
29
+ and `whois.sx` for [`.sx`](https://www.iana.org/domains/root/db/sx.html).
30
+ IANA has no WHOIS listing for `.ga`; ANINF's current [official
31
+ webWHOIS](https://whois.nic.ga/) and [registration
32
+ policy](https://www.mon.ga/policy/registry_policies.pdf) establish its provenance.
33
+ The `.ga` and `.sx` source terms restrict circulation or use of WHOIS data,
34
+ so the repository fixtures are synthetic technical-shape controls, not
35
+ copies of the captured replies. See the fixture README for details.
36
+
37
+ #### Release 0.4.5 (2026-10-18)
38
+
39
+ - ADDED: Added current CoCCA response parsing for `.bf`, `.td`, and `.mr`,
40
+ requiring one valid domain identity and an exact `active` or `ok` EPP
41
+ registration state. `.bf` accepts `Domain Status: No Object Found`; `.td`,
42
+ `.mr`, and `.kn` require the exact absence line
43
+ `The queried object does not exist: No Object Found`. `.kn` also recognizes
44
+ its current CoCCA response while retaining the legacy format. Mixed or
45
+ incomplete replies remain unknown.
46
+ - ADDED: Added strict `.mc` parsing: registration requires one valid domain,
47
+ `Status: ACTIVE`, and a parseable `Created` value; absence requires the exact
48
+ `>> No data found for domain : <name>` line. Malformed or mixed replies
49
+ remain unknown.
50
+ - SAFETY: `.ws` recognizes the current `Domain Name` and `Creation Date` format
51
+ while preserving the legacy `Domain Created` format and exact absence
52
+ response. Invalid, inconsistent, or duplicate fields remain unknown.
53
+ - EVIDENCE: IANA lists the official hosts `whois.registre.bf`, `whois.nic.td`,
54
+ `whois.nic.mr`, `whois.nic.kn`, `whois.nic.mc`, and `whois.website.ws` for
55
+ [`.bf`](https://www.iana.org/domains/root/db/bf.html),
56
+ [`.td`](https://www.iana.org/domains/root/db/td.html),
57
+ [`.mr`](https://www.iana.org/domains/root/db/mr.html),
58
+ [`.kn`](https://www.iana.org/domains/root/db/kn.html),
59
+ [`.mc`](https://www.iana.org/domains/root/db/mc.html), and
60
+ [`.ws`](https://www.iana.org/domains/root/db/ws.html). Production-host queries
61
+ on 2026-10-18 observed registered and absent pairs for `.bf`, `.td`, `.mr`,
62
+ `.kn`, and `.mc`. Local-network queries observed both `.ws` states; the
63
+ production-proxy query confirmed a registered response only, so a production
64
+ registered/absent pair remains unverified. Committed examples are minimal
65
+ synthetic technical-shape controls without contact details.
66
+ - TESTED: The full suite passes 7,074 examples with 0 failures on Ruby 3.2.2
67
+ and 3.4.5. Final package smoke and supported-Ruby CI remain release gates.
68
+
5
69
  #### Release 0.4.4 (2026-10-18)
6
70
 
7
71
  - ADDED: Added parsers for the current `.gh` and `.do` CoCCA WHOIS response
@@ -1,6 +1,6 @@
1
1
  module Whois
2
2
  class Parser
3
3
  # The current library version.
4
- VERSION = "0.4.4".freeze
4
+ VERSION = "0.4.6".freeze
5
5
  end
6
6
  end
@@ -8,6 +8,7 @@
8
8
 
9
9
 
10
10
  require_relative 'base'
11
+ require_relative 'registry_response_safety'
11
12
 
12
13
 
13
14
  module Whois
@@ -25,19 +26,20 @@ module Whois
25
26
  # and examples.
26
27
  #
27
28
  class WhoisIsocOrgIl < Base
29
+ include RegistryResponseSafety
28
30
 
29
31
  property_supported :status do
30
- if content_for_scanner =~ /status:\s+(.*?)\n/
31
- case ::Regexp.last_match(1).downcase
32
- when "transfer locked"
33
- :registered
34
- when "transfer allowed"
35
- :registered
36
- else
37
- Whois::Parser.bug!(ParserError, "Unknown status `#{::Regexp.last_match(1)}'.")
38
- end
39
- else
32
+ names = content_for_scanner.scan(/^domain:[ \t]*(.+)$/i).flatten.map(&:strip)
33
+ states = content_for_scanner.scan(/^status:[ \t]*(.+)$/i).flatten.map { |value| value.strip.downcase }
34
+ missing = content_for_scanner.scan(/^% No data was found to match the request criteria\.[ \t]*$/).size
35
+ if missing == 1 && names.empty? && states.empty?
40
36
  :available
37
+ elsif missing.zero? && names.size == 1 && states.size == 1 &&
38
+ names.first.match?(/\A(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+il\z/i) &&
39
+ ['transfer locked', 'transfer allowed'].include?(states.first)
40
+ :registered
41
+ else
42
+ :unknown
41
43
  end
42
44
  end
43
45
 
@@ -46,7 +48,7 @@ module Whois
46
48
  end
47
49
 
48
50
  property_supported :registered? do
49
- !available?
51
+ status == :registered
50
52
  end
51
53
 
52
54
 
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base'
4
+ require_relative 'registry_response_safety'
5
+
6
+ module Whois
7
+ class Parsers
8
+ # ANINF's current French-language registry response, observed 2026-10-19.
9
+ class WhoisNicGa < Base
10
+ include RegistryResponseSafety
11
+
12
+ property_supported(:domain) { header_field('Nom de domaine')&.downcase }
13
+ property_supported(:domain_id) { header_field('Domain ID') }
14
+ property_supported(:status) do
15
+ names = content_for_scanner.scan(/^Nom de domaine:[ \t]*(.+)$/).flatten
16
+ missing = content_for_scanner.scan(/^%% NOT FOUND[ \t]*$/).size
17
+ if missing == 1 && names.empty? && !header_field('Domain ID')
18
+ :available
19
+ elsif missing.zero? && names.size == 1 &&
20
+ names.first.strip.match?(/\A[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.ga\z/i) &&
21
+ header_field('Domain ID') && header_field('Statut') == 'actif' &&
22
+ valid_creation_date?
23
+ :registered
24
+ else
25
+ :unknown
26
+ end
27
+ end
28
+ property_supported(:available?) { status == :available }
29
+ property_supported(:registered?) { status == :registered }
30
+ property_supported(:created_on) { header_date('Date de création') }
31
+ property_supported(:updated_on) { header_date('Dernière modification') }
32
+ property_supported(:expires_on) { header_date("Date d'expiration") }
33
+ property_supported(:registrar) do
34
+ name = header_field('Registrar')
35
+ Parser::Registrar.new(name: name) if name
36
+ end
37
+ property_supported(:nameservers) do
38
+ content_for_scanner.scan(/^Serveur de noms:[ \t]*(\S+)[ \t]*$/).flatten.map do |name|
39
+ Parser::Nameserver.new(name: name.downcase)
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ def header_field(label)
46
+ header = content_for_scanner.split(/^\[/, 2).first.to_s
47
+ values = header.scan(/^#{Regexp.escape(label)}:[ \t]*(.+)$/).flatten.map(&:strip)
48
+ values.first if values.size == 1 && !values.first.empty?
49
+ end
50
+
51
+ def header_date(label)
52
+ value = header_field(label)
53
+ parse_time(value) if value
54
+ end
55
+
56
+ def valid_creation_date?
57
+ value = header_field('Date de création')
58
+ value && value.match?(/\A\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z\z/) && Date.iso8601(value[0, 10]) && Time.iso8601(value)
59
+ rescue ArgumentError
60
+ false
61
+ end
62
+ end
63
+ end
64
+ end
@@ -1,8 +1,17 @@
1
1
  require_relative 'base_icann_compliant'
2
+ require_relative 'cocca_epp_status'
2
3
 
3
4
  module Whois
4
5
  class Parsers
5
6
  class WhoisNicKn < BaseIcannCompliant
7
+ include CoccaEppStatus
8
+ CURRENT_COCCA_SUFFIX = "kn".freeze
9
+
10
+ property_supported(:status) { current_cocca_status || super() }
11
+ property_supported :available? do
12
+ current = current_cocca_status
13
+ current.nil? ? super() : current == :available
14
+ end
6
15
  end
7
16
  end
8
17
  end
@@ -0,0 +1,46 @@
1
+ require_relative 'base'
2
+ require_relative 'registry_response_safety'
3
+
4
+ module Whois
5
+ class Parsers
6
+ class WhoisNicMc < Base
7
+ include RegistryResponseSafety
8
+
9
+ property_supported(:domain) { content_for_scanner[/^Domain[ \t]*:[ \t]*(\S+)[ \t]*\r?$/i, 1]&.downcase }
10
+
11
+ property_supported :status do
12
+ text = content_for_scanner
13
+ names = text.scan(/^Domain[ \t]*:[ \t]*(\S+)[ \t]*\r?$/i).flatten
14
+ absent = text.scan(/^>> No data found for domain : (\S+)[ \t]*\r?$/i).flatten
15
+ dates = text.scan(/^Created[ \t]*:[ \t]*([^\r\n]+)$/i).flatten
16
+ statuses = text.scan(/^Status[ \t]*:[ \t]*([^\r\n]+)$/i).flatten.map(&:strip)
17
+ if absent.any?
18
+ absent.one? && valid_mc_domain?(absent.first) && names.empty? && dates.empty? && statuses.empty? ? :available : :unknown
19
+ else
20
+ valid_date = dates.one? && begin
21
+ !!parse_time(dates.first.strip)
22
+ rescue ArgumentError
23
+ false
24
+ end
25
+ names.one? && valid_mc_domain?(names.first) && statuses == ['ACTIVE'] && valid_date ? :registered : :unknown
26
+ end
27
+ end
28
+ property_supported(:registered?) { status == :registered }
29
+ property_supported(:available?) { status == :available }
30
+ property_supported :created_on do
31
+ value = content_for_scanner[/^Created[ \t]*:[ \t]*([^\r\n]+)$/i, 1]
32
+ parse_time(value.strip) if value
33
+ end
34
+ property_supported :expires_on do
35
+ value = content_for_scanner[/^Expires on[ \t]*:[ \t]*([^\r\n]+)$/i, 1]
36
+ parse_time(value.strip) if value
37
+ end
38
+
39
+ private
40
+
41
+ def valid_mc_domain?(name)
42
+ name.match?(/\A(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+mc\z/i)
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,15 @@
1
+ require_relative 'base_cocca2'
2
+ require_relative 'cocca_epp_status'
3
+
4
+ module Whois
5
+ class Parsers
6
+ class WhoisNicMr < BaseCocca2
7
+ include CoccaEppStatus
8
+ CURRENT_COCCA_SUFFIX = "mr".freeze
9
+
10
+ property_supported(:status) { current_cocca_status || :unknown }
11
+ property_supported(:available?) { status == :available }
12
+ property_supported(:registered?) { status == :registered }
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base_cocca2'
4
+ require_relative 'registry_response_safety'
5
+ require 'whois/scanners/whois.nic.net.jo'
6
+
7
+ module Whois
8
+ class Parsers
9
+ # Jordan's official registry endpoint, observed 2026-10-19.
10
+ class WhoisNicNetJo < BaseCocca2
11
+ include RegistryResponseSafety
12
+ self.scanner = Scanners::WhoisNicNetJo
13
+
14
+ property_supported(:status) do
15
+ names = content_for_scanner.scan(/^Domain Name:[ \t]*(.+)$/i).flatten.map(&:strip)
16
+ absent = content_for_scanner.scan(/^No match for domain "([^"\n]+)"[ \t]*$/i).flatten
17
+ statuses = content_for_scanner.scan(/^Domain Status:[ \t]*(.+)$/i).flatten.map(&:strip)
18
+ valid_name = names.size == 1 && names.first.match?(/\A(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+jo\z/i)
19
+ if valid_name && absent.size == 1 && absent.first.casecmp?(names.first) && statuses.empty? &&
20
+ !content_for_scanner.match?(/^Creation Date:/i)
21
+ :available
22
+ elsif valid_name && absent.empty? && statuses == ['Active'] && valid_creation_date?
23
+ :registered
24
+ else
25
+ :unknown
26
+ end
27
+ end
28
+ property_supported(:available?) { status == :available }
29
+ property_supported(:registered?) { status == :registered }
30
+
31
+ private
32
+
33
+ def valid_creation_date?
34
+ values = content_for_scanner.scan(/^Creation Date:[ \t]*(.+)$/i).flatten.map(&:strip)
35
+ values.size == 1 && values.first.match?(/\A\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z\z/) && Date.iso8601(values.first[0, 10]) && Time.iso8601(values.first)
36
+ rescue ArgumentError
37
+ false
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,15 @@
1
+ require_relative 'base_cocca2'
2
+ require_relative 'cocca_epp_status'
3
+
4
+ module Whois
5
+ class Parsers
6
+ class WhoisNicTd < BaseCocca2
7
+ include CoccaEppStatus
8
+ CURRENT_COCCA_SUFFIX = "td".freeze
9
+
10
+ property_supported(:status) { current_cocca_status || :unknown }
11
+ property_supported(:available?) { status == :available }
12
+ property_supported(:registered?) { status == :registered }
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ require_relative 'base_cocca2'
2
+ require_relative 'cocca_epp_status'
3
+
4
+ module Whois
5
+ class Parsers
6
+ class WhoisRegistreBf < BaseCocca2
7
+ include CoccaEppStatus
8
+ CURRENT_COCCA_SUFFIX = "bf".freeze
9
+
10
+ property_supported(:status) { current_cocca_status || :unknown }
11
+ property_supported(:available?) { status == :available }
12
+ property_supported(:registered?) { status == :registered }
13
+ end
14
+ end
15
+ end
@@ -8,6 +8,7 @@
8
8
 
9
9
 
10
10
  require_relative 'base'
11
+ require_relative 'registry_response_safety'
11
12
  require 'whois/scanners/whois.sx.rb'
12
13
 
13
14
 
@@ -20,6 +21,7 @@ module Whois
20
21
  # The Example parser for the list of all available methods.
21
22
  #
22
23
  class WhoisSx < Base
24
+ include RegistryResponseSafety
23
25
  include Scanners::Scannable
24
26
 
25
27
  self.scanner = Scanners::WhoisSx
@@ -31,7 +33,7 @@ module Whois
31
33
 
32
34
 
33
35
  property_supported :domain do
34
- node("Domain Name", &:downcase)
36
+ (node("Domain Name") || node("Not found"))&.downcase
35
37
  end
36
38
 
37
39
  property_supported :domain_id do
@@ -40,6 +42,9 @@ module Whois
40
42
 
41
43
 
42
44
  property_supported :status do
45
+ current = current_registry_status
46
+ return current if current
47
+
43
48
  case (s = node("Domain Status", &:downcase))
44
49
  when "available"
45
50
  :available
@@ -103,6 +108,34 @@ module Whois
103
108
  end
104
109
 
105
110
 
111
+ # Keep the historical scanner for old fixtures, while recognizing the
112
+ # current EPP record and exact missing reply before scanning legacy text.
113
+ def current_registry_status
114
+ names = content_for_scanner.scan(/^Domain Name:[ \t]*(.+)$/i).flatten.map(&:strip)
115
+ absent = content_for_scanner.scan(/^Not found:[ \t]*(\S+)[ \t]*$/i).flatten
116
+ return nil if absent.empty? && !content_for_scanner.match?(/^Registry Domain ID:/i)
117
+
118
+ valid = ->(name) { name.match?(/\A[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.sx\z/i) }
119
+ if absent.size == 1 && names.empty? && valid.call(absent.first) &&
120
+ !content_for_scanner.match?(/^(?:Creation Date|Registry Domain ID|Domain Status):/i)
121
+ return :available
122
+ end
123
+ return :unknown unless absent.empty? && names.size == 1 && valid.call(names.first)
124
+
125
+ statuses = content_for_scanner.scan(/^Domain Status:[ \t]*(\S+)(?:[^\n]*)$/i).flatten
126
+ dates = content_for_scanner.scan(/^Creation Date:[ \t]*(.+)$/i).flatten.map(&:strip)
127
+ return :unknown unless dates.size == 1 && dates.first.match?(/\A\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z\z/)
128
+ Date.iso8601(dates.first[0, 10])
129
+ Time.iso8601(dates.first)
130
+ if statuses.any? && statuses.all? { |value| value.match?(/\A(?:ok|active|(?:client|server)(?:Delete|Transfer|Update|Renew)Prohibited)\z/) }
131
+ :registered
132
+ else
133
+ :unknown
134
+ end
135
+ rescue ArgumentError
136
+ :unknown
137
+ end
138
+
106
139
  private
107
140
 
108
141
  def build_contact(element, type)
@@ -26,19 +26,25 @@ module Whois
26
26
  class WhoisWebsiteWs < Base
27
27
  include RegistryResponseSafety
28
28
 
29
+ property_supported :domain do
30
+ content_for_scanner[/^[ \t]*Domain Name:[ \t]*(\S+)[ \t]*\r?$/i, 1]&.downcase
31
+ end
32
+
29
33
  property_supported :status do
30
- if available?
31
- :available
32
- elsif content_for_scanner.match?(/^\s+Domain Created:\s+/i)
33
- :registered
34
+ body = content_for_scanner
35
+ names = body.scan(/^[ \t]*Domain Name:[ \t]*(\S+)[ \t]*\r?$/i).flatten
36
+ missing = body.scan(/^(?:No match for "([^"\r\n]+)"\.|The queried object does not exist: ([^\r\n]+)\.)[ \t]*\r?$/i).map { |parts| parts.compact.first }
37
+ dates = body.scan(/^[ \t]*(?:Creation Date|Domain Created):[ \t]*([^\r\n]+)$/i).flatten
38
+ if missing.any?
39
+ missing.one? && names.empty? && dates.empty? && valid_ws_domain?(missing.first) ? :available : :unknown
34
40
  else
35
- :unknown
41
+ times = dates.map { |date| begin parse_time(date.strip); rescue ArgumentError; nil; end }
42
+ names.one? && valid_ws_domain?(names.first) && times.any? && times.none?(&:nil?) && times.uniq.one? ? :registered : :unknown
36
43
  end
37
44
  end
38
45
 
39
46
  property_supported :available? do
40
- !!(content_for_scanner =~ /^No match for "\S+"\.$/ ||
41
- content_for_scanner =~ /^The queried object does not exist: \S+\.$/)
47
+ status == :available
42
48
  end
43
49
 
44
50
  property_supported :registered? do
@@ -47,9 +53,8 @@ module Whois
47
53
 
48
54
 
49
55
  property_supported :created_on do
50
- if content_for_scanner =~ /\s+Domain Created:\s+(.*)\n/
51
- parse_time(::Regexp.last_match(1))
52
- end
56
+ value = content_for_scanner[/^[ \t]*(?:Creation Date|Domain Created):[ \t]*([^\r\n]+)$/i, 1]
57
+ parse_time(value.strip) if value
53
58
  end
54
59
 
55
60
  property_supported :updated_on do
@@ -73,6 +78,12 @@ module Whois
73
78
  end
74
79
  end
75
80
 
81
+ private
82
+
83
+ def valid_ws_domain?(name)
84
+ name.match?(/\A(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+ws\z/i)
85
+ end
86
+
76
87
  end
77
88
 
78
89
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base_cocca2'
4
+
5
+ module Whois
6
+ module Scanners
7
+ class WhoisNicNetJo < BaseCocca2
8
+ self.tokenizers += [:skip_jordan_absence]
9
+
10
+ tokenizer :skip_jordan_absence do
11
+ @input.skip(/^No match for domain "[^"\n]+"[ \t]*\n/i)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -11,6 +11,7 @@ module Whois
11
11
  :scan_keyvalue,
12
12
  :skip_lastupdate,
13
13
  :scan_disclaimer,
14
+ :skip_comment,
14
15
  ]
15
16
 
16
17
 
@@ -25,6 +26,10 @@ module Whois
25
26
  @input.skip(/>>>(.+?)<<<\n/)
26
27
  end
27
28
 
29
+ tokenizer :skip_comment do
30
+ @input.skip(/^%[^\n]*\n/)
31
+ end
32
+
28
33
  tokenizer :scan_disclaimer do
29
34
  if @input.match?(/^% WHOIS LEGAL STATEMENT/)
30
35
  @ast["field:disclaimer"] = _scan_lines_to_array(/%(.*)\n/).map(&:strip).join("\n")
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: whois-parser-next
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.4
4
+ version: 0.4.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Simone Carletti
@@ -439,6 +439,7 @@ files:
439
439
  - lib/whois/parsers/whois.nic.furniture.rb
440
440
  - lib/whois/parsers/whois.nic.futbol.rb
441
441
  - lib/whois/parsers/whois.nic.fyi.rb
442
+ - lib/whois/parsers/whois.nic.ga.rb
442
443
  - lib/whois/parsers/whois.nic.gal.rb
443
444
  - lib/whois/parsers/whois.nic.games.rb
444
445
  - lib/whois/parsers/whois.nic.gd.rb
@@ -513,6 +514,7 @@ files:
513
514
  - lib/whois/parsers/whois.nic.management.rb
514
515
  - lib/whois/parsers/whois.nic.market.rb
515
516
  - lib/whois/parsers/whois.nic.mba.rb
517
+ - lib/whois/parsers/whois.nic.mc.rb
516
518
  - lib/whois/parsers/whois.nic.md.rb
517
519
  - lib/whois/parsers/whois.nic.me.rb
518
520
  - lib/whois/parsers/whois.nic.media.rb
@@ -528,6 +530,7 @@ files:
528
530
  - lib/whois/parsers/whois.nic.monster.rb
529
531
  - lib/whois/parsers/whois.nic.mortgage.rb
530
532
  - lib/whois/parsers/whois.nic.moscow.rb
533
+ - lib/whois/parsers/whois.nic.mr.rb
531
534
  - lib/whois/parsers/whois.nic.ms.rb
532
535
  - lib/whois/parsers/whois.nic.mu.rb
533
536
  - lib/whois/parsers/whois.nic.museum.rb
@@ -535,6 +538,7 @@ files:
535
538
  - lib/whois/parsers/whois.nic.mx.rb
536
539
  - lib/whois/parsers/whois.nic.name.rb
537
540
  - lib/whois/parsers/whois.nic.net.bw.rb
541
+ - lib/whois/parsers/whois.nic.net.jo.rb
538
542
  - lib/whois/parsers/whois.nic.net.ng.rb
539
543
  - lib/whois/parsers/whois.nic.net.sa.rb
540
544
  - lib/whois/parsers/whois.nic.net.sb.rb
@@ -624,6 +628,7 @@ files:
624
628
  - lib/whois/parsers/whois.nic.taipei.rb
625
629
  - lib/whois/parsers/whois.nic.tatar.rb
626
630
  - lib/whois/parsers/whois.nic.tc.rb
631
+ - lib/whois/parsers/whois.nic.td.rb
627
632
  - lib/whois/parsers/whois.nic.team.rb
628
633
  - lib/whois/parsers/whois.nic.tech.rb
629
634
  - lib/whois/parsers/whois.nic.technology.rb
@@ -698,6 +703,7 @@ files:
698
703
  - lib/whois/parsers/whois.register.bg.rb
699
704
  - lib/whois/parsers/whois.register.com.rb
700
705
  - lib/whois/parsers/whois.register.si.rb
706
+ - lib/whois/parsers/whois.registre.bf.rb
701
707
  - lib/whois/parsers/whois.registre.ma.rb
702
708
  - lib/whois/parsers/whois.registro.br.rb
703
709
  - lib/whois/parsers/whois.registry.click.rb
@@ -774,6 +780,7 @@ files:
774
780
  - lib/whois/scanners/whois.nc.rb
775
781
  - lib/whois/scanners/whois.nic.cz.rb
776
782
  - lib/whois/scanners/whois.nic.it.rb
783
+ - lib/whois/scanners/whois.nic.net.jo.rb
777
784
  - lib/whois/scanners/whois.pir.org.rb
778
785
  - lib/whois/scanners/whois.rnids.rs.rb
779
786
  - lib/whois/scanners/whois.smallregistry.net.rb