//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//------------------------------------------------------------------------------
namespace System.Web.Security.AntiXss {
using System.Collections;
using System.Globalization;
///
/// Provides safe list utility functions.
///
internal static class SafeList {
///
/// Generates a safe character array representing the specified value.
///
/// A safe character array representing the specified value.
/// The value to generate a safe representation for.
internal delegate char[] GenerateSafeValue(int value);
///
/// Generates a new safe list of the specified size, using the specified function to produce safe values.
///
/// The length of the safe list to generate.
/// The function to use.
/// A new safe list.
internal static char[][] Generate(int length, GenerateSafeValue generateSafeValue) {
char[][] allCharacters = new char[length + 1][];
for (int i = 0; i <= length; i++) {
allCharacters[i] = generateSafeValue(i);
}
return allCharacters;
}
///
/// Marks characters from the specified languages as safe.
///
/// The safe list to punch holes in.
/// The combination of lower code charts to use.
/// The combination of lower mid code charts to use.
/// The combination of mid code charts to use.
/// The combination of upper mid code charts to use.
/// The combination of upper code charts to use.
internal static void PunchUnicodeThrough(
ref char[][] safeList,
LowerCodeCharts lowerCodeCharts,
LowerMidCodeCharts lowerMidCodeCharts,
MidCodeCharts midCodeCharts,
UpperMidCodeCharts upperMidCodeCharts,
UpperCodeCharts upperCodeCharts) {
if (lowerCodeCharts != LowerCodeCharts.None) {
PunchCodeCharts(ref safeList, lowerCodeCharts);
}
if (lowerMidCodeCharts != LowerMidCodeCharts.None) {
PunchCodeCharts(ref safeList, lowerMidCodeCharts);
}
if (midCodeCharts != MidCodeCharts.None) {
PunchCodeCharts(ref safeList, midCodeCharts);
}
if (upperMidCodeCharts != UpperMidCodeCharts.None) {
PunchCodeCharts(ref safeList, upperMidCodeCharts);
}
if (upperCodeCharts != UpperCodeCharts.None) {
PunchCodeCharts(ref safeList, upperCodeCharts);
}
}
///
/// Punches holes as necessary.
///
/// The safe list to punch through.
/// The list of character positions to punch.
internal static void PunchSafeList(ref char[][] safeList, IEnumerable whiteListedCharacters) {
PunchHolesIfNeeded(ref safeList, true, whiteListedCharacters);
}
///
/// Generates a hash prefixed character array representing the specified value.
///
/// The source value.
/// A character array representing the specified value.
///
/// Example inputs and encoded outputs:
///
/// - 1#1
/// - 10#10
/// - 100#100
///
///
internal static char[] HashThenValueGenerator(int value) {
return StringToCharArrayWithHashPrefix(value.ToString(CultureInfo.InvariantCulture));
}
///
/// Generates a hash prefixed character array representing the specified value in hexadecimal.
///
/// The source value.
/// A character array representing the specified value.
///
/// Example inputs and encoded outputs:
///
/// - 1#1
/// - 10#0a
/// - 100#64
///
///
internal static char[] HashThenHexValueGenerator(int value) {
return StringToCharArrayWithHashPrefix(value.ToString("x2", CultureInfo.InvariantCulture));
}
///
/// Generates a percent prefixed character array representing the specified value in hexadecimal.
///
/// The source value.
/// A character array representing the specified value.
///
/// Example inputs and encoded outputs:
///
/// - 1%01
/// - 10%0A
/// - 100%64
///
///
internal static char[] PercentThenHexValueGenerator(int value) {
return StringToCharArrayWithPercentPrefix(value.ToString("X2", CultureInfo.InvariantCulture));
}
///
/// Generates a slash prefixed character array representing the specified value in hexadecimal.
///
/// The source value.
/// A character array representing the specified value.
///
/// Example inputs and encoded outputs:
///
/// - 1\01
/// - 10\0a
/// - 100\64
///
///
internal static char[] SlashThenHexValueGenerator(int value) {
return StringToCharArrayWithSlashPrefix(value.ToString("x2", CultureInfo.InvariantCulture));
}
///
/// Generates a slash prefixed character array representing the specified value in hexadecimal.
///
/// The source value.
/// A character array representing the specified value.
///
/// Example inputs and encoded outputs:
///
/// - 1\000001
/// - 10\000000A
/// - 100\000064
///
///
internal static char[] SlashThenSixDigitHexValueGenerator(long value) {
return StringToCharArrayWithSlashPrefix(value.ToString("X6", CultureInfo.InvariantCulture));
}
///
/// Generates a slash prefixed character array representing the specified value in hexadecimal.
///
/// The source value.
/// A character array representing the specified value.
///
/// Example inputs and encoded outputs:
///
/// - 1\000001
/// - 10\000000A
/// - 100\000064
///
///
internal static char[] SlashThenSixDigitHexValueGenerator(int value) {
return StringToCharArrayWithSlashPrefix(value.ToString("X6", CultureInfo.InvariantCulture));
}
///
/// Generates a hash prefixed character array representing the specified value.
///
/// The source value.
/// A character array representing the specified value.
///
/// Example inputs and encoded outputs:
///
/// - 1#1
/// - 10#10
/// - 100#100
///
///
internal static char[] HashThenValueGenerator(long value) {
return StringToCharArrayWithHashPrefix(value.ToString(CultureInfo.InvariantCulture));
}
///
/// Generates a hash prefixed character array from the specified string.
///
/// The source value.
/// A character array representing the specified value.
///
/// Example inputs and encoded outputs:
///
/// - 1#1
/// - 10#10
/// - 100#100
///
///
private static char[] StringToCharArrayWithHashPrefix(string value) {
return StringToCharArrayWithPrefix(value, '#');
}
///
/// Generates a percent prefixed character array from the specified string.
///
/// The source value.
/// A character array representing the specified value.
///
/// Example inputs and encoded outputs:
///
/// - 1%1
/// - 10%10
/// - 100%100
///
///
private static char[] StringToCharArrayWithPercentPrefix(string value) {
return StringToCharArrayWithPrefix(value, '%');
}
///
/// Generates a slash prefixed character array from the specified string.
///
/// The source value.
/// A character array representing the specified value.
///
/// Example inputs and encoded outputs:
///
/// - 1\1
/// - 10\10
/// - 100\100
///
///
private static char[] StringToCharArrayWithSlashPrefix(string value) {
return StringToCharArrayWithPrefix(value, '\\');
}
///
/// Generates a prefixed character array from the specified string and prefix.
///
/// The source value.
/// The prefix to use.
/// A prefixed character array representing the specified value.
private static char[] StringToCharArrayWithPrefix(string value, char prefix) {
int valueAsStringLength = value.Length;
char[] valueAsCharArray = new char[valueAsStringLength + 1];
valueAsCharArray[0] = prefix;
for (int j = 0; j < valueAsStringLength; j++) {
valueAsCharArray[j + 1] = value[j];
}
return valueAsCharArray;
}
///
/// Punch appropriate holes for the selected code charts.
///
/// The safe list to punch through.
/// The code charts to punch.
private static void PunchCodeCharts(ref char[][] safeList, LowerCodeCharts codeCharts) {
PunchHolesIfNeeded(ref safeList, CodeCharts.Lower.IsFlagSet(codeCharts, LowerCodeCharts.BasicLatin), CodeCharts.Lower.BasicLatin());
PunchHolesIfNeeded(ref safeList, CodeCharts.Lower.IsFlagSet(codeCharts, LowerCodeCharts.C1ControlsAndLatin1Supplement), CodeCharts.Lower.Latin1Supplement());
PunchHolesIfNeeded(ref safeList, CodeCharts.Lower.IsFlagSet(codeCharts, LowerCodeCharts.LatinExtendedA), CodeCharts.Lower.LatinExtendedA());
PunchHolesIfNeeded(ref safeList, CodeCharts.Lower.IsFlagSet(codeCharts, LowerCodeCharts.LatinExtendedB), CodeCharts.Lower.LatinExtendedB());
PunchHolesIfNeeded(ref safeList, CodeCharts.Lower.IsFlagSet(codeCharts, LowerCodeCharts.IpaExtensions), CodeCharts.Lower.IpaExtensions());
PunchHolesIfNeeded(ref safeList, CodeCharts.Lower.IsFlagSet(codeCharts, LowerCodeCharts.SpacingModifierLetters), CodeCharts.Lower.SpacingModifierLetters());
PunchHolesIfNeeded(ref safeList, CodeCharts.Lower.IsFlagSet(codeCharts, LowerCodeCharts.CombiningDiacriticalMarks), CodeCharts.Lower.CombiningDiacriticalMarks());
PunchHolesIfNeeded(ref safeList, CodeCharts.Lower.IsFlagSet(codeCharts, LowerCodeCharts.GreekAndCoptic), CodeCharts.Lower.GreekAndCoptic());
PunchHolesIfNeeded(ref safeList, CodeCharts.Lower.IsFlagSet(codeCharts, LowerCodeCharts.Cyrillic), CodeCharts.Lower.Cyrillic());
PunchHolesIfNeeded(ref safeList, CodeCharts.Lower.IsFlagSet(codeCharts, LowerCodeCharts.CyrillicSupplement), CodeCharts.Lower.CyrillicSupplement());
PunchHolesIfNeeded(ref safeList, CodeCharts.Lower.IsFlagSet(codeCharts, LowerCodeCharts.Armenian), CodeCharts.Lower.Armenian());
PunchHolesIfNeeded(ref safeList, CodeCharts.Lower.IsFlagSet(codeCharts, LowerCodeCharts.Hebrew), CodeCharts.Lower.Hebrew());
PunchHolesIfNeeded(ref safeList, CodeCharts.Lower.IsFlagSet(codeCharts, LowerCodeCharts.Arabic), CodeCharts.Lower.Arabic());
PunchHolesIfNeeded(ref safeList, CodeCharts.Lower.IsFlagSet(codeCharts, LowerCodeCharts.Syriac), CodeCharts.Lower.Syriac());
PunchHolesIfNeeded(ref safeList, CodeCharts.Lower.IsFlagSet(codeCharts, LowerCodeCharts.ArabicSupplement), CodeCharts.Lower.ArabicSupplement());
PunchHolesIfNeeded(ref safeList, CodeCharts.Lower.IsFlagSet(codeCharts, LowerCodeCharts.Thaana), CodeCharts.Lower.Thaana());
PunchHolesIfNeeded(ref safeList, CodeCharts.Lower.IsFlagSet(codeCharts, LowerCodeCharts.Nko), CodeCharts.Lower.Nko());
PunchHolesIfNeeded(ref safeList, CodeCharts.Lower.IsFlagSet(codeCharts, LowerCodeCharts.Samaritan), CodeCharts.Lower.Samaritan());
PunchHolesIfNeeded(ref safeList, CodeCharts.Lower.IsFlagSet(codeCharts, LowerCodeCharts.Devanagari), CodeCharts.Lower.Devanagari());
PunchHolesIfNeeded(ref safeList, CodeCharts.Lower.IsFlagSet(codeCharts, LowerCodeCharts.Bengali), CodeCharts.Lower.Bengali());
PunchHolesIfNeeded(ref safeList, CodeCharts.Lower.IsFlagSet(codeCharts, LowerCodeCharts.Gurmukhi), CodeCharts.Lower.Gurmukhi());
PunchHolesIfNeeded(ref safeList, CodeCharts.Lower.IsFlagSet(codeCharts, LowerCodeCharts.Gujarati), CodeCharts.Lower.Gujarati());
PunchHolesIfNeeded(ref safeList, CodeCharts.Lower.IsFlagSet(codeCharts, LowerCodeCharts.Oriya), CodeCharts.Lower.Oriya());
PunchHolesIfNeeded(ref safeList, CodeCharts.Lower.IsFlagSet(codeCharts, LowerCodeCharts.Tamil), CodeCharts.Lower.Tamil());
PunchHolesIfNeeded(ref safeList, CodeCharts.Lower.IsFlagSet(codeCharts, LowerCodeCharts.Telugu), CodeCharts.Lower.Telugu());
PunchHolesIfNeeded(ref safeList, CodeCharts.Lower.IsFlagSet(codeCharts, LowerCodeCharts.Kannada), CodeCharts.Lower.Kannada());
PunchHolesIfNeeded(ref safeList, CodeCharts.Lower.IsFlagSet(codeCharts, LowerCodeCharts.Malayalam), CodeCharts.Lower.Malayalam());
PunchHolesIfNeeded(ref safeList, CodeCharts.Lower.IsFlagSet(codeCharts, LowerCodeCharts.Sinhala), CodeCharts.Lower.Sinhala());
PunchHolesIfNeeded(ref safeList, CodeCharts.Lower.IsFlagSet(codeCharts, LowerCodeCharts.Thai), CodeCharts.Lower.Thai());
PunchHolesIfNeeded(ref safeList, CodeCharts.Lower.IsFlagSet(codeCharts, LowerCodeCharts.Lao), CodeCharts.Lower.Lao());
PunchHolesIfNeeded(ref safeList, CodeCharts.Lower.IsFlagSet(codeCharts, LowerCodeCharts.Tibetan), CodeCharts.Lower.Tibetan());
}
///
/// Punch appropriate holes for the selected code charts.
///
/// The safe list to punch through.
/// The code charts to punch.
private static void PunchCodeCharts(ref char[][] safeList, LowerMidCodeCharts codeCharts) {
PunchHolesIfNeeded(ref safeList, CodeCharts.LowerMiddle.IsFlagSet(codeCharts, LowerMidCodeCharts.Myanmar), CodeCharts.LowerMiddle.Myanmar());
PunchHolesIfNeeded(ref safeList, CodeCharts.LowerMiddle.IsFlagSet(codeCharts, LowerMidCodeCharts.Georgian), CodeCharts.LowerMiddle.Georgian());
PunchHolesIfNeeded(ref safeList, CodeCharts.LowerMiddle.IsFlagSet(codeCharts, LowerMidCodeCharts.HangulJamo), CodeCharts.LowerMiddle.HangulJamo());
PunchHolesIfNeeded(ref safeList, CodeCharts.LowerMiddle.IsFlagSet(codeCharts, LowerMidCodeCharts.Ethiopic), CodeCharts.LowerMiddle.Ethiopic());
PunchHolesIfNeeded(ref safeList, CodeCharts.LowerMiddle.IsFlagSet(codeCharts, LowerMidCodeCharts.EthiopicSupplement), CodeCharts.LowerMiddle.EthiopicSupplement());
PunchHolesIfNeeded(ref safeList, CodeCharts.LowerMiddle.IsFlagSet(codeCharts, LowerMidCodeCharts.Cherokee), CodeCharts.LowerMiddle.Cherokee());
PunchHolesIfNeeded(ref safeList, CodeCharts.LowerMiddle.IsFlagSet(codeCharts, LowerMidCodeCharts.UnifiedCanadianAboriginalSyllabics), CodeCharts.LowerMiddle.UnifiedCanadianAboriginalSyllabics());
PunchHolesIfNeeded(ref safeList, CodeCharts.LowerMiddle.IsFlagSet(codeCharts, LowerMidCodeCharts.Ogham), CodeCharts.LowerMiddle.Ogham());
PunchHolesIfNeeded(ref safeList, CodeCharts.LowerMiddle.IsFlagSet(codeCharts, LowerMidCodeCharts.Runic), CodeCharts.LowerMiddle.Runic());
PunchHolesIfNeeded(ref safeList, CodeCharts.LowerMiddle.IsFlagSet(codeCharts, LowerMidCodeCharts.Tagalog), CodeCharts.LowerMiddle.Tagalog());
PunchHolesIfNeeded(ref safeList, CodeCharts.LowerMiddle.IsFlagSet(codeCharts, LowerMidCodeCharts.Hanunoo), CodeCharts.LowerMiddle.Hanunoo());
PunchHolesIfNeeded(ref safeList, CodeCharts.LowerMiddle.IsFlagSet(codeCharts, LowerMidCodeCharts.Buhid), CodeCharts.LowerMiddle.Buhid());
PunchHolesIfNeeded(ref safeList, CodeCharts.LowerMiddle.IsFlagSet(codeCharts, LowerMidCodeCharts.Tagbanwa), CodeCharts.LowerMiddle.Tagbanwa());
PunchHolesIfNeeded(ref safeList, CodeCharts.LowerMiddle.IsFlagSet(codeCharts, LowerMidCodeCharts.Khmer), CodeCharts.LowerMiddle.Khmer());
PunchHolesIfNeeded(ref safeList, CodeCharts.LowerMiddle.IsFlagSet(codeCharts, LowerMidCodeCharts.Mongolian), CodeCharts.LowerMiddle.Mongolian());
PunchHolesIfNeeded(ref safeList, CodeCharts.LowerMiddle.IsFlagSet(codeCharts, LowerMidCodeCharts.UnifiedCanadianAboriginalSyllabicsExtended), CodeCharts.LowerMiddle.UnifiedCanadianAboriginalSyllabicsExtended());
PunchHolesIfNeeded(ref safeList, CodeCharts.LowerMiddle.IsFlagSet(codeCharts, LowerMidCodeCharts.Limbu), CodeCharts.LowerMiddle.Limbu());
PunchHolesIfNeeded(ref safeList, CodeCharts.LowerMiddle.IsFlagSet(codeCharts, LowerMidCodeCharts.TaiLe), CodeCharts.LowerMiddle.TaiLe());
PunchHolesIfNeeded(ref safeList, CodeCharts.LowerMiddle.IsFlagSet(codeCharts, LowerMidCodeCharts.NewTaiLue), CodeCharts.LowerMiddle.NewTaiLue());
PunchHolesIfNeeded(ref safeList, CodeCharts.LowerMiddle.IsFlagSet(codeCharts, LowerMidCodeCharts.KhmerSymbols), CodeCharts.LowerMiddle.KhmerSymbols());
PunchHolesIfNeeded(ref safeList, CodeCharts.LowerMiddle.IsFlagSet(codeCharts, LowerMidCodeCharts.Buginese), CodeCharts.LowerMiddle.Buginese());
PunchHolesIfNeeded(ref safeList, CodeCharts.LowerMiddle.IsFlagSet(codeCharts, LowerMidCodeCharts.TaiTham), CodeCharts.LowerMiddle.TaiTham());
PunchHolesIfNeeded(ref safeList, CodeCharts.LowerMiddle.IsFlagSet(codeCharts, LowerMidCodeCharts.Balinese), CodeCharts.LowerMiddle.Balinese());
PunchHolesIfNeeded(ref safeList, CodeCharts.LowerMiddle.IsFlagSet(codeCharts, LowerMidCodeCharts.Sudanese), CodeCharts.LowerMiddle.Sudanese());
PunchHolesIfNeeded(ref safeList, CodeCharts.LowerMiddle.IsFlagSet(codeCharts, LowerMidCodeCharts.Lepcha), CodeCharts.LowerMiddle.Lepcha());
PunchHolesIfNeeded(ref safeList, CodeCharts.LowerMiddle.IsFlagSet(codeCharts, LowerMidCodeCharts.OlChiki), CodeCharts.LowerMiddle.OlChiki());
PunchHolesIfNeeded(ref safeList, CodeCharts.LowerMiddle.IsFlagSet(codeCharts, LowerMidCodeCharts.VedicExtensions), CodeCharts.LowerMiddle.VedicExtensions());
PunchHolesIfNeeded(ref safeList, CodeCharts.LowerMiddle.IsFlagSet(codeCharts, LowerMidCodeCharts.PhoneticExtensions), CodeCharts.LowerMiddle.PhoneticExtensions());
PunchHolesIfNeeded(ref safeList, CodeCharts.LowerMiddle.IsFlagSet(codeCharts, LowerMidCodeCharts.PhoneticExtensionsSupplement), CodeCharts.LowerMiddle.PhoneticExtensionsSupplement());
PunchHolesIfNeeded(ref safeList, CodeCharts.LowerMiddle.IsFlagSet(codeCharts, LowerMidCodeCharts.CombiningDiacriticalMarksSupplement), CodeCharts.LowerMiddle.CombiningDiacriticalMarksSupplement());
PunchHolesIfNeeded(ref safeList, CodeCharts.LowerMiddle.IsFlagSet(codeCharts, LowerMidCodeCharts.LatinExtendedAdditional), CodeCharts.LowerMiddle.LatinExtendedAdditional());
}
///
/// Punch appropriate holes for the selected code charts.
///
/// The safe list to punch through.
/// The code charts to punch.
private static void PunchCodeCharts(ref char[][] safeList, MidCodeCharts codeCharts) {
PunchHolesIfNeeded(ref safeList, CodeCharts.Middle.IsFlagSet(codeCharts, MidCodeCharts.GreekExtended), CodeCharts.Middle.GreekExtended());
PunchHolesIfNeeded(ref safeList, CodeCharts.Middle.IsFlagSet(codeCharts, MidCodeCharts.GeneralPunctuation), CodeCharts.Middle.GeneralPunctuation());
PunchHolesIfNeeded(ref safeList, CodeCharts.Middle.IsFlagSet(codeCharts, MidCodeCharts.SuperscriptsAndSubscripts), CodeCharts.Middle.SuperscriptsAndSubscripts());
PunchHolesIfNeeded(ref safeList, CodeCharts.Middle.IsFlagSet(codeCharts, MidCodeCharts.CurrencySymbols), CodeCharts.Middle.CurrencySymbols());
PunchHolesIfNeeded(ref safeList, CodeCharts.Middle.IsFlagSet(codeCharts, MidCodeCharts.CombiningDiacriticalMarksForSymbols), CodeCharts.Middle.CombiningDiacriticalMarksForSymbols());
PunchHolesIfNeeded(ref safeList, CodeCharts.Middle.IsFlagSet(codeCharts, MidCodeCharts.LetterlikeSymbols), CodeCharts.Middle.LetterlikeSymbols());
PunchHolesIfNeeded(ref safeList, CodeCharts.Middle.IsFlagSet(codeCharts, MidCodeCharts.NumberForms), CodeCharts.Middle.NumberForms());
PunchHolesIfNeeded(ref safeList, CodeCharts.Middle.IsFlagSet(codeCharts, MidCodeCharts.Arrows), CodeCharts.Middle.Arrows());
PunchHolesIfNeeded(ref safeList, CodeCharts.Middle.IsFlagSet(codeCharts, MidCodeCharts.MathematicalOperators), CodeCharts.Middle.MathematicalOperators());
PunchHolesIfNeeded(ref safeList, CodeCharts.Middle.IsFlagSet(codeCharts, MidCodeCharts.MiscellaneousTechnical), CodeCharts.Middle.MiscellaneousTechnical());
PunchHolesIfNeeded(ref safeList, CodeCharts.Middle.IsFlagSet(codeCharts, MidCodeCharts.ControlPictures), CodeCharts.Middle.ControlPictures());
PunchHolesIfNeeded(ref safeList, CodeCharts.Middle.IsFlagSet(codeCharts, MidCodeCharts.OpticalCharacterRecognition), CodeCharts.Middle.OpticalCharacterRecognition());
PunchHolesIfNeeded(ref safeList, CodeCharts.Middle.IsFlagSet(codeCharts, MidCodeCharts.EnclosedAlphanumerics), CodeCharts.Middle.EnclosedAlphanumerics());
PunchHolesIfNeeded(ref safeList, CodeCharts.Middle.IsFlagSet(codeCharts, MidCodeCharts.BoxDrawing), CodeCharts.Middle.BoxDrawing());
PunchHolesIfNeeded(ref safeList, CodeCharts.Middle.IsFlagSet(codeCharts, MidCodeCharts.BlockElements), CodeCharts.Middle.BlockElements());
PunchHolesIfNeeded(ref safeList, CodeCharts.Middle.IsFlagSet(codeCharts, MidCodeCharts.GeometricShapes), CodeCharts.Middle.GeometricShapes());
PunchHolesIfNeeded(ref safeList, CodeCharts.Middle.IsFlagSet(codeCharts, MidCodeCharts.MiscellaneousSymbols), CodeCharts.Middle.MiscellaneousSymbols());
PunchHolesIfNeeded(ref safeList, CodeCharts.Middle.IsFlagSet(codeCharts, MidCodeCharts.Dingbats), CodeCharts.Middle.Dingbats());
PunchHolesIfNeeded(ref safeList, CodeCharts.Middle.IsFlagSet(codeCharts, MidCodeCharts.MiscellaneousMathematicalSymbolsA), CodeCharts.Middle.MiscellaneousMathematicalSymbolsA());
PunchHolesIfNeeded(ref safeList, CodeCharts.Middle.IsFlagSet(codeCharts, MidCodeCharts.SupplementalArrowsA), CodeCharts.Middle.SupplementalArrowsA());
PunchHolesIfNeeded(ref safeList, CodeCharts.Middle.IsFlagSet(codeCharts, MidCodeCharts.BraillePatterns), CodeCharts.Middle.BraillePatterns());
PunchHolesIfNeeded(ref safeList, CodeCharts.Middle.IsFlagSet(codeCharts, MidCodeCharts.SupplementalArrowsB), CodeCharts.Middle.SupplementalArrowsB());
PunchHolesIfNeeded(ref safeList, CodeCharts.Middle.IsFlagSet(codeCharts, MidCodeCharts.MiscellaneousMathematicalSymbolsB), CodeCharts.Middle.MiscellaneousMathematicalSymbolsB());
PunchHolesIfNeeded(ref safeList, CodeCharts.Middle.IsFlagSet(codeCharts, MidCodeCharts.SupplementalMathematicalOperators), CodeCharts.Middle.SupplementalMathematicalOperators());
PunchHolesIfNeeded(ref safeList, CodeCharts.Middle.IsFlagSet(codeCharts, MidCodeCharts.MiscellaneousSymbolsAndArrows), CodeCharts.Middle.MiscellaneousSymbolsAndArrows());
PunchHolesIfNeeded(ref safeList, CodeCharts.Middle.IsFlagSet(codeCharts, MidCodeCharts.Glagolitic), CodeCharts.Middle.Glagolitic());
PunchHolesIfNeeded(ref safeList, CodeCharts.Middle.IsFlagSet(codeCharts, MidCodeCharts.LatinExtendedC), CodeCharts.Middle.LatinExtendedC());
PunchHolesIfNeeded(ref safeList, CodeCharts.Middle.IsFlagSet(codeCharts, MidCodeCharts.Coptic), CodeCharts.Middle.Coptic());
PunchHolesIfNeeded(ref safeList, CodeCharts.Middle.IsFlagSet(codeCharts, MidCodeCharts.GeorgianSupplement), CodeCharts.Middle.GeorgianSupplement());
PunchHolesIfNeeded(ref safeList, CodeCharts.Middle.IsFlagSet(codeCharts, MidCodeCharts.Tifinagh), CodeCharts.Middle.Tifinagh());
PunchHolesIfNeeded(ref safeList, CodeCharts.Middle.IsFlagSet(codeCharts, MidCodeCharts.EthiopicExtended), CodeCharts.Middle.EthiopicExtended());
}
///
/// Punch appropriate holes for the selected code charts.
///
/// The safe list to punch through.
/// The code charts to punch.
private static void PunchCodeCharts(ref char[][] safeList, UpperMidCodeCharts codeCharts) {
PunchHolesIfNeeded(ref safeList, CodeCharts.UpperMiddle.IsFlagSet(codeCharts, UpperMidCodeCharts.CyrillicExtendedA), CodeCharts.UpperMiddle.CyrillicExtendedA());
PunchHolesIfNeeded(ref safeList, CodeCharts.UpperMiddle.IsFlagSet(codeCharts, UpperMidCodeCharts.SupplementalPunctuation), CodeCharts.UpperMiddle.SupplementalPunctuation());
PunchHolesIfNeeded(ref safeList, CodeCharts.UpperMiddle.IsFlagSet(codeCharts, UpperMidCodeCharts.CjkRadicalsSupplement), CodeCharts.UpperMiddle.CjkRadicalsSupplement());
PunchHolesIfNeeded(ref safeList, CodeCharts.UpperMiddle.IsFlagSet(codeCharts, UpperMidCodeCharts.KangxiRadicals), CodeCharts.UpperMiddle.KangxiRadicals());
PunchHolesIfNeeded(ref safeList, CodeCharts.UpperMiddle.IsFlagSet(codeCharts, UpperMidCodeCharts.IdeographicDescriptionCharacters), CodeCharts.UpperMiddle.IdeographicDescriptionCharacters());
PunchHolesIfNeeded(ref safeList, CodeCharts.UpperMiddle.IsFlagSet(codeCharts, UpperMidCodeCharts.CjkSymbolsAndPunctuation), CodeCharts.UpperMiddle.CjkSymbolsAndPunctuation());
PunchHolesIfNeeded(ref safeList, CodeCharts.UpperMiddle.IsFlagSet(codeCharts, UpperMidCodeCharts.Hiragana), CodeCharts.UpperMiddle.Hiragana());
PunchHolesIfNeeded(ref safeList, CodeCharts.UpperMiddle.IsFlagSet(codeCharts, UpperMidCodeCharts.Katakana), CodeCharts.UpperMiddle.Katakana());
PunchHolesIfNeeded(ref safeList, CodeCharts.UpperMiddle.IsFlagSet(codeCharts, UpperMidCodeCharts.Bopomofo), CodeCharts.UpperMiddle.Bopomofo());
PunchHolesIfNeeded(ref safeList, CodeCharts.UpperMiddle.IsFlagSet(codeCharts, UpperMidCodeCharts.HangulCompatibilityJamo), CodeCharts.UpperMiddle.HangulCompatibilityJamo());
PunchHolesIfNeeded(ref safeList, CodeCharts.UpperMiddle.IsFlagSet(codeCharts, UpperMidCodeCharts.Kanbun), CodeCharts.UpperMiddle.Kanbun());
PunchHolesIfNeeded(ref safeList, CodeCharts.UpperMiddle.IsFlagSet(codeCharts, UpperMidCodeCharts.BopomofoExtended), CodeCharts.UpperMiddle.BopomofoExtended());
PunchHolesIfNeeded(ref safeList, CodeCharts.UpperMiddle.IsFlagSet(codeCharts, UpperMidCodeCharts.CjkStrokes), CodeCharts.UpperMiddle.CjkStrokes());
PunchHolesIfNeeded(ref safeList, CodeCharts.UpperMiddle.IsFlagSet(codeCharts, UpperMidCodeCharts.KatakanaPhoneticExtensions), CodeCharts.UpperMiddle.KatakanaPhoneticExtensions());
PunchHolesIfNeeded(ref safeList, CodeCharts.UpperMiddle.IsFlagSet(codeCharts, UpperMidCodeCharts.EnclosedCjkLettersAndMonths), CodeCharts.UpperMiddle.EnclosedCjkLettersAndMonths());
PunchHolesIfNeeded(ref safeList, CodeCharts.UpperMiddle.IsFlagSet(codeCharts, UpperMidCodeCharts.CjkCompatibility), CodeCharts.UpperMiddle.CjkCompatibility());
PunchHolesIfNeeded(ref safeList, CodeCharts.UpperMiddle.IsFlagSet(codeCharts, UpperMidCodeCharts.CjkUnifiedIdeographsExtensionA), CodeCharts.UpperMiddle.CjkUnifiedIdeographsExtensionA());
PunchHolesIfNeeded(ref safeList, CodeCharts.UpperMiddle.IsFlagSet(codeCharts, UpperMidCodeCharts.YijingHexagramSymbols), CodeCharts.UpperMiddle.YijingHexagramSymbols());
PunchHolesIfNeeded(ref safeList, CodeCharts.UpperMiddle.IsFlagSet(codeCharts, UpperMidCodeCharts.CjkUnifiedIdeographs), CodeCharts.UpperMiddle.CjkUnifiedIdeographs());
PunchHolesIfNeeded(ref safeList, CodeCharts.UpperMiddle.IsFlagSet(codeCharts, UpperMidCodeCharts.YiSyllables), CodeCharts.UpperMiddle.YiSyllables());
PunchHolesIfNeeded(ref safeList, CodeCharts.UpperMiddle.IsFlagSet(codeCharts, UpperMidCodeCharts.YiRadicals), CodeCharts.UpperMiddle.YiRadicals());
PunchHolesIfNeeded(ref safeList, CodeCharts.UpperMiddle.IsFlagSet(codeCharts, UpperMidCodeCharts.Lisu), CodeCharts.UpperMiddle.Lisu());
PunchHolesIfNeeded(ref safeList, CodeCharts.UpperMiddle.IsFlagSet(codeCharts, UpperMidCodeCharts.Vai), CodeCharts.UpperMiddle.Vai());
PunchHolesIfNeeded(ref safeList, CodeCharts.UpperMiddle.IsFlagSet(codeCharts, UpperMidCodeCharts.CyrillicExtendedB), CodeCharts.UpperMiddle.CyrillicExtendedB());
PunchHolesIfNeeded(ref safeList, CodeCharts.UpperMiddle.IsFlagSet(codeCharts, UpperMidCodeCharts.Bamum), CodeCharts.UpperMiddle.Bamum());
PunchHolesIfNeeded(ref safeList, CodeCharts.UpperMiddle.IsFlagSet(codeCharts, UpperMidCodeCharts.ModifierToneLetters), CodeCharts.UpperMiddle.ModifierToneLetters());
PunchHolesIfNeeded(ref safeList, CodeCharts.UpperMiddle.IsFlagSet(codeCharts, UpperMidCodeCharts.LatinExtendedD), CodeCharts.UpperMiddle.LatinExtendedD());
PunchHolesIfNeeded(ref safeList, CodeCharts.UpperMiddle.IsFlagSet(codeCharts, UpperMidCodeCharts.SylotiNagri), CodeCharts.UpperMiddle.SylotiNagri());
PunchHolesIfNeeded(ref safeList, CodeCharts.UpperMiddle.IsFlagSet(codeCharts, UpperMidCodeCharts.CommonIndicNumberForms), CodeCharts.UpperMiddle.CommonIndicNumberForms());
PunchHolesIfNeeded(ref safeList, CodeCharts.UpperMiddle.IsFlagSet(codeCharts, UpperMidCodeCharts.Phagspa), CodeCharts.UpperMiddle.Phagspa());
PunchHolesIfNeeded(ref safeList, CodeCharts.UpperMiddle.IsFlagSet(codeCharts, UpperMidCodeCharts.Saurashtra), CodeCharts.UpperMiddle.Saurashtra());
}
///
/// Punch appropriate holes for the selected code charts.
///
/// The safe list to punch through.
/// The code charts to punch.
private static void PunchCodeCharts(ref char[][] safeList, UpperCodeCharts codeCharts) {
PunchHolesIfNeeded(ref safeList, CodeCharts.Upper.IsFlagSet(codeCharts, UpperCodeCharts.DevanagariExtended), CodeCharts.Upper.DevanagariExtended());
PunchHolesIfNeeded(ref safeList, CodeCharts.Upper.IsFlagSet(codeCharts, UpperCodeCharts.KayahLi), CodeCharts.Upper.KayahLi());
PunchHolesIfNeeded(ref safeList, CodeCharts.Upper.IsFlagSet(codeCharts, UpperCodeCharts.Rejang), CodeCharts.Upper.Rejang());
PunchHolesIfNeeded(ref safeList, CodeCharts.Upper.IsFlagSet(codeCharts, UpperCodeCharts.HangulJamoExtendedA), CodeCharts.Upper.HangulJamoExtendedA());
PunchHolesIfNeeded(ref safeList, CodeCharts.Upper.IsFlagSet(codeCharts, UpperCodeCharts.Javanese), CodeCharts.Upper.Javanese());
PunchHolesIfNeeded(ref safeList, CodeCharts.Upper.IsFlagSet(codeCharts, UpperCodeCharts.Cham), CodeCharts.Upper.Cham());
PunchHolesIfNeeded(ref safeList, CodeCharts.Upper.IsFlagSet(codeCharts, UpperCodeCharts.MyanmarExtendedA), CodeCharts.Upper.MyanmarExtendedA());
PunchHolesIfNeeded(ref safeList, CodeCharts.Upper.IsFlagSet(codeCharts, UpperCodeCharts.TaiViet), CodeCharts.Upper.TaiViet());
PunchHolesIfNeeded(ref safeList, CodeCharts.Upper.IsFlagSet(codeCharts, UpperCodeCharts.MeeteiMayek), CodeCharts.Upper.MeeteiMayek());
PunchHolesIfNeeded(ref safeList, CodeCharts.Upper.IsFlagSet(codeCharts, UpperCodeCharts.HangulSyllables), CodeCharts.Upper.HangulSyllables());
PunchHolesIfNeeded(ref safeList, CodeCharts.Upper.IsFlagSet(codeCharts, UpperCodeCharts.HangulJamoExtendedB), CodeCharts.Upper.HangulJamoExtendedB());
PunchHolesIfNeeded(ref safeList, CodeCharts.Upper.IsFlagSet(codeCharts, UpperCodeCharts.CjkCompatibilityIdeographs), CodeCharts.Upper.CjkCompatibilityIdeographs());
PunchHolesIfNeeded(ref safeList, CodeCharts.Upper.IsFlagSet(codeCharts, UpperCodeCharts.AlphabeticPresentationForms), CodeCharts.Upper.AlphabeticPresentationForms());
PunchHolesIfNeeded(ref safeList, CodeCharts.Upper.IsFlagSet(codeCharts, UpperCodeCharts.ArabicPresentationFormsA), CodeCharts.Upper.ArabicPresentationFormsA());
PunchHolesIfNeeded(ref safeList, CodeCharts.Upper.IsFlagSet(codeCharts, UpperCodeCharts.VariationSelectors), CodeCharts.Upper.VariationSelectors());
PunchHolesIfNeeded(ref safeList, CodeCharts.Upper.IsFlagSet(codeCharts, UpperCodeCharts.VerticalForms), CodeCharts.Upper.VerticalForms());
PunchHolesIfNeeded(ref safeList, CodeCharts.Upper.IsFlagSet(codeCharts, UpperCodeCharts.CombiningHalfMarks), CodeCharts.Upper.CombiningHalfMarks());
PunchHolesIfNeeded(ref safeList, CodeCharts.Upper.IsFlagSet(codeCharts, UpperCodeCharts.CjkCompatibilityForms), CodeCharts.Upper.CjkCompatibilityForms());
PunchHolesIfNeeded(ref safeList, CodeCharts.Upper.IsFlagSet(codeCharts, UpperCodeCharts.SmallFormVariants), CodeCharts.Upper.SmallFormVariants());
PunchHolesIfNeeded(ref safeList, CodeCharts.Upper.IsFlagSet(codeCharts, UpperCodeCharts.ArabicPresentationFormsB), CodeCharts.Upper.ArabicPresentationFormsB());
PunchHolesIfNeeded(ref safeList, CodeCharts.Upper.IsFlagSet(codeCharts, UpperCodeCharts.HalfWidthAndFullWidthForms), CodeCharts.Upper.HalfWidthAndFullWidthForms());
PunchHolesIfNeeded(ref safeList, CodeCharts.Upper.IsFlagSet(codeCharts, UpperCodeCharts.Specials), CodeCharts.Upper.Specials());
}
///
/// Punches holes as necessary.
///
/// The safe list to punch through.
/// Value indicating whether the holes should be punched.
/// The list of character positions to punch.
private static void PunchHolesIfNeeded(ref char[][] safeList, bool isNeeded, IEnumerable whiteListedCharacters) {
if (!isNeeded) {
return;
}
foreach (int offset in whiteListedCharacters) {
safeList[offset] = null;
}
}
}
}