module Net::IMAP::StringPrep::SASLprep

SASLprep#saslprep can be used to prepare a string according to [RFC4013].

SASLprep maps characters three ways: to nothing, to space, and Unicode normalization form KC. SASLprep prohibits codepoints from nearly all standard StringPrep tables (RFC3454, Appendix “C”), and uses StringPrep’s standard bidirectional characters requirements (Appendix “D”). SASLprep also uses StringPrep’s definition of “Unassigned” codepoints (Appendix “A”).

Constants

ASCII_NO_CTRLS

Used to short-circuit strings that don’t need preparation.

BIDI_FAILURE

Bidirectional Characters [StringPrep, §6]

A Regexp for strings that don’t satisfy StringPrep’s Bidirectional Characters rules.

Equal to StringPrep::Tables::BIDI_FAILURE. Redefined here to avoid loading StringPrep::Tables unless necessary.

MAP_TO_NOTHING

RFC4013 §2.1 Mapping - mapped to nothing

the “commonly mapped to nothing” characters (StringPrep["B.1"]) that can be mapped to nothing.

Equal to StringPrep["B.1"]. Redefined here to avoid loading StringPrep::Tables unless necessary.

MAP_TO_SPACE

RFC4013 §2.1 Mapping - mapped to space

non-ASCII space characters (StringPrep["C.1.2"]) that can be mapped to SPACE (U+0020)

Equal to StringPrep["C.1.2"]. Redefined here to avoid loading StringPrep::Tables unless necessary.

PROHIBITED

A Regexp matching strings prohibited by RFC4013 §2.3 and §2.4.

This combines PROHIBITED_OUTPUT and BIDI_FAILURE.

PROHIBITED_OUTPUT

A Regexp matching codepoints prohibited by RFC4013 §2.3.

This combines all of the TABLES_PROHIBITED tables.

PROHIBITED_OUTPUT_STORED

A Regexp matching codepoints prohibited by RFC4013 §2.3 and §2.5.

This combines PROHIBITED_OUTPUT and UNASSIGNED.

PROHIBITED_STORED

A Regexp matching strings prohibited by RFC4013 §2.3, §2.4, and §2.5.

This combines PROHIBITED_OUTPUT_STORED and BIDI_FAILURE.

TABLES_PROHIBITED

RFC4013 §2.3 Prohibited Output

  • Non-ASCII space characters — StringPrep["C.1.2"]

  • ASCII control characters — StringPrep["C.2.1"]

  • Non-ASCII control characters — StringPrep["C.2.2"]

  • Private Use characters — StringPrep["C.3"]

  • Non-character code points — StringPrep["C.4"]

  • Surrogate code points — StringPrep["C.5"]

  • Inappropriate for plain text characters — StringPrep["C.6"]

  • Inappropriate for canonical representation characters — StringPrep["C.7"]

  • Change display properties or deprecated characters — StringPrep["C.8"]

  • Tagging characters — StringPrep["C.9"]

TABLES_PROHIBITED_STORED

Adds unassigned (by Unicode 3.2) codepoints to TABLES_PROHIBITED.

RFC4013 §2.5 Unassigned Code Points

This profile specifies the StringPrep["A.1"] table as its list of unassigned code points.

UNASSIGNED

RFC4013 §2.5 Unassigned Code Points

This profile specifies the StringPrep["A.1"] table as its list of unassigned code points.

Equal to StringPrep["A.1"]. Redefined here to avoid loading StringPrep::Tables unless necessary.

Public Instance Methods

saslprep(str, stored: false, exception: false) click to toggle source

Prepares a UTF-8 string for comparison, using the SASLprep profile RFC4013 of the StringPrep algorithm RFC3454.

By default, prohibited strings will return nil. When exception is true, a StringPrepError describing the violation will be raised.

When stored is true, “unassigned” codepoints will be prohibited. For StringPrep and the SASLprep profile, “unassigned” refers to Unicode 3.2, and not later versions. See RFC3454 §7 for more information.

# File lib/net/imap/stringprep/saslprep.rb, line 42
def saslprep(str, stored: false, exception: false)
  return str if ASCII_NO_CTRLS.match?(str) # incompatible encoding raises
  str = str.encode("UTF-8") # also dups (and raises for invalid encoding)
  str.gsub!(MAP_TO_SPACE, " ")
  str.gsub!(MAP_TO_NOTHING, "")
  str.unicode_normalize!(:nfkc)
  # These regexps combine the prohibited and bidirectional checks
  return str unless str.match?(stored ? PROHIBITED_STORED : PROHIBITED)
  return nil unless exception
  # raise helpful errors to indicate *why* it failed:
  tables = stored ? TABLES_PROHIBITED_STORED : TABLES_PROHIBITED
  StringPrep.check_prohibited! str, *tables, bidi: true, profile: "SASLprep"
  raise InvalidStringError.new(
    "unknown error", string: string, profile: "SASLprep"
  )
rescue ArgumentError, Encoding::CompatibilityError => ex
  if /invalid byte sequence|incompatible encoding/.match? ex.message
    return nil unless exception
    raise StringPrepError.new(ex.message, string: str, profile: "saslprep")
  end
  raise ex
end