/// <summary> /// Apply the SASLprep profile [RFC4013] of the "stringprep" algorithm [RFC3454] as the normalization /// algorithm to a UTF-8 [RFC3629] encoded string. /// </summary> /// <param name="input">the string to prep.</param> /// <param name="allowUnassigned">true if the name may contain unassigned code points.</param> /// <returns> the prepped name. /// @throws StringprepException If the name cannot be prepped with /// this profile. /// @throws NullPointerException If the name is null. /// </returns> public static string SaslPrep(string input, bool allowUnassigned) { if (input == null) { throw new System.NullReferenceException(); } StringBuilder s = new StringBuilder(input); // Unassigned Code Points if (!allowUnassigned && Stringprep.Contains(s, RFC3454.A1)) { throw new StringprepException(StringprepException.CONTAINS_UNASSIGNED); } // Mapping Stringprep.Filter(s, RFC3454.B1); Stringprep.Map(s, RFC3454.C12, C11Replace); // Normalization s = new StringBuilder(NFKC.NormalizeNFKC(s.ToString())); // Prohibited Output if (Stringprep.Contains(s, RFC3454.C12) || // - Non-ASCII space characters [StringPrep, C.1.2] Stringprep.Contains(s, RFC3454.C21) || // - ASCII control characters [StringPrep, C.2.1] Stringprep.Contains(s, RFC3454.C22) || // - Non-ASCII control characters [StringPrep, C.2.2] Stringprep.Contains(s, RFC3454.C3) || // - Private Use characters [StringPrep, C.3] Stringprep.Contains(s, RFC3454.C4) || // - Non-character code points [StringPrep, C.4] Stringprep.Contains(s, RFC3454.C5) || // - Surrogate code points [StringPrep, C.5] Stringprep.Contains(s, RFC3454.C6) || // - Inappropriate for plain text characters [StringPrep, C.6] Stringprep.Contains(s, RFC3454.C7) || // - Inappropriate for canonical representation characters [StringPrep, C.7] Stringprep.Contains(s, RFC3454.C8)) // - Change display properties or deprecated characters [StringPrep, C.8] { // Table C.9 only contains code points > 0xFFFF which Java doesn't handle throw new StringprepException(StringprepException.CONTAINS_PROHIBITED); } // Bidirectional Characters bool r = Stringprep.Contains(s, RFC3454.D1); bool l = Stringprep.Contains(s, RFC3454.D2); // RFC 3454, section 6, requirement 1: already handled above (table C.8) // RFC 3454, section 6, requirement 2 if (r && l) { throw new StringprepException(StringprepException.BIDI_BOTHRAL); } // RFC 3454, section 6, requirement 3 if (r) { if (!Stringprep.Contains(s[0], RFC3454.D1) || !Stringprep.Contains(s[s.Length - 1], RFC3454.D1)) { throw new StringprepException(StringprepException.BIDI_LTRAL); } } return(s.ToString()); }