net-imap 0.3.7 → 0.4.2
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 +69 -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} +21 -11
- data/lib/net/imap/sasl/digest_md5_authenticator.rb +180 -0
- data/lib/net/imap/sasl/external_authenticator.rb +83 -0
- data/lib/net/imap/sasl/gs2_header.rb +80 -0
- data/lib/net/imap/{authenticators/login.rb → sasl/login_authenticator.rb} +25 -16
- data/lib/net/imap/sasl/oauthbearer_authenticator.rb +199 -0
- data/lib/net/imap/sasl/plain_authenticator.rb +101 -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 +287 -0
- data/lib/net/imap/sasl/stringprep.rb +6 -66
- data/lib/net/imap/sasl/xoauth2_authenticator.rb +106 -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/digest_md5.rb +0 -115
- 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/lib/net/imap/sasl.rb
CHANGED
@@ -6,12 +6,11 @@ module Net
|
|
6
6
|
# Pluggable authentication mechanisms for protocols which support SASL
|
7
7
|
# (Simple Authentication and Security Layer), such as IMAP4, SMTP, LDAP, and
|
8
8
|
# XMPP. {RFC-4422}[https://tools.ietf.org/html/rfc4422] specifies the
|
9
|
-
# common SASL framework
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
# between protocols and mechanisms as illustrated in the following diagram."
|
9
|
+
# common \SASL framework:
|
10
|
+
# >>>
|
11
|
+
# SASL is conceptually a framework that provides an abstraction layer
|
12
|
+
# between protocols and mechanisms as illustrated in the following
|
13
|
+
# diagram.
|
15
14
|
#
|
16
15
|
# SMTP LDAP XMPP Other protocols ...
|
17
16
|
# \ | | /
|
@@ -21,58 +20,160 @@ module Net
|
|
21
20
|
# / | | \
|
22
21
|
# EXTERNAL GSSAPI PLAIN Other mechanisms ...
|
23
22
|
#
|
23
|
+
# Net::IMAP uses SASL via the Net::IMAP#authenticate method.
|
24
|
+
#
|
25
|
+
# == Mechanisms
|
26
|
+
#
|
27
|
+
# Each mechanism has different properties and requirements. Please consult
|
28
|
+
# the documentation for the specific mechanisms you are using:
|
29
|
+
#
|
30
|
+
# +ANONYMOUS+::
|
31
|
+
# See AnonymousAuthenticator.
|
32
|
+
#
|
33
|
+
# Allows the user to gain access to public services or resources without
|
34
|
+
# authenticating or disclosing an identity.
|
35
|
+
#
|
36
|
+
# +EXTERNAL+::
|
37
|
+
# See ExternalAuthenticator.
|
38
|
+
#
|
39
|
+
# Authenticates using already established credentials, such as a TLS
|
40
|
+
# certificate or IPsec.
|
41
|
+
#
|
42
|
+
# +OAUTHBEARER+::
|
43
|
+
# See OAuthBearerAuthenticator.
|
44
|
+
#
|
45
|
+
# Login using an OAuth2 Bearer token. This is the standard mechanism
|
46
|
+
# for using OAuth2 with \SASL, but it is not yet deployed as widely as
|
47
|
+
# +XOAUTH2+.
|
48
|
+
#
|
49
|
+
# +PLAIN+::
|
50
|
+
# See PlainAuthenticator.
|
51
|
+
#
|
52
|
+
# Login using clear-text username and password.
|
53
|
+
#
|
54
|
+
# +SCRAM-SHA-1+::
|
55
|
+
# +SCRAM-SHA-256+::
|
56
|
+
# See ScramAuthenticator.
|
57
|
+
#
|
58
|
+
# Login by username and password. The password is not sent to the
|
59
|
+
# server but is used in a salted challenge/response exchange.
|
60
|
+
# +SCRAM-SHA-1+ and +SCRAM-SHA-256+ are directly supported by
|
61
|
+
# Net::IMAP::SASL. New authenticators can easily be added for any other
|
62
|
+
# <tt>SCRAM-*</tt> mechanism if the digest algorithm is supported by
|
63
|
+
# OpenSSL::Digest.
|
64
|
+
#
|
65
|
+
# +XOAUTH2+::
|
66
|
+
# See XOAuth2Authenticator.
|
67
|
+
#
|
68
|
+
# Login using a username and an OAuth2 access token. Non-standard and
|
69
|
+
# obsoleted by +OAUTHBEARER+, but widely supported.
|
70
|
+
#
|
71
|
+
# See the {SASL mechanism
|
72
|
+
# registry}[https://www.iana.org/assignments/sasl-mechanisms/sasl-mechanisms.xhtml]
|
73
|
+
# for a list of all SASL mechanisms and their specifications. To register
|
74
|
+
# new authenticators, see Authenticators.
|
75
|
+
#
|
76
|
+
# === Deprecated mechanisms
|
77
|
+
#
|
78
|
+
# <em>Obsolete mechanisms should be avoided, but are still available for
|
79
|
+
# backwards compatibility.</em>
|
80
|
+
#
|
81
|
+
# >>>
|
82
|
+
# For +DIGEST-MD5+ see DigestMD5Authenticator.
|
83
|
+
#
|
84
|
+
# For +LOGIN+, see LoginAuthenticator.
|
85
|
+
#
|
86
|
+
# For +CRAM-MD5+, see CramMD5Authenticator.
|
87
|
+
#
|
88
|
+
# <em>Using a deprecated mechanism will print a warning.</em>
|
89
|
+
#
|
24
90
|
module SASL
|
91
|
+
# Exception class for any client error detected during the authentication
|
92
|
+
# exchange.
|
93
|
+
#
|
94
|
+
# When the _server_ reports an authentication failure, it will respond
|
95
|
+
# with a protocol specific error instead, e.g: +BAD+ or +NO+ in IMAP.
|
96
|
+
#
|
97
|
+
# When the client encounters any error, it *must* consider the
|
98
|
+
# authentication exchange to be unsuccessful and it might need to drop the
|
99
|
+
# connection. For example, if the server reports that the authentication
|
100
|
+
# exchange was successful or the protocol does not allow additional
|
101
|
+
# authentication attempts.
|
102
|
+
Error = Class.new(StandardError)
|
25
103
|
|
26
|
-
#
|
104
|
+
# Indicates an authentication exchange that will be or has been canceled
|
105
|
+
# by the client, not due to any error or failure during processing.
|
106
|
+
AuthenticationCanceled = Class.new(Error)
|
27
107
|
|
28
|
-
|
29
|
-
|
108
|
+
# Indicates an error when processing a server challenge, e.g: an invalid
|
109
|
+
# or unparsable challenge. An underlying exception may be available as
|
110
|
+
# the exception's #cause.
|
111
|
+
AuthenticationError = Class.new(Error)
|
30
112
|
|
31
|
-
#
|
32
|
-
#
|
33
|
-
|
34
|
-
attr_reader :string, :profile
|
113
|
+
# Indicates that authentication cannot proceed because one of the server's
|
114
|
+
# messages has not passed integrity checks.
|
115
|
+
AuthenticationFailed = Class.new(Error)
|
35
116
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
end
|
117
|
+
# Indicates that authentication cannot proceed because one of the server's
|
118
|
+
# ended authentication prematurely.
|
119
|
+
class AuthenticationIncomplete < AuthenticationFailed
|
120
|
+
# The success response from the server
|
121
|
+
attr_reader :response
|
42
122
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
attr_reader :table
|
47
|
-
|
48
|
-
def initialize(table, *args, **kwargs)
|
49
|
-
@table = -table.to_str
|
50
|
-
details = (title = StringPrep::TABLE_TITLES[table]) ?
|
51
|
-
"%s [%s]" % [title, table] : table
|
52
|
-
message = "String contains a prohibited codepoint: %s" % [details]
|
53
|
-
super(message, *args, **kwargs)
|
123
|
+
def initialize(response, message = "authentication ended prematurely")
|
124
|
+
super(message)
|
125
|
+
@response = response
|
54
126
|
end
|
55
127
|
end
|
56
128
|
|
57
|
-
#
|
58
|
-
|
59
|
-
|
129
|
+
# autoloading to avoid loading all of the regexps when they aren't used.
|
130
|
+
sasl_stringprep_rb = File.expand_path("sasl/stringprep", __dir__)
|
131
|
+
autoload :StringPrep, sasl_stringprep_rb
|
132
|
+
autoload :SASLprep, sasl_stringprep_rb
|
133
|
+
autoload :StringPrepError, sasl_stringprep_rb
|
134
|
+
autoload :ProhibitedCodepoint, sasl_stringprep_rb
|
135
|
+
autoload :BidiStringError, sasl_stringprep_rb
|
136
|
+
|
137
|
+
sasl_dir = File.expand_path("sasl", __dir__)
|
138
|
+
autoload :AuthenticationExchange, "#{sasl_dir}/authentication_exchange"
|
139
|
+
autoload :ClientAdapter, "#{sasl_dir}/client_adapter"
|
140
|
+
autoload :ProtocolAdapters, "#{sasl_dir}/protocol_adapters"
|
141
|
+
|
142
|
+
autoload :Authenticators, "#{sasl_dir}/authenticators"
|
143
|
+
autoload :GS2Header, "#{sasl_dir}/gs2_header"
|
144
|
+
autoload :ScramAlgorithm, "#{sasl_dir}/scram_algorithm"
|
145
|
+
|
146
|
+
autoload :AnonymousAuthenticator, "#{sasl_dir}/anonymous_authenticator"
|
147
|
+
autoload :ExternalAuthenticator, "#{sasl_dir}/external_authenticator"
|
148
|
+
autoload :OAuthBearerAuthenticator, "#{sasl_dir}/oauthbearer_authenticator"
|
149
|
+
autoload :PlainAuthenticator, "#{sasl_dir}/plain_authenticator"
|
150
|
+
autoload :ScramAuthenticator, "#{sasl_dir}/scram_authenticator"
|
151
|
+
autoload :ScramSHA1Authenticator, "#{sasl_dir}/scram_authenticator"
|
152
|
+
autoload :ScramSHA256Authenticator, "#{sasl_dir}/scram_authenticator"
|
153
|
+
autoload :XOAuth2Authenticator, "#{sasl_dir}/xoauth2_authenticator"
|
154
|
+
|
155
|
+
autoload :CramMD5Authenticator, "#{sasl_dir}/cram_md5_authenticator"
|
156
|
+
autoload :DigestMD5Authenticator, "#{sasl_dir}/digest_md5_authenticator"
|
157
|
+
autoload :LoginAuthenticator, "#{sasl_dir}/login_authenticator"
|
158
|
+
|
159
|
+
# Returns the default global SASL::Authenticators instance.
|
160
|
+
def self.authenticators; @authenticators ||= Authenticators.new end
|
161
|
+
|
162
|
+
# Delegates to <tt>registry.new</tt> See Authenticators#new.
|
163
|
+
def self.authenticator(*args, registry: authenticators, **kwargs, &block)
|
164
|
+
registry.new(*args, **kwargs, &block)
|
60
165
|
end
|
61
166
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
extend self
|
167
|
+
# Delegates to ::authenticators. See Authenticators#add_authenticator.
|
168
|
+
def self.add_authenticator(...) authenticators.add_authenticator(...) end
|
169
|
+
|
170
|
+
module_function
|
67
171
|
|
68
|
-
# See SASLprep#saslprep.
|
172
|
+
# See Net::IMAP::StringPrep::SASLprep#saslprep.
|
69
173
|
def saslprep(string, **opts)
|
70
|
-
SASLprep.saslprep(string, **opts)
|
174
|
+
Net::IMAP::StringPrep::SASLprep.saslprep(string, **opts)
|
71
175
|
end
|
72
176
|
|
73
177
|
end
|
74
178
|
end
|
75
|
-
|
76
179
|
end
|
77
|
-
|
78
|
-
Net::IMAP.extend Net::IMAP::SASL
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Net
|
4
|
+
class IMAP
|
5
|
+
|
6
|
+
# Experimental
|
7
|
+
class SASLAdapter < SASL::ClientAdapter
|
8
|
+
include SASL::ProtocolAdapters::IMAP
|
9
|
+
|
10
|
+
RESPONSE_ERRORS = [NoResponseError, BadResponseError, ByeResponseError]
|
11
|
+
.freeze
|
12
|
+
|
13
|
+
def response_errors; RESPONSE_ERRORS end
|
14
|
+
def sasl_ir_capable?; client.capable?("SASL-IR") end
|
15
|
+
def auth_capable?(mechanism); client.auth_capable?(mechanism) end
|
16
|
+
def drop_connection; client.logout! end
|
17
|
+
def drop_connection!; client.disconnect end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Net
|
4
|
+
class IMAP
|
5
|
+
module StringPrep
|
6
|
+
|
7
|
+
# Defined in RFC3491[https://tools.ietf.org/html/rfc3491], the +nameprep+
|
8
|
+
# profile of "Stringprep" is:
|
9
|
+
# >>>
|
10
|
+
# used by the IDNA protocol for preparing domain names; it is not
|
11
|
+
# designed for any other purpose. It is explicitly not designed for
|
12
|
+
# processing arbitrary free text and SHOULD NOT be used for that
|
13
|
+
# purpose.
|
14
|
+
#
|
15
|
+
# ...
|
16
|
+
#
|
17
|
+
# This profile specifies prohibiting using the following tables...:
|
18
|
+
#
|
19
|
+
# - C.1.2 (Non-ASCII space characters)
|
20
|
+
# - C.2.2 (Non-ASCII control characters)
|
21
|
+
# - C.3 (Private use characters)
|
22
|
+
# - C.4 (Non-character code points)
|
23
|
+
# - C.5 (Surrogate codes)
|
24
|
+
# - C.6 (Inappropriate for plain text)
|
25
|
+
# - C.7 (Inappropriate for canonical representation)
|
26
|
+
# - C.8 (Change display properties are deprecated)
|
27
|
+
# - C.9 (Tagging characters)
|
28
|
+
#
|
29
|
+
# IMPORTANT NOTE: This profile MUST be used with the IDNA protocol.
|
30
|
+
# The IDNA protocol has additional prohibitions that are checked
|
31
|
+
# outside of this profile.
|
32
|
+
module NamePrep
|
33
|
+
|
34
|
+
# From RFC3491[https://www.rfc-editor.org/rfc/rfc3491.html] §10
|
35
|
+
STRINGPREP_PROFILE = "nameprep"
|
36
|
+
|
37
|
+
# From RFC3491[https://www.rfc-editor.org/rfc/rfc3491.html] §2
|
38
|
+
UNASSIGNED_TABLE = "A.1"
|
39
|
+
|
40
|
+
# From RFC3491[https://www.rfc-editor.org/rfc/rfc3491.html] §3
|
41
|
+
MAPPING_TABLES = %w[B.1 B.2].freeze
|
42
|
+
|
43
|
+
# From RFC3491[https://www.rfc-editor.org/rfc/rfc3491.html] §4
|
44
|
+
NORMALIZATION = :nfkc
|
45
|
+
|
46
|
+
# From RFC3491[https://www.rfc-editor.org/rfc/rfc3491.html] §5
|
47
|
+
PROHIBITED_TABLES = %w[C.1.2 C.2.2 C.3 C.4 C.5 C.6 C.7 C.8 C.9].freeze
|
48
|
+
|
49
|
+
# From RFC3491[https://www.rfc-editor.org/rfc/rfc3491.html] §6
|
50
|
+
CHECK_BIDI = true
|
51
|
+
|
52
|
+
module_function
|
53
|
+
|
54
|
+
def nameprep(string, **opts)
|
55
|
+
StringPrep.stringprep(
|
56
|
+
string,
|
57
|
+
unassigned: UNASSIGNED_TABLE,
|
58
|
+
maps: MAPPING_TABLES,
|
59
|
+
prohibited: PROHIBITED_TABLES,
|
60
|
+
normalization: NORMALIZATION,
|
61
|
+
bidi: CHECK_BIDI,
|
62
|
+
profile: STRINGPREP_PROFILE,
|
63
|
+
**opts,
|
64
|
+
)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Net
|
4
|
+
class IMAP
|
5
|
+
module StringPrep
|
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
|
12
|
+
# \StringPrep's standard bidirectional characters requirements (Appendix
|
13
|
+
# "D"). \SASLprep also uses \StringPrep's definition of "Unassigned"
|
14
|
+
# codepoints (Appendix "A").
|
15
|
+
module SASLprep
|
16
|
+
|
17
|
+
# Used to short-circuit strings that don't need preparation.
|
18
|
+
ASCII_NO_CTRLS = /\A[\x20-\x7e]*\z/u.freeze
|
19
|
+
|
20
|
+
# Avoid loading these tables unless they are needed (they are only
|
21
|
+
# needed for non-ASCII).
|
22
|
+
saslprep_tables = File.expand_path("saslprep_tables", __dir__)
|
23
|
+
autoload :MAP_TO_NOTHING, saslprep_tables
|
24
|
+
autoload :MAP_TO_SPACE, saslprep_tables
|
25
|
+
autoload :PROHIBITED, saslprep_tables
|
26
|
+
autoload :PROHIBITED_STORED, saslprep_tables
|
27
|
+
autoload :TABLES_PROHIBITED, saslprep_tables
|
28
|
+
autoload :TABLES_PROHIBITED_STORED, saslprep_tables
|
29
|
+
|
30
|
+
module_function
|
31
|
+
|
32
|
+
# Prepares a UTF-8 +string+ for comparison, using the \SASLprep profile
|
33
|
+
# RFC4013 of the StringPrep algorithm RFC3454.
|
34
|
+
#
|
35
|
+
# By default, prohibited strings will return +nil+. When +exception+ is
|
36
|
+
# +true+, a StringPrepError describing the violation will be raised.
|
37
|
+
#
|
38
|
+
# When +stored+ is +true+, "unassigned" codepoints will be prohibited.
|
39
|
+
# For \StringPrep and the \SASLprep profile, "unassigned" refers to
|
40
|
+
# Unicode 3.2, and not later versions. See RFC3454 §7 for more
|
41
|
+
# information.
|
42
|
+
def saslprep(str, stored: false, exception: false)
|
43
|
+
return str if ASCII_NO_CTRLS.match?(str) # incompatible encoding raises
|
44
|
+
str = str.encode("UTF-8") # also dups (and raises for invalid encoding)
|
45
|
+
str.gsub!(MAP_TO_SPACE, " ")
|
46
|
+
str.gsub!(MAP_TO_NOTHING, "")
|
47
|
+
str.unicode_normalize!(:nfkc)
|
48
|
+
# These regexps combine the prohibited and bidirectional checks
|
49
|
+
return str unless str.match?(stored ? PROHIBITED_STORED : PROHIBITED)
|
50
|
+
return nil unless exception
|
51
|
+
# raise helpful errors to indicate *why* it failed:
|
52
|
+
tables = stored ? TABLES_PROHIBITED_STORED : TABLES_PROHIBITED
|
53
|
+
StringPrep.check_prohibited! str, *tables, bidi: true, profile: "SASLprep"
|
54
|
+
raise InvalidStringError.new(
|
55
|
+
"unknown error", string: string, profile: "SASLprep"
|
56
|
+
)
|
57
|
+
rescue ArgumentError, Encoding::CompatibilityError => ex
|
58
|
+
if /invalid byte sequence|incompatible encoding/.match? ex.message
|
59
|
+
return nil unless exception
|
60
|
+
raise StringPrepError.new(ex.message, string: str, profile: "saslprep")
|
61
|
+
end
|
62
|
+
raise ex
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,96 @@
|
|
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::StringPrep
|
8
|
+
|
9
|
+
module SASLprep
|
10
|
+
|
11
|
+
# RFC4013 §2.1 Mapping - mapped to space
|
12
|
+
# >>>
|
13
|
+
# non-ASCII space characters (\StringPrep\[\"C.1.2\"]) that can
|
14
|
+
# be mapped to SPACE (U+0020)
|
15
|
+
#
|
16
|
+
# Equal to \StringPrep\[\"C.1.2\"].
|
17
|
+
# Redefined here to avoid loading StringPrep::Tables unless necessary.
|
18
|
+
MAP_TO_SPACE = /[\u200b\p{Zs}&&[^ ]]/.freeze
|
19
|
+
|
20
|
+
# RFC4013 §2.1 Mapping - mapped to nothing
|
21
|
+
# >>>
|
22
|
+
# the "commonly mapped to nothing" characters
|
23
|
+
# (\StringPrep\[\"B.1\"]) that can be mapped to nothing.
|
24
|
+
#
|
25
|
+
# Equal to \StringPrep\[\"B.1\"].
|
26
|
+
# Redefined here to avoid loading StringPrep::Tables unless necessary.
|
27
|
+
MAP_TO_NOTHING = /[\u{00ad 034f 1806 2060 feff}\u{180b}-\u{180d}\u{200b}-\u{200d}\u{fe00}-\u{fe0f}]/.freeze
|
28
|
+
|
29
|
+
# RFC4013 §2.3 Prohibited Output
|
30
|
+
# >>>
|
31
|
+
# * Non-ASCII space characters — \StringPrep\[\"C.1.2\"]
|
32
|
+
# * ASCII control characters — \StringPrep\[\"C.2.1\"]
|
33
|
+
# * Non-ASCII control characters — \StringPrep\[\"C.2.2\"]
|
34
|
+
# * Private Use characters — \StringPrep\[\"C.3\"]
|
35
|
+
# * Non-character code points — \StringPrep\[\"C.4\"]
|
36
|
+
# * Surrogate code points — \StringPrep\[\"C.5\"]
|
37
|
+
# * Inappropriate for plain text characters — \StringPrep\[\"C.6\"]
|
38
|
+
# * Inappropriate for canonical representation characters — \StringPrep\[\"C.7\"]
|
39
|
+
# * Change display properties or deprecated characters — \StringPrep\[\"C.8\"]
|
40
|
+
# * Tagging characters — \StringPrep\[\"C.9\"]
|
41
|
+
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
|
42
|
+
|
43
|
+
# Adds unassigned (by Unicode 3.2) codepoints to TABLES_PROHIBITED.
|
44
|
+
#
|
45
|
+
# RFC4013 §2.5 Unassigned Code Points
|
46
|
+
# >>>
|
47
|
+
# This profile specifies the \StringPrep\[\"A.1\"] table as its
|
48
|
+
# list of unassigned code points.
|
49
|
+
TABLES_PROHIBITED_STORED = ["A.1", *TABLES_PROHIBITED].freeze
|
50
|
+
|
51
|
+
# A Regexp matching codepoints prohibited by RFC4013 §2.3.
|
52
|
+
#
|
53
|
+
# This combines all of the TABLES_PROHIBITED tables.
|
54
|
+
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
|
55
|
+
|
56
|
+
# RFC4013 §2.5 Unassigned Code Points
|
57
|
+
# >>>
|
58
|
+
# This profile specifies the \StringPrep\[\"A.1\"] table as its
|
59
|
+
# list of unassigned code points.
|
60
|
+
#
|
61
|
+
# Equal to \StringPrep\[\"A.1\"].
|
62
|
+
# Redefined here to avoid loading StringPrep::Tables unless necessary.
|
63
|
+
UNASSIGNED = /\p{^AGE=3.2}/.freeze
|
64
|
+
|
65
|
+
# A Regexp matching codepoints prohibited by RFC4013 §2.3 and §2.5.
|
66
|
+
#
|
67
|
+
# This combines PROHIBITED_OUTPUT and UNASSIGNED.
|
68
|
+
PROHIBITED_OUTPUT_STORED = Regexp.union(
|
69
|
+
UNASSIGNED, PROHIBITED_OUTPUT
|
70
|
+
).freeze
|
71
|
+
|
72
|
+
# Bidirectional Characters [StringPrep, §6]
|
73
|
+
#
|
74
|
+
# A Regexp for strings that don't satisfy StringPrep's Bidirectional
|
75
|
+
# Characters rules.
|
76
|
+
#
|
77
|
+
# Equal to StringPrep::Tables::BIDI_FAILURE.
|
78
|
+
# Redefined here to avoid loading StringPrep::Tables unless necessary.
|
79
|
+
BIDI_FAILURE = /(?-mix:(?m-ix:(?-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}]).*?(?-mix:[\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}]))|(?m-ix:(?-mix:[\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}]).*?(?-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}])))|(?-mix:(?m-ix:\A(?-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}]).*?(?-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}]))|(?m-ix:(?-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}]).*?(?-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}])\z))/.freeze
|
80
|
+
|
81
|
+
# A Regexp matching strings prohibited by RFC4013 §2.3 and §2.4.
|
82
|
+
#
|
83
|
+
# This combines PROHIBITED_OUTPUT and BIDI_FAILURE.
|
84
|
+
PROHIBITED = Regexp.union(
|
85
|
+
PROHIBITED_OUTPUT, BIDI_FAILURE,
|
86
|
+
)
|
87
|
+
|
88
|
+
# A Regexp matching strings prohibited by RFC4013 §2.3, §2.4, and §2.5.
|
89
|
+
#
|
90
|
+
# This combines PROHIBITED_OUTPUT_STORED and BIDI_FAILURE.
|
91
|
+
PROHIBITED_STORED = Regexp.union(
|
92
|
+
PROHIBITED_OUTPUT_STORED, BIDI_FAILURE,
|
93
|
+
)
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|