module Net::IMAP::StringPrep
def self.[](table)
def self.[](table) Tables::REGEXPS.fetch(table) end
def check_bidi!(string, c_8: false, profile: nil)
requirements are met. +profile+ is an optional string which will be
Raises either ProhibitedCodepoint or BidiStringError unless all
checked when c_8: true.
This is usually combined with #check_prohibited!, so table "C.8" is only
RandALCat character MUST be the last character of the string.
character MUST be the first character of the string, and a
* If a string contains any RandALCat character, a RandALCat
contain any LCat character.
* If a string contains any RandALCat character, the string MUST NOT
* The characters in \StringPrep\[\"C.8\"] MUST be prohibited
requirements in RFC-3454, ยง6:
Checks that +string+ obeys all of the "Bidirectional Characters"
def check_bidi!(string, c_8: false, profile: nil) check_prohibited!(string, "C.8", profile: profile) if c_8 if Tables::BIDI_FAILS_REQ2.match?(string) raise BidiStringError.new( Tables::BIDI_DESC_REQ2, string: string, profile: profile, ) elsif Tables::BIDI_FAILS_REQ3.match?(string) raise BidiStringError.new( Tables::BIDI_DESC_REQ3, string: string, profile: profile, ) end end
def check_prohibited!(string,
+profile+ is an optional string which will be added to any exception that
raise a BidiStringError.
Also checks bidirectional characters, when bidi: true, which may
ProhibitedCodepoint describing the first matching table.
Checks +string+ for any codepoint in +tables+. Raises a
def check_prohibited!(string, *tables, bidi: false, unassigned: "A.1", stored: false, profile: nil) tables = Tables::TITLES.keys.grep(/^C/) if tables.empty? tables |= [unassigned] if stored tables |= %w[C.8] if bidi table = tables.find {|t| case t when String then Tables::REGEXPS.fetch(t).match?(string) when Regexp then t.match?(string) else raise ArgumentError, "only table names and regexps can be checked" end } if table raise ProhibitedCodepoint.new( table, string: string, profile: profile ) end check_bidi!(string, profile: profile) if bidi end
def map_tables!(string, *tables)
def map_tables!(string, *tables) tables.each do |table| regexp, replacements = Tables::MAPPINGS.fetch(table) string.gsub!(regexp, replacements) end string end
def stringprep(string,
this specification.
The above steps MUST be performed in the order given to comply with
error. This is described in section 6.
satisfy the requirements for bidirectional strings, return an
requirements for bidirectional strings. If the string does not
any are found, make sure that the whole string satisfies the
4. Check bidi -- Possibly check for right-to-left characters, and if
section 5.
output. If any are found, return an error. This is described in
3. Prohibit -- Check for any characters that are not allowed in the
normalization. This is described in section 4.
2. Normalize -- Possibly normalize the result of step 1 using Unicode
section 3.
and, if so, replace it with its mapping. This is described in
1. Map -- For each character in the input, check if it has a mapping
>>>
def stringprep(string, maps:, normalization:, prohibited:, **opts) string = string.encode("UTF-8") # also dups (and raises invalid encoding) map_tables!(string, *maps) if maps string.unicode_normalize!(normalization) if normalization check_prohibited!(string, *prohibited, **opts) if prohibited string end