net-imap 0.3.7 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/pages.yml +46 -0
- data/.github/workflows/test.yml +5 -12
- data/Gemfile +1 -0
- data/README.md +15 -4
- data/Rakefile +0 -7
- data/benchmarks/generate_parser_benchmarks +52 -0
- data/benchmarks/parser.yml +578 -0
- data/benchmarks/stringprep.yml +1 -1
- data/lib/net/imap/authenticators.rb +26 -57
- data/lib/net/imap/command_data.rb +13 -6
- data/lib/net/imap/deprecated_client_options.rb +139 -0
- data/lib/net/imap/response_data.rb +46 -41
- data/lib/net/imap/response_parser/parser_utils.rb +230 -0
- data/lib/net/imap/response_parser.rb +665 -627
- data/lib/net/imap/sasl/anonymous_authenticator.rb +68 -0
- data/lib/net/imap/sasl/authentication_exchange.rb +107 -0
- data/lib/net/imap/sasl/authenticators.rb +118 -0
- data/lib/net/imap/sasl/client_adapter.rb +72 -0
- data/lib/net/imap/{authenticators/cram_md5.rb → sasl/cram_md5_authenticator.rb} +15 -9
- data/lib/net/imap/{authenticators/digest_md5.rb → sasl/digest_md5_authenticator.rb} +74 -21
- data/lib/net/imap/sasl/external_authenticator.rb +62 -0
- data/lib/net/imap/sasl/gs2_header.rb +80 -0
- data/lib/net/imap/{authenticators/login.rb → sasl/login_authenticator.rb} +19 -14
- data/lib/net/imap/sasl/oauthbearer_authenticator.rb +164 -0
- data/lib/net/imap/sasl/plain_authenticator.rb +93 -0
- data/lib/net/imap/sasl/protocol_adapters.rb +45 -0
- data/lib/net/imap/sasl/scram_algorithm.rb +58 -0
- data/lib/net/imap/sasl/scram_authenticator.rb +278 -0
- data/lib/net/imap/sasl/stringprep.rb +6 -66
- data/lib/net/imap/sasl/xoauth2_authenticator.rb +88 -0
- data/lib/net/imap/sasl.rb +144 -43
- data/lib/net/imap/sasl_adapter.rb +21 -0
- data/lib/net/imap/stringprep/nameprep.rb +70 -0
- data/lib/net/imap/stringprep/saslprep.rb +69 -0
- data/lib/net/imap/stringprep/saslprep_tables.rb +96 -0
- data/lib/net/imap/stringprep/tables.rb +146 -0
- data/lib/net/imap/stringprep/trace.rb +85 -0
- data/lib/net/imap/stringprep.rb +159 -0
- data/lib/net/imap.rb +976 -590
- data/net-imap.gemspec +1 -1
- data/rakelib/saslprep.rake +4 -4
- data/rakelib/string_prep_tables_generator.rb +82 -60
- metadata +30 -11
- data/lib/net/imap/authenticators/plain.rb +0 -41
- data/lib/net/imap/authenticators/xoauth2.rb +0 -20
- data/lib/net/imap/sasl/saslprep.rb +0 -55
- data/lib/net/imap/sasl/saslprep_tables.rb +0 -98
- data/lib/net/imap/sasl/stringprep_tables.rb +0 -153
data/net-imap.gemspec
CHANGED
@@ -16,7 +16,7 @@ Gem::Specification.new do |spec|
|
|
16
16
|
spec.summary = %q{Ruby client api for Internet Message Access Protocol}
|
17
17
|
spec.description = %q{Ruby client api for Internet Message Access Protocol}
|
18
18
|
spec.homepage = "https://github.com/ruby/net-imap"
|
19
|
-
spec.required_ruby_version = Gem::Requirement.new(">= 2.
|
19
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.7.3")
|
20
20
|
spec.licenses = ["Ruby", "BSD-2-Clause"]
|
21
21
|
|
22
22
|
spec.metadata["homepage_uri"] = spec.homepage
|
data/rakelib/saslprep.rake
CHANGED
@@ -10,17 +10,17 @@ end
|
|
10
10
|
|
11
11
|
directory "lib/net/imap/sasl"
|
12
12
|
|
13
|
-
file "lib/net/imap/
|
13
|
+
file "lib/net/imap/stringprep/tables.rb" => generator.rb_deps do |t|
|
14
14
|
File.write t.name, generator.stringprep_rb
|
15
15
|
end
|
16
16
|
|
17
|
-
file "lib/net/imap/
|
17
|
+
file "lib/net/imap/stringprep/saslprep_tables.rb" => generator.rb_deps do |t|
|
18
18
|
File.write t.name, generator.saslprep_rb
|
19
19
|
end
|
20
20
|
|
21
21
|
GENERATED_RUBY = FileList.new(
|
22
|
-
"lib/net/imap/
|
23
|
-
"lib/net/imap/
|
22
|
+
"lib/net/imap/stringprep/tables.rb",
|
23
|
+
"lib/net/imap/stringprep/saslprep_tables.rb",
|
24
24
|
)
|
25
25
|
|
26
26
|
CLEAN.include generator.clean_deps
|
@@ -62,9 +62,9 @@ class StringPrepTablesGenerator
|
|
62
62
|
# This file is generated from RFC3454, by rake. Don't edit directly.
|
63
63
|
#++
|
64
64
|
|
65
|
-
module Net::IMAP::
|
65
|
+
module Net::IMAP::StringPrep
|
66
66
|
|
67
|
-
module
|
67
|
+
module Tables
|
68
68
|
|
69
69
|
#{asgn_table "A.1"}
|
70
70
|
|
@@ -74,6 +74,12 @@ class StringPrepTablesGenerator
|
|
74
74
|
|
75
75
|
#{asgn_table "B.3"}
|
76
76
|
|
77
|
+
#{asgn_mapping "B.1", ""}
|
78
|
+
|
79
|
+
#{asgn_mapping "B.2"}
|
80
|
+
|
81
|
+
#{asgn_mapping "B.3"}
|
82
|
+
|
77
83
|
#{asgn_table "C.1.1"}
|
78
84
|
|
79
85
|
#{asgn_table "C.1.2"}
|
@@ -105,14 +111,16 @@ class StringPrepTablesGenerator
|
|
105
111
|
|
106
112
|
BIDI_DESC_REQ2 = "A string with RandALCat characters must not contain LCat characters."
|
107
113
|
|
108
|
-
# Bidirectional Characters [StringPrep, §6], Requirement 2
|
114
|
+
# Bidirectional Characters [StringPrep, §6], Requirement 2
|
115
|
+
# >>>
|
109
116
|
# If a string contains any RandALCat character, the string MUST NOT
|
110
117
|
# contain any LCat character.
|
111
118
|
BIDI_FAILS_REQ2 = #{bidi_fails_req2.inspect}.freeze
|
112
119
|
|
113
120
|
BIDI_DESC_REQ3 = "A string with RandALCat characters must start and end with RandALCat characters."
|
114
121
|
|
115
|
-
# Bidirectional Characters [StringPrep, §6], Requirement 3
|
122
|
+
# Bidirectional Characters [StringPrep, §6], Requirement 3
|
123
|
+
# >>>
|
116
124
|
# If a string contains any RandALCat character, a RandALCat
|
117
125
|
# character MUST be the first character of the string, and a
|
118
126
|
# RandALCat character MUST be the last character of the string.
|
@@ -122,15 +130,21 @@ class StringPrepTablesGenerator
|
|
122
130
|
BIDI_FAILURE = #{bidi_failure_regexp.inspect}.freeze
|
123
131
|
|
124
132
|
# Names of each codepoint table in the RFC-3454 appendices
|
125
|
-
|
133
|
+
TITLES = {
|
126
134
|
#{table_titles_rb}
|
127
135
|
}.freeze
|
128
136
|
|
129
137
|
# Regexps matching each codepoint table in the RFC-3454 appendices
|
130
|
-
|
138
|
+
REGEXPS = {
|
131
139
|
#{table_regexps_rb}
|
132
140
|
}.freeze
|
133
141
|
|
142
|
+
MAPPINGS = {
|
143
|
+
"B.1" => [IN_B_1, MAP_B_1].freeze,
|
144
|
+
"B.2" => [IN_B_2, MAP_B_2].freeze,
|
145
|
+
"B.3" => [IN_B_3, MAP_B_3].freeze,
|
146
|
+
}.freeze
|
147
|
+
|
134
148
|
end
|
135
149
|
end
|
136
150
|
RUBY
|
@@ -157,27 +171,30 @@ class StringPrepTablesGenerator
|
|
157
171
|
# This file is generated from RFC3454, by rake. Don't edit directly.
|
158
172
|
#++
|
159
173
|
|
160
|
-
module Net::IMAP::
|
174
|
+
module Net::IMAP::StringPrep
|
161
175
|
|
162
176
|
module SASLprep
|
163
177
|
|
164
178
|
# RFC4013 §2.1 Mapping - mapped to space
|
165
|
-
#
|
166
|
-
#
|
179
|
+
# >>>
|
180
|
+
# non-ASCII space characters (\\StringPrep\\[\\"C.1.2\\"]) that can
|
181
|
+
# be mapped to SPACE (U+0020)
|
167
182
|
#
|
168
183
|
# Equal to \\StringPrep\\[\\"C.1.2\\"].
|
169
|
-
# Redefined here to avoid loading
|
184
|
+
# Redefined here to avoid loading StringPrep::Tables unless necessary.
|
170
185
|
MAP_TO_SPACE = #{regex_str "C.1.2"}
|
171
186
|
|
172
187
|
# RFC4013 §2.1 Mapping - mapped to nothing
|
173
|
-
#
|
174
|
-
#
|
188
|
+
# >>>
|
189
|
+
# the "commonly mapped to nothing" characters
|
190
|
+
# (\\StringPrep\\[\\"B.1\\"]) that can be mapped to nothing.
|
175
191
|
#
|
176
192
|
# Equal to \\StringPrep\\[\\"B.1\\"].
|
177
|
-
# Redefined here to avoid loading
|
193
|
+
# Redefined here to avoid loading StringPrep::Tables unless necessary.
|
178
194
|
MAP_TO_NOTHING = #{regex_str "B.1"}
|
179
195
|
|
180
|
-
# RFC4013 §2.3 Prohibited Output
|
196
|
+
# RFC4013 §2.3 Prohibited Output
|
197
|
+
# >>>
|
181
198
|
# * Non-ASCII space characters — \\StringPrep\\[\\"C.1.2\\"]
|
182
199
|
# * ASCII control characters — \\StringPrep\\[\\"C.2.1\\"]
|
183
200
|
# * Non-ASCII control characters — \\StringPrep\\[\\"C.2.2\\"]
|
@@ -192,45 +209,52 @@ class StringPrepTablesGenerator
|
|
192
209
|
|
193
210
|
# Adds unassigned (by Unicode 3.2) codepoints to TABLES_PROHIBITED.
|
194
211
|
#
|
195
|
-
# RFC4013 §2.5 Unassigned Code Points
|
196
|
-
#
|
197
|
-
#
|
212
|
+
# RFC4013 §2.5 Unassigned Code Points
|
213
|
+
# >>>
|
214
|
+
# This profile specifies the \\StringPrep\\[\\"A.1\\"] table as its
|
215
|
+
# list of unassigned code points.
|
198
216
|
TABLES_PROHIBITED_STORED = ["A.1", *TABLES_PROHIBITED].freeze
|
199
217
|
|
200
|
-
#
|
218
|
+
# A Regexp matching codepoints prohibited by RFC4013 §2.3.
|
201
219
|
#
|
202
|
-
#
|
203
|
-
#
|
204
|
-
# Equal to +Regexp.union+ of the TABLES_PROHIBITED tables. Redefined
|
205
|
-
# here to avoid loading the StringPrep module unless necessary.
|
220
|
+
# This combines all of the TABLES_PROHIBITED tables.
|
206
221
|
PROHIBITED_OUTPUT = #{regex_str(*SASL_TABLES_PROHIBITED)}
|
207
222
|
|
208
|
-
# RFC4013 §2.5 Unassigned Code Points
|
209
|
-
#
|
210
|
-
#
|
223
|
+
# RFC4013 §2.5 Unassigned Code Points
|
224
|
+
# >>>
|
225
|
+
# This profile specifies the \\StringPrep\\[\\"A.1\\"] table as its
|
226
|
+
# list of unassigned code points.
|
227
|
+
#
|
228
|
+
# Equal to \\StringPrep\\[\\"A.1\\"].
|
229
|
+
# Redefined here to avoid loading StringPrep::Tables unless necessary.
|
211
230
|
UNASSIGNED = #{regex_str "A.1"}
|
212
231
|
|
213
|
-
#
|
232
|
+
# A Regexp matching codepoints prohibited by RFC4013 §2.3 and §2.5.
|
214
233
|
#
|
215
|
-
#
|
234
|
+
# This combines PROHIBITED_OUTPUT and UNASSIGNED.
|
216
235
|
PROHIBITED_OUTPUT_STORED = Regexp.union(
|
217
236
|
UNASSIGNED, PROHIBITED_OUTPUT
|
218
237
|
).freeze
|
219
238
|
|
220
239
|
# Bidirectional Characters [StringPrep, §6]
|
240
|
+
#
|
241
|
+
# A Regexp for strings that don't satisfy StringPrep's Bidirectional
|
242
|
+
# Characters rules.
|
243
|
+
#
|
244
|
+
# Equal to StringPrep::Tables::BIDI_FAILURE.
|
245
|
+
# Redefined here to avoid loading StringPrep::Tables unless necessary.
|
221
246
|
BIDI_FAILURE = #{bidi_failure_regexp.inspect}.freeze
|
222
247
|
|
223
|
-
#
|
248
|
+
# A Regexp matching strings prohibited by RFC4013 §2.3 and §2.4.
|
224
249
|
#
|
225
|
-
# This
|
250
|
+
# This combines PROHIBITED_OUTPUT and BIDI_FAILURE.
|
226
251
|
PROHIBITED = Regexp.union(
|
227
252
|
PROHIBITED_OUTPUT, BIDI_FAILURE,
|
228
253
|
)
|
229
254
|
|
230
|
-
#
|
255
|
+
# A Regexp matching strings prohibited by RFC4013 §2.3, §2.4, and §2.5.
|
231
256
|
#
|
232
|
-
# This
|
233
|
-
# unassigned codepoints.
|
257
|
+
# This combines PROHIBITED_OUTPUT_STORED and BIDI_FAILURE.
|
234
258
|
PROHIBITED_STORED = Regexp.union(
|
235
259
|
PROHIBITED_OUTPUT_STORED, BIDI_FAILURE,
|
236
260
|
)
|
@@ -284,6 +308,15 @@ class StringPrepTablesGenerator
|
|
284
308
|
.map{|s,e| s..(e || s)}
|
285
309
|
end
|
286
310
|
|
311
|
+
# TODO: DRY with unicode_normalize
|
312
|
+
def to_map(table)
|
313
|
+
table = table.to_hash
|
314
|
+
.transform_keys { Integer _1, 16 }
|
315
|
+
.transform_keys { [_1].pack("U*") }
|
316
|
+
.transform_values {|cps| cps.map { Integer _1, 16 } }
|
317
|
+
.transform_values { _1.pack("U*") }
|
318
|
+
end
|
319
|
+
|
287
320
|
# Starting from a codepoints array (rather than ranges) to deduplicate merged
|
288
321
|
# tables.
|
289
322
|
def to_regexp(codepoints, negate: false)
|
@@ -352,6 +385,13 @@ class StringPrepTablesGenerator
|
|
352
385
|
asgn_regex(name, regexp_for(name, negate: negate), negate: negate)
|
353
386
|
end
|
354
387
|
|
388
|
+
def asgn_mapping(name, replacement = to_map(tables[name]))
|
389
|
+
cname = name.tr(?., ?_).upcase
|
390
|
+
"# Replacements for %s\n%s%s = %p.freeze" % [
|
391
|
+
"IN_#{name}", " " * 2, "MAP_#{cname}", replacement,
|
392
|
+
]
|
393
|
+
end
|
394
|
+
|
355
395
|
def regexp_const_desc(name, negate: false)
|
356
396
|
if negate then "Matches the negation of the %s table" % [name]
|
357
397
|
else %q{%s \\StringPrep\\[\\"%s\\"]} % [titles.fetch(name), name]
|
@@ -376,40 +416,22 @@ class StringPrepTablesGenerator
|
|
376
416
|
def bidi_L ; regexp_for "D.2" end
|
377
417
|
|
378
418
|
def bidi_fails_req2
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
| # RandALCat preceded by LCat
|
384
|
-
\g<l_cat> .*? \g<r_and_al_cat>
|
385
|
-
/mux
|
419
|
+
Regexp.union(
|
420
|
+
/#{bidi_R_AL}.*?#{bidi_L}/mu, # RandALCat followed by LCat
|
421
|
+
/#{bidi_L}.*?#{bidi_R_AL}/mu, # RandALCat preceded by LCat
|
422
|
+
)
|
386
423
|
end
|
387
424
|
|
388
425
|
def bidi_fails_req3
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
\g<r_and_al_cat> .*? \g<not_r_nor_al>\z
|
395
|
-
/mux
|
426
|
+
# contains RandALCat:
|
427
|
+
Regexp.union(
|
428
|
+
/\A#{bidi_not_R_AL}.*?#{bidi_R_AL}/mu, # but doesn't start with RandALCat
|
429
|
+
/#{bidi_R_AL}.*?#{bidi_not_R_AL}\z/mu, # but doesn't end with RandALCat
|
430
|
+
)
|
396
431
|
end
|
397
432
|
|
398
|
-
# shares the bidi_R_AL definition between both req2 and req3
|
399
433
|
def bidi_failure_regexp
|
400
|
-
|
401
|
-
.gsub(%r{\(\?\<r_and_al_cat\>\(.*?\)\)}, "\g<r_and_al_cat>")
|
402
|
-
.then{|re|"(?mx-i:#{re})"}
|
403
|
-
/#{bidi_fails_req2} | #{req3_with_backref}/mux
|
404
|
-
end
|
405
|
-
|
406
|
-
def bidi_consts
|
407
|
-
<<~RUBY
|
408
|
-
#############
|
409
|
-
# Bidirectional checks.
|
410
|
-
#
|
411
|
-
|
412
|
-
RUBY
|
434
|
+
Regexp.union(bidi_fails_req2, bidi_fails_req3)
|
413
435
|
end
|
414
436
|
|
415
437
|
SASL_TABLES_PROHIBITED = %w[
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: net-imap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shugo Maeda
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2023-
|
12
|
+
date: 2023-10-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: net-protocol
|
@@ -76,33 +76,52 @@ extensions: []
|
|
76
76
|
extra_rdoc_files: []
|
77
77
|
files:
|
78
78
|
- ".github/dependabot.yml"
|
79
|
+
- ".github/workflows/pages.yml"
|
79
80
|
- ".github/workflows/test.yml"
|
80
81
|
- ".gitignore"
|
81
82
|
- Gemfile
|
82
83
|
- LICENSE.txt
|
83
84
|
- README.md
|
84
85
|
- Rakefile
|
86
|
+
- benchmarks/generate_parser_benchmarks
|
87
|
+
- benchmarks/parser.yml
|
85
88
|
- benchmarks/stringprep.yml
|
86
89
|
- benchmarks/table-regexps.yml
|
87
90
|
- docs/styles.css
|
88
91
|
- lib/net/imap.rb
|
89
92
|
- lib/net/imap/authenticators.rb
|
90
|
-
- lib/net/imap/authenticators/cram_md5.rb
|
91
|
-
- lib/net/imap/authenticators/digest_md5.rb
|
92
|
-
- lib/net/imap/authenticators/login.rb
|
93
|
-
- lib/net/imap/authenticators/plain.rb
|
94
|
-
- lib/net/imap/authenticators/xoauth2.rb
|
95
93
|
- lib/net/imap/command_data.rb
|
96
94
|
- lib/net/imap/data_encoding.rb
|
95
|
+
- lib/net/imap/deprecated_client_options.rb
|
97
96
|
- lib/net/imap/errors.rb
|
98
97
|
- lib/net/imap/flags.rb
|
99
98
|
- lib/net/imap/response_data.rb
|
100
99
|
- lib/net/imap/response_parser.rb
|
100
|
+
- lib/net/imap/response_parser/parser_utils.rb
|
101
101
|
- lib/net/imap/sasl.rb
|
102
|
-
- lib/net/imap/sasl/
|
103
|
-
- lib/net/imap/sasl/
|
102
|
+
- lib/net/imap/sasl/anonymous_authenticator.rb
|
103
|
+
- lib/net/imap/sasl/authentication_exchange.rb
|
104
|
+
- lib/net/imap/sasl/authenticators.rb
|
105
|
+
- lib/net/imap/sasl/client_adapter.rb
|
106
|
+
- lib/net/imap/sasl/cram_md5_authenticator.rb
|
107
|
+
- lib/net/imap/sasl/digest_md5_authenticator.rb
|
108
|
+
- lib/net/imap/sasl/external_authenticator.rb
|
109
|
+
- lib/net/imap/sasl/gs2_header.rb
|
110
|
+
- lib/net/imap/sasl/login_authenticator.rb
|
111
|
+
- lib/net/imap/sasl/oauthbearer_authenticator.rb
|
112
|
+
- lib/net/imap/sasl/plain_authenticator.rb
|
113
|
+
- lib/net/imap/sasl/protocol_adapters.rb
|
114
|
+
- lib/net/imap/sasl/scram_algorithm.rb
|
115
|
+
- lib/net/imap/sasl/scram_authenticator.rb
|
104
116
|
- lib/net/imap/sasl/stringprep.rb
|
105
|
-
- lib/net/imap/sasl/
|
117
|
+
- lib/net/imap/sasl/xoauth2_authenticator.rb
|
118
|
+
- lib/net/imap/sasl_adapter.rb
|
119
|
+
- lib/net/imap/stringprep.rb
|
120
|
+
- lib/net/imap/stringprep/nameprep.rb
|
121
|
+
- lib/net/imap/stringprep/saslprep.rb
|
122
|
+
- lib/net/imap/stringprep/saslprep_tables.rb
|
123
|
+
- lib/net/imap/stringprep/tables.rb
|
124
|
+
- lib/net/imap/stringprep/trace.rb
|
106
125
|
- net-imap.gemspec
|
107
126
|
- rakelib/rdoc.rake
|
108
127
|
- rakelib/rfcs.rake
|
@@ -123,7 +142,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
123
142
|
requirements:
|
124
143
|
- - ">="
|
125
144
|
- !ruby/object:Gem::Version
|
126
|
-
version: 2.
|
145
|
+
version: 2.7.3
|
127
146
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
128
147
|
requirements:
|
129
148
|
- - ">="
|
@@ -1,41 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# Authenticator for the "+PLAIN+" SASL mechanism, specified in
|
4
|
-
# RFC4616[https://tools.ietf.org/html/rfc4616]. See Net::IMAP#authenticate.
|
5
|
-
#
|
6
|
-
# +PLAIN+ authentication sends the password in cleartext.
|
7
|
-
# RFC3501[https://tools.ietf.org/html/rfc3501] encourages servers to disable
|
8
|
-
# cleartext authentication until after TLS has been negotiated.
|
9
|
-
# RFC8314[https://tools.ietf.org/html/rfc8314] recommends TLS version 1.2 or
|
10
|
-
# greater be used for all traffic, and deprecate cleartext access ASAP. +PLAIN+
|
11
|
-
# can be secured by TLS encryption.
|
12
|
-
class Net::IMAP::PlainAuthenticator
|
13
|
-
|
14
|
-
def process(data)
|
15
|
-
return "#@authzid\0#@username\0#@password"
|
16
|
-
end
|
17
|
-
|
18
|
-
# :nodoc:
|
19
|
-
NULL = -"\0".b
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
# +username+ is the authentication identity, the identity whose +password+ is
|
24
|
-
# used. +username+ is referred to as +authcid+ by
|
25
|
-
# RFC4616[https://tools.ietf.org/html/rfc4616].
|
26
|
-
#
|
27
|
-
# +authzid+ is the authorization identity (identity to act as). It can
|
28
|
-
# usually be left blank. When +authzid+ is left blank (nil or empty string)
|
29
|
-
# the server will derive an identity from the credentials and use that as the
|
30
|
-
# authorization identity.
|
31
|
-
def initialize(username, password, authzid: nil)
|
32
|
-
raise ArgumentError, "username contains NULL" if username&.include?(NULL)
|
33
|
-
raise ArgumentError, "password contains NULL" if password&.include?(NULL)
|
34
|
-
raise ArgumentError, "authzid contains NULL" if authzid&.include?(NULL)
|
35
|
-
@username = username
|
36
|
-
@password = password
|
37
|
-
@authzid = authzid
|
38
|
-
end
|
39
|
-
|
40
|
-
Net::IMAP.add_authenticator "PLAIN", self
|
41
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class Net::IMAP::XOauth2Authenticator
|
4
|
-
def process(_data)
|
5
|
-
build_oauth2_string(@user, @oauth2_token)
|
6
|
-
end
|
7
|
-
|
8
|
-
private
|
9
|
-
|
10
|
-
def initialize(user, oauth2_token, **_)
|
11
|
-
@user = user
|
12
|
-
@oauth2_token = oauth2_token
|
13
|
-
end
|
14
|
-
|
15
|
-
def build_oauth2_string(user, oauth2_token)
|
16
|
-
format("user=%s\1auth=Bearer %s\1\1", user, oauth2_token)
|
17
|
-
end
|
18
|
-
|
19
|
-
Net::IMAP.add_authenticator 'XOAUTH2', self
|
20
|
-
end
|
@@ -1,55 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "saslprep_tables"
|
4
|
-
|
5
|
-
module Net::IMAP::SASL
|
6
|
-
|
7
|
-
# SASLprep#saslprep can be used to prepare a string according to [RFC4013].
|
8
|
-
#
|
9
|
-
# \SASLprep maps characters three ways: to nothing, to space, and Unicode
|
10
|
-
# normalization form KC. \SASLprep prohibits codepoints from nearly all
|
11
|
-
# standard StringPrep tables (RFC3454, Appendix "C"), and uses \StringPrep's
|
12
|
-
# standard bidirectional characters requirements (Appendix "D"). \SASLprep
|
13
|
-
# also uses \StringPrep's definition of "Unassigned" codepoints (Appendix "A").
|
14
|
-
module SASLprep
|
15
|
-
|
16
|
-
# Used to short-circuit strings that don't need preparation.
|
17
|
-
ASCII_NO_CTRLS = /\A[\x20-\x7e]*\z/u.freeze
|
18
|
-
|
19
|
-
module_function
|
20
|
-
|
21
|
-
# Prepares a UTF-8 +string+ for comparison, using the \SASLprep profile
|
22
|
-
# RFC4013 of the StringPrep algorithm RFC3454.
|
23
|
-
#
|
24
|
-
# By default, prohibited strings will return +nil+. When +exception+ is
|
25
|
-
# +true+, a StringPrepError describing the violation will be raised.
|
26
|
-
#
|
27
|
-
# When +stored+ is +true+, "unassigned" codepoints will be prohibited. For
|
28
|
-
# \StringPrep and the \SASLprep profile, "unassigned" refers to Unicode 3.2,
|
29
|
-
# and not later versions. See RFC3454 §7 for more information.
|
30
|
-
#
|
31
|
-
def saslprep(str, stored: false, exception: false)
|
32
|
-
return str if ASCII_NO_CTRLS.match?(str) # raises on incompatible encoding
|
33
|
-
str = str.encode("UTF-8") # also dups (and raises for invalid encoding)
|
34
|
-
str.gsub!(MAP_TO_SPACE, " ")
|
35
|
-
str.gsub!(MAP_TO_NOTHING, "")
|
36
|
-
str.unicode_normalize!(:nfkc)
|
37
|
-
# These regexps combine the prohibited and bidirectional checks
|
38
|
-
return str unless str.match?(stored ? PROHIBITED_STORED : PROHIBITED)
|
39
|
-
return nil unless exception
|
40
|
-
# raise helpful errors to indicate *why* it failed:
|
41
|
-
tables = stored ? TABLES_PROHIBITED_STORED : TABLES_PROHIBITED
|
42
|
-
StringPrep.check_prohibited! str, *tables, bidi: true, profile: "SASLprep"
|
43
|
-
raise StringPrep::InvalidStringError.new(
|
44
|
-
"unknown error", string: string, profile: "SASLprep"
|
45
|
-
)
|
46
|
-
rescue ArgumentError, Encoding::CompatibilityError => ex
|
47
|
-
if /invalid byte sequence|incompatible encoding/.match? ex.message
|
48
|
-
return nil unless exception
|
49
|
-
raise StringPrepError.new(ex.message, string: str, profile: "saslprep")
|
50
|
-
end
|
51
|
-
raise ex
|
52
|
-
end
|
53
|
-
|
54
|
-
end
|
55
|
-
end
|
@@ -1,98 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
#--
|
4
|
-
# This file is generated from RFC3454, by rake. Don't edit directly.
|
5
|
-
#++
|
6
|
-
|
7
|
-
module Net::IMAP::SASL
|
8
|
-
|
9
|
-
module SASLprep
|
10
|
-
|
11
|
-
# RFC4013 §2.1 Mapping - mapped to space
|
12
|
-
# * non-ASCII space characters (\StringPrep\[\"C.1.2\"]) that can be
|
13
|
-
# mapped to SPACE (U+0020), and
|
14
|
-
#
|
15
|
-
# Equal to \StringPrep\[\"C.1.2\"].
|
16
|
-
# Redefined here to avoid loading the StringPrep module.
|
17
|
-
MAP_TO_SPACE = /[\u200b\p{Zs}&&[^ ]]/.freeze
|
18
|
-
|
19
|
-
# RFC4013 §2.1 Mapping - mapped to nothing
|
20
|
-
# the "commonly mapped to nothing" characters (\StringPrep\[\"B.1\"])
|
21
|
-
# that can be mapped to nothing.
|
22
|
-
#
|
23
|
-
# Equal to \StringPrep\[\"B.1\"].
|
24
|
-
# Redefined here to avoid loading the StringPrep module.
|
25
|
-
MAP_TO_NOTHING = /[\u{00ad 034f 1806 2060 feff}\u{180b}-\u{180d}\u{200b}-\u{200d}\u{fe00}-\u{fe0f}]/.freeze
|
26
|
-
|
27
|
-
# RFC4013 §2.3 Prohibited Output::
|
28
|
-
# * Non-ASCII space characters — \StringPrep\[\"C.1.2\"]
|
29
|
-
# * ASCII control characters — \StringPrep\[\"C.2.1\"]
|
30
|
-
# * Non-ASCII control characters — \StringPrep\[\"C.2.2\"]
|
31
|
-
# * Private Use characters — \StringPrep\[\"C.3\"]
|
32
|
-
# * Non-character code points — \StringPrep\[\"C.4\"]
|
33
|
-
# * Surrogate code points — \StringPrep\[\"C.5\"]
|
34
|
-
# * Inappropriate for plain text characters — \StringPrep\[\"C.6\"]
|
35
|
-
# * Inappropriate for canonical representation characters — \StringPrep\[\"C.7\"]
|
36
|
-
# * Change display properties or deprecated characters — \StringPrep\[\"C.8\"]
|
37
|
-
# * Tagging characters — \StringPrep\[\"C.9\"]
|
38
|
-
TABLES_PROHIBITED = ["C.1.2", "C.2.1", "C.2.2", "C.3", "C.4", "C.5", "C.6", "C.7", "C.8", "C.9"].freeze
|
39
|
-
|
40
|
-
# Adds unassigned (by Unicode 3.2) codepoints to TABLES_PROHIBITED.
|
41
|
-
#
|
42
|
-
# RFC4013 §2.5 Unassigned Code Points::
|
43
|
-
# This profile specifies the \StringPrep\[\"A.1\"] table as its list of
|
44
|
-
# unassigned code points.
|
45
|
-
TABLES_PROHIBITED_STORED = ["A.1", *TABLES_PROHIBITED].freeze
|
46
|
-
|
47
|
-
# Matches codepoints prohibited by RFC4013 §2.3.
|
48
|
-
#
|
49
|
-
# See TABLES_PROHIBITED.
|
50
|
-
#
|
51
|
-
# Equal to +Regexp.union+ of the TABLES_PROHIBITED tables. Redefined
|
52
|
-
# here to avoid loading the StringPrep module unless necessary.
|
53
|
-
PROHIBITED_OUTPUT = /[\u{06dd 070f 1680 180e 3000 feff e0001}\u{0000}-\u{001f}\u{007f}-\u{00a0}\u{0340}-\u{0341}\u{2000}-\u{200f}\u{2028}-\u{202f}\u{205f}-\u{2063}\u{206a}-\u{206f}\u{2ff0}-\u{2ffb}\u{e000}-\u{f8ff}\u{fdd0}-\u{fdef}\u{fff9}-\u{ffff}\u{1d173}-\u{1d17a}\u{1fffe}-\u{1ffff}\u{2fffe}-\u{2ffff}\u{3fffe}-\u{3ffff}\u{4fffe}-\u{4ffff}\u{5fffe}-\u{5ffff}\u{6fffe}-\u{6ffff}\u{7fffe}-\u{7ffff}\u{8fffe}-\u{8ffff}\u{9fffe}-\u{9ffff}\u{afffe}-\u{affff}\u{bfffe}-\u{bffff}\u{cfffe}-\u{cffff}\u{dfffe}-\u{dffff}\u{e0020}-\u{e007f}\u{efffe}-\u{10ffff}\p{Cs}]/.freeze
|
54
|
-
|
55
|
-
# RFC4013 §2.5 Unassigned Code Points::
|
56
|
-
# This profile specifies the \StringPrep\[\"A.1\"] table as its list of
|
57
|
-
# unassigned code points.
|
58
|
-
UNASSIGNED = /\p{^AGE=3.2}/.freeze
|
59
|
-
|
60
|
-
# Matches codepoints prohibited by RFC4013 §2.3 and §2.5.
|
61
|
-
#
|
62
|
-
# See TABLES_PROHIBITED_STORED.
|
63
|
-
PROHIBITED_OUTPUT_STORED = Regexp.union(
|
64
|
-
UNASSIGNED, PROHIBITED_OUTPUT
|
65
|
-
).freeze
|
66
|
-
|
67
|
-
# Bidirectional Characters [StringPrep, §6]
|
68
|
-
BIDI_FAILURE = /(?mx-i: # RandALCat followed by LCat
|
69
|
-
(?<r_and_al_cat>[\u{05be 05c0 05c3 061b 061f 06dd 0710 07b1 200f fb1d fb3e}\u{05d0}-\u{05ea}\u{05f0}-\u{05f4}\u{0621}-\u{063a}\u{0640}-\u{064a}\u{066d}-\u{066f}\u{0671}-\u{06d5}\u{06e5}-\u{06e6}\u{06fa}-\u{06fe}\u{0700}-\u{070d}\u{0712}-\u{072c}\u{0780}-\u{07a5}\u{fb1f}-\u{fb28}\u{fb2a}-\u{fb36}\u{fb38}-\u{fb3c}\u{fb40}-\u{fb41}\u{fb43}-\u{fb44}\u{fb46}-\u{fbb1}\u{fbd3}-\u{fd3d}\u{fd50}-\u{fd8f}\u{fd92}-\u{fdc7}\u{fdf0}-\u{fdfc}\u{fe70}-\u{fe74}\u{fe76}-\u{fefc}])
|
70
|
-
.*?
|
71
|
-
(?<l_cat>[\u{00aa 00b5 00ba 02ee 037a 0386 038c 0589 0903 0950 09b2 09d7 0a5e 0a83 0a8d 0ac9 0ad0 0ae0 0b40 0b57 0b83 0b9c 0bd7 0cbe 0cde 0d57 0dbd 0e84 0e8a 0e8d 0ea5 0ea7 0ebd 0ec6 0f36 0f38 0f7f 0f85 0fcf 102c 1031 1038 10fb 1248 1258 1288 12b0 12c0 1310 17dc 1f59 1f5b 1f5d 1fbe 200e 2071 207f 2102 2107 2115 2124 2126 2128 2395 1d4a2 1d4bb 1d546}\u{0041}-\u{005a}\u{0061}-\u{007a}\u{00c0}-\u{00d6}\u{00d8}-\u{00f6}\u{00f8}-\u{0220}\u{0222}-\u{0233}\u{0250}-\u{02ad}\u{02b0}-\u{02b8}\u{02bb}-\u{02c1}\u{02d0}-\u{02d1}\u{02e0}-\u{02e4}\u{0388}-\u{038a}\u{038e}-\u{03a1}\u{03a3}-\u{03ce}\u{03d0}-\u{03f5}\u{0400}-\u{0482}\u{048a}-\u{04ce}\u{04d0}-\u{04f5}\u{04f8}-\u{04f9}\u{0500}-\u{050f}\u{0531}-\u{0556}\u{0559}-\u{055f}\u{0561}-\u{0587}\u{0905}-\u{0939}\u{093d}-\u{0940}\u{0949}-\u{094c}\u{0958}-\u{0961}\u{0964}-\u{0970}\u{0982}-\u{0983}\u{0985}-\u{098c}\u{098f}-\u{0990}\u{0993}-\u{09a8}\u{09aa}-\u{09b0}\u{09b6}-\u{09b9}\u{09be}-\u{09c0}\u{09c7}-\u{09c8}\u{09cb}-\u{09cc}\u{09dc}-\u{09dd}\u{09df}-\u{09e1}\u{09e6}-\u{09f1}\u{09f4}-\u{09fa}\u{0a05}-\u{0a0a}\u{0a0f}-\u{0a10}\u{0a13}-\u{0a28}\u{0a2a}-\u{0a30}\u{0a32}-\u{0a33}\u{0a35}-\u{0a36}\u{0a38}-\u{0a39}\u{0a3e}-\u{0a40}\u{0a59}-\u{0a5c}\u{0a66}-\u{0a6f}\u{0a72}-\u{0a74}\u{0a85}-\u{0a8b}\u{0a8f}-\u{0a91}\u{0a93}-\u{0aa8}\u{0aaa}-\u{0ab0}\u{0ab2}-\u{0ab3}\u{0ab5}-\u{0ab9}\u{0abd}-\u{0ac0}\u{0acb}-\u{0acc}\u{0ae6}-\u{0aef}\u{0b02}-\u{0b03}\u{0b05}-\u{0b0c}\u{0b0f}-\u{0b10}\u{0b13}-\u{0b28}\u{0b2a}-\u{0b30}\u{0b32}-\u{0b33}\u{0b36}-\u{0b39}\u{0b3d}-\u{0b3e}\u{0b47}-\u{0b48}\u{0b4b}-\u{0b4c}\u{0b5c}-\u{0b5d}\u{0b5f}-\u{0b61}\u{0b66}-\u{0b70}\u{0b85}-\u{0b8a}\u{0b8e}-\u{0b90}\u{0b92}-\u{0b95}\u{0b99}-\u{0b9a}\u{0b9e}-\u{0b9f}\u{0ba3}-\u{0ba4}\u{0ba8}-\u{0baa}\u{0bae}-\u{0bb5}\u{0bb7}-\u{0bb9}\u{0bbe}-\u{0bbf}\u{0bc1}-\u{0bc2}\u{0bc6}-\u{0bc8}\u{0bca}-\u{0bcc}\u{0be7}-\u{0bf2}\u{0c01}-\u{0c03}\u{0c05}-\u{0c0c}\u{0c0e}-\u{0c10}\u{0c12}-\u{0c28}\u{0c2a}-\u{0c33}\u{0c35}-\u{0c39}\u{0c41}-\u{0c44}\u{0c60}-\u{0c61}\u{0c66}-\u{0c6f}\u{0c82}-\u{0c83}\u{0c85}-\u{0c8c}\u{0c8e}-\u{0c90}\u{0c92}-\u{0ca8}\u{0caa}-\u{0cb3}\u{0cb5}-\u{0cb9}\u{0cc0}-\u{0cc4}\u{0cc7}-\u{0cc8}\u{0cca}-\u{0ccb}\u{0cd5}-\u{0cd6}\u{0ce0}-\u{0ce1}\u{0ce6}-\u{0cef}\u{0d02}-\u{0d03}\u{0d05}-\u{0d0c}\u{0d0e}-\u{0d10}\u{0d12}-\u{0d28}\u{0d2a}-\u{0d39}\u{0d3e}-\u{0d40}\u{0d46}-\u{0d48}\u{0d4a}-\u{0d4c}\u{0d60}-\u{0d61}\u{0d66}-\u{0d6f}\u{0d82}-\u{0d83}\u{0d85}-\u{0d96}\u{0d9a}-\u{0db1}\u{0db3}-\u{0dbb}\u{0dc0}-\u{0dc6}\u{0dcf}-\u{0dd1}\u{0dd8}-\u{0ddf}\u{0df2}-\u{0df4}\u{0e01}-\u{0e30}\u{0e32}-\u{0e33}\u{0e40}-\u{0e46}\u{0e4f}-\u{0e5b}\u{0e81}-\u{0e82}\u{0e87}-\u{0e88}\u{0e94}-\u{0e97}\u{0e99}-\u{0e9f}\u{0ea1}-\u{0ea3}\u{0eaa}-\u{0eab}\u{0ead}-\u{0eb0}\u{0eb2}-\u{0eb3}\u{0ec0}-\u{0ec4}\u{0ed0}-\u{0ed9}\u{0edc}-\u{0edd}\u{0f00}-\u{0f17}\u{0f1a}-\u{0f34}\u{0f3e}-\u{0f47}\u{0f49}-\u{0f6a}\u{0f88}-\u{0f8b}\u{0fbe}-\u{0fc5}\u{0fc7}-\u{0fcc}\u{1000}-\u{1021}\u{1023}-\u{1027}\u{1029}-\u{102a}\u{1040}-\u{1057}\u{10a0}-\u{10c5}\u{10d0}-\u{10f8}\u{1100}-\u{1159}\u{115f}-\u{11a2}\u{11a8}-\u{11f9}\u{1200}-\u{1206}\u{1208}-\u{1246}\u{124a}-\u{124d}\u{1250}-\u{1256}\u{125a}-\u{125d}\u{1260}-\u{1286}\u{128a}-\u{128d}\u{1290}-\u{12ae}\u{12b2}-\u{12b5}\u{12b8}-\u{12be}\u{12c2}-\u{12c5}\u{12c8}-\u{12ce}\u{12d0}-\u{12d6}\u{12d8}-\u{12ee}\u{12f0}-\u{130e}\u{1312}-\u{1315}\u{1318}-\u{131e}\u{1320}-\u{1346}\u{1348}-\u{135a}\u{1361}-\u{137c}\u{13a0}-\u{13f4}\u{1401}-\u{1676}\u{1681}-\u{169a}\u{16a0}-\u{16f0}\u{1700}-\u{170c}\u{170e}-\u{1711}\u{1720}-\u{1731}\u{1735}-\u{1736}\u{1740}-\u{1751}\u{1760}-\u{176c}\u{176e}-\u{1770}\u{1780}-\u{17b6}\u{17be}-\u{17c5}\u{17c7}-\u{17c8}\u{17d4}-\u{17da}\u{17e0}-\u{17e9}\u{1810}-\u{1819}\u{1820}-\u{1877}\u{1880}-\u{18a8}\u{1e00}-\u{1e9b}\u{1ea0}-\u{1ef9}\u{1f00}-\u{1f15}\u{1f18}-\u{1f1d}\u{1f20}-\u{1f45}\u{1f48}-\u{1f4d}\u{1f50}-\u{1f57}\u{1f5f}-\u{1f7d}\u{1f80}-\u{1fb4}\u{1fb6}-\u{1fbc}\u{1fc2}-\u{1fc4}\u{1fc6}-\u{1fcc}\u{1fd0}-\u{1fd3}\u{1fd6}-\u{1fdb}\u{1fe0}-\u{1fec}\u{1ff2}-\u{1ff4}\u{1ff6}-\u{1ffc}\u{210a}-\u{2113}\u{2119}-\u{211d}\u{212a}-\u{212d}\u{212f}-\u{2131}\u{2133}-\u{2139}\u{213d}-\u{213f}\u{2145}-\u{2149}\u{2160}-\u{2183}\u{2336}-\u{237a}\u{249c}-\u{24e9}\u{3005}-\u{3007}\u{3021}-\u{3029}\u{3031}-\u{3035}\u{3038}-\u{303c}\u{3041}-\u{3096}\u{309d}-\u{309f}\u{30a1}-\u{30fa}\u{30fc}-\u{30ff}\u{3105}-\u{312c}\u{3131}-\u{318e}\u{3190}-\u{31b7}\u{31f0}-\u{321c}\u{3220}-\u{3243}\u{3260}-\u{327b}\u{327f}-\u{32b0}\u{32c0}-\u{32cb}\u{32d0}-\u{32fe}\u{3300}-\u{3376}\u{337b}-\u{33dd}\u{33e0}-\u{33fe}\u{3400}-\u{4db5}\u{4e00}-\u{9fa5}\u{a000}-\u{a48c}\u{ac00}-\u{d7a3}\u{e000}-\u{fa2d}\u{fa30}-\u{fa6a}\u{fb00}-\u{fb06}\u{fb13}-\u{fb17}\u{ff21}-\u{ff3a}\u{ff41}-\u{ff5a}\u{ff66}-\u{ffbe}\u{ffc2}-\u{ffc7}\u{ffca}-\u{ffcf}\u{ffd2}-\u{ffd7}\u{ffda}-\u{ffdc}\u{10300}-\u{1031e}\u{10320}-\u{10323}\u{10330}-\u{1034a}\u{10400}-\u{10425}\u{10428}-\u{1044d}\u{1d000}-\u{1d0f5}\u{1d100}-\u{1d126}\u{1d12a}-\u{1d166}\u{1d16a}-\u{1d172}\u{1d183}-\u{1d184}\u{1d18c}-\u{1d1a9}\u{1d1ae}-\u{1d1dd}\u{1d400}-\u{1d454}\u{1d456}-\u{1d49c}\u{1d49e}-\u{1d49f}\u{1d4a5}-\u{1d4a6}\u{1d4a9}-\u{1d4ac}\u{1d4ae}-\u{1d4b9}\u{1d4bd}-\u{1d4c0}\u{1d4c2}-\u{1d4c3}\u{1d4c5}-\u{1d505}\u{1d507}-\u{1d50a}\u{1d50d}-\u{1d514}\u{1d516}-\u{1d51c}\u{1d51e}-\u{1d539}\u{1d53b}-\u{1d53e}\u{1d540}-\u{1d544}\u{1d54a}-\u{1d550}\u{1d552}-\u{1d6a3}\u{1d6a8}-\u{1d7c9}\u{20000}-\u{2a6d6}\u{2f800}-\u{2fa1d}\u{f0000}-\u{ffffd}\u{100000}-\u{10fffd}\p{Cs}])
|
72
|
-
| # RandALCat preceded by LCat
|
73
|
-
\g<l_cat> .*? \g<r_and_al_cat>
|
74
|
-
) | (?mx-i: # contains RandALCat but doesn't start with RandALCat
|
75
|
-
\A(?<not_r_nor_al>(?-mix:[^\u{05be 05c0 05c3 061b 061f 06dd 0710 07b1 200f fb1d fb3e}\u{05d0}-\u{05ea}\u{05f0}-\u{05f4}\u{0621}-\u{063a}\u{0640}-\u{064a}\u{066d}-\u{066f}\u{0671}-\u{06d5}\u{06e5}-\u{06e6}\u{06fa}-\u{06fe}\u{0700}-\u{070d}\u{0712}-\u{072c}\u{0780}-\u{07a5}\u{fb1f}-\u{fb28}\u{fb2a}-\u{fb36}\u{fb38}-\u{fb3c}\u{fb40}-\u{fb41}\u{fb43}-\u{fb44}\u{fb46}-\u{fbb1}\u{fbd3}-\u{fd3d}\u{fd50}-\u{fd8f}\u{fd92}-\u{fdc7}\u{fdf0}-\u{fdfc}\u{fe70}-\u{fe74}\u{fe76}-\u{fefc}]))
|
76
|
-
.*?
|
77
|
-
g<r_and_al_cat>
|
78
|
-
| # contains RandALCat but doesn't end with RandALCat
|
79
|
-
\g<r_and_al_cat> .*? \g<not_r_nor_al>\z
|
80
|
-
)/mx.freeze
|
81
|
-
|
82
|
-
# Matches strings prohibited by RFC4013 §2.3 and §2.4.
|
83
|
-
#
|
84
|
-
# This checks prohibited output and bidirectional characters.
|
85
|
-
PROHIBITED = Regexp.union(
|
86
|
-
PROHIBITED_OUTPUT, BIDI_FAILURE,
|
87
|
-
)
|
88
|
-
|
89
|
-
# Matches strings prohibited by RFC4013 §2.3, §2.4, and §2.5.
|
90
|
-
#
|
91
|
-
# This checks prohibited output, bidirectional characters, and
|
92
|
-
# unassigned codepoints.
|
93
|
-
PROHIBITED_STORED = Regexp.union(
|
94
|
-
PROHIBITED_OUTPUT_STORED, BIDI_FAILURE,
|
95
|
-
)
|
96
|
-
|
97
|
-
end
|
98
|
-
end
|