public_suffix 2.0.5 → 4.0.7
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 +5 -5
- data/.github/FUNDING.yml +12 -0
- data/.github/dependabot.yml +8 -0
- data/.github/workflows/release.yml +16 -0
- data/.github/workflows/tests.yml +28 -0
- data/.gitignore +5 -8
- data/.rubocop.yml +19 -1
- data/{.rubocop_defaults.yml → .rubocop_opinionated.yml} +62 -34
- data/CHANGELOG.md +156 -54
- data/Gemfile +9 -5
- data/LICENSE.txt +1 -1
- data/README.md +44 -15
- data/Rakefile +9 -4
- data/SECURITY.md +104 -0
- data/bin/console +15 -0
- data/data/list.txt +3163 -973
- data/lib/public_suffix/domain.rb +4 -4
- data/lib/public_suffix/errors.rb +3 -1
- data/lib/public_suffix/list.rb +78 -117
- data/lib/public_suffix/rule.rb +54 -62
- data/lib/public_suffix/version.rb +8 -3
- data/lib/public_suffix.rb +38 -32
- data/public_suffix.gemspec +9 -5
- data/test/.empty +2 -0
- data/test/acceptance_test.rb +43 -31
- data/test/benchmarks/bm_find.rb +66 -0
- data/test/benchmarks/bm_find_all.rb +102 -0
- data/test/benchmarks/bm_names.rb +91 -0
- data/test/benchmarks/bm_select.rb +26 -0
- data/test/benchmarks/bm_select_incremental.rb +25 -0
- data/test/benchmarks/bm_valid.rb +101 -0
- data/test/profilers/domain_profiler.rb +12 -0
- data/test/profilers/find_profiler.rb +12 -0
- data/test/profilers/find_profiler_jp.rb +12 -0
- data/test/{initialization_profiler.rb → profilers/initialization_profiler.rb} +1 -1
- data/test/profilers/list_profsize.rb +11 -0
- data/test/profilers/object_binsize.rb +57 -0
- data/test/psl_test.rb +7 -4
- data/test/test_helper.rb +3 -14
- data/test/unit/domain_test.rb +17 -15
- data/test/unit/errors_test.rb +2 -0
- data/test/unit/list_test.rb +54 -72
- data/test/unit/public_suffix_test.rb +24 -22
- data/test/unit/rule_test.rb +77 -79
- metadata +32 -70
- data/.ruby-gemset +0 -1
- data/.travis.yml +0 -23
- data/test/benchmark_helper.rb +0 -4
- data/test/execution_profiler.rb +0 -14
- data/test/performance_benchmark.rb +0 -38
data/lib/public_suffix/domain.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# = Public Suffix
|
2
4
|
#
|
3
5
|
# Domain name parser based on the Public Suffix List.
|
4
6
|
#
|
5
|
-
# Copyright (c) 2009-
|
7
|
+
# Copyright (c) 2009-2022 Simone Carletti <weppos@weppos.net>
|
6
8
|
|
7
9
|
module PublicSuffix
|
8
10
|
|
@@ -43,7 +45,7 @@ module PublicSuffix
|
|
43
45
|
# Initializes with a +tld+, +sld+ and +trd+.
|
44
46
|
# @param [String] tld The TLD (extension)
|
45
47
|
# @param [String] sld The SLD (domain)
|
46
|
-
# @param [String]
|
48
|
+
# @param [String] trd The TRD (subdomain)
|
47
49
|
#
|
48
50
|
# @yield [self] Yields on self.
|
49
51
|
# @yieldparam [PublicSuffix::Domain] self The newly creates instance
|
@@ -173,8 +175,6 @@ module PublicSuffix
|
|
173
175
|
# This method doesn't actually validate the domain.
|
174
176
|
# It only checks whether the instance contains
|
175
177
|
# a value for the {#tld} and {#sld} attributes.
|
176
|
-
# If you also want to validate the domain,
|
177
|
-
# use {#valid_domain?} instead.
|
178
178
|
#
|
179
179
|
# @example
|
180
180
|
#
|
data/lib/public_suffix/errors.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# = Public Suffix
|
2
4
|
#
|
3
5
|
# Domain name parser based on the Public Suffix List.
|
4
6
|
#
|
5
|
-
# Copyright (c) 2009-
|
7
|
+
# Copyright (c) 2009-2022 Simone Carletti <weppos@weppos.net>
|
6
8
|
|
7
9
|
module PublicSuffix
|
8
10
|
|
data/lib/public_suffix/list.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# = Public Suffix
|
2
4
|
#
|
3
5
|
# Domain name parser based on the Public Suffix List.
|
4
6
|
#
|
5
|
-
# Copyright (c) 2009-
|
7
|
+
# Copyright (c) 2009-2022 Simone Carletti <weppos@weppos.net>
|
6
8
|
|
7
9
|
module PublicSuffix
|
8
10
|
|
@@ -35,12 +37,9 @@ module PublicSuffix
|
|
35
37
|
# The {PublicSuffix::List.default} rule list is used
|
36
38
|
# to tokenize and validate a domain.
|
37
39
|
#
|
38
|
-
# {PublicSuffix::List} implements +Enumerable+ module.
|
39
|
-
#
|
40
40
|
class List
|
41
|
-
include Enumerable
|
42
41
|
|
43
|
-
DEFAULT_LIST_PATH = File.
|
42
|
+
DEFAULT_LIST_PATH = File.expand_path("../../data/list.txt", __dir__)
|
44
43
|
|
45
44
|
# Gets the default rule list.
|
46
45
|
#
|
@@ -49,39 +48,27 @@ module PublicSuffix
|
|
49
48
|
#
|
50
49
|
# @return [PublicSuffix::List]
|
51
50
|
def self.default(**options)
|
52
|
-
@default ||= parse(File.read(DEFAULT_LIST_PATH), options)
|
51
|
+
@default ||= parse(File.read(DEFAULT_LIST_PATH), **options)
|
53
52
|
end
|
54
53
|
|
55
54
|
# Sets the default rule list to +value+.
|
56
55
|
#
|
57
|
-
# @param [PublicSuffix::List]
|
58
|
-
# The new rule list.
|
59
|
-
#
|
56
|
+
# @param value [PublicSuffix::List] the new list
|
60
57
|
# @return [PublicSuffix::List]
|
61
58
|
def self.default=(value)
|
62
59
|
@default = value
|
63
60
|
end
|
64
61
|
|
65
|
-
# Sets the default rule list to +nil+.
|
66
|
-
#
|
67
|
-
# @return [self]
|
68
|
-
def self.clear
|
69
|
-
self.default = nil
|
70
|
-
self
|
71
|
-
end
|
72
|
-
|
73
|
-
# rubocop:disable Metrics/MethodLength
|
74
|
-
|
75
62
|
# Parse given +input+ treating the content as Public Suffix List.
|
76
63
|
#
|
77
64
|
# See http://publicsuffix.org/format/ for more details about input format.
|
78
65
|
#
|
79
|
-
# @param
|
80
|
-
# @param
|
81
|
-
# @return [
|
66
|
+
# @param input [#each_line] the list to parse
|
67
|
+
# @param private_domains [Boolean] whether to ignore the private domains section
|
68
|
+
# @return [PublicSuffix::List]
|
82
69
|
def self.parse(input, private_domains: true)
|
83
|
-
comment_token = "//"
|
84
|
-
private_token = "===BEGIN PRIVATE DOMAINS==="
|
70
|
+
comment_token = "//"
|
71
|
+
private_token = "===BEGIN PRIVATE DOMAINS==="
|
85
72
|
section = nil # 1 == ICANN, 2 == PRIVATE
|
86
73
|
|
87
74
|
new do |list|
|
@@ -96,6 +83,7 @@ module PublicSuffix
|
|
96
83
|
# include private domains or stop scanner
|
97
84
|
when line.include?(private_token)
|
98
85
|
break if !private_domains
|
86
|
+
|
99
87
|
section = 2
|
100
88
|
|
101
89
|
# skip comments
|
@@ -103,53 +91,21 @@ module PublicSuffix
|
|
103
91
|
next
|
104
92
|
|
105
93
|
else
|
106
|
-
list.add(Rule.factory(line, private: section == 2)
|
94
|
+
list.add(Rule.factory(line, private: section == 2))
|
107
95
|
|
108
96
|
end
|
109
97
|
end
|
110
98
|
end
|
111
99
|
end
|
112
|
-
# rubocop:enable Metrics/MethodLength
|
113
|
-
|
114
|
-
|
115
|
-
# Gets the array of rules.
|
116
|
-
#
|
117
|
-
# @return [Array<PublicSuffix::Rule::*>]
|
118
|
-
attr_reader :rules
|
119
100
|
|
120
101
|
|
121
102
|
# Initializes an empty {PublicSuffix::List}.
|
122
103
|
#
|
123
104
|
# @yield [self] Yields on self.
|
124
105
|
# @yieldparam [PublicSuffix::List] self The newly created instance.
|
125
|
-
#
|
126
106
|
def initialize
|
127
|
-
@rules =
|
107
|
+
@rules = {}
|
128
108
|
yield(self) if block_given?
|
129
|
-
reindex!
|
130
|
-
end
|
131
|
-
|
132
|
-
|
133
|
-
# Creates a naive index for +@rules+. Just a hash that will tell
|
134
|
-
# us where the elements of +@rules+ are relative to its first
|
135
|
-
# {PublicSuffix::Rule::Base#labels} element.
|
136
|
-
#
|
137
|
-
# For instance if @rules[5] and @rules[4] are the only elements of the list
|
138
|
-
# where Rule#labels.first is 'us' @indexes['us'] #=> [5,4], that way in
|
139
|
-
# select we can avoid mapping every single rule against the candidate domain.
|
140
|
-
def reindex!
|
141
|
-
@indexes = {}
|
142
|
-
@rules.each_with_index do |rule, index|
|
143
|
-
tld = Domain.name_to_labels(rule.value).last
|
144
|
-
@indexes[tld] ||= []
|
145
|
-
@indexes[tld] << index
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
# Gets the naive index, a hash that with the keys being the first label of
|
150
|
-
# every rule pointing to an array of integers (indexes of the rules in @rules).
|
151
|
-
def indexes
|
152
|
-
@indexes.dup
|
153
109
|
end
|
154
110
|
|
155
111
|
|
@@ -159,42 +115,36 @@ module PublicSuffix
|
|
159
115
|
# {PublicSuffix::List} and each +PublicSuffix::Rule::*+
|
160
116
|
# in list <tt>one</tt> is available in list <tt>two</tt>, in the same order.
|
161
117
|
#
|
162
|
-
# @param [PublicSuffix::List]
|
163
|
-
# The List to compare.
|
164
|
-
#
|
118
|
+
# @param other [PublicSuffix::List] the List to compare
|
165
119
|
# @return [Boolean]
|
166
120
|
def ==(other)
|
167
121
|
return false unless other.is_a?(List)
|
168
|
-
|
122
|
+
|
123
|
+
equal?(other) || @rules == other.rules
|
169
124
|
end
|
170
125
|
alias eql? ==
|
171
126
|
|
172
127
|
# Iterates each rule in the list.
|
173
|
-
def each(
|
174
|
-
|
128
|
+
def each(&block)
|
129
|
+
Enumerator.new do |y|
|
130
|
+
@rules.each do |key, node|
|
131
|
+
y << entry_to_rule(node, key)
|
132
|
+
end
|
133
|
+
end.each(&block)
|
175
134
|
end
|
176
135
|
|
177
136
|
|
178
137
|
# Adds the given object to the list and optionally refreshes the rule index.
|
179
138
|
#
|
180
|
-
# @param [PublicSuffix::Rule::*] rule
|
181
|
-
# The rule to add to the list.
|
182
|
-
# @param [Boolean] reindex
|
183
|
-
# Set to true to recreate the rule index
|
184
|
-
# after the rule has been added to the list.
|
185
|
-
#
|
139
|
+
# @param rule [PublicSuffix::Rule::*] the rule to add to the list
|
186
140
|
# @return [self]
|
187
|
-
|
188
|
-
|
189
|
-
#
|
190
|
-
def add(rule, reindex: true)
|
191
|
-
@rules << rule
|
192
|
-
reindex! if reindex
|
141
|
+
def add(rule)
|
142
|
+
@rules[rule.value] = rule_to_entry(rule)
|
193
143
|
self
|
194
144
|
end
|
195
145
|
alias << add
|
196
146
|
|
197
|
-
# Gets the number of
|
147
|
+
# Gets the number of rules in the list.
|
198
148
|
#
|
199
149
|
# @return [Integer]
|
200
150
|
def size
|
@@ -208,70 +158,65 @@ module PublicSuffix
|
|
208
158
|
@rules.empty?
|
209
159
|
end
|
210
160
|
|
211
|
-
# Removes all
|
161
|
+
# Removes all rules.
|
212
162
|
#
|
213
163
|
# @return [self]
|
214
164
|
def clear
|
215
165
|
@rules.clear
|
216
|
-
reindex!
|
217
166
|
self
|
218
167
|
end
|
219
168
|
|
220
|
-
# Finds and returns the
|
221
|
-
#
|
222
|
-
# From the Public Suffix List documentation:
|
223
|
-
#
|
224
|
-
# - If a hostname matches more than one rule in the file,
|
225
|
-
# the longest matching rule (the one with the most levels) will be used.
|
226
|
-
# - An exclamation mark (!) at the start of a rule marks an exception to a previous wildcard rule.
|
227
|
-
# An exception rule takes priority over any other matching rule.
|
228
|
-
#
|
229
|
-
# ## Algorithm description
|
169
|
+
# Finds and returns the rule corresponding to the longest public suffix for the hostname.
|
230
170
|
#
|
231
|
-
#
|
232
|
-
#
|
233
|
-
# 3. If more than one rule matches, the prevailing rule is the one which is an exception rule.
|
234
|
-
# 4. If there is no matching exception rule, the prevailing rule is the one with the most labels.
|
235
|
-
# 5. If the prevailing rule is a exception rule, modify it by removing the leftmost label.
|
236
|
-
# 6. The public suffix is the set of labels from the domain
|
237
|
-
# which directly match the labels of the prevailing rule (joined by dots).
|
238
|
-
# 7. The registered domain is the public suffix plus one additional label.
|
239
|
-
#
|
240
|
-
# @param name [String, #to_s] The domain name.
|
241
|
-
# @param [PublicSuffix::Rule::*] default The default rule to return in case no rule matches.
|
171
|
+
# @param name [#to_s] the hostname
|
172
|
+
# @param default [PublicSuffix::Rule::*] the default rule to return in case no rule matches
|
242
173
|
# @return [PublicSuffix::Rule::*]
|
243
174
|
def find(name, default: default_rule, **options)
|
244
175
|
rule = select(name, **options).inject do |l, r|
|
245
|
-
return r if r.
|
176
|
+
return r if r.instance_of?(Rule::Exception)
|
177
|
+
|
246
178
|
l.length > r.length ? l : r
|
247
179
|
end
|
248
180
|
rule || default
|
249
181
|
end
|
250
182
|
|
251
|
-
# Selects all the rules matching given
|
252
|
-
#
|
253
|
-
# Internally, the lookup heavily rely on the `@indexes`. The input is split into labels,
|
254
|
-
# and we retriever from the index only the rules that end with the input label. After that,
|
255
|
-
# a sequential scan is performed. In most cases, where the number of rules for the same label
|
256
|
-
# is limited, this algorithm is efficient enough.
|
183
|
+
# Selects all the rules matching given hostame.
|
257
184
|
#
|
258
|
-
# If `ignore_private` is set to true, the algorithm will skip the rules that are flagged as
|
259
|
-
# Note that the rules will still be part of the loop.
|
260
|
-
#
|
185
|
+
# If `ignore_private` is set to true, the algorithm will skip the rules that are flagged as
|
186
|
+
# private domain. Note that the rules will still be part of the loop.
|
187
|
+
# If you frequently need to access lists ignoring the private domains,
|
188
|
+
# you should create a list that doesn't include these domains setting the
|
261
189
|
# `private_domains: false` option when calling {.parse}.
|
262
190
|
#
|
263
|
-
#
|
264
|
-
#
|
191
|
+
# Note that this method is currently private, as you should not rely on it. Instead,
|
192
|
+
# the public interface is {#find}. The current internal algorithm allows to return all
|
193
|
+
# matching rules, but different data structures may not be able to do it, and instead would
|
194
|
+
# return only the match. For this reason, you should rely on {#find}.
|
195
|
+
#
|
196
|
+
# @param name [#to_s] the hostname
|
197
|
+
# @param ignore_private [Boolean]
|
265
198
|
# @return [Array<PublicSuffix::Rule::*>]
|
266
199
|
def select(name, ignore_private: false)
|
267
200
|
name = name.to_s
|
268
|
-
indices = (@indexes[Domain.name_to_labels(name).last] || [])
|
269
201
|
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
202
|
+
parts = name.split(DOT).reverse!
|
203
|
+
index = 0
|
204
|
+
query = parts[index]
|
205
|
+
rules = []
|
206
|
+
|
207
|
+
loop do
|
208
|
+
match = @rules[query]
|
209
|
+
rules << entry_to_rule(match, query) if !match.nil? && (ignore_private == false || match.private == false)
|
210
|
+
|
211
|
+
index += 1
|
212
|
+
break if index >= parts.size
|
213
|
+
|
214
|
+
query = parts[index] + DOT + query
|
215
|
+
end
|
216
|
+
|
217
|
+
rules
|
274
218
|
end
|
219
|
+
private :select
|
275
220
|
|
276
221
|
# Gets the default rule.
|
277
222
|
#
|
@@ -282,5 +227,21 @@ module PublicSuffix
|
|
282
227
|
PublicSuffix::Rule.default
|
283
228
|
end
|
284
229
|
|
230
|
+
|
231
|
+
protected
|
232
|
+
|
233
|
+
attr_reader :rules
|
234
|
+
|
235
|
+
|
236
|
+
private
|
237
|
+
|
238
|
+
def entry_to_rule(entry, value)
|
239
|
+
entry.type.new(value: value, length: entry.length, private: entry.private)
|
240
|
+
end
|
241
|
+
|
242
|
+
def rule_to_entry(rule)
|
243
|
+
Rule::Entry.new(rule.class, rule.length, rule.private)
|
244
|
+
end
|
245
|
+
|
285
246
|
end
|
286
247
|
end
|
data/lib/public_suffix/rule.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# = Public Suffix
|
2
4
|
#
|
3
5
|
# Domain name parser based on the Public Suffix List.
|
4
6
|
#
|
5
|
-
# Copyright (c) 2009-
|
7
|
+
# Copyright (c) 2009-2022 Simone Carletti <weppos@weppos.net>
|
6
8
|
|
7
9
|
module PublicSuffix
|
8
10
|
|
@@ -19,6 +21,9 @@ module PublicSuffix
|
|
19
21
|
#
|
20
22
|
module Rule
|
21
23
|
|
24
|
+
# @api internal
|
25
|
+
Entry = Struct.new(:type, :length, :private) # rubocop:disable Lint/StructNewOverride
|
26
|
+
|
22
27
|
# = Abstract rule class
|
23
28
|
#
|
24
29
|
# This represent the base class for a Rule definition
|
@@ -99,25 +104,36 @@ module PublicSuffix
|
|
99
104
|
# @return [String] the rule definition
|
100
105
|
attr_reader :value
|
101
106
|
|
107
|
+
# @return [String] the length of the rule
|
108
|
+
attr_reader :length
|
109
|
+
|
102
110
|
# @return [Boolean] true if the rule is a private domain
|
103
111
|
attr_reader :private
|
104
112
|
|
105
113
|
|
106
|
-
# Initializes a new rule
|
107
|
-
#
|
114
|
+
# Initializes a new rule from the content.
|
115
|
+
#
|
116
|
+
# @param content [String] the content of the rule
|
117
|
+
# @param private [Boolean]
|
118
|
+
def self.build(content, private: false)
|
119
|
+
new(value: content, private: private)
|
120
|
+
end
|
121
|
+
|
122
|
+
# Initializes a new rule.
|
108
123
|
#
|
109
|
-
# @param
|
110
|
-
|
124
|
+
# @param value [String]
|
125
|
+
# @param private [Boolean]
|
126
|
+
def initialize(value:, length: nil, private: false)
|
111
127
|
@value = value.to_s
|
128
|
+
@length = length || @value.count(DOT) + 1
|
112
129
|
@private = private
|
113
130
|
end
|
114
131
|
|
115
132
|
# Checks whether this rule is equal to <tt>other</tt>.
|
116
133
|
#
|
117
|
-
# @param [PublicSuffix::Rule::*]
|
118
|
-
# @return [Boolean]
|
119
|
-
#
|
120
|
-
# and has the same value, false otherwise.
|
134
|
+
# @param other [PublicSuffix::Rule::*] The rule to compare
|
135
|
+
# @return [Boolean] true if this rule and other are instances of the same class
|
136
|
+
# and has the same value, false otherwise.
|
121
137
|
def ==(other)
|
122
138
|
equal?(other) || (self.class == other.class && value == other.value)
|
123
139
|
end
|
@@ -137,12 +153,12 @@ module PublicSuffix
|
|
137
153
|
# @see https://publicsuffix.org/list/
|
138
154
|
#
|
139
155
|
# @example
|
140
|
-
# Rule.factory("com").match?("example.com")
|
156
|
+
# PublicSuffix::Rule.factory("com").match?("example.com")
|
141
157
|
# # => true
|
142
|
-
# Rule.factory("com").match?("example.net")
|
158
|
+
# PublicSuffix::Rule.factory("com").match?("example.net")
|
143
159
|
# # => false
|
144
160
|
#
|
145
|
-
# @param name [String
|
161
|
+
# @param name [String] the domain name to check
|
146
162
|
# @return [Boolean]
|
147
163
|
def match?(name)
|
148
164
|
# Note: it works because of the assumption there are no
|
@@ -150,7 +166,7 @@ module PublicSuffix
|
|
150
166
|
# we need to properly walk the input and skip parts according
|
151
167
|
# to wildcard component.
|
152
168
|
diff = name.chomp(value)
|
153
|
-
diff.empty? || diff
|
169
|
+
diff.empty? || diff.end_with?(DOT)
|
154
170
|
end
|
155
171
|
|
156
172
|
# @abstract
|
@@ -159,12 +175,7 @@ module PublicSuffix
|
|
159
175
|
end
|
160
176
|
|
161
177
|
# @abstract
|
162
|
-
|
163
|
-
raise NotImplementedError
|
164
|
-
end
|
165
|
-
|
166
|
-
# @abstract
|
167
|
-
# @param [String, #to_s] name The domain name to decompose
|
178
|
+
# @param domain [#to_s] The domain name to decompose
|
168
179
|
# @return [Array<String, nil>]
|
169
180
|
def decompose(*)
|
170
181
|
raise NotImplementedError
|
@@ -184,7 +195,7 @@ module PublicSuffix
|
|
184
195
|
|
185
196
|
# Decomposes the domain name according to rule properties.
|
186
197
|
#
|
187
|
-
# @param [
|
198
|
+
# @param domain [#to_s] The domain name to decompose
|
188
199
|
# @return [Array<String>] The array with [trd + sld, tld].
|
189
200
|
def decompose(domain)
|
190
201
|
suffix = parts.join('\.')
|
@@ -200,27 +211,27 @@ module PublicSuffix
|
|
200
211
|
@value.split(DOT)
|
201
212
|
end
|
202
213
|
|
203
|
-
# Gets the length of this rule for comparison,
|
204
|
-
# represented by the number of dot-separated parts in the rule.
|
205
|
-
#
|
206
|
-
# @return [Integer] The length of the rule.
|
207
|
-
def length
|
208
|
-
@length ||= parts.length
|
209
|
-
end
|
210
|
-
|
211
214
|
end
|
212
215
|
|
213
216
|
# Wildcard represents a wildcard rule (e.g. *.co.uk).
|
214
217
|
class Wildcard < Base
|
215
218
|
|
216
|
-
# Initializes a new rule from
|
219
|
+
# Initializes a new rule from the content.
|
217
220
|
#
|
218
|
-
#
|
219
|
-
#
|
221
|
+
# @param content [String] the content of the rule
|
222
|
+
# @param private [Boolean]
|
223
|
+
def self.build(content, private: false)
|
224
|
+
new(value: content.to_s[2..-1], private: private)
|
225
|
+
end
|
226
|
+
|
227
|
+
# Initializes a new rule.
|
220
228
|
#
|
221
|
-
# @param
|
222
|
-
|
223
|
-
|
229
|
+
# @param value [String]
|
230
|
+
# @param length [Integer]
|
231
|
+
# @param private [Boolean]
|
232
|
+
def initialize(value:, length: nil, private: false)
|
233
|
+
super(value: value, length: length, private: private)
|
234
|
+
length or @length += 1 # * counts as 1
|
224
235
|
end
|
225
236
|
|
226
237
|
# Gets the original rule definition.
|
@@ -232,7 +243,7 @@ module PublicSuffix
|
|
232
243
|
|
233
244
|
# Decomposes the domain name according to rule properties.
|
234
245
|
#
|
235
|
-
# @param [
|
246
|
+
# @param domain [#to_s] The domain name to decompose
|
236
247
|
# @return [Array<String>] The array with [trd + sld, tld].
|
237
248
|
def decompose(domain)
|
238
249
|
suffix = ([".*?"] + parts).join('\.')
|
@@ -248,28 +259,17 @@ module PublicSuffix
|
|
248
259
|
@value.split(DOT)
|
249
260
|
end
|
250
261
|
|
251
|
-
# Gets the length of this rule for comparison,
|
252
|
-
# represented by the number of dot-separated parts in the rule
|
253
|
-
# plus 1 for the *.
|
254
|
-
#
|
255
|
-
# @return [Integer] The length of the rule.
|
256
|
-
def length
|
257
|
-
@length ||= parts.length + 1 # * counts as 1
|
258
|
-
end
|
259
|
-
|
260
262
|
end
|
261
263
|
|
262
264
|
# Exception represents an exception rule (e.g. !parliament.uk).
|
263
265
|
class Exception < Base
|
264
266
|
|
265
|
-
# Initializes a new rule from
|
266
|
-
#
|
267
|
-
# The bang ! is removed from the value, as it's common
|
268
|
-
# for each wildcard rule.
|
267
|
+
# Initializes a new rule from the content.
|
269
268
|
#
|
270
|
-
# @param
|
271
|
-
|
272
|
-
|
269
|
+
# @param content [#to_s] the content of the rule
|
270
|
+
# @param private [Boolean]
|
271
|
+
def self.build(content, private: false)
|
272
|
+
new(value: content.to_s[1..-1], private: private)
|
273
273
|
end
|
274
274
|
|
275
275
|
# Gets the original rule definition.
|
@@ -281,7 +281,7 @@ module PublicSuffix
|
|
281
281
|
|
282
282
|
# Decomposes the domain name according to rule properties.
|
283
283
|
#
|
284
|
-
# @param [
|
284
|
+
# @param domain [#to_s] The domain name to decompose
|
285
285
|
# @return [Array<String>] The array with [trd + sld, tld].
|
286
286
|
def decompose(domain)
|
287
287
|
suffix = parts.join('\.')
|
@@ -302,14 +302,6 @@ module PublicSuffix
|
|
302
302
|
@value.split(DOT)[1..-1]
|
303
303
|
end
|
304
304
|
|
305
|
-
# Gets the length of this rule for comparison,
|
306
|
-
# represented by the number of dot-separated parts in the rule.
|
307
|
-
#
|
308
|
-
# @return [Integer] The length of the rule.
|
309
|
-
def length
|
310
|
-
@length ||= parts.length
|
311
|
-
end
|
312
|
-
|
313
305
|
end
|
314
306
|
|
315
307
|
|
@@ -329,7 +321,7 @@ module PublicSuffix
|
|
329
321
|
# PublicSuffix::Rule.factory("!congresodelalengua3.ar")
|
330
322
|
# # => #<PublicSuffix::Rule::Exception>
|
331
323
|
#
|
332
|
-
# @param [
|
324
|
+
# @param content [#to_s] the content of the rule
|
333
325
|
# @return [PublicSuffix::Rule::*] A rule instance.
|
334
326
|
def self.factory(content, private: false)
|
335
327
|
case content.to_s[0, 1]
|
@@ -339,7 +331,7 @@ module PublicSuffix
|
|
339
331
|
Exception
|
340
332
|
else
|
341
333
|
Normal
|
342
|
-
end.
|
334
|
+
end.build(content, private: private)
|
343
335
|
end
|
344
336
|
|
345
337
|
# The default rule to use if no rule match.
|
@@ -1,10 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
1
4
|
# = Public Suffix
|
2
5
|
#
|
3
6
|
# Domain name parser based on the Public Suffix List.
|
4
7
|
#
|
5
|
-
# Copyright (c) 2009-
|
8
|
+
# Copyright (c) 2009-2022 Simone Carletti <weppos@weppos.net>
|
6
9
|
|
7
10
|
module PublicSuffix
|
8
|
-
|
9
|
-
|
11
|
+
|
12
|
+
# @return [String] The current library version.
|
13
|
+
VERSION = "4.0.7"
|
14
|
+
|
10
15
|
end
|