net-imap 0.3.7 → 0.4.0
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.
Potentially problematic release.
This version of net-imap might be problematic. Click here for more details.
- 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/authenticators.rb +112 -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/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 +139 -44
- 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 +967 -588
- data/net-imap.gemspec +1 -1
- data/rakelib/saslprep.rake +4 -4
- data/rakelib/string_prep_tables_generator.rb +82 -60
- metadata +26 -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.0
         | 
| 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-04 00:00:00.000000000 Z
         | 
| 13 13 | 
             
            dependencies:
         | 
| 14 14 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 15 15 | 
             
              name: net-protocol
         | 
| @@ -76,33 +76,48 @@ 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/authenticators.rb
         | 
| 104 | 
            +
            - lib/net/imap/sasl/cram_md5_authenticator.rb
         | 
| 105 | 
            +
            - lib/net/imap/sasl/digest_md5_authenticator.rb
         | 
| 106 | 
            +
            - lib/net/imap/sasl/external_authenticator.rb
         | 
| 107 | 
            +
            - lib/net/imap/sasl/gs2_header.rb
         | 
| 108 | 
            +
            - lib/net/imap/sasl/login_authenticator.rb
         | 
| 109 | 
            +
            - lib/net/imap/sasl/oauthbearer_authenticator.rb
         | 
| 110 | 
            +
            - lib/net/imap/sasl/plain_authenticator.rb
         | 
| 111 | 
            +
            - lib/net/imap/sasl/scram_algorithm.rb
         | 
| 112 | 
            +
            - lib/net/imap/sasl/scram_authenticator.rb
         | 
| 104 113 | 
             
            - lib/net/imap/sasl/stringprep.rb
         | 
| 105 | 
            -
            - lib/net/imap/sasl/ | 
| 114 | 
            +
            - lib/net/imap/sasl/xoauth2_authenticator.rb
         | 
| 115 | 
            +
            - lib/net/imap/stringprep.rb
         | 
| 116 | 
            +
            - lib/net/imap/stringprep/nameprep.rb
         | 
| 117 | 
            +
            - lib/net/imap/stringprep/saslprep.rb
         | 
| 118 | 
            +
            - lib/net/imap/stringprep/saslprep_tables.rb
         | 
| 119 | 
            +
            - lib/net/imap/stringprep/tables.rb
         | 
| 120 | 
            +
            - lib/net/imap/stringprep/trace.rb
         | 
| 106 121 | 
             
            - net-imap.gemspec
         | 
| 107 122 | 
             
            - rakelib/rdoc.rake
         | 
| 108 123 | 
             
            - rakelib/rfcs.rake
         | 
| @@ -123,7 +138,7 @@ required_ruby_version: !ruby/object:Gem::Requirement | |
| 123 138 | 
             
              requirements:
         | 
| 124 139 | 
             
              - - ">="
         | 
| 125 140 | 
             
                - !ruby/object:Gem::Version
         | 
| 126 | 
            -
                  version: 2. | 
| 141 | 
            +
                  version: 2.7.3
         | 
| 127 142 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 128 143 | 
             
              requirements:
         | 
| 129 144 | 
             
              - - ">="
         | 
| @@ -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
         |