whois-parser-next 0.4.0 → 0.4.2
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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 638978b26282a734fc56d9b8fca805a2808a6a3eaf4aaa9804be31a1b1760a46
|
|
4
|
+
data.tar.gz: 216cfa13ce249145a3d4dff1eeb9ced17c21b2d2c0dcac5faaa1b3279666bc2e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6dc981427e17392f85c4d99f03ac033b9d62bfe525f6ad3785f4b1ed0d22ddf05ed1bc1848e0f0b6599a0f776ae9cfb4b938a6e913c997222313cc5693d20178
|
|
7
|
+
data.tar.gz: fa74d6035567289e6d29f140740a04ae5b1694c2f483ddbb3c1f1e54e1964a0f6621f3be95efb4ae1fd3a964d74141c5bf6d1b8cd33edcf38d1ba662d91bc329
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,41 @@
|
|
|
2
2
|
|
|
3
3
|
This project uses [Semantic Versioning 2.0.0](http://semver.org/).
|
|
4
4
|
|
|
5
|
+
#### Release 0.4.2 (2026-10-18)
|
|
6
|
+
|
|
7
|
+
- SAFETY: `.ma` accepts the observed `active https://icann.org/epp#active`
|
|
8
|
+
status as registered only with exactly one valid `.ma` domain name and no
|
|
9
|
+
contradictory absence marker. Incomplete, multiple-domain, or mixed replies
|
|
10
|
+
remain unknown.
|
|
11
|
+
- SAFETY: `.sh` accepts the exact `Domain not found.` response as absence while
|
|
12
|
+
retaining the legacy `NOT FOUND` marker. Partial text, repeated absence
|
|
13
|
+
markers, record data mixed with absence, and error replies do not become
|
|
14
|
+
available.
|
|
15
|
+
- EVIDENCE: The `.ma` active-state meaning is documented by
|
|
16
|
+
[Registre.ma](https://www.registre.ma/language/en/domain-name/e-statuts);
|
|
17
|
+
IANA lists `whois.registre.ma` for `.ma` and `whois.nic.sh` for `.sh`
|
|
18
|
+
([`.ma`](https://www.iana.org/domains/root/db/ma.html),
|
|
19
|
+
[`.sh`](https://www.iana.org/domains/root/db/sh.html)). Only minimal public
|
|
20
|
+
technical fields and synthetic ambiguity cases are used in tests; no
|
|
21
|
+
personal response data is included.
|
|
22
|
+
- TESTED: The full suite passes 7,024 examples with 0 failures on Ruby 3.2.2
|
|
23
|
+
and 3.4.5. The package smoke check passes on both versions.
|
|
24
|
+
|
|
25
|
+
#### Release 0.4.1 (2026-10-17)
|
|
26
|
+
|
|
27
|
+
- SAFETY: `.lu` records are registered only when the response contains a
|
|
28
|
+
domain name and an exact `domaintype: ACTIVE` field. The exact existing
|
|
29
|
+
absence marker is accepted only without a record; mixed, incomplete, or
|
|
30
|
+
ambiguous replies remain unknown.
|
|
31
|
+
- SAFETY: `.lu` query-rate limits, including the registry's repeated-percent
|
|
32
|
+
`%% Maximum query rate reached` response, raise a throttled-response error
|
|
33
|
+
even when the reply also contains a domain record or absence marker.
|
|
34
|
+
- TESTED: The parser suite passes 7,016 examples with 0 failures and the
|
|
35
|
+
package smoke check passes on Ruby 3.2 and 3.4.5.
|
|
36
|
+
- EVIDENCE: The [2026-10-17 DomScan audit](docs/audits/domscan-whois-usage-2026-10-17.md)
|
|
37
|
+
documents the fixed false-availability path and explains why its fixture
|
|
38
|
+
overlap and bounded replay do not establish 99% live accuracy.
|
|
39
|
+
|
|
5
40
|
#### Release 0.4.0 (2026-09-29)
|
|
6
41
|
|
|
7
42
|
- ADDED: Expanded and tightened first-class parsing for current official WHOIS
|
data/lib/whois/parser/version.rb
CHANGED
|
@@ -11,7 +11,7 @@ module Whois
|
|
|
11
11
|
content_for_scanner.match?(
|
|
12
12
|
/^(?:[ \t]*(?:%|#)[ \t]*)?(?:whois\s+)?query\s+(?:rate\s+)?limit\s+exceeded\b/i
|
|
13
13
|
) || content_for_scanner.match?(
|
|
14
|
-
/^(?:[ \t]*(?:%|#)[ \t]*)?maximum\s+query\s+rate\s+reached\b/i
|
|
14
|
+
/^(?:[ \t]*(?:%|#)+[ \t]*)?maximum\s+query\s+rate\s+reached\b/i
|
|
15
15
|
) || content_for_scanner.match?(
|
|
16
16
|
/^(?:[ \t]*(?:%|#)[ \t]*)?excessive\s+querying\b/i
|
|
17
17
|
) || content_for_scanner.match?(
|
|
@@ -27,17 +27,19 @@ module Whois
|
|
|
27
27
|
include RegistryResponseSafety
|
|
28
28
|
|
|
29
29
|
property_supported :status do
|
|
30
|
-
if
|
|
30
|
+
if response_unavailable? || response_throttled? || (lu_record? && lu_absence?)
|
|
31
|
+
:unknown
|
|
32
|
+
elsif lu_record? && content_for_scanner.match?(/^domaintype:[ \t]+active[ \t]*$/i)
|
|
31
33
|
:registered
|
|
32
|
-
elsif
|
|
34
|
+
elsif lu_absence? && !lu_record?
|
|
33
35
|
:available
|
|
34
36
|
else
|
|
35
|
-
|
|
37
|
+
:unknown
|
|
36
38
|
end
|
|
37
39
|
end
|
|
38
40
|
|
|
39
41
|
property_supported :available? do
|
|
40
|
-
|
|
42
|
+
status == :available
|
|
41
43
|
end
|
|
42
44
|
|
|
43
45
|
property_supported :registered? do
|
|
@@ -92,6 +94,14 @@ module Whois
|
|
|
92
94
|
|
|
93
95
|
private
|
|
94
96
|
|
|
97
|
+
def lu_record?
|
|
98
|
+
content_for_scanner.match?(/^domainname:[ \t]+\S+[ \t]*$/i)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def lu_absence?
|
|
102
|
+
content_for_scanner.match?(/^%[ \t]+No such domain(?:[ \t]*[.:].*)?[ \t]*$/i)
|
|
103
|
+
end
|
|
104
|
+
|
|
95
105
|
def build_contact(element, type)
|
|
96
106
|
return unless (name = value_for_key(format("%s-name", element)))
|
|
97
107
|
|
|
@@ -19,6 +19,33 @@ module Whois
|
|
|
19
19
|
# The Example parser for the list of all available methods.
|
|
20
20
|
#
|
|
21
21
|
class WhoisNicSh < BaseIcb
|
|
22
|
+
self.scanner = Scanners::BaseIcannCompliant, {
|
|
23
|
+
pattern_available: /^(?:NOT FOUND|Domain not found\.)[ \t]*\r?$/i,
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
property_supported :status do
|
|
27
|
+
if absence_marker_count.positive?
|
|
28
|
+
available? ? :available : :unknown
|
|
29
|
+
else
|
|
30
|
+
super()
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
property_supported :available? do
|
|
35
|
+
absence_marker_count == 1 && !record_details_present?
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
def absence_marker_count
|
|
41
|
+
content_for_scanner.scan(/^(?:NOT FOUND|Domain not found\.)[ \t]*\r?$/i).length
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def record_details_present?
|
|
45
|
+
content_for_scanner.match?(
|
|
46
|
+
/^[ \t]*(?:Domain Name|Registry Domain ID|Domain Status|Creation Date|Updated Date|Registry Expiry Date|Registrar|Name Server):/i
|
|
47
|
+
)
|
|
48
|
+
end
|
|
22
49
|
end
|
|
23
50
|
|
|
24
51
|
end
|
|
@@ -77,7 +77,10 @@ module Whois
|
|
|
77
77
|
end
|
|
78
78
|
|
|
79
79
|
def current_record_evidence?
|
|
80
|
-
|
|
80
|
+
[
|
|
81
|
+
['clientTransferProhibited https://icann.org/epp#clientTransferProhibited'],
|
|
82
|
+
['active https://icann.org/epp#active'],
|
|
83
|
+
].include?(domain_status_values)
|
|
81
84
|
end
|
|
82
85
|
|
|
83
86
|
def legacy_record_evidence?
|