Merge mozilla-central to autoland

This commit is contained in:
Carsten "Tomcat" Book 2017-04-10 10:40:31 +02:00
Родитель 99c84ca5b6 4c26e8c411
Коммит 722fb789d0
64 изменённых файлов: 74995 добавлений и 70921 удалений

Просмотреть файл

@ -83,6 +83,7 @@ included_inclnames_to_ignore = set([
'unicode/timezone.h', # ICU
'unicode/plurrule.h', # ICU
'unicode/ucal.h', # ICU
'unicode/uchar.h', # ICU
'unicode/uclean.h', # ICU
'unicode/ucol.h', # ICU
'unicode/udat.h', # ICU

Просмотреть файл

@ -24,6 +24,7 @@
#include "jsfriendapi.h"
#include "jsobj.h"
#include "jsstr.h"
#include "jsutil.h"
#include "builtin/IntlTimeZoneData.h"
#include "ds/Sort.h"
@ -45,6 +46,7 @@
#include "vm/Interpreter.h"
#include "vm/SelfHosting.h"
#include "vm/Stack.h"
#include "vm/String.h"
#include "vm/StringBuffer.h"
#include "vm/Unicode.h"
@ -815,6 +817,20 @@ uplrules_select(const UPluralRules *uplrules, double number, UChar *keyword, int
MOZ_CRASH("uplrules_select: Intl API disabled");
}
int32_t
u_strToLower(UChar* dest, int32_t destCapacity, const UChar* src, int32_t srcLength,
const char* locale, UErrorCode* pErrorCode)
{
MOZ_CRASH("u_strToLower: Intl API disabled");
}
int32_t
u_strToUpper(UChar* dest, int32_t destCapacity, const UChar* src, int32_t srcLength,
const char* locale, UErrorCode* pErrorCode)
{
MOZ_CRASH("u_strToUpper: Intl API disabled");
}
} // anonymous namespace
#endif
@ -2503,7 +2519,7 @@ static const JSFunctionSpec dateTimeFormat_static_methods[] = {
static const JSFunctionSpec dateTimeFormat_methods[] = {
JS_SELF_HOSTED_FN("resolvedOptions", "Intl_DateTimeFormat_resolvedOptions", 0, 0),
JS_SELF_HOSTED_FN("formatToParts", "Intl_DateTimeFormat_formatToParts", 0, 0),
JS_SELF_HOSTED_FN("formatToParts", "Intl_DateTimeFormat_formatToParts", 1, 0),
#if JS_HAS_TOSOURCE
JS_FN(js_toSource_str, dateTimeFormat_toSource, 0, 0),
#endif
@ -3887,6 +3903,131 @@ js::intl_GetPluralCategories(JSContext* cx, unsigned argc, Value* vp)
}
/******************** String ********************/
static const char*
CaseMappingLocale(JSLinearString* locale)
{
MOZ_ASSERT(locale->length() >= 2, "locale is a valid language tag");
// Lithuanian, Turkish, and Azeri have language dependent case mappings.
static const char languagesWithSpecialCasing[][3] = { "lt", "tr", "az" };
// All strings in |languagesWithSpecialCasing| are of length two, so we
// only need to compare the first two characters to find a matching locale.
// ES2017 Intl, §9.2.2 BestAvailableLocale
if (locale->length() == 2 || locale->latin1OrTwoByteChar(2) == '-') {
for (const auto& language : languagesWithSpecialCasing) {
if (locale->latin1OrTwoByteChar(0) == language[0] &&
locale->latin1OrTwoByteChar(1) == language[1])
{
return language;
}
}
}
return ""; // ICU root locale
}
static bool
HasLanguageDependentCasing(JSLinearString* locale)
{
return !equal(CaseMappingLocale(locale), "");
}
bool
js::intl_toLocaleLowerCase(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
MOZ_ASSERT(args.length() == 2);
MOZ_ASSERT(args[0].isString());
MOZ_ASSERT(args[1].isString());
RootedLinearString linear(cx, args[0].toString()->ensureLinear(cx));
if (!linear)
return false;
RootedLinearString locale(cx, args[1].toString()->ensureLinear(cx));
if (!locale)
return false;
// Call String.prototype.toLowerCase() for language independent casing.
if (!HasLanguageDependentCasing(locale)) {
JSString* str = js::StringToLowerCase(cx, linear);
if (!str)
return false;
args.rval().setString(str);
return true;
}
AutoStableStringChars inputChars(cx);
if (!inputChars.initTwoByte(cx, linear))
return false;
mozilla::Range<const char16_t> input = inputChars.twoByteRange();
// Maximum case mapping length is three characters.
static_assert(JSString::MAX_LENGTH < INT32_MAX / 3,
"Case conversion doesn't overflow int32_t indices");
JSString* str = Call(cx, [&input, &locale](UChar* chars, int32_t size, UErrorCode* status) {
return u_strToLower(chars, size, Char16ToUChar(input.begin().get()), input.length(),
CaseMappingLocale(locale), status);
});
if (!str)
return false;
args.rval().setString(str);
return true;
}
bool
js::intl_toLocaleUpperCase(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
MOZ_ASSERT(args.length() == 2);
MOZ_ASSERT(args[0].isString());
MOZ_ASSERT(args[1].isString());
RootedLinearString linear(cx, args[0].toString()->ensureLinear(cx));
if (!linear)
return false;
RootedLinearString locale(cx, args[1].toString()->ensureLinear(cx));
if (!locale)
return false;
// Call String.prototype.toUpperCase() for language independent casing.
if (!HasLanguageDependentCasing(locale)) {
JSString* str = js::StringToUpperCase(cx, linear);
if (!str)
return false;
args.rval().setString(str);
return true;
}
AutoStableStringChars inputChars(cx);
if (!inputChars.initTwoByte(cx, linear))
return false;
mozilla::Range<const char16_t> input = inputChars.twoByteRange();
// Maximum case mapping length is three characters.
static_assert(JSString::MAX_LENGTH < INT32_MAX / 3,
"Case conversion doesn't overflow int32_t indices");
JSString* str = Call(cx, [&input, &locale](UChar* chars, int32_t size, UErrorCode* status) {
return u_strToUpper(chars, size, Char16ToUChar(input.begin().get()), input.length(),
CaseMappingLocale(locale), status);
});
if (!str)
return false;
args.rval().setString(str);
return true;
}
/******************** Intl ********************/
bool

Просмотреть файл

@ -667,6 +667,27 @@ intl_GetLocaleInfo(JSContext* cx, unsigned argc, Value* vp);
extern MOZ_MUST_USE bool
intl_ComputeDisplayNames(JSContext* cx, unsigned argc, Value* vp);
/******************** String ********************/
/**
* Returns the input string converted to lower case based on the language
* specific case mappings for the input locale.
*
* Usage: lowerCase = intl_toLocaleLowerCase(string, locale)
*/
extern MOZ_MUST_USE bool
intl_toLocaleLowerCase(JSContext* cx, unsigned argc, Value* vp);
/**
* Returns the input string converted to upper case based on the language
* specific case mappings for the input locale.
*
* Usage: upperCase = intl_toLocaleUpperCase(string, locale)
*/
extern MOZ_MUST_USE bool
intl_toLocaleUpperCase(JSContext* cx, unsigned argc, Value* vp);
#if ENABLE_INTL_API
/**
* Cast char16_t* strings to UChar* strings used by ICU.

Просмотреть файл

@ -472,6 +472,63 @@ function CanonicalizeLanguageTag(locale) {
}
/**
* Returns true if the input contains only ASCII alphabetical characters.
*/
function IsASCIIAlphaString(s) {
assert(typeof s === "string", "IsASCIIAlphaString");
for (var i = 0; i < s.length; i++) {
var c = callFunction(std_String_charCodeAt, s, i);
if (!((0x41 <= c && c <= 0x5A) || (0x61 <= c && c <= 0x7A)))
return false
}
return true;
}
/**
* Validates and canonicalizes the given language tag.
*/
function ValidateAndCanonicalizeLanguageTag(locale) {
assert(typeof locale === "string", "ValidateAndCanonicalizeLanguageTag");
// Handle the common case (a standalone language) first.
// Only the following BCP47 subset is accepted:
// Language-Tag = langtag
// langtag = language
// language = 2*3ALPHA ; shortest ISO 639 code
// For three character long strings we need to make sure it's not a
// private use only language tag, for example "x-x".
if (locale.length === 2 || (locale.length === 3 && locale[1] !== "-")) {
if (!IsASCIIAlphaString(locale))
ThrowRangeError(JSMSG_INVALID_LANGUAGE_TAG, locale);
assert(IsStructurallyValidLanguageTag(locale), "2*3ALPHA is a valid language tag");
// The language subtag is canonicalized to lower case.
locale = callFunction(std_String_toLowerCase, locale);
// langTagMappings doesn't contain any 2*3ALPHA keys, so we don't need
// to check for possible replacements in this map.
assert(!callFunction(std_Object_hasOwnProperty, langTagMappings, locale),
"langTagMappings contains no 2*3ALPHA mappings");
// Replace deprecated subtags with their preferred values.
locale = callFunction(std_Object_hasOwnProperty, langSubtagMappings, locale)
? langSubtagMappings[locale]
: locale;
assert(locale === CanonicalizeLanguageTag(locale), "expected same canonicalization");
return locale;
}
if (!IsStructurallyValidLanguageTag(locale))
ThrowRangeError(JSMSG_INVALID_LANGUAGE_TAG, locale);
return CanonicalizeLanguageTag(locale);
}
function localeContainsNoUnicodeExtensions(locale) {
// No "-u-", no possible Unicode extension.
if (callFunction(std_String_indexOf, locale, "-u-") === -1)
@ -1658,13 +1715,19 @@ function collatorSearchLocaleData(locale) {
* Spec: ECMAScript Internationalization API Specification, 12.3.2.
*/
function collatorCompareToBind(x, y) {
// Steps 1.a.i-ii implemented by ECMAScript declaration binding instantiation,
// ES5.1 10.5, step 4.d.ii.
// Step 1.
var collator = this;
// Step 1.a.iii-v.
// Step 2.
assert(IsObject(collator), "collatorCompareToBind called with non-object");
assert(IsCollator(collator), "collatorCompareToBind called with non-Collator");
// Steps 3-6
var X = ToString(x);
var Y = ToString(y);
return intl_CompareStrings(this, X, Y);
// Step 7.
return intl_CompareStrings(collator, X, Y);
}
@ -1678,23 +1741,26 @@ function collatorCompareToBind(x, y) {
* Spec: ECMAScript Internationalization API Specification, 10.3.2.
*/
function Intl_Collator_compare_get() {
// Check "this Collator object" per introduction of section 10.3.
if (!IsObject(this) || !IsCollator(this))
// Step 1.
var collator = this;
// Steps 2-3.
if (!IsObject(collator) || !IsCollator(collator))
ThrowTypeError(JSMSG_INTL_OBJECT_NOT_INITED, "Collator", "compare", "Collator");
var internals = getCollatorInternals(this);
var internals = getCollatorInternals(collator);
// Step 1.
// Step 4.
if (internals.boundCompare === undefined) {
// Step 1.a.
// Step 4.a.
var F = collatorCompareToBind;
// Steps 1.b-d.
var bc = callFunction(FunctionBind, F, this);
// Steps 4.b-d.
var bc = callFunction(FunctionBind, F, collator);
internals.boundCompare = bc;
}
// Step 2.
// Step 5.
return internals.boundCompare;
}
_SetCanonicalName(Intl_Collator_compare_get, "get compare");
@ -2107,12 +2173,18 @@ function numberFormatLocaleData(locale) {
* Spec: ECMAScript Internationalization API Specification, 11.3.2.
*/
function numberFormatFormatToBind(value) {
// Steps 1.a.i implemented by ECMAScript declaration binding instantiation,
// ES5.1 10.5, step 4.d.ii.
// Step 1.
var nf = this;
// Step 1.a.ii-iii.
// Step 2.
assert(IsObject(nf), "InitializeNumberFormat called with non-object");
assert(IsNumberFormat(nf), "InitializeNumberFormat called with non-NumberFormat");
// Steps 3-4.
var x = ToNumber(value);
return intl_FormatNumber(this, x, /* formatToParts = */ false);
// Step 5.
return intl_FormatNumber(nf, x, /* formatToParts = */ false);
}
@ -2795,13 +2867,19 @@ function dateTimeFormatLocaleData(locale) {
*
* Spec: ECMAScript Internationalization API Specification, 12.3.2.
*/
function dateTimeFormatFormatToBind() {
// Steps 1.a.i-ii
var date = arguments.length > 0 ? arguments[0] : undefined;
function dateTimeFormatFormatToBind(date) {
// Step 1.
var dtf = this;
// Step 2.
assert(IsObject(dtf), "dateTimeFormatFormatToBind called with non-Object");
assert(IsDateTimeFormat(dtf), "dateTimeFormatFormatToBind called with non-DateTimeFormat");
// Steps 3-4.
var x = (date === undefined) ? std_Date_now() : ToNumber(date);
// Step 1.a.iii.
return intl_FormatDateTime(this, x, /* formatToParts = */ false);
// Step 5.
return intl_FormatDateTime(dtf, x, /* formatToParts = */ false);
}
/**
@ -2833,7 +2911,10 @@ function Intl_DateTimeFormat_format_get() {
_SetCanonicalName(Intl_DateTimeFormat_format_get, "get format");
function Intl_DateTimeFormat_formatToParts() {
/**
* Intl.DateTimeFormat.prototype.formatToParts ( date )
*/
function Intl_DateTimeFormat_formatToParts(date) {
// Steps 1-3.
var dtf = UnwrapDateTimeFormat(this, "formatToParts");
@ -2841,7 +2922,6 @@ function Intl_DateTimeFormat_formatToParts() {
getDateTimeFormatInternals(dtf);
// Steps 4-5.
var date = arguments.length > 0 ? arguments[0] : undefined;
var x = (date === undefined) ? std_Date_now() : ToNumber(date);
// Step 6.

Просмотреть файл

@ -601,6 +601,88 @@ function String_localeCompare(that) {
return intl_CompareStrings(collator, S, That);
}
/**
* 13.1.2 String.prototype.toLocaleLowerCase ( [ locales ] )
*
* ES2017 Intl draft rev 94045d234762ad107a3d09bb6f7381a65f1a2f9b
*/
function String_toLocaleLowerCase() {
// Step 1.
RequireObjectCoercible(this);
// Step 2.
var string = ToString(this);
// Handle the common cases (no locales argument or a single string
// argument) first.
var locales = arguments.length > 0 ? arguments[0] : undefined;
var requestedLocale;
if (locales === undefined) {
// Steps 3, 6.
requestedLocale = undefined;
} else if (typeof locales === "string") {
// Steps 3, 5.
requestedLocale = ValidateAndCanonicalizeLanguageTag(locales);
} else {
// Step 3.
var requestedLocales = CanonicalizeLocaleList(locales);
// Steps 4-6.
requestedLocale = requestedLocales.length > 0 ? requestedLocales[0] : undefined;
}
// Trivial case: When the input is empty, directly return the empty string.
if (string.length === 0)
return "";
if (requestedLocale === undefined)
requestedLocale = DefaultLocale();
// Steps 7-16.
return intl_toLocaleLowerCase(string, requestedLocale);
}
/**
* 13.1.3 String.prototype.toLocaleUpperCase ( [ locales ] )
*
* ES2017 Intl draft rev 94045d234762ad107a3d09bb6f7381a65f1a2f9b
*/
function String_toLocaleUpperCase() {
// Step 1.
RequireObjectCoercible(this);
// Step 2.
var string = ToString(this);
// Handle the common cases (no locales argument or a single string
// argument) first.
var locales = arguments.length > 0 ? arguments[0] : undefined;
var requestedLocale;
if (locales === undefined) {
// Steps 3, 6.
requestedLocale = undefined;
} else if (typeof locales === "string") {
// Steps 3, 5.
requestedLocale = ValidateAndCanonicalizeLanguageTag(locales);
} else {
// Step 3.
var requestedLocales = CanonicalizeLocaleList(locales);
// Steps 4-6.
requestedLocale = requestedLocales.length > 0 ? requestedLocales[0] : undefined;
}
// Trivial case: When the input is empty, directly return the empty string.
if (string.length === 0)
return "";
if (requestedLocale === undefined)
requestedLocale = DefaultLocale();
// Steps 7-16.
return intl_toLocaleUpperCase(string, requestedLocale);
}
/* ES6 Draft May 22, 2014 21.1.2.4 */
function String_static_raw(callSite, ...substitutions) {
// Step 1 (implicit).
@ -869,14 +951,28 @@ function String_static_toLocaleLowerCase(string) {
WarnDeprecatedStringMethod(STRING_GENERICS_TO_LOCALE_LOWER_CASE, "toLocaleLowerCase");
if (arguments.length < 1)
ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "String.toLocaleLowerCase");
/* eslint-disable no-unreachable */
#if EXPOSE_INTL_API
var locales = arguments.length > 1 ? arguments[1] : undefined;
return callFunction(String_toLocaleLowerCase, string, locales);
#else
return callFunction(std_String_toLocaleLowerCase, string);
#endif
/* eslint-enable no-unreachable */
}
function String_static_toLocaleUpperCase(string) {
WarnDeprecatedStringMethod(STRING_GENERICS_TO_LOCALE_UPPER_CASE, "toLocaleUpperCase");
if (arguments.length < 1)
ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "String.toLocaleUpperCase");
/* eslint-disable no-unreachable */
#if EXPOSE_INTL_API
var locales = arguments.length > 1 ? arguments[1] : undefined;
return callFunction(String_toLocaleUpperCase, string, locales);
#else
return callFunction(std_String_toLocaleUpperCase, string);
#endif
/* eslint-enable no-unreachable */
}
#if EXPOSE_INTL_API

Просмотреть файл

@ -156,6 +156,10 @@ def readRegistry(registry):
# Special case for heploc.
langTagMappings["ja-latn-hepburn-heploc"] = "ja-Latn-alalc97"
# ValidateAndCanonicalizeLanguageTag in Intl.js expects langTagMappings
# contains no 2*3ALPHA.
assert all(len(lang) > 3 for lang in langTagMappings.iterkeys())
return {"fileDate": fileDate,
"langTagMappings": langTagMappings,
"langSubtagMappings": langSubtagMappings,

Просмотреть файл

@ -2500,7 +2500,7 @@ Parser<FullParseHandler>::standaloneFunction(HandleFunction fun,
if (!tokenStream.getToken(&tt))
return null();
if (generatorKind == StarGenerator && asyncKind == SyncFunction) {
if (generatorKind == StarGenerator) {
MOZ_ASSERT(tt == TOK_MUL);
if (!tokenStream.getToken(&tt))
return null();
@ -7004,6 +7004,7 @@ JSOpFromPropertyType(PropertyType propType)
case PropertyType::Method:
case PropertyType::GeneratorMethod:
case PropertyType::AsyncMethod:
case PropertyType::AsyncGeneratorMethod:
case PropertyType::Constructor:
case PropertyType::DerivedConstructor:
return JSOP_INITPROP;
@ -7121,7 +7122,8 @@ Parser<ParseHandler>::classDefinition(YieldHandling yieldHandling,
if (propType != PropertyType::Getter && propType != PropertyType::Setter &&
propType != PropertyType::Method && propType != PropertyType::GeneratorMethod &&
propType != PropertyType::AsyncMethod)
propType != PropertyType::AsyncMethod &&
propType != PropertyType::AsyncGeneratorMethod)
{
errorAt(nameOffset, JSMSG_BAD_METHOD_DEF);
return null();
@ -9342,6 +9344,9 @@ Parser<ParseHandler>::propertyName(YieldHandling yieldHandling, Node propList,
// AsyncMethod[Yield, Await]:
// async [no LineTerminator here] PropertyName[?Yield, ?Await] ...
//
// AsyncGeneratorMethod[Yield, Await]:
// async [no LineTerminator here] * PropertyName[?Yield, ?Await] ...
//
// PropertyName:
// LiteralPropertyName
// ComputedPropertyName[?Yield, ?Await]
@ -9357,7 +9362,7 @@ Parser<ParseHandler>::propertyName(YieldHandling yieldHandling, Node propList,
if (!tokenStream.peekTokenSameLine(&tt))
return null();
if (tt == TOK_STRING || tt == TOK_NUMBER || tt == TOK_LB ||
TokenKindIsPossibleIdentifierName(tt))
TokenKindIsPossibleIdentifierName(tt) || tt == TOK_MUL)
{
isAsync = true;
tokenStream.consumeKnownToken(tt);
@ -9503,7 +9508,9 @@ Parser<ParseHandler>::propertyName(YieldHandling yieldHandling, Node propList,
if (tt == TOK_LP) {
tokenStream.ungetToken();
if (isGenerator)
if (isGenerator && isAsync)
*propType = PropertyType::AsyncGeneratorMethod;
else if (isGenerator)
*propType = PropertyType::GeneratorMethod;
else if (isAsync)
*propType = PropertyType::AsyncMethod;
@ -9747,6 +9754,7 @@ Parser<ParseHandler>::methodDefinition(uint32_t preludeStart, PropertyType propT
case PropertyType::Method:
case PropertyType::GeneratorMethod:
case PropertyType::AsyncMethod:
case PropertyType::AsyncGeneratorMethod:
kind = Method;
break;
@ -9762,11 +9770,13 @@ Parser<ParseHandler>::methodDefinition(uint32_t preludeStart, PropertyType propT
MOZ_CRASH("unexpected property type");
}
GeneratorKind generatorKind = propType == PropertyType::GeneratorMethod
GeneratorKind generatorKind = (propType == PropertyType::GeneratorMethod ||
propType == PropertyType::AsyncGeneratorMethod)
? StarGenerator
: NotGenerator;
FunctionAsyncKind asyncKind = (propType == PropertyType::AsyncMethod)
FunctionAsyncKind asyncKind = (propType == PropertyType::AsyncMethod ||
propType == PropertyType::AsyncGeneratorMethod)
? AsyncFunction
: SyncFunction;

Просмотреть файл

@ -578,6 +578,7 @@ enum class PropertyType {
Method,
GeneratorMethod,
AsyncMethod,
AsyncGeneratorMethod,
Constructor,
DerivedConstructor
};

Просмотреть файл

@ -5309,8 +5309,8 @@ JS_ResetDefaultLocale(JSContext* cx);
* Locale specific string conversion and error message callbacks.
*/
struct JSLocaleCallbacks {
JSLocaleToUpperCase localeToUpperCase;
JSLocaleToLowerCase localeToLowerCase;
JSLocaleToUpperCase localeToUpperCase; // not used #if EXPOSE_INTL_API
JSLocaleToLowerCase localeToLowerCase; // not used #if EXPOSE_INTL_API
JSLocaleCompare localeCompare; // not used #if EXPOSE_INTL_API
JSLocaleToUnicode localeToUnicode;
};

Просмотреть файл

@ -1677,7 +1677,7 @@ FunctionConstructor(JSContext* cx, const CallArgs& args, GeneratorKind generator
}
if (!sb.append("function"))
return false;
if (isStarGenerator && !isAsync) {
if (isStarGenerator) {
if (!sb.append('*'))
return false;
}
@ -1762,9 +1762,12 @@ FunctionConstructor(JSContext* cx, const CallArgs& args, GeneratorKind generator
// Step 25-32 (reordered).
RootedObject globalLexical(cx, &global->lexicalEnvironment());
JSFunction::Flags flags = (isStarGenerator || isAsync)
? JSFunction::INTERPRETED_LAMBDA_GENERATOR_OR_ASYNC
: JSFunction::INTERPRETED_LAMBDA;
AllocKind allocKind = isAsync ? AllocKind::FUNCTION_EXTENDED : AllocKind::FUNCTION;
RootedFunction fun(cx, NewFunctionWithProto(cx, nullptr, 0,
JSFunction::INTERPRETED_LAMBDA, globalLexical,
flags, globalLexical,
anonymousAtom, proto,
allocKind, TenuredObject));
if (!fun)

Просмотреть файл

@ -37,6 +37,7 @@
#include "js/Conversions.h"
#include "js/UniquePtr.h"
#if ENABLE_INTL_API
#include "unicode/uchar.h"
#include "unicode/unorm2.h"
#endif
#include "vm/GlobalObject.h"
@ -602,19 +603,212 @@ js::SubstringKernel(JSContext* cx, HandleString str, int32_t beginInt, int32_t l
return NewDependentString(cx, str, begin, len);
}
template <typename CharT>
static auto
ReallocChars(JSContext* cx, UniquePtr<CharT[], JS::FreePolicy> chars, size_t oldLength,
size_t newLength)
-> decltype(chars)
{
using AnyCharPtr = decltype(chars);
CharT* oldChars = chars.release();
CharT* newChars = cx->pod_realloc(oldChars, oldLength, newLength);
if (!newChars) {
js_free(oldChars);
return AnyCharPtr();
}
return AnyCharPtr(newChars);
}
/**
* U+03A3 GREEK CAPITAL LETTER SIGMA has two different lower case mappings
* depending on its context:
* When it's preceded by a cased character and not followed by another cased
* character, its lower case form is U+03C2 GREEK SMALL LETTER FINAL SIGMA.
* Otherwise its lower case mapping is U+03C3 GREEK SMALL LETTER SIGMA.
*
* Unicode 9.0, §3.13 Default Case Algorithms
*/
static char16_t
Final_Sigma(const char16_t* chars, size_t length, size_t index)
{
MOZ_ASSERT(index < length);
MOZ_ASSERT(chars[index] == unicode::GREEK_CAPITAL_LETTER_SIGMA);
MOZ_ASSERT(unicode::ToLowerCase(unicode::GREEK_CAPITAL_LETTER_SIGMA) ==
unicode::GREEK_SMALL_LETTER_SIGMA);
#if ENABLE_INTL_API
// Tell the analysis the BinaryProperty.contains function pointer called by
// u_hasBinaryProperty cannot GC.
JS::AutoSuppressGCAnalysis nogc;
bool precededByCased = false;
for (size_t i = index; i > 0; ) {
char16_t c = chars[--i];
uint32_t codePoint = c;
if (unicode::IsTrailSurrogate(c) && i > 0) {
char16_t lead = chars[i - 1];
if (unicode::IsLeadSurrogate(lead)) {
codePoint = unicode::UTF16Decode(lead, c);
i--;
}
}
// Ignore any characters with the property Case_Ignorable.
// NB: We need to skip over all Case_Ignorable characters, even when
// they also have the Cased binary property.
if (u_hasBinaryProperty(codePoint, UCHAR_CASE_IGNORABLE))
continue;
precededByCased = u_hasBinaryProperty(codePoint, UCHAR_CASED);
break;
}
if (!precededByCased)
return unicode::GREEK_SMALL_LETTER_SIGMA;
bool followedByCased = false;
for (size_t i = index + 1; i < length; ) {
char16_t c = chars[i++];
uint32_t codePoint = c;
if (unicode::IsLeadSurrogate(c) && i < length) {
char16_t trail = chars[i];
if (unicode::IsTrailSurrogate(trail)) {
codePoint = unicode::UTF16Decode(c, trail);
i++;
}
}
// Ignore any characters with the property Case_Ignorable.
// NB: We need to skip over all Case_Ignorable characters, even when
// they also have the Cased binary property.
if (u_hasBinaryProperty(codePoint, UCHAR_CASE_IGNORABLE))
continue;
followedByCased = u_hasBinaryProperty(codePoint, UCHAR_CASED);
break;
}
if (!followedByCased)
return unicode::GREEK_SMALL_LETTER_FINAL_SIGMA;
#endif
return unicode::GREEK_SMALL_LETTER_SIGMA;
}
static Latin1Char
Final_Sigma(const Latin1Char* chars, size_t length, size_t index)
{
MOZ_ASSERT_UNREACHABLE("U+03A3 is not a Latin-1 character");
return 0;
}
// If |srcLength == destLength| is true, the destination buffer was allocated
// with the same size as the source buffer. When we append characters which
// have special casing mappings, we test |srcLength == destLength| to decide
// if we need to back out and reallocate a sufficiently large destination
// buffer. Otherwise the destination buffer was allocated with the correct
// size to hold all lower case mapped characters, i.e.
// |destLength == ToLowerCaseLength(srcChars, 0, srcLength)| is true.
template <typename CharT>
static size_t
ToLowerCaseImpl(CharT* destChars, const CharT* srcChars, size_t startIndex, size_t srcLength,
size_t destLength)
{
MOZ_ASSERT(startIndex < srcLength);
MOZ_ASSERT(srcLength <= destLength);
MOZ_ASSERT_IF((IsSame<CharT, Latin1Char>::value), srcLength == destLength);
size_t j = startIndex;
for (size_t i = startIndex; i < srcLength; i++) {
char16_t c = srcChars[i];
if (!IsSame<CharT, Latin1Char>::value) {
if (unicode::IsLeadSurrogate(c) && i + 1 < srcLength) {
char16_t trail = srcChars[i + 1];
if (unicode::IsTrailSurrogate(trail)) {
trail = unicode::ToLowerCaseNonBMPTrail(c, trail);
destChars[j++] = c;
destChars[j++] = trail;
i++;
continue;
}
}
// Special case: U+0130 LATIN CAPITAL LETTER I WITH DOT ABOVE
// lowercases to <U+0069 U+0307>.
if (c == unicode::LATIN_CAPITAL_LETTER_I_WITH_DOT_ABOVE) {
// Return if the output buffer is too small.
if (srcLength == destLength)
return i;
destChars[j++] = CharT('i');
destChars[j++] = CharT(unicode::COMBINING_DOT_ABOVE);
continue;
}
// Special case: U+03A3 GREEK CAPITAL LETTER SIGMA lowercases to
// one of two codepoints depending on context.
if (c == unicode::GREEK_CAPITAL_LETTER_SIGMA) {
destChars[j++] = Final_Sigma(srcChars, srcLength, i);
continue;
}
}
c = unicode::ToLowerCase(c);
MOZ_ASSERT_IF((IsSame<CharT, Latin1Char>::value), c <= JSString::MAX_LATIN1_CHAR);
destChars[j++] = c;
}
MOZ_ASSERT(j == destLength);
destChars[destLength] = '\0';
return srcLength;
}
static size_t
ToLowerCaseLength(const char16_t* chars, size_t startIndex, size_t length)
{
size_t lowerLength = length;
for (size_t i = startIndex; i < length; i++) {
char16_t c = chars[i];
// U+0130 is lowercased to the two-element sequence <U+0069 U+0307>.
if (c == unicode::LATIN_CAPITAL_LETTER_I_WITH_DOT_ABOVE)
lowerLength += 1;
}
return lowerLength;
}
static size_t
ToLowerCaseLength(const Latin1Char* chars, size_t startIndex, size_t length)
{
MOZ_ASSERT_UNREACHABLE("never called for Latin-1 strings");
return 0;
}
template <typename CharT>
static JSString*
ToLowerCase(JSContext* cx, JSLinearString* str)
{
// Unlike toUpperCase, toLowerCase has the nice invariant that if the input
// is a Latin1 string, the output is also a Latin1 string.
UniquePtr<CharT[], JS::FreePolicy> newChars;
size_t length = str->length();
// Unlike toUpperCase, toLowerCase has the nice invariant that if the
// input is a Latin-1 string, the output is also a Latin-1 string.
using AnyCharPtr = UniquePtr<CharT[], JS::FreePolicy>;
AnyCharPtr newChars;
const size_t length = str->length();
size_t resultLength;
{
AutoCheckCannotGC nogc;
const CharT* chars = str->chars<CharT>(nogc);
// Look for the first upper case character.
// We don't need extra special casing checks in the loop below,
// because U+0130 LATIN CAPITAL LETTER I WITH DOT ABOVE and U+03A3
// GREEK CAPITAL LETTER SIGMA already have simple lower case mappings.
MOZ_ASSERT(unicode::CanLowerCase(unicode::LATIN_CAPITAL_LETTER_I_WITH_DOT_ABOVE),
"U+0130 has a simple lower case mapping");
MOZ_ASSERT(unicode::CanLowerCase(unicode::GREEK_CAPITAL_LETTER_SIGMA),
"U+03A3 has a simple lower case mapping");
// Look for the first character that changes when lowercased.
size_t i = 0;
for (; i < length; i++) {
char16_t c = chars[i];
@ -634,40 +828,35 @@ ToLowerCase(JSContext* cx, JSLinearString* str)
break;
}
// If all characters are lower case, return the input string.
// If no character needs to change, return the input string.
if (i == length)
return str;
newChars = cx->make_pod_array<CharT>(length + 1);
resultLength = length;
newChars = cx->make_pod_array<CharT>(resultLength + 1);
if (!newChars)
return nullptr;
PodCopy(newChars.get(), chars, i);
for (; i < length; i++) {
char16_t c = chars[i];
if (!IsSame<CharT, Latin1Char>::value) {
if (unicode::IsLeadSurrogate(c) && i + 1 < length) {
char16_t trail = chars[i + 1];
if (unicode::IsTrailSurrogate(trail)) {
trail = unicode::ToLowerCaseNonBMPTrail(c, trail);
newChars[i] = c;
newChars[i + 1] = trail;
i++;
continue;
}
}
}
size_t readChars = ToLowerCaseImpl(newChars.get(), chars, i, length, resultLength);
if (readChars < length) {
MOZ_ASSERT((!IsSame<CharT, Latin1Char>::value),
"Latin-1 strings don't have special lower case mappings");
resultLength = ToLowerCaseLength(chars, readChars, length);
c = unicode::ToLowerCase(c);
MOZ_ASSERT_IF((IsSame<CharT, Latin1Char>::value), c <= JSString::MAX_LATIN1_CHAR);
newChars[i] = c;
AnyCharPtr buf = ReallocChars(cx, Move(newChars), length + 1, resultLength + 1);
if (!buf)
return nullptr;
newChars = Move(buf);
MOZ_ALWAYS_TRUE(length ==
ToLowerCaseImpl(newChars.get(), chars, readChars, length, resultLength));
}
newChars[length] = 0;
}
JSString* res = NewStringDontDeflate<CanGC>(cx, newChars.get(), length);
JSString* res = NewStringDontDeflate<CanGC>(cx, newChars.get(), resultLength);
if (!res)
return nullptr;
@ -675,48 +864,50 @@ ToLowerCase(JSContext* cx, JSLinearString* str)
return res;
}
static inline bool
ToLowerCaseHelper(JSContext* cx, const CallArgs& args)
JSString*
js::StringToLowerCase(JSContext* cx, HandleLinearString string)
{
RootedString str(cx, ToStringForStringFunction(cx, args.thisv()));
if (!str)
return false;
JSLinearString* linear = str->ensureLinear(cx);
if (!linear)
return false;
if (linear->hasLatin1Chars())
str = ToLowerCase<Latin1Char>(cx, linear);
else
str = ToLowerCase<char16_t>(cx, linear);
if (!str)
return false;
args.rval().setString(str);
return true;
if (string->hasLatin1Chars())
return ToLowerCase<Latin1Char>(cx, string);
return ToLowerCase<char16_t>(cx, string);
}
bool
js::str_toLowerCase(JSContext* cx, unsigned argc, Value* vp)
{
return ToLowerCaseHelper(cx, CallArgsFromVp(argc, vp));
CallArgs args = CallArgsFromVp(argc, vp);
RootedString str(cx, ToStringForStringFunction(cx, args.thisv()));
if (!str)
return false;
RootedLinearString linear(cx, str->ensureLinear(cx));
if (!linear)
return false;
JSString* result = StringToLowerCase(cx, linear);
if (!result)
return false;
args.rval().setString(result);
return true;
}
#if !EXPOSE_INTL_API
bool
js::str_toLocaleLowerCase(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
RootedString str(cx, ToStringForStringFunction(cx, args.thisv()));
if (!str)
return false;
/*
* Forcefully ignore the first (or any) argument and return toLowerCase(),
* ECMA has reserved that argument, presumably for defining the locale.
*/
if (cx->runtime()->localeCallbacks && cx->runtime()->localeCallbacks->localeToLowerCase) {
RootedString str(cx, ToStringForStringFunction(cx, args.thisv()));
if (!str)
return false;
RootedValue result(cx);
if (!cx->runtime()->localeCallbacks->localeToLowerCase(cx, str, &result))
return false;
@ -725,54 +916,205 @@ js::str_toLocaleLowerCase(JSContext* cx, unsigned argc, Value* vp)
return true;
}
return ToLowerCaseHelper(cx, args);
RootedLinearString linear(cx, str->ensureLinear(cx));
if (!linear)
return false;
JSString* result = StringToLowerCase(cx, linear);
if (!result)
return false;
args.rval().setString(result);
return true;
}
#endif /* !EXPOSE_INTL_API */
static inline bool
CanUpperCaseSpecialCasing(Latin1Char charCode)
{
// Handle U+00DF LATIN SMALL LETTER SHARP S inline, all other Latin-1
// characters don't have special casing rules.
MOZ_ASSERT_IF(charCode != unicode::LATIN_SMALL_LETTER_SHARP_S,
!unicode::CanUpperCaseSpecialCasing(charCode));
return charCode == unicode::LATIN_SMALL_LETTER_SHARP_S;
}
template <typename DestChar, typename SrcChar>
static void
ToUpperCaseImpl(DestChar* destChars, const SrcChar* srcChars, size_t firstLowerCase, size_t length)
static inline bool
CanUpperCaseSpecialCasing(char16_t charCode)
{
MOZ_ASSERT(firstLowerCase < length);
return unicode::CanUpperCaseSpecialCasing(charCode);
}
for (size_t i = 0; i < firstLowerCase; i++)
destChars[i] = srcChars[i];
static inline size_t
LengthUpperCaseSpecialCasing(Latin1Char charCode)
{
// U+00DF LATIN SMALL LETTER SHARP S is uppercased to two 'S'.
MOZ_ASSERT(charCode == unicode::LATIN_SMALL_LETTER_SHARP_S);
for (size_t i = firstLowerCase; i < length; i++) {
return 2;
}
static inline size_t
LengthUpperCaseSpecialCasing(char16_t charCode)
{
MOZ_ASSERT(CanUpperCaseSpecialCasing(charCode));
return unicode::LengthUpperCaseSpecialCasing(charCode);
}
static inline void
AppendUpperCaseSpecialCasing(char16_t charCode, Latin1Char* elements, size_t* index)
{
// U+00DF LATIN SMALL LETTER SHARP S is uppercased to two 'S'.
MOZ_ASSERT(charCode == unicode::LATIN_SMALL_LETTER_SHARP_S);
static_assert('S' <= JSString::MAX_LATIN1_CHAR, "'S' is a Latin-1 character");
elements[(*index)++] = 'S';
elements[(*index)++] = 'S';
}
static inline void
AppendUpperCaseSpecialCasing(char16_t charCode, char16_t* elements, size_t* index)
{
unicode::AppendUpperCaseSpecialCasing(charCode, elements, index);
}
// See ToLowerCaseImpl for an explanation of the parameters.
template <typename DestChar, typename SrcChar>
static size_t
ToUpperCaseImpl(DestChar* destChars, const SrcChar* srcChars, size_t startIndex, size_t srcLength,
size_t destLength)
{
static_assert(IsSame<SrcChar, Latin1Char>::value || !IsSame<DestChar, Latin1Char>::value,
"cannot write non-Latin-1 characters into Latin-1 string");
MOZ_ASSERT(startIndex < srcLength);
MOZ_ASSERT(srcLength <= destLength);
size_t j = startIndex;
for (size_t i = startIndex; i < srcLength; i++) {
char16_t c = srcChars[i];
if (!IsSame<DestChar, Latin1Char>::value) {
if (unicode::IsLeadSurrogate(c) && i + 1 < length) {
if (unicode::IsLeadSurrogate(c) && i + 1 < srcLength) {
char16_t trail = srcChars[i + 1];
if (unicode::IsTrailSurrogate(trail)) {
trail = unicode::ToUpperCaseNonBMPTrail(c, trail);
destChars[i] = c;
destChars[i + 1] = trail;
destChars[j++] = c;
destChars[j++] = trail;
i++;
continue;
}
}
}
if (MOZ_UNLIKELY(c > 0x7f && CanUpperCaseSpecialCasing(static_cast<SrcChar>(c)))) {
// Return if the output buffer is too small.
if (srcLength == destLength)
return i;
AppendUpperCaseSpecialCasing(c, destChars, &j);
continue;
}
c = unicode::ToUpperCase(c);
MOZ_ASSERT_IF((IsSame<DestChar, Latin1Char>::value), c <= JSString::MAX_LATIN1_CHAR);
destChars[i] = c;
destChars[j++] = c;
}
destChars[length] = '\0';
MOZ_ASSERT(j == destLength);
destChars[destLength] = '\0';
return srcLength;
}
// Explicit instantiation so we don't hit the static_assert from above.
static bool
ToUpperCaseImpl(Latin1Char* destChars, const char16_t* srcChars, size_t startIndex,
size_t srcLength, size_t destLength)
{
MOZ_ASSERT_UNREACHABLE("cannot write non-Latin-1 characters into Latin-1 string");
return false;
}
template <typename CharT>
static size_t
ToUpperCaseLength(const CharT* chars, size_t startIndex, size_t length)
{
size_t upperLength = length;
for (size_t i = startIndex; i < length; i++) {
char16_t c = chars[i];
if (c > 0x7f && CanUpperCaseSpecialCasing(static_cast<CharT>(c)))
upperLength += LengthUpperCaseSpecialCasing(static_cast<CharT>(c)) - 1;
}
return upperLength;
}
template <typename DestChar, typename SrcChar>
static inline void
CopyChars(DestChar* destChars, const SrcChar* srcChars, size_t length)
{
static_assert(!IsSame<DestChar, SrcChar>::value, "PodCopy is used for the same type case");
for (size_t i = 0; i < length; i++)
destChars[i] = srcChars[i];
}
template <typename CharT>
static inline void
CopyChars(CharT* destChars, const CharT* srcChars, size_t length)
{
PodCopy(destChars, srcChars, length);
}
template <typename DestChar, typename SrcChar>
static inline UniquePtr<DestChar[], JS::FreePolicy>
ToUpperCase(JSContext* cx, const SrcChar* chars, size_t startIndex, size_t length,
size_t* resultLength)
{
MOZ_ASSERT(startIndex < length);
using DestCharPtr = UniquePtr<DestChar[], JS::FreePolicy>;
*resultLength = length;
DestCharPtr buf = cx->make_pod_array<DestChar>(length + 1);
if (!buf)
return buf;
CopyChars(buf.get(), chars, startIndex);
size_t readChars = ToUpperCaseImpl(buf.get(), chars, startIndex, length, length);
if (readChars < length) {
size_t actualLength = ToUpperCaseLength(chars, readChars, length);
*resultLength = actualLength;
DestCharPtr buf2 = ReallocChars(cx, Move(buf), length + 1, actualLength + 1);
if (!buf2)
return buf2;
buf = Move(buf2);
MOZ_ALWAYS_TRUE(length ==
ToUpperCaseImpl(buf.get(), chars, readChars, length, actualLength));
}
return buf;
}
template <typename CharT>
static JSString*
ToUpperCase(JSContext* cx, JSLinearString* str)
{
typedef UniquePtr<Latin1Char[], JS::FreePolicy> Latin1CharPtr;
typedef UniquePtr<char16_t[], JS::FreePolicy> TwoByteCharPtr;
using Latin1CharPtr = UniquePtr<Latin1Char[], JS::FreePolicy>;
using TwoByteCharPtr = UniquePtr<char16_t[], JS::FreePolicy>;
mozilla::MaybeOneOf<Latin1CharPtr, TwoByteCharPtr> newChars;
size_t length = str->length();
const size_t length = str->length();
size_t resultLength;
{
AutoCheckCannotGC nogc;
const CharT* chars = str->chars<CharT>(nogc);
// Look for the first lower case character.
// Look for the first character that changes when uppercased.
size_t i = 0;
for (; i < length; i++) {
char16_t c = chars[i];
@ -790,21 +1132,33 @@ ToUpperCase(JSContext* cx, JSLinearString* str)
}
if (unicode::CanUpperCase(c))
break;
if (MOZ_UNLIKELY(c > 0x7f && CanUpperCaseSpecialCasing(static_cast<CharT>(c))))
break;
}
// If all characters are upper case, return the input string.
// If no character needs to change, return the input string.
if (i == length)
return str;
// If the string is Latin1, check if it contains the MICRO SIGN (0xb5)
// or SMALL LETTER Y WITH DIAERESIS (0xff) character. The corresponding
// upper case characters are not in the Latin1 range.
// The string changes when uppercased, so we must create a new string.
// Can it be Latin-1?
//
// If the original string is Latin-1, it can -- unless the string
// contains U+00B5 MICRO SIGN or U+00FF SMALL LETTER Y WITH DIAERESIS,
// the only Latin-1 codepoints that don't uppercase within Latin-1.
// Search for those codepoints to decide whether the new string can be
// Latin-1.
// If the original string is a two-byte string, its uppercase form is
// so rarely Latin-1 that we don't even consider creating a new
// Latin-1 string.
bool resultIsLatin1;
if (IsSame<CharT, Latin1Char>::value) {
resultIsLatin1 = true;
for (size_t j = i; j < length; j++) {
Latin1Char c = chars[j];
if (c == 0xb5 || c == 0xff) {
if (c == unicode::MICRO_SIGN ||
c == unicode::LATIN_SMALL_LETTER_Y_WITH_DIAERESIS)
{
MOZ_ASSERT(unicode::ToUpperCase(c) > JSString::MAX_LATIN1_CHAR);
resultIsLatin1 = false;
break;
@ -817,31 +1171,29 @@ ToUpperCase(JSContext* cx, JSLinearString* str)
}
if (resultIsLatin1) {
Latin1CharPtr buf = cx->make_pod_array<Latin1Char>(length + 1);
Latin1CharPtr buf = ToUpperCase<Latin1Char>(cx, chars, i, length, &resultLength);
if (!buf)
return nullptr;
ToUpperCaseImpl(buf.get(), chars, i, length);
newChars.construct<Latin1CharPtr>(Move(buf));
} else {
TwoByteCharPtr buf = cx->make_pod_array<char16_t>(length + 1);
TwoByteCharPtr buf = ToUpperCase<char16_t>(cx, chars, i, length, &resultLength);
if (!buf)
return nullptr;
ToUpperCaseImpl(buf.get(), chars, i, length);
newChars.construct<TwoByteCharPtr>(Move(buf));
}
}
JSString* res;
if (newChars.constructed<Latin1CharPtr>()) {
res = NewStringDontDeflate<CanGC>(cx, newChars.ref<Latin1CharPtr>().get(), length);
res = NewStringDontDeflate<CanGC>(cx, newChars.ref<Latin1CharPtr>().get(), resultLength);
if (!res)
return nullptr;
mozilla::Unused << newChars.ref<Latin1CharPtr>().release();
} else {
res = NewStringDontDeflate<CanGC>(cx, newChars.ref<TwoByteCharPtr>().get(), length);
res = NewStringDontDeflate<CanGC>(cx, newChars.ref<TwoByteCharPtr>().get(), resultLength);
if (!res)
return nullptr;
@ -851,48 +1203,50 @@ ToUpperCase(JSContext* cx, JSLinearString* str)
return res;
}
static bool
ToUpperCaseHelper(JSContext* cx, const CallArgs& args)
JSString*
js::StringToUpperCase(JSContext* cx, HandleLinearString string)
{
RootedString str(cx, ToStringForStringFunction(cx, args.thisv()));
if (!str)
return false;
JSLinearString* linear = str->ensureLinear(cx);
if (!linear)
return false;
if (linear->hasLatin1Chars())
str = ToUpperCase<Latin1Char>(cx, linear);
else
str = ToUpperCase<char16_t>(cx, linear);
if (!str)
return false;
args.rval().setString(str);
return true;
if (string->hasLatin1Chars())
return ToUpperCase<Latin1Char>(cx, string);
return ToUpperCase<char16_t>(cx, string);
}
bool
js::str_toUpperCase(JSContext* cx, unsigned argc, Value* vp)
{
return ToUpperCaseHelper(cx, CallArgsFromVp(argc, vp));
CallArgs args = CallArgsFromVp(argc, vp);
RootedString str(cx, ToStringForStringFunction(cx, args.thisv()));
if (!str)
return false;
RootedLinearString linear(cx, str->ensureLinear(cx));
if (!linear)
return false;
JSString* result = StringToUpperCase(cx, linear);
if (!result)
return false;
args.rval().setString(result);
return true;
}
#if !EXPOSE_INTL_API
bool
js::str_toLocaleUpperCase(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
RootedString str(cx, ToStringForStringFunction(cx, args.thisv()));
if (!str)
return false;
/*
* Forcefully ignore the first (or any) argument and return toUpperCase(),
* ECMA has reserved that argument, presumably for defining the locale.
*/
if (cx->runtime()->localeCallbacks && cx->runtime()->localeCallbacks->localeToUpperCase) {
RootedString str(cx, ToStringForStringFunction(cx, args.thisv()));
if (!str)
return false;
RootedValue result(cx);
if (!cx->runtime()->localeCallbacks->localeToUpperCase(cx, str, &result))
return false;
@ -901,8 +1255,18 @@ js::str_toLocaleUpperCase(JSContext* cx, unsigned argc, Value* vp)
return true;
}
return ToUpperCaseHelper(cx, args);
RootedLinearString linear(cx, str->ensureLinear(cx));
if (!linear)
return false;
JSString* result = StringToUpperCase(cx, linear);
if (!result)
return false;
args.rval().setString(result);
return true;
}
#endif /* !EXPOSE_INTL_API */
#if !EXPOSE_INTL_API
bool
@ -981,7 +1345,7 @@ js::str_normalize(JSContext* cx, unsigned argc, Value* vp)
if (!linear)
return false;
// Latin1 strings are already in Normalization Form C.
// Latin-1 strings are already in Normalization Form C.
if (form == NFC && linear->hasLatin1Chars()) {
// Step 7.
args.rval().setString(str);
@ -1397,7 +1761,7 @@ StringMatch(const TextChar* text, uint32_t textLen, const PatChar* pat, uint32_t
/*
* For big patterns with large potential overlap we want the SIMD-optimized
* speed of memcmp. For small patterns, a simple loop is faster. We also can't
* use memcmp if one of the strings is TwoByte and the other is Latin1.
* use memcmp if one of the strings is TwoByte and the other is Latin-1.
*
* FIXME: Linux memcmp performance is sad and the manual loop is faster.
*/
@ -1594,7 +1958,7 @@ RopeMatch(JSContext* cx, JSRope* text, JSLinearString* pat, int* match)
* need to build the list of leaf nodes. Do both here: iterate over the
* nodes so long as there are not too many.
*
* We also don't use rope matching if the rope contains both Latin1 and
* We also don't use rope matching if the rope contains both Latin-1 and
* TwoByte nodes, to simplify the match algorithm.
*/
{
@ -2665,11 +3029,13 @@ static const JSFunctionSpec string_methods[] = {
JS_FN("trim", str_trim, 0,0),
JS_FN("trimLeft", str_trimLeft, 0,0),
JS_FN("trimRight", str_trimRight, 0,0),
JS_FN("toLocaleLowerCase", str_toLocaleLowerCase, 0,0),
JS_FN("toLocaleUpperCase", str_toLocaleUpperCase, 0,0),
#if EXPOSE_INTL_API
JS_SELF_HOSTED_FN("toLocaleLowerCase", "String_toLocaleLowerCase", 0,0),
JS_SELF_HOSTED_FN("toLocaleUpperCase", "String_toLocaleUpperCase", 0,0),
JS_SELF_HOSTED_FN("localeCompare", "String_localeCompare", 1,0),
#else
JS_FN("toLocaleLowerCase", str_toLocaleLowerCase, 0,0),
JS_FN("toLocaleUpperCase", str_toLocaleUpperCase, 0,0),
JS_FN("localeCompare", str_localeCompare, 1,0),
#endif
JS_SELF_HOSTED_FN("repeat", "String_repeat", 1,0),
@ -2776,7 +3142,7 @@ js::str_fromCharCode(JSContext* cx, unsigned argc, Value* vp)
// string (thin or fat) and so we don't need to malloc the chars. (We could
// cover some cases where args.length() goes up to
// JSFatInlineString::MAX_LENGTH_LATIN1 if we also checked if the chars are
// all Latin1, but it doesn't seem worth the effort.)
// all Latin-1, but it doesn't seem worth the effort.)
if (args.length() <= JSFatInlineString::MAX_LENGTH_TWO_BYTE)
return str_fromCharCode_few_args(cx, args);
@ -2919,7 +3285,7 @@ js::str_fromCodePoint(JSContext* cx, unsigned argc, Value* vp)
// string (thin or fat) and so we don't need to malloc the chars. (We could
// cover some cases where |args.length()| goes up to
// JSFatInlineString::MAX_LENGTH_LATIN1 / 2 if we also checked if the chars
// are all Latin1, but it doesn't seem worth the effort.)
// are all Latin-1, but it doesn't seem worth the effort.)
if (args.length() <= JSFatInlineString::MAX_LENGTH_TWO_BYTE / 2)
return str_fromCodePoint_few_args(cx, args);

Просмотреть файл

@ -371,13 +371,13 @@ str_trimLeft(JSContext* cx, unsigned argc, Value* vp);
extern bool
str_trimRight(JSContext* cx, unsigned argc, Value* vp);
#if !EXPOSE_INTL_API
extern bool
str_toLocaleLowerCase(JSContext* cx, unsigned argc, Value* vp);
extern bool
str_toLocaleUpperCase(JSContext* cx, unsigned argc, Value* vp);
#if !EXPOSE_INTL_API
extern bool
str_localeCompare(JSContext* cx, unsigned argc, Value* vp);
#else
@ -481,6 +481,12 @@ JSString*
str_replace_string_raw(JSContext* cx, HandleString string, HandleString pattern,
HandleString replacement);
extern JSString*
StringToLowerCase(JSContext* cx, HandleLinearString string);
extern JSString*
StringToUpperCase(JSContext* cx, HandleLinearString string);
extern bool
StringConstructor(JSContext* cx, unsigned argc, Value* vp);

Просмотреть файл

Просмотреть файл

@ -0,0 +1,69 @@
// |reftest| skip-if(!this.hasOwnProperty("Intl"))
// Test language dependent special casing with different language tags.
for (let locale of ["tr", "TR", "tr-TR", "tr-u-co-search", "tr-x-turkish"]) {
assertEq("\u0130".toLocaleLowerCase(locale), "i");
assertEq("\u0130".toLocaleLowerCase([locale]), "i");
// Additional language tags are ignored.
assertEq("\u0130".toLocaleLowerCase([locale, "und"]), "i");
assertEq("\u0130".toLocaleLowerCase(["und", locale]), "\u0069\u0307");
}
// Ensure "trl" (Traveller Scottish) isn't misrecognized as "tr", even though
// both share the same prefix.
assertEq("\u0130".toLocaleLowerCase("trl"), "\u0069\u0307");
assertEq("\u0130".toLocaleLowerCase(["trl"]), "\u0069\u0307");
// Language tag is always verified.
for (let locale of ["no_locale", "tr-invalid_ext", ["no_locale"], ["en", "no_locale"]]) {
// Empty input string.
assertThrowsInstanceOf(() => "".toLocaleLowerCase(locale), RangeError);
// Non-empty input string.
assertThrowsInstanceOf(() => "x".toLocaleLowerCase(locale), RangeError);
}
// The language tag fast-path for String.prototype.toLocaleLowerCase doesn't
// trip up on three element private-use only language tags.
assertEq("A".toLocaleLowerCase("x-x"), "a");
assertEq("A".toLocaleLowerCase("x-0"), "a");
// No locale argument, undefined as locale, and empty array or array-like all
// return the same result. Testing with "a/A" because it has only simple case
// mappings.
assertEq("A".toLocaleLowerCase(), "a");
assertEq("A".toLocaleLowerCase(undefined), "a");
assertEq("A".toLocaleLowerCase([]), "a");
assertEq("A".toLocaleLowerCase({}), "a");
assertEq("A".toLocaleLowerCase({length: 0}), "a");
assertEq("A".toLocaleLowerCase({length: -1}), "a");
// Test with incorrect locale type.
for (let locale of [null, 0, Math.PI, NaN, Infinity, true, false, Symbol()]) {
// Empty input string.
assertThrowsInstanceOf(() => "".toLocaleLowerCase([locale]), TypeError);
// Non-empty input string.
assertThrowsInstanceOf(() => "A".toLocaleLowerCase([locale]), TypeError);
}
// Primitives are converted with ToObject and then queried for .length property.
for (let locale of [null]) {
// Empty input string.
assertThrowsInstanceOf(() => "".toLocaleLowerCase([locale]), TypeError);
// Non-empty input string.
assertThrowsInstanceOf(() => "A".toLocaleLowerCase([locale]), TypeError);
}
// ToLength(ToObject(<primitive>)) returns 0.
for (let locale of [0, Math.PI, NaN, Infinity, true, false, Symbol()]) {
// Empty input string.
assertEq("".toLocaleLowerCase(locale), "");
// Non-empty input string.
assertEq("A".toLocaleLowerCase(locale), "a");
}
if (typeof reportCompare === "function")
reportCompare(0, 0, "ok");

Просмотреть файл

@ -0,0 +1,69 @@
// |reftest| skip-if(!this.hasOwnProperty("Intl"))
// Test language dependent special casing with different language tags.
for (let locale of ["lt", "LT", "lt-LT", "lt-u-co-phonebk", "lt-x-lietuva"]) {
assertEq("i\u0307".toLocaleUpperCase(locale), "I");
assertEq("i\u0307".toLocaleUpperCase([locale]), "I");
// Additional language tags are ignored.
assertEq("i\u0307".toLocaleUpperCase([locale, "und"]), "I");
assertEq("i\u0307".toLocaleUpperCase(["und", locale]), "I\u0307");
}
// Ensure "lti" (Leti) isn't misrecognized as "lt", even though both share the
// same prefix.
assertEq("i\u0307".toLocaleUpperCase("lti"), "I\u0307");
assertEq("i\u0307".toLocaleUpperCase(["lti"]), "I\u0307");
// Language tag is always verified.
for (let locale of ["no_locale", "lt-invalid_ext", ["no_locale"], ["en", "no_locale"]]) {
// Empty input string.
assertThrowsInstanceOf(() => "".toLocaleUpperCase(locale), RangeError);
// Non-empty input string.
assertThrowsInstanceOf(() => "a".toLocaleUpperCase(locale), RangeError);
}
// The language tag fast-path for String.prototype.toLocaleUpperCase doesn't
// trip up on three element private-use only language tags.
assertEq("a".toLocaleUpperCase("x-x"), "A");
assertEq("a".toLocaleUpperCase("x-0"), "A");
// No locale argument, undefined as locale, and empty array or array-like all
// return the same result. Testing with "a/A" because it has only simple case
// mappings.
assertEq("a".toLocaleUpperCase(), "A");
assertEq("a".toLocaleUpperCase(undefined), "A");
assertEq("a".toLocaleUpperCase([]), "A");
assertEq("a".toLocaleUpperCase({}), "A");
assertEq("a".toLocaleUpperCase({length: 0}), "A");
assertEq("a".toLocaleUpperCase({length: -1}), "A");
// Test with incorrect locale type.
for (let locale of [null, 0, Math.PI, NaN, Infinity, true, false, Symbol()]) {
// Empty input string.
assertThrowsInstanceOf(() => "".toLocaleUpperCase([locale]), TypeError);
// Non-empty input string.
assertThrowsInstanceOf(() => "a".toLocaleUpperCase([locale]), TypeError);
}
// Primitives are converted with ToObject and then queried for .length property.
for (let locale of [null]) {
// Empty input string.
assertThrowsInstanceOf(() => "".toLocaleUpperCase([locale]), TypeError);
// Non-empty input string.
assertThrowsInstanceOf(() => "a".toLocaleUpperCase([locale]), TypeError);
}
// ToLength(ToObject(<primitive>)) returns 0.
for (let locale of [0, Math.PI, NaN, Infinity, true, false, Symbol()]) {
// Empty input string.
assertEq("".toLocaleUpperCase(locale), "");
// Non-empty input string.
assertEq("a".toLocaleUpperCase(locale), "A");
}
if (typeof reportCompare === "function")
reportCompare(0, 0, "ok");

Просмотреть файл

@ -35,6 +35,9 @@ writeHeaderToLog( SECTION + " "+ TITLE);
// Armenian
// Range: U+0530 to U+058F
for ( var i = 0x0530; i <= 0x058F; i++ ) {
// U+0587 (ARMENIAN SMALL LIGATURE ECH YIWN) has special upper casing.
if (i == 0x0587) continue;
var U = new Unicode( i );
/*
new TestCase( SECTION,

Просмотреть файл

@ -5,7 +5,33 @@
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
var onlySpace = String.fromCharCode(0x9, 0xa, 0xb, 0xc, 0xd, 0x20, 0xa0, 0x1680, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200a, 0x2028, 0x2029, 0x202f, 0x205f, 0x3000, 0xfeff);
var onlySpace = String.fromCharCode(
0x0009 /* <control> (CHARACTER TABULATION) */,
0x000A /* <control> (LINE FEED (LF)) */,
0x000B /* <control> (LINE TABULATION) */,
0x000C /* <control> (FORM FEED (FF)) */,
0x000D /* <control> (CARRIAGE RETURN (CR)) */,
0x0020 /* SPACE */,
0x00A0 /* NO-BREAK SPACE (NON-BREAKING SPACE) */,
0x1680 /* OGHAM SPACE MARK */,
0x2000 /* EN QUAD */,
0x2001 /* EM QUAD */,
0x2002 /* EN SPACE */,
0x2003 /* EM SPACE */,
0x2004 /* THREE-PER-EM SPACE */,
0x2005 /* FOUR-PER-EM SPACE */,
0x2006 /* SIX-PER-EM SPACE */,
0x2007 /* FIGURE SPACE */,
0x2008 /* PUNCTUATION SPACE */,
0x2009 /* THIN SPACE */,
0x200A /* HAIR SPACE */,
0x2028 /* LINE SEPARATOR */,
0x2029 /* PARAGRAPH SEPARATOR */,
0x202F /* NARROW NO-BREAK SPACE */,
0x205F /* MEDIUM MATHEMATICAL SPACE */,
0x3000 /* IDEOGRAPHIC SPACE */,
0xFEFF /* ZERO WIDTH NO-BREAK SPACE (BYTE ORDER MARK) */
);
assertEq(onlySpace.trim(), "");
assertEq((onlySpace + 'aaaa').trim(), 'aaaa');

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -5,7 +5,33 @@
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
var onlySpace = String.fromCodePoint(0x9, 0xa, 0xb, 0xc, 0xd, 0x20, 0xa0, 0x1680, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200a, 0x2028, 0x2029, 0x202f, 0x205f, 0x3000, 0xfeff);
var onlySpace = String.fromCodePoint(
0x0009 /* <control> (CHARACTER TABULATION) */,
0x000A /* <control> (LINE FEED (LF)) */,
0x000B /* <control> (LINE TABULATION) */,
0x000C /* <control> (FORM FEED (FF)) */,
0x000D /* <control> (CARRIAGE RETURN (CR)) */,
0x0020 /* SPACE */,
0x00A0 /* NO-BREAK SPACE (NON-BREAKING SPACE) */,
0x1680 /* OGHAM SPACE MARK */,
0x2000 /* EN QUAD */,
0x2001 /* EM QUAD */,
0x2002 /* EN SPACE */,
0x2003 /* EM SPACE */,
0x2004 /* THREE-PER-EM SPACE */,
0x2005 /* FOUR-PER-EM SPACE */,
0x2006 /* SIX-PER-EM SPACE */,
0x2007 /* FIGURE SPACE */,
0x2008 /* PUNCTUATION SPACE */,
0x2009 /* THIN SPACE */,
0x200A /* HAIR SPACE */,
0x2028 /* LINE SEPARATOR */,
0x2029 /* PARAGRAPH SEPARATOR */,
0x202F /* NARROW NO-BREAK SPACE */,
0x205F /* MEDIUM MATHEMATICAL SPACE */,
0x3000 /* IDEOGRAPHIC SPACE */,
0xFEFF /* ZERO WIDTH NO-BREAK SPACE (BYTE ORDER MARK) */
);
assertEq(/^\s+$/.exec(onlySpace) !== null, true);
assertEq(/^[\s]+$/.exec(onlySpace) !== null, true);

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -5,392 +5,392 @@
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
assertEq(String.fromCodePoint(0x10428).toUpperCase().codePointAt(0), 0x10400);
assertEq(String.fromCodePoint(0x10429).toUpperCase().codePointAt(0), 0x10401);
assertEq(String.fromCodePoint(0x1042a).toUpperCase().codePointAt(0), 0x10402);
assertEq(String.fromCodePoint(0x1042b).toUpperCase().codePointAt(0), 0x10403);
assertEq(String.fromCodePoint(0x1042c).toUpperCase().codePointAt(0), 0x10404);
assertEq(String.fromCodePoint(0x1042d).toUpperCase().codePointAt(0), 0x10405);
assertEq(String.fromCodePoint(0x1042e).toUpperCase().codePointAt(0), 0x10406);
assertEq(String.fromCodePoint(0x1042f).toUpperCase().codePointAt(0), 0x10407);
assertEq(String.fromCodePoint(0x10430).toUpperCase().codePointAt(0), 0x10408);
assertEq(String.fromCodePoint(0x10431).toUpperCase().codePointAt(0), 0x10409);
assertEq(String.fromCodePoint(0x10432).toUpperCase().codePointAt(0), 0x1040a);
assertEq(String.fromCodePoint(0x10433).toUpperCase().codePointAt(0), 0x1040b);
assertEq(String.fromCodePoint(0x10434).toUpperCase().codePointAt(0), 0x1040c);
assertEq(String.fromCodePoint(0x10435).toUpperCase().codePointAt(0), 0x1040d);
assertEq(String.fromCodePoint(0x10436).toUpperCase().codePointAt(0), 0x1040e);
assertEq(String.fromCodePoint(0x10437).toUpperCase().codePointAt(0), 0x1040f);
assertEq(String.fromCodePoint(0x10438).toUpperCase().codePointAt(0), 0x10410);
assertEq(String.fromCodePoint(0x10439).toUpperCase().codePointAt(0), 0x10411);
assertEq(String.fromCodePoint(0x1043a).toUpperCase().codePointAt(0), 0x10412);
assertEq(String.fromCodePoint(0x1043b).toUpperCase().codePointAt(0), 0x10413);
assertEq(String.fromCodePoint(0x1043c).toUpperCase().codePointAt(0), 0x10414);
assertEq(String.fromCodePoint(0x1043d).toUpperCase().codePointAt(0), 0x10415);
assertEq(String.fromCodePoint(0x1043e).toUpperCase().codePointAt(0), 0x10416);
assertEq(String.fromCodePoint(0x1043f).toUpperCase().codePointAt(0), 0x10417);
assertEq(String.fromCodePoint(0x10440).toUpperCase().codePointAt(0), 0x10418);
assertEq(String.fromCodePoint(0x10441).toUpperCase().codePointAt(0), 0x10419);
assertEq(String.fromCodePoint(0x10442).toUpperCase().codePointAt(0), 0x1041a);
assertEq(String.fromCodePoint(0x10443).toUpperCase().codePointAt(0), 0x1041b);
assertEq(String.fromCodePoint(0x10444).toUpperCase().codePointAt(0), 0x1041c);
assertEq(String.fromCodePoint(0x10445).toUpperCase().codePointAt(0), 0x1041d);
assertEq(String.fromCodePoint(0x10446).toUpperCase().codePointAt(0), 0x1041e);
assertEq(String.fromCodePoint(0x10447).toUpperCase().codePointAt(0), 0x1041f);
assertEq(String.fromCodePoint(0x10448).toUpperCase().codePointAt(0), 0x10420);
assertEq(String.fromCodePoint(0x10449).toUpperCase().codePointAt(0), 0x10421);
assertEq(String.fromCodePoint(0x1044a).toUpperCase().codePointAt(0), 0x10422);
assertEq(String.fromCodePoint(0x1044b).toUpperCase().codePointAt(0), 0x10423);
assertEq(String.fromCodePoint(0x1044c).toUpperCase().codePointAt(0), 0x10424);
assertEq(String.fromCodePoint(0x1044d).toUpperCase().codePointAt(0), 0x10425);
assertEq(String.fromCodePoint(0x1044e).toUpperCase().codePointAt(0), 0x10426);
assertEq(String.fromCodePoint(0x1044f).toUpperCase().codePointAt(0), 0x10427);
assertEq(String.fromCodePoint(0x104d8).toUpperCase().codePointAt(0), 0x104b0);
assertEq(String.fromCodePoint(0x104d9).toUpperCase().codePointAt(0), 0x104b1);
assertEq(String.fromCodePoint(0x104da).toUpperCase().codePointAt(0), 0x104b2);
assertEq(String.fromCodePoint(0x104db).toUpperCase().codePointAt(0), 0x104b3);
assertEq(String.fromCodePoint(0x104dc).toUpperCase().codePointAt(0), 0x104b4);
assertEq(String.fromCodePoint(0x104dd).toUpperCase().codePointAt(0), 0x104b5);
assertEq(String.fromCodePoint(0x104de).toUpperCase().codePointAt(0), 0x104b6);
assertEq(String.fromCodePoint(0x104df).toUpperCase().codePointAt(0), 0x104b7);
assertEq(String.fromCodePoint(0x104e0).toUpperCase().codePointAt(0), 0x104b8);
assertEq(String.fromCodePoint(0x104e1).toUpperCase().codePointAt(0), 0x104b9);
assertEq(String.fromCodePoint(0x104e2).toUpperCase().codePointAt(0), 0x104ba);
assertEq(String.fromCodePoint(0x104e3).toUpperCase().codePointAt(0), 0x104bb);
assertEq(String.fromCodePoint(0x104e4).toUpperCase().codePointAt(0), 0x104bc);
assertEq(String.fromCodePoint(0x104e5).toUpperCase().codePointAt(0), 0x104bd);
assertEq(String.fromCodePoint(0x104e6).toUpperCase().codePointAt(0), 0x104be);
assertEq(String.fromCodePoint(0x104e7).toUpperCase().codePointAt(0), 0x104bf);
assertEq(String.fromCodePoint(0x104e8).toUpperCase().codePointAt(0), 0x104c0);
assertEq(String.fromCodePoint(0x104e9).toUpperCase().codePointAt(0), 0x104c1);
assertEq(String.fromCodePoint(0x104ea).toUpperCase().codePointAt(0), 0x104c2);
assertEq(String.fromCodePoint(0x104eb).toUpperCase().codePointAt(0), 0x104c3);
assertEq(String.fromCodePoint(0x104ec).toUpperCase().codePointAt(0), 0x104c4);
assertEq(String.fromCodePoint(0x104ed).toUpperCase().codePointAt(0), 0x104c5);
assertEq(String.fromCodePoint(0x104ee).toUpperCase().codePointAt(0), 0x104c6);
assertEq(String.fromCodePoint(0x104ef).toUpperCase().codePointAt(0), 0x104c7);
assertEq(String.fromCodePoint(0x104f0).toUpperCase().codePointAt(0), 0x104c8);
assertEq(String.fromCodePoint(0x104f1).toUpperCase().codePointAt(0), 0x104c9);
assertEq(String.fromCodePoint(0x104f2).toUpperCase().codePointAt(0), 0x104ca);
assertEq(String.fromCodePoint(0x104f3).toUpperCase().codePointAt(0), 0x104cb);
assertEq(String.fromCodePoint(0x104f4).toUpperCase().codePointAt(0), 0x104cc);
assertEq(String.fromCodePoint(0x104f5).toUpperCase().codePointAt(0), 0x104cd);
assertEq(String.fromCodePoint(0x104f6).toUpperCase().codePointAt(0), 0x104ce);
assertEq(String.fromCodePoint(0x104f7).toUpperCase().codePointAt(0), 0x104cf);
assertEq(String.fromCodePoint(0x104f8).toUpperCase().codePointAt(0), 0x104d0);
assertEq(String.fromCodePoint(0x104f9).toUpperCase().codePointAt(0), 0x104d1);
assertEq(String.fromCodePoint(0x104fa).toUpperCase().codePointAt(0), 0x104d2);
assertEq(String.fromCodePoint(0x104fb).toUpperCase().codePointAt(0), 0x104d3);
assertEq(String.fromCodePoint(0x10cc0).toUpperCase().codePointAt(0), 0x10c80);
assertEq(String.fromCodePoint(0x10cc1).toUpperCase().codePointAt(0), 0x10c81);
assertEq(String.fromCodePoint(0x10cc2).toUpperCase().codePointAt(0), 0x10c82);
assertEq(String.fromCodePoint(0x10cc3).toUpperCase().codePointAt(0), 0x10c83);
assertEq(String.fromCodePoint(0x10cc4).toUpperCase().codePointAt(0), 0x10c84);
assertEq(String.fromCodePoint(0x10cc5).toUpperCase().codePointAt(0), 0x10c85);
assertEq(String.fromCodePoint(0x10cc6).toUpperCase().codePointAt(0), 0x10c86);
assertEq(String.fromCodePoint(0x10cc7).toUpperCase().codePointAt(0), 0x10c87);
assertEq(String.fromCodePoint(0x10cc8).toUpperCase().codePointAt(0), 0x10c88);
assertEq(String.fromCodePoint(0x10cc9).toUpperCase().codePointAt(0), 0x10c89);
assertEq(String.fromCodePoint(0x10cca).toUpperCase().codePointAt(0), 0x10c8a);
assertEq(String.fromCodePoint(0x10ccb).toUpperCase().codePointAt(0), 0x10c8b);
assertEq(String.fromCodePoint(0x10ccc).toUpperCase().codePointAt(0), 0x10c8c);
assertEq(String.fromCodePoint(0x10ccd).toUpperCase().codePointAt(0), 0x10c8d);
assertEq(String.fromCodePoint(0x10cce).toUpperCase().codePointAt(0), 0x10c8e);
assertEq(String.fromCodePoint(0x10ccf).toUpperCase().codePointAt(0), 0x10c8f);
assertEq(String.fromCodePoint(0x10cd0).toUpperCase().codePointAt(0), 0x10c90);
assertEq(String.fromCodePoint(0x10cd1).toUpperCase().codePointAt(0), 0x10c91);
assertEq(String.fromCodePoint(0x10cd2).toUpperCase().codePointAt(0), 0x10c92);
assertEq(String.fromCodePoint(0x10cd3).toUpperCase().codePointAt(0), 0x10c93);
assertEq(String.fromCodePoint(0x10cd4).toUpperCase().codePointAt(0), 0x10c94);
assertEq(String.fromCodePoint(0x10cd5).toUpperCase().codePointAt(0), 0x10c95);
assertEq(String.fromCodePoint(0x10cd6).toUpperCase().codePointAt(0), 0x10c96);
assertEq(String.fromCodePoint(0x10cd7).toUpperCase().codePointAt(0), 0x10c97);
assertEq(String.fromCodePoint(0x10cd8).toUpperCase().codePointAt(0), 0x10c98);
assertEq(String.fromCodePoint(0x10cd9).toUpperCase().codePointAt(0), 0x10c99);
assertEq(String.fromCodePoint(0x10cda).toUpperCase().codePointAt(0), 0x10c9a);
assertEq(String.fromCodePoint(0x10cdb).toUpperCase().codePointAt(0), 0x10c9b);
assertEq(String.fromCodePoint(0x10cdc).toUpperCase().codePointAt(0), 0x10c9c);
assertEq(String.fromCodePoint(0x10cdd).toUpperCase().codePointAt(0), 0x10c9d);
assertEq(String.fromCodePoint(0x10cde).toUpperCase().codePointAt(0), 0x10c9e);
assertEq(String.fromCodePoint(0x10cdf).toUpperCase().codePointAt(0), 0x10c9f);
assertEq(String.fromCodePoint(0x10ce0).toUpperCase().codePointAt(0), 0x10ca0);
assertEq(String.fromCodePoint(0x10ce1).toUpperCase().codePointAt(0), 0x10ca1);
assertEq(String.fromCodePoint(0x10ce2).toUpperCase().codePointAt(0), 0x10ca2);
assertEq(String.fromCodePoint(0x10ce3).toUpperCase().codePointAt(0), 0x10ca3);
assertEq(String.fromCodePoint(0x10ce4).toUpperCase().codePointAt(0), 0x10ca4);
assertEq(String.fromCodePoint(0x10ce5).toUpperCase().codePointAt(0), 0x10ca5);
assertEq(String.fromCodePoint(0x10ce6).toUpperCase().codePointAt(0), 0x10ca6);
assertEq(String.fromCodePoint(0x10ce7).toUpperCase().codePointAt(0), 0x10ca7);
assertEq(String.fromCodePoint(0x10ce8).toUpperCase().codePointAt(0), 0x10ca8);
assertEq(String.fromCodePoint(0x10ce9).toUpperCase().codePointAt(0), 0x10ca9);
assertEq(String.fromCodePoint(0x10cea).toUpperCase().codePointAt(0), 0x10caa);
assertEq(String.fromCodePoint(0x10ceb).toUpperCase().codePointAt(0), 0x10cab);
assertEq(String.fromCodePoint(0x10cec).toUpperCase().codePointAt(0), 0x10cac);
assertEq(String.fromCodePoint(0x10ced).toUpperCase().codePointAt(0), 0x10cad);
assertEq(String.fromCodePoint(0x10cee).toUpperCase().codePointAt(0), 0x10cae);
assertEq(String.fromCodePoint(0x10cef).toUpperCase().codePointAt(0), 0x10caf);
assertEq(String.fromCodePoint(0x10cf0).toUpperCase().codePointAt(0), 0x10cb0);
assertEq(String.fromCodePoint(0x10cf1).toUpperCase().codePointAt(0), 0x10cb1);
assertEq(String.fromCodePoint(0x10cf2).toUpperCase().codePointAt(0), 0x10cb2);
assertEq(String.fromCodePoint(0x118c0).toUpperCase().codePointAt(0), 0x118a0);
assertEq(String.fromCodePoint(0x118c1).toUpperCase().codePointAt(0), 0x118a1);
assertEq(String.fromCodePoint(0x118c2).toUpperCase().codePointAt(0), 0x118a2);
assertEq(String.fromCodePoint(0x118c3).toUpperCase().codePointAt(0), 0x118a3);
assertEq(String.fromCodePoint(0x118c4).toUpperCase().codePointAt(0), 0x118a4);
assertEq(String.fromCodePoint(0x118c5).toUpperCase().codePointAt(0), 0x118a5);
assertEq(String.fromCodePoint(0x118c6).toUpperCase().codePointAt(0), 0x118a6);
assertEq(String.fromCodePoint(0x118c7).toUpperCase().codePointAt(0), 0x118a7);
assertEq(String.fromCodePoint(0x118c8).toUpperCase().codePointAt(0), 0x118a8);
assertEq(String.fromCodePoint(0x118c9).toUpperCase().codePointAt(0), 0x118a9);
assertEq(String.fromCodePoint(0x118ca).toUpperCase().codePointAt(0), 0x118aa);
assertEq(String.fromCodePoint(0x118cb).toUpperCase().codePointAt(0), 0x118ab);
assertEq(String.fromCodePoint(0x118cc).toUpperCase().codePointAt(0), 0x118ac);
assertEq(String.fromCodePoint(0x118cd).toUpperCase().codePointAt(0), 0x118ad);
assertEq(String.fromCodePoint(0x118ce).toUpperCase().codePointAt(0), 0x118ae);
assertEq(String.fromCodePoint(0x118cf).toUpperCase().codePointAt(0), 0x118af);
assertEq(String.fromCodePoint(0x118d0).toUpperCase().codePointAt(0), 0x118b0);
assertEq(String.fromCodePoint(0x118d1).toUpperCase().codePointAt(0), 0x118b1);
assertEq(String.fromCodePoint(0x118d2).toUpperCase().codePointAt(0), 0x118b2);
assertEq(String.fromCodePoint(0x118d3).toUpperCase().codePointAt(0), 0x118b3);
assertEq(String.fromCodePoint(0x118d4).toUpperCase().codePointAt(0), 0x118b4);
assertEq(String.fromCodePoint(0x118d5).toUpperCase().codePointAt(0), 0x118b5);
assertEq(String.fromCodePoint(0x118d6).toUpperCase().codePointAt(0), 0x118b6);
assertEq(String.fromCodePoint(0x118d7).toUpperCase().codePointAt(0), 0x118b7);
assertEq(String.fromCodePoint(0x118d8).toUpperCase().codePointAt(0), 0x118b8);
assertEq(String.fromCodePoint(0x118d9).toUpperCase().codePointAt(0), 0x118b9);
assertEq(String.fromCodePoint(0x118da).toUpperCase().codePointAt(0), 0x118ba);
assertEq(String.fromCodePoint(0x118db).toUpperCase().codePointAt(0), 0x118bb);
assertEq(String.fromCodePoint(0x118dc).toUpperCase().codePointAt(0), 0x118bc);
assertEq(String.fromCodePoint(0x118dd).toUpperCase().codePointAt(0), 0x118bd);
assertEq(String.fromCodePoint(0x118de).toUpperCase().codePointAt(0), 0x118be);
assertEq(String.fromCodePoint(0x118df).toUpperCase().codePointAt(0), 0x118bf);
assertEq(String.fromCodePoint(0x1e922).toUpperCase().codePointAt(0), 0x1e900);
assertEq(String.fromCodePoint(0x1e923).toUpperCase().codePointAt(0), 0x1e901);
assertEq(String.fromCodePoint(0x1e924).toUpperCase().codePointAt(0), 0x1e902);
assertEq(String.fromCodePoint(0x1e925).toUpperCase().codePointAt(0), 0x1e903);
assertEq(String.fromCodePoint(0x1e926).toUpperCase().codePointAt(0), 0x1e904);
assertEq(String.fromCodePoint(0x1e927).toUpperCase().codePointAt(0), 0x1e905);
assertEq(String.fromCodePoint(0x1e928).toUpperCase().codePointAt(0), 0x1e906);
assertEq(String.fromCodePoint(0x1e929).toUpperCase().codePointAt(0), 0x1e907);
assertEq(String.fromCodePoint(0x1e92a).toUpperCase().codePointAt(0), 0x1e908);
assertEq(String.fromCodePoint(0x1e92b).toUpperCase().codePointAt(0), 0x1e909);
assertEq(String.fromCodePoint(0x1e92c).toUpperCase().codePointAt(0), 0x1e90a);
assertEq(String.fromCodePoint(0x1e92d).toUpperCase().codePointAt(0), 0x1e90b);
assertEq(String.fromCodePoint(0x1e92e).toUpperCase().codePointAt(0), 0x1e90c);
assertEq(String.fromCodePoint(0x1e92f).toUpperCase().codePointAt(0), 0x1e90d);
assertEq(String.fromCodePoint(0x1e930).toUpperCase().codePointAt(0), 0x1e90e);
assertEq(String.fromCodePoint(0x1e931).toUpperCase().codePointAt(0), 0x1e90f);
assertEq(String.fromCodePoint(0x1e932).toUpperCase().codePointAt(0), 0x1e910);
assertEq(String.fromCodePoint(0x1e933).toUpperCase().codePointAt(0), 0x1e911);
assertEq(String.fromCodePoint(0x1e934).toUpperCase().codePointAt(0), 0x1e912);
assertEq(String.fromCodePoint(0x1e935).toUpperCase().codePointAt(0), 0x1e913);
assertEq(String.fromCodePoint(0x1e936).toUpperCase().codePointAt(0), 0x1e914);
assertEq(String.fromCodePoint(0x1e937).toUpperCase().codePointAt(0), 0x1e915);
assertEq(String.fromCodePoint(0x1e938).toUpperCase().codePointAt(0), 0x1e916);
assertEq(String.fromCodePoint(0x1e939).toUpperCase().codePointAt(0), 0x1e917);
assertEq(String.fromCodePoint(0x1e93a).toUpperCase().codePointAt(0), 0x1e918);
assertEq(String.fromCodePoint(0x1e93b).toUpperCase().codePointAt(0), 0x1e919);
assertEq(String.fromCodePoint(0x1e93c).toUpperCase().codePointAt(0), 0x1e91a);
assertEq(String.fromCodePoint(0x1e93d).toUpperCase().codePointAt(0), 0x1e91b);
assertEq(String.fromCodePoint(0x1e93e).toUpperCase().codePointAt(0), 0x1e91c);
assertEq(String.fromCodePoint(0x1e93f).toUpperCase().codePointAt(0), 0x1e91d);
assertEq(String.fromCodePoint(0x1e940).toUpperCase().codePointAt(0), 0x1e91e);
assertEq(String.fromCodePoint(0x1e941).toUpperCase().codePointAt(0), 0x1e91f);
assertEq(String.fromCodePoint(0x1e942).toUpperCase().codePointAt(0), 0x1e920);
assertEq(String.fromCodePoint(0x1e943).toUpperCase().codePointAt(0), 0x1e921);
assertEq(String.fromCodePoint(0x10400).toLowerCase().codePointAt(0), 0x10428);
assertEq(String.fromCodePoint(0x10401).toLowerCase().codePointAt(0), 0x10429);
assertEq(String.fromCodePoint(0x10402).toLowerCase().codePointAt(0), 0x1042a);
assertEq(String.fromCodePoint(0x10403).toLowerCase().codePointAt(0), 0x1042b);
assertEq(String.fromCodePoint(0x10404).toLowerCase().codePointAt(0), 0x1042c);
assertEq(String.fromCodePoint(0x10405).toLowerCase().codePointAt(0), 0x1042d);
assertEq(String.fromCodePoint(0x10406).toLowerCase().codePointAt(0), 0x1042e);
assertEq(String.fromCodePoint(0x10407).toLowerCase().codePointAt(0), 0x1042f);
assertEq(String.fromCodePoint(0x10408).toLowerCase().codePointAt(0), 0x10430);
assertEq(String.fromCodePoint(0x10409).toLowerCase().codePointAt(0), 0x10431);
assertEq(String.fromCodePoint(0x1040a).toLowerCase().codePointAt(0), 0x10432);
assertEq(String.fromCodePoint(0x1040b).toLowerCase().codePointAt(0), 0x10433);
assertEq(String.fromCodePoint(0x1040c).toLowerCase().codePointAt(0), 0x10434);
assertEq(String.fromCodePoint(0x1040d).toLowerCase().codePointAt(0), 0x10435);
assertEq(String.fromCodePoint(0x1040e).toLowerCase().codePointAt(0), 0x10436);
assertEq(String.fromCodePoint(0x1040f).toLowerCase().codePointAt(0), 0x10437);
assertEq(String.fromCodePoint(0x10410).toLowerCase().codePointAt(0), 0x10438);
assertEq(String.fromCodePoint(0x10411).toLowerCase().codePointAt(0), 0x10439);
assertEq(String.fromCodePoint(0x10412).toLowerCase().codePointAt(0), 0x1043a);
assertEq(String.fromCodePoint(0x10413).toLowerCase().codePointAt(0), 0x1043b);
assertEq(String.fromCodePoint(0x10414).toLowerCase().codePointAt(0), 0x1043c);
assertEq(String.fromCodePoint(0x10415).toLowerCase().codePointAt(0), 0x1043d);
assertEq(String.fromCodePoint(0x10416).toLowerCase().codePointAt(0), 0x1043e);
assertEq(String.fromCodePoint(0x10417).toLowerCase().codePointAt(0), 0x1043f);
assertEq(String.fromCodePoint(0x10418).toLowerCase().codePointAt(0), 0x10440);
assertEq(String.fromCodePoint(0x10419).toLowerCase().codePointAt(0), 0x10441);
assertEq(String.fromCodePoint(0x1041a).toLowerCase().codePointAt(0), 0x10442);
assertEq(String.fromCodePoint(0x1041b).toLowerCase().codePointAt(0), 0x10443);
assertEq(String.fromCodePoint(0x1041c).toLowerCase().codePointAt(0), 0x10444);
assertEq(String.fromCodePoint(0x1041d).toLowerCase().codePointAt(0), 0x10445);
assertEq(String.fromCodePoint(0x1041e).toLowerCase().codePointAt(0), 0x10446);
assertEq(String.fromCodePoint(0x1041f).toLowerCase().codePointAt(0), 0x10447);
assertEq(String.fromCodePoint(0x10420).toLowerCase().codePointAt(0), 0x10448);
assertEq(String.fromCodePoint(0x10421).toLowerCase().codePointAt(0), 0x10449);
assertEq(String.fromCodePoint(0x10422).toLowerCase().codePointAt(0), 0x1044a);
assertEq(String.fromCodePoint(0x10423).toLowerCase().codePointAt(0), 0x1044b);
assertEq(String.fromCodePoint(0x10424).toLowerCase().codePointAt(0), 0x1044c);
assertEq(String.fromCodePoint(0x10425).toLowerCase().codePointAt(0), 0x1044d);
assertEq(String.fromCodePoint(0x10426).toLowerCase().codePointAt(0), 0x1044e);
assertEq(String.fromCodePoint(0x10427).toLowerCase().codePointAt(0), 0x1044f);
assertEq(String.fromCodePoint(0x104b0).toLowerCase().codePointAt(0), 0x104d8);
assertEq(String.fromCodePoint(0x104b1).toLowerCase().codePointAt(0), 0x104d9);
assertEq(String.fromCodePoint(0x104b2).toLowerCase().codePointAt(0), 0x104da);
assertEq(String.fromCodePoint(0x104b3).toLowerCase().codePointAt(0), 0x104db);
assertEq(String.fromCodePoint(0x104b4).toLowerCase().codePointAt(0), 0x104dc);
assertEq(String.fromCodePoint(0x104b5).toLowerCase().codePointAt(0), 0x104dd);
assertEq(String.fromCodePoint(0x104b6).toLowerCase().codePointAt(0), 0x104de);
assertEq(String.fromCodePoint(0x104b7).toLowerCase().codePointAt(0), 0x104df);
assertEq(String.fromCodePoint(0x104b8).toLowerCase().codePointAt(0), 0x104e0);
assertEq(String.fromCodePoint(0x104b9).toLowerCase().codePointAt(0), 0x104e1);
assertEq(String.fromCodePoint(0x104ba).toLowerCase().codePointAt(0), 0x104e2);
assertEq(String.fromCodePoint(0x104bb).toLowerCase().codePointAt(0), 0x104e3);
assertEq(String.fromCodePoint(0x104bc).toLowerCase().codePointAt(0), 0x104e4);
assertEq(String.fromCodePoint(0x104bd).toLowerCase().codePointAt(0), 0x104e5);
assertEq(String.fromCodePoint(0x104be).toLowerCase().codePointAt(0), 0x104e6);
assertEq(String.fromCodePoint(0x104bf).toLowerCase().codePointAt(0), 0x104e7);
assertEq(String.fromCodePoint(0x104c0).toLowerCase().codePointAt(0), 0x104e8);
assertEq(String.fromCodePoint(0x104c1).toLowerCase().codePointAt(0), 0x104e9);
assertEq(String.fromCodePoint(0x104c2).toLowerCase().codePointAt(0), 0x104ea);
assertEq(String.fromCodePoint(0x104c3).toLowerCase().codePointAt(0), 0x104eb);
assertEq(String.fromCodePoint(0x104c4).toLowerCase().codePointAt(0), 0x104ec);
assertEq(String.fromCodePoint(0x104c5).toLowerCase().codePointAt(0), 0x104ed);
assertEq(String.fromCodePoint(0x104c6).toLowerCase().codePointAt(0), 0x104ee);
assertEq(String.fromCodePoint(0x104c7).toLowerCase().codePointAt(0), 0x104ef);
assertEq(String.fromCodePoint(0x104c8).toLowerCase().codePointAt(0), 0x104f0);
assertEq(String.fromCodePoint(0x104c9).toLowerCase().codePointAt(0), 0x104f1);
assertEq(String.fromCodePoint(0x104ca).toLowerCase().codePointAt(0), 0x104f2);
assertEq(String.fromCodePoint(0x104cb).toLowerCase().codePointAt(0), 0x104f3);
assertEq(String.fromCodePoint(0x104cc).toLowerCase().codePointAt(0), 0x104f4);
assertEq(String.fromCodePoint(0x104cd).toLowerCase().codePointAt(0), 0x104f5);
assertEq(String.fromCodePoint(0x104ce).toLowerCase().codePointAt(0), 0x104f6);
assertEq(String.fromCodePoint(0x104cf).toLowerCase().codePointAt(0), 0x104f7);
assertEq(String.fromCodePoint(0x104d0).toLowerCase().codePointAt(0), 0x104f8);
assertEq(String.fromCodePoint(0x104d1).toLowerCase().codePointAt(0), 0x104f9);
assertEq(String.fromCodePoint(0x104d2).toLowerCase().codePointAt(0), 0x104fa);
assertEq(String.fromCodePoint(0x104d3).toLowerCase().codePointAt(0), 0x104fb);
assertEq(String.fromCodePoint(0x10c80).toLowerCase().codePointAt(0), 0x10cc0);
assertEq(String.fromCodePoint(0x10c81).toLowerCase().codePointAt(0), 0x10cc1);
assertEq(String.fromCodePoint(0x10c82).toLowerCase().codePointAt(0), 0x10cc2);
assertEq(String.fromCodePoint(0x10c83).toLowerCase().codePointAt(0), 0x10cc3);
assertEq(String.fromCodePoint(0x10c84).toLowerCase().codePointAt(0), 0x10cc4);
assertEq(String.fromCodePoint(0x10c85).toLowerCase().codePointAt(0), 0x10cc5);
assertEq(String.fromCodePoint(0x10c86).toLowerCase().codePointAt(0), 0x10cc6);
assertEq(String.fromCodePoint(0x10c87).toLowerCase().codePointAt(0), 0x10cc7);
assertEq(String.fromCodePoint(0x10c88).toLowerCase().codePointAt(0), 0x10cc8);
assertEq(String.fromCodePoint(0x10c89).toLowerCase().codePointAt(0), 0x10cc9);
assertEq(String.fromCodePoint(0x10c8a).toLowerCase().codePointAt(0), 0x10cca);
assertEq(String.fromCodePoint(0x10c8b).toLowerCase().codePointAt(0), 0x10ccb);
assertEq(String.fromCodePoint(0x10c8c).toLowerCase().codePointAt(0), 0x10ccc);
assertEq(String.fromCodePoint(0x10c8d).toLowerCase().codePointAt(0), 0x10ccd);
assertEq(String.fromCodePoint(0x10c8e).toLowerCase().codePointAt(0), 0x10cce);
assertEq(String.fromCodePoint(0x10c8f).toLowerCase().codePointAt(0), 0x10ccf);
assertEq(String.fromCodePoint(0x10c90).toLowerCase().codePointAt(0), 0x10cd0);
assertEq(String.fromCodePoint(0x10c91).toLowerCase().codePointAt(0), 0x10cd1);
assertEq(String.fromCodePoint(0x10c92).toLowerCase().codePointAt(0), 0x10cd2);
assertEq(String.fromCodePoint(0x10c93).toLowerCase().codePointAt(0), 0x10cd3);
assertEq(String.fromCodePoint(0x10c94).toLowerCase().codePointAt(0), 0x10cd4);
assertEq(String.fromCodePoint(0x10c95).toLowerCase().codePointAt(0), 0x10cd5);
assertEq(String.fromCodePoint(0x10c96).toLowerCase().codePointAt(0), 0x10cd6);
assertEq(String.fromCodePoint(0x10c97).toLowerCase().codePointAt(0), 0x10cd7);
assertEq(String.fromCodePoint(0x10c98).toLowerCase().codePointAt(0), 0x10cd8);
assertEq(String.fromCodePoint(0x10c99).toLowerCase().codePointAt(0), 0x10cd9);
assertEq(String.fromCodePoint(0x10c9a).toLowerCase().codePointAt(0), 0x10cda);
assertEq(String.fromCodePoint(0x10c9b).toLowerCase().codePointAt(0), 0x10cdb);
assertEq(String.fromCodePoint(0x10c9c).toLowerCase().codePointAt(0), 0x10cdc);
assertEq(String.fromCodePoint(0x10c9d).toLowerCase().codePointAt(0), 0x10cdd);
assertEq(String.fromCodePoint(0x10c9e).toLowerCase().codePointAt(0), 0x10cde);
assertEq(String.fromCodePoint(0x10c9f).toLowerCase().codePointAt(0), 0x10cdf);
assertEq(String.fromCodePoint(0x10ca0).toLowerCase().codePointAt(0), 0x10ce0);
assertEq(String.fromCodePoint(0x10ca1).toLowerCase().codePointAt(0), 0x10ce1);
assertEq(String.fromCodePoint(0x10ca2).toLowerCase().codePointAt(0), 0x10ce2);
assertEq(String.fromCodePoint(0x10ca3).toLowerCase().codePointAt(0), 0x10ce3);
assertEq(String.fromCodePoint(0x10ca4).toLowerCase().codePointAt(0), 0x10ce4);
assertEq(String.fromCodePoint(0x10ca5).toLowerCase().codePointAt(0), 0x10ce5);
assertEq(String.fromCodePoint(0x10ca6).toLowerCase().codePointAt(0), 0x10ce6);
assertEq(String.fromCodePoint(0x10ca7).toLowerCase().codePointAt(0), 0x10ce7);
assertEq(String.fromCodePoint(0x10ca8).toLowerCase().codePointAt(0), 0x10ce8);
assertEq(String.fromCodePoint(0x10ca9).toLowerCase().codePointAt(0), 0x10ce9);
assertEq(String.fromCodePoint(0x10caa).toLowerCase().codePointAt(0), 0x10cea);
assertEq(String.fromCodePoint(0x10cab).toLowerCase().codePointAt(0), 0x10ceb);
assertEq(String.fromCodePoint(0x10cac).toLowerCase().codePointAt(0), 0x10cec);
assertEq(String.fromCodePoint(0x10cad).toLowerCase().codePointAt(0), 0x10ced);
assertEq(String.fromCodePoint(0x10cae).toLowerCase().codePointAt(0), 0x10cee);
assertEq(String.fromCodePoint(0x10caf).toLowerCase().codePointAt(0), 0x10cef);
assertEq(String.fromCodePoint(0x10cb0).toLowerCase().codePointAt(0), 0x10cf0);
assertEq(String.fromCodePoint(0x10cb1).toLowerCase().codePointAt(0), 0x10cf1);
assertEq(String.fromCodePoint(0x10cb2).toLowerCase().codePointAt(0), 0x10cf2);
assertEq(String.fromCodePoint(0x118a0).toLowerCase().codePointAt(0), 0x118c0);
assertEq(String.fromCodePoint(0x118a1).toLowerCase().codePointAt(0), 0x118c1);
assertEq(String.fromCodePoint(0x118a2).toLowerCase().codePointAt(0), 0x118c2);
assertEq(String.fromCodePoint(0x118a3).toLowerCase().codePointAt(0), 0x118c3);
assertEq(String.fromCodePoint(0x118a4).toLowerCase().codePointAt(0), 0x118c4);
assertEq(String.fromCodePoint(0x118a5).toLowerCase().codePointAt(0), 0x118c5);
assertEq(String.fromCodePoint(0x118a6).toLowerCase().codePointAt(0), 0x118c6);
assertEq(String.fromCodePoint(0x118a7).toLowerCase().codePointAt(0), 0x118c7);
assertEq(String.fromCodePoint(0x118a8).toLowerCase().codePointAt(0), 0x118c8);
assertEq(String.fromCodePoint(0x118a9).toLowerCase().codePointAt(0), 0x118c9);
assertEq(String.fromCodePoint(0x118aa).toLowerCase().codePointAt(0), 0x118ca);
assertEq(String.fromCodePoint(0x118ab).toLowerCase().codePointAt(0), 0x118cb);
assertEq(String.fromCodePoint(0x118ac).toLowerCase().codePointAt(0), 0x118cc);
assertEq(String.fromCodePoint(0x118ad).toLowerCase().codePointAt(0), 0x118cd);
assertEq(String.fromCodePoint(0x118ae).toLowerCase().codePointAt(0), 0x118ce);
assertEq(String.fromCodePoint(0x118af).toLowerCase().codePointAt(0), 0x118cf);
assertEq(String.fromCodePoint(0x118b0).toLowerCase().codePointAt(0), 0x118d0);
assertEq(String.fromCodePoint(0x118b1).toLowerCase().codePointAt(0), 0x118d1);
assertEq(String.fromCodePoint(0x118b2).toLowerCase().codePointAt(0), 0x118d2);
assertEq(String.fromCodePoint(0x118b3).toLowerCase().codePointAt(0), 0x118d3);
assertEq(String.fromCodePoint(0x118b4).toLowerCase().codePointAt(0), 0x118d4);
assertEq(String.fromCodePoint(0x118b5).toLowerCase().codePointAt(0), 0x118d5);
assertEq(String.fromCodePoint(0x118b6).toLowerCase().codePointAt(0), 0x118d6);
assertEq(String.fromCodePoint(0x118b7).toLowerCase().codePointAt(0), 0x118d7);
assertEq(String.fromCodePoint(0x118b8).toLowerCase().codePointAt(0), 0x118d8);
assertEq(String.fromCodePoint(0x118b9).toLowerCase().codePointAt(0), 0x118d9);
assertEq(String.fromCodePoint(0x118ba).toLowerCase().codePointAt(0), 0x118da);
assertEq(String.fromCodePoint(0x118bb).toLowerCase().codePointAt(0), 0x118db);
assertEq(String.fromCodePoint(0x118bc).toLowerCase().codePointAt(0), 0x118dc);
assertEq(String.fromCodePoint(0x118bd).toLowerCase().codePointAt(0), 0x118dd);
assertEq(String.fromCodePoint(0x118be).toLowerCase().codePointAt(0), 0x118de);
assertEq(String.fromCodePoint(0x118bf).toLowerCase().codePointAt(0), 0x118df);
assertEq(String.fromCodePoint(0x1e900).toLowerCase().codePointAt(0), 0x1e922);
assertEq(String.fromCodePoint(0x1e901).toLowerCase().codePointAt(0), 0x1e923);
assertEq(String.fromCodePoint(0x1e902).toLowerCase().codePointAt(0), 0x1e924);
assertEq(String.fromCodePoint(0x1e903).toLowerCase().codePointAt(0), 0x1e925);
assertEq(String.fromCodePoint(0x1e904).toLowerCase().codePointAt(0), 0x1e926);
assertEq(String.fromCodePoint(0x1e905).toLowerCase().codePointAt(0), 0x1e927);
assertEq(String.fromCodePoint(0x1e906).toLowerCase().codePointAt(0), 0x1e928);
assertEq(String.fromCodePoint(0x1e907).toLowerCase().codePointAt(0), 0x1e929);
assertEq(String.fromCodePoint(0x1e908).toLowerCase().codePointAt(0), 0x1e92a);
assertEq(String.fromCodePoint(0x1e909).toLowerCase().codePointAt(0), 0x1e92b);
assertEq(String.fromCodePoint(0x1e90a).toLowerCase().codePointAt(0), 0x1e92c);
assertEq(String.fromCodePoint(0x1e90b).toLowerCase().codePointAt(0), 0x1e92d);
assertEq(String.fromCodePoint(0x1e90c).toLowerCase().codePointAt(0), 0x1e92e);
assertEq(String.fromCodePoint(0x1e90d).toLowerCase().codePointAt(0), 0x1e92f);
assertEq(String.fromCodePoint(0x1e90e).toLowerCase().codePointAt(0), 0x1e930);
assertEq(String.fromCodePoint(0x1e90f).toLowerCase().codePointAt(0), 0x1e931);
assertEq(String.fromCodePoint(0x1e910).toLowerCase().codePointAt(0), 0x1e932);
assertEq(String.fromCodePoint(0x1e911).toLowerCase().codePointAt(0), 0x1e933);
assertEq(String.fromCodePoint(0x1e912).toLowerCase().codePointAt(0), 0x1e934);
assertEq(String.fromCodePoint(0x1e913).toLowerCase().codePointAt(0), 0x1e935);
assertEq(String.fromCodePoint(0x1e914).toLowerCase().codePointAt(0), 0x1e936);
assertEq(String.fromCodePoint(0x1e915).toLowerCase().codePointAt(0), 0x1e937);
assertEq(String.fromCodePoint(0x1e916).toLowerCase().codePointAt(0), 0x1e938);
assertEq(String.fromCodePoint(0x1e917).toLowerCase().codePointAt(0), 0x1e939);
assertEq(String.fromCodePoint(0x1e918).toLowerCase().codePointAt(0), 0x1e93a);
assertEq(String.fromCodePoint(0x1e919).toLowerCase().codePointAt(0), 0x1e93b);
assertEq(String.fromCodePoint(0x1e91a).toLowerCase().codePointAt(0), 0x1e93c);
assertEq(String.fromCodePoint(0x1e91b).toLowerCase().codePointAt(0), 0x1e93d);
assertEq(String.fromCodePoint(0x1e91c).toLowerCase().codePointAt(0), 0x1e93e);
assertEq(String.fromCodePoint(0x1e91d).toLowerCase().codePointAt(0), 0x1e93f);
assertEq(String.fromCodePoint(0x1e91e).toLowerCase().codePointAt(0), 0x1e940);
assertEq(String.fromCodePoint(0x1e91f).toLowerCase().codePointAt(0), 0x1e941);
assertEq(String.fromCodePoint(0x1e920).toLowerCase().codePointAt(0), 0x1e942);
assertEq(String.fromCodePoint(0x1e921).toLowerCase().codePointAt(0), 0x1e943);
assertEq(String.fromCodePoint(0x10428).toUpperCase().codePointAt(0), 0x10400); // DESERET SMALL LETTER LONG I, DESERET CAPITAL LETTER LONG I
assertEq(String.fromCodePoint(0x10429).toUpperCase().codePointAt(0), 0x10401); // DESERET SMALL LETTER LONG E, DESERET CAPITAL LETTER LONG E
assertEq(String.fromCodePoint(0x1042A).toUpperCase().codePointAt(0), 0x10402); // DESERET SMALL LETTER LONG A, DESERET CAPITAL LETTER LONG A
assertEq(String.fromCodePoint(0x1042B).toUpperCase().codePointAt(0), 0x10403); // DESERET SMALL LETTER LONG AH, DESERET CAPITAL LETTER LONG AH
assertEq(String.fromCodePoint(0x1042C).toUpperCase().codePointAt(0), 0x10404); // DESERET SMALL LETTER LONG O, DESERET CAPITAL LETTER LONG O
assertEq(String.fromCodePoint(0x1042D).toUpperCase().codePointAt(0), 0x10405); // DESERET SMALL LETTER LONG OO, DESERET CAPITAL LETTER LONG OO
assertEq(String.fromCodePoint(0x1042E).toUpperCase().codePointAt(0), 0x10406); // DESERET SMALL LETTER SHORT I, DESERET CAPITAL LETTER SHORT I
assertEq(String.fromCodePoint(0x1042F).toUpperCase().codePointAt(0), 0x10407); // DESERET SMALL LETTER SHORT E, DESERET CAPITAL LETTER SHORT E
assertEq(String.fromCodePoint(0x10430).toUpperCase().codePointAt(0), 0x10408); // DESERET SMALL LETTER SHORT A, DESERET CAPITAL LETTER SHORT A
assertEq(String.fromCodePoint(0x10431).toUpperCase().codePointAt(0), 0x10409); // DESERET SMALL LETTER SHORT AH, DESERET CAPITAL LETTER SHORT AH
assertEq(String.fromCodePoint(0x10432).toUpperCase().codePointAt(0), 0x1040A); // DESERET SMALL LETTER SHORT O, DESERET CAPITAL LETTER SHORT O
assertEq(String.fromCodePoint(0x10433).toUpperCase().codePointAt(0), 0x1040B); // DESERET SMALL LETTER SHORT OO, DESERET CAPITAL LETTER SHORT OO
assertEq(String.fromCodePoint(0x10434).toUpperCase().codePointAt(0), 0x1040C); // DESERET SMALL LETTER AY, DESERET CAPITAL LETTER AY
assertEq(String.fromCodePoint(0x10435).toUpperCase().codePointAt(0), 0x1040D); // DESERET SMALL LETTER OW, DESERET CAPITAL LETTER OW
assertEq(String.fromCodePoint(0x10436).toUpperCase().codePointAt(0), 0x1040E); // DESERET SMALL LETTER WU, DESERET CAPITAL LETTER WU
assertEq(String.fromCodePoint(0x10437).toUpperCase().codePointAt(0), 0x1040F); // DESERET SMALL LETTER YEE, DESERET CAPITAL LETTER YEE
assertEq(String.fromCodePoint(0x10438).toUpperCase().codePointAt(0), 0x10410); // DESERET SMALL LETTER H, DESERET CAPITAL LETTER H
assertEq(String.fromCodePoint(0x10439).toUpperCase().codePointAt(0), 0x10411); // DESERET SMALL LETTER PEE, DESERET CAPITAL LETTER PEE
assertEq(String.fromCodePoint(0x1043A).toUpperCase().codePointAt(0), 0x10412); // DESERET SMALL LETTER BEE, DESERET CAPITAL LETTER BEE
assertEq(String.fromCodePoint(0x1043B).toUpperCase().codePointAt(0), 0x10413); // DESERET SMALL LETTER TEE, DESERET CAPITAL LETTER TEE
assertEq(String.fromCodePoint(0x1043C).toUpperCase().codePointAt(0), 0x10414); // DESERET SMALL LETTER DEE, DESERET CAPITAL LETTER DEE
assertEq(String.fromCodePoint(0x1043D).toUpperCase().codePointAt(0), 0x10415); // DESERET SMALL LETTER CHEE, DESERET CAPITAL LETTER CHEE
assertEq(String.fromCodePoint(0x1043E).toUpperCase().codePointAt(0), 0x10416); // DESERET SMALL LETTER JEE, DESERET CAPITAL LETTER JEE
assertEq(String.fromCodePoint(0x1043F).toUpperCase().codePointAt(0), 0x10417); // DESERET SMALL LETTER KAY, DESERET CAPITAL LETTER KAY
assertEq(String.fromCodePoint(0x10440).toUpperCase().codePointAt(0), 0x10418); // DESERET SMALL LETTER GAY, DESERET CAPITAL LETTER GAY
assertEq(String.fromCodePoint(0x10441).toUpperCase().codePointAt(0), 0x10419); // DESERET SMALL LETTER EF, DESERET CAPITAL LETTER EF
assertEq(String.fromCodePoint(0x10442).toUpperCase().codePointAt(0), 0x1041A); // DESERET SMALL LETTER VEE, DESERET CAPITAL LETTER VEE
assertEq(String.fromCodePoint(0x10443).toUpperCase().codePointAt(0), 0x1041B); // DESERET SMALL LETTER ETH, DESERET CAPITAL LETTER ETH
assertEq(String.fromCodePoint(0x10444).toUpperCase().codePointAt(0), 0x1041C); // DESERET SMALL LETTER THEE, DESERET CAPITAL LETTER THEE
assertEq(String.fromCodePoint(0x10445).toUpperCase().codePointAt(0), 0x1041D); // DESERET SMALL LETTER ES, DESERET CAPITAL LETTER ES
assertEq(String.fromCodePoint(0x10446).toUpperCase().codePointAt(0), 0x1041E); // DESERET SMALL LETTER ZEE, DESERET CAPITAL LETTER ZEE
assertEq(String.fromCodePoint(0x10447).toUpperCase().codePointAt(0), 0x1041F); // DESERET SMALL LETTER ESH, DESERET CAPITAL LETTER ESH
assertEq(String.fromCodePoint(0x10448).toUpperCase().codePointAt(0), 0x10420); // DESERET SMALL LETTER ZHEE, DESERET CAPITAL LETTER ZHEE
assertEq(String.fromCodePoint(0x10449).toUpperCase().codePointAt(0), 0x10421); // DESERET SMALL LETTER ER, DESERET CAPITAL LETTER ER
assertEq(String.fromCodePoint(0x1044A).toUpperCase().codePointAt(0), 0x10422); // DESERET SMALL LETTER EL, DESERET CAPITAL LETTER EL
assertEq(String.fromCodePoint(0x1044B).toUpperCase().codePointAt(0), 0x10423); // DESERET SMALL LETTER EM, DESERET CAPITAL LETTER EM
assertEq(String.fromCodePoint(0x1044C).toUpperCase().codePointAt(0), 0x10424); // DESERET SMALL LETTER EN, DESERET CAPITAL LETTER EN
assertEq(String.fromCodePoint(0x1044D).toUpperCase().codePointAt(0), 0x10425); // DESERET SMALL LETTER ENG, DESERET CAPITAL LETTER ENG
assertEq(String.fromCodePoint(0x1044E).toUpperCase().codePointAt(0), 0x10426); // DESERET SMALL LETTER OI, DESERET CAPITAL LETTER OI
assertEq(String.fromCodePoint(0x1044F).toUpperCase().codePointAt(0), 0x10427); // DESERET SMALL LETTER EW, DESERET CAPITAL LETTER EW
assertEq(String.fromCodePoint(0x104D8).toUpperCase().codePointAt(0), 0x104B0); // OSAGE SMALL LETTER A, OSAGE CAPITAL LETTER A
assertEq(String.fromCodePoint(0x104D9).toUpperCase().codePointAt(0), 0x104B1); // OSAGE SMALL LETTER AI, OSAGE CAPITAL LETTER AI
assertEq(String.fromCodePoint(0x104DA).toUpperCase().codePointAt(0), 0x104B2); // OSAGE SMALL LETTER AIN, OSAGE CAPITAL LETTER AIN
assertEq(String.fromCodePoint(0x104DB).toUpperCase().codePointAt(0), 0x104B3); // OSAGE SMALL LETTER AH, OSAGE CAPITAL LETTER AH
assertEq(String.fromCodePoint(0x104DC).toUpperCase().codePointAt(0), 0x104B4); // OSAGE SMALL LETTER BRA, OSAGE CAPITAL LETTER BRA
assertEq(String.fromCodePoint(0x104DD).toUpperCase().codePointAt(0), 0x104B5); // OSAGE SMALL LETTER CHA, OSAGE CAPITAL LETTER CHA
assertEq(String.fromCodePoint(0x104DE).toUpperCase().codePointAt(0), 0x104B6); // OSAGE SMALL LETTER EHCHA, OSAGE CAPITAL LETTER EHCHA
assertEq(String.fromCodePoint(0x104DF).toUpperCase().codePointAt(0), 0x104B7); // OSAGE SMALL LETTER E, OSAGE CAPITAL LETTER E
assertEq(String.fromCodePoint(0x104E0).toUpperCase().codePointAt(0), 0x104B8); // OSAGE SMALL LETTER EIN, OSAGE CAPITAL LETTER EIN
assertEq(String.fromCodePoint(0x104E1).toUpperCase().codePointAt(0), 0x104B9); // OSAGE SMALL LETTER HA, OSAGE CAPITAL LETTER HA
assertEq(String.fromCodePoint(0x104E2).toUpperCase().codePointAt(0), 0x104BA); // OSAGE SMALL LETTER HYA, OSAGE CAPITAL LETTER HYA
assertEq(String.fromCodePoint(0x104E3).toUpperCase().codePointAt(0), 0x104BB); // OSAGE SMALL LETTER I, OSAGE CAPITAL LETTER I
assertEq(String.fromCodePoint(0x104E4).toUpperCase().codePointAt(0), 0x104BC); // OSAGE SMALL LETTER KA, OSAGE CAPITAL LETTER KA
assertEq(String.fromCodePoint(0x104E5).toUpperCase().codePointAt(0), 0x104BD); // OSAGE SMALL LETTER EHKA, OSAGE CAPITAL LETTER EHKA
assertEq(String.fromCodePoint(0x104E6).toUpperCase().codePointAt(0), 0x104BE); // OSAGE SMALL LETTER KYA, OSAGE CAPITAL LETTER KYA
assertEq(String.fromCodePoint(0x104E7).toUpperCase().codePointAt(0), 0x104BF); // OSAGE SMALL LETTER LA, OSAGE CAPITAL LETTER LA
assertEq(String.fromCodePoint(0x104E8).toUpperCase().codePointAt(0), 0x104C0); // OSAGE SMALL LETTER MA, OSAGE CAPITAL LETTER MA
assertEq(String.fromCodePoint(0x104E9).toUpperCase().codePointAt(0), 0x104C1); // OSAGE SMALL LETTER NA, OSAGE CAPITAL LETTER NA
assertEq(String.fromCodePoint(0x104EA).toUpperCase().codePointAt(0), 0x104C2); // OSAGE SMALL LETTER O, OSAGE CAPITAL LETTER O
assertEq(String.fromCodePoint(0x104EB).toUpperCase().codePointAt(0), 0x104C3); // OSAGE SMALL LETTER OIN, OSAGE CAPITAL LETTER OIN
assertEq(String.fromCodePoint(0x104EC).toUpperCase().codePointAt(0), 0x104C4); // OSAGE SMALL LETTER PA, OSAGE CAPITAL LETTER PA
assertEq(String.fromCodePoint(0x104ED).toUpperCase().codePointAt(0), 0x104C5); // OSAGE SMALL LETTER EHPA, OSAGE CAPITAL LETTER EHPA
assertEq(String.fromCodePoint(0x104EE).toUpperCase().codePointAt(0), 0x104C6); // OSAGE SMALL LETTER SA, OSAGE CAPITAL LETTER SA
assertEq(String.fromCodePoint(0x104EF).toUpperCase().codePointAt(0), 0x104C7); // OSAGE SMALL LETTER SHA, OSAGE CAPITAL LETTER SHA
assertEq(String.fromCodePoint(0x104F0).toUpperCase().codePointAt(0), 0x104C8); // OSAGE SMALL LETTER TA, OSAGE CAPITAL LETTER TA
assertEq(String.fromCodePoint(0x104F1).toUpperCase().codePointAt(0), 0x104C9); // OSAGE SMALL LETTER EHTA, OSAGE CAPITAL LETTER EHTA
assertEq(String.fromCodePoint(0x104F2).toUpperCase().codePointAt(0), 0x104CA); // OSAGE SMALL LETTER TSA, OSAGE CAPITAL LETTER TSA
assertEq(String.fromCodePoint(0x104F3).toUpperCase().codePointAt(0), 0x104CB); // OSAGE SMALL LETTER EHTSA, OSAGE CAPITAL LETTER EHTSA
assertEq(String.fromCodePoint(0x104F4).toUpperCase().codePointAt(0), 0x104CC); // OSAGE SMALL LETTER TSHA, OSAGE CAPITAL LETTER TSHA
assertEq(String.fromCodePoint(0x104F5).toUpperCase().codePointAt(0), 0x104CD); // OSAGE SMALL LETTER DHA, OSAGE CAPITAL LETTER DHA
assertEq(String.fromCodePoint(0x104F6).toUpperCase().codePointAt(0), 0x104CE); // OSAGE SMALL LETTER U, OSAGE CAPITAL LETTER U
assertEq(String.fromCodePoint(0x104F7).toUpperCase().codePointAt(0), 0x104CF); // OSAGE SMALL LETTER WA, OSAGE CAPITAL LETTER WA
assertEq(String.fromCodePoint(0x104F8).toUpperCase().codePointAt(0), 0x104D0); // OSAGE SMALL LETTER KHA, OSAGE CAPITAL LETTER KHA
assertEq(String.fromCodePoint(0x104F9).toUpperCase().codePointAt(0), 0x104D1); // OSAGE SMALL LETTER GHA, OSAGE CAPITAL LETTER GHA
assertEq(String.fromCodePoint(0x104FA).toUpperCase().codePointAt(0), 0x104D2); // OSAGE SMALL LETTER ZA, OSAGE CAPITAL LETTER ZA
assertEq(String.fromCodePoint(0x104FB).toUpperCase().codePointAt(0), 0x104D3); // OSAGE SMALL LETTER ZHA, OSAGE CAPITAL LETTER ZHA
assertEq(String.fromCodePoint(0x10CC0).toUpperCase().codePointAt(0), 0x10C80); // OLD HUNGARIAN SMALL LETTER A, OLD HUNGARIAN CAPITAL LETTER A
assertEq(String.fromCodePoint(0x10CC1).toUpperCase().codePointAt(0), 0x10C81); // OLD HUNGARIAN SMALL LETTER AA, OLD HUNGARIAN CAPITAL LETTER AA
assertEq(String.fromCodePoint(0x10CC2).toUpperCase().codePointAt(0), 0x10C82); // OLD HUNGARIAN SMALL LETTER EB, OLD HUNGARIAN CAPITAL LETTER EB
assertEq(String.fromCodePoint(0x10CC3).toUpperCase().codePointAt(0), 0x10C83); // OLD HUNGARIAN SMALL LETTER AMB, OLD HUNGARIAN CAPITAL LETTER AMB
assertEq(String.fromCodePoint(0x10CC4).toUpperCase().codePointAt(0), 0x10C84); // OLD HUNGARIAN SMALL LETTER EC, OLD HUNGARIAN CAPITAL LETTER EC
assertEq(String.fromCodePoint(0x10CC5).toUpperCase().codePointAt(0), 0x10C85); // OLD HUNGARIAN SMALL LETTER ENC, OLD HUNGARIAN CAPITAL LETTER ENC
assertEq(String.fromCodePoint(0x10CC6).toUpperCase().codePointAt(0), 0x10C86); // OLD HUNGARIAN SMALL LETTER ECS, OLD HUNGARIAN CAPITAL LETTER ECS
assertEq(String.fromCodePoint(0x10CC7).toUpperCase().codePointAt(0), 0x10C87); // OLD HUNGARIAN SMALL LETTER ED, OLD HUNGARIAN CAPITAL LETTER ED
assertEq(String.fromCodePoint(0x10CC8).toUpperCase().codePointAt(0), 0x10C88); // OLD HUNGARIAN SMALL LETTER AND, OLD HUNGARIAN CAPITAL LETTER AND
assertEq(String.fromCodePoint(0x10CC9).toUpperCase().codePointAt(0), 0x10C89); // OLD HUNGARIAN SMALL LETTER E, OLD HUNGARIAN CAPITAL LETTER E
assertEq(String.fromCodePoint(0x10CCA).toUpperCase().codePointAt(0), 0x10C8A); // OLD HUNGARIAN SMALL LETTER CLOSE E, OLD HUNGARIAN CAPITAL LETTER CLOSE E
assertEq(String.fromCodePoint(0x10CCB).toUpperCase().codePointAt(0), 0x10C8B); // OLD HUNGARIAN SMALL LETTER EE, OLD HUNGARIAN CAPITAL LETTER EE
assertEq(String.fromCodePoint(0x10CCC).toUpperCase().codePointAt(0), 0x10C8C); // OLD HUNGARIAN SMALL LETTER EF, OLD HUNGARIAN CAPITAL LETTER EF
assertEq(String.fromCodePoint(0x10CCD).toUpperCase().codePointAt(0), 0x10C8D); // OLD HUNGARIAN SMALL LETTER EG, OLD HUNGARIAN CAPITAL LETTER EG
assertEq(String.fromCodePoint(0x10CCE).toUpperCase().codePointAt(0), 0x10C8E); // OLD HUNGARIAN SMALL LETTER EGY, OLD HUNGARIAN CAPITAL LETTER EGY
assertEq(String.fromCodePoint(0x10CCF).toUpperCase().codePointAt(0), 0x10C8F); // OLD HUNGARIAN SMALL LETTER EH, OLD HUNGARIAN CAPITAL LETTER EH
assertEq(String.fromCodePoint(0x10CD0).toUpperCase().codePointAt(0), 0x10C90); // OLD HUNGARIAN SMALL LETTER I, OLD HUNGARIAN CAPITAL LETTER I
assertEq(String.fromCodePoint(0x10CD1).toUpperCase().codePointAt(0), 0x10C91); // OLD HUNGARIAN SMALL LETTER II, OLD HUNGARIAN CAPITAL LETTER II
assertEq(String.fromCodePoint(0x10CD2).toUpperCase().codePointAt(0), 0x10C92); // OLD HUNGARIAN SMALL LETTER EJ, OLD HUNGARIAN CAPITAL LETTER EJ
assertEq(String.fromCodePoint(0x10CD3).toUpperCase().codePointAt(0), 0x10C93); // OLD HUNGARIAN SMALL LETTER EK, OLD HUNGARIAN CAPITAL LETTER EK
assertEq(String.fromCodePoint(0x10CD4).toUpperCase().codePointAt(0), 0x10C94); // OLD HUNGARIAN SMALL LETTER AK, OLD HUNGARIAN CAPITAL LETTER AK
assertEq(String.fromCodePoint(0x10CD5).toUpperCase().codePointAt(0), 0x10C95); // OLD HUNGARIAN SMALL LETTER UNK, OLD HUNGARIAN CAPITAL LETTER UNK
assertEq(String.fromCodePoint(0x10CD6).toUpperCase().codePointAt(0), 0x10C96); // OLD HUNGARIAN SMALL LETTER EL, OLD HUNGARIAN CAPITAL LETTER EL
assertEq(String.fromCodePoint(0x10CD7).toUpperCase().codePointAt(0), 0x10C97); // OLD HUNGARIAN SMALL LETTER ELY, OLD HUNGARIAN CAPITAL LETTER ELY
assertEq(String.fromCodePoint(0x10CD8).toUpperCase().codePointAt(0), 0x10C98); // OLD HUNGARIAN SMALL LETTER EM, OLD HUNGARIAN CAPITAL LETTER EM
assertEq(String.fromCodePoint(0x10CD9).toUpperCase().codePointAt(0), 0x10C99); // OLD HUNGARIAN SMALL LETTER EN, OLD HUNGARIAN CAPITAL LETTER EN
assertEq(String.fromCodePoint(0x10CDA).toUpperCase().codePointAt(0), 0x10C9A); // OLD HUNGARIAN SMALL LETTER ENY, OLD HUNGARIAN CAPITAL LETTER ENY
assertEq(String.fromCodePoint(0x10CDB).toUpperCase().codePointAt(0), 0x10C9B); // OLD HUNGARIAN SMALL LETTER O, OLD HUNGARIAN CAPITAL LETTER O
assertEq(String.fromCodePoint(0x10CDC).toUpperCase().codePointAt(0), 0x10C9C); // OLD HUNGARIAN SMALL LETTER OO, OLD HUNGARIAN CAPITAL LETTER OO
assertEq(String.fromCodePoint(0x10CDD).toUpperCase().codePointAt(0), 0x10C9D); // OLD HUNGARIAN SMALL LETTER NIKOLSBURG OE, OLD HUNGARIAN CAPITAL LETTER NIKOLSBURG OE
assertEq(String.fromCodePoint(0x10CDE).toUpperCase().codePointAt(0), 0x10C9E); // OLD HUNGARIAN SMALL LETTER RUDIMENTA OE, OLD HUNGARIAN CAPITAL LETTER RUDIMENTA OE
assertEq(String.fromCodePoint(0x10CDF).toUpperCase().codePointAt(0), 0x10C9F); // OLD HUNGARIAN SMALL LETTER OEE, OLD HUNGARIAN CAPITAL LETTER OEE
assertEq(String.fromCodePoint(0x10CE0).toUpperCase().codePointAt(0), 0x10CA0); // OLD HUNGARIAN SMALL LETTER EP, OLD HUNGARIAN CAPITAL LETTER EP
assertEq(String.fromCodePoint(0x10CE1).toUpperCase().codePointAt(0), 0x10CA1); // OLD HUNGARIAN SMALL LETTER EMP, OLD HUNGARIAN CAPITAL LETTER EMP
assertEq(String.fromCodePoint(0x10CE2).toUpperCase().codePointAt(0), 0x10CA2); // OLD HUNGARIAN SMALL LETTER ER, OLD HUNGARIAN CAPITAL LETTER ER
assertEq(String.fromCodePoint(0x10CE3).toUpperCase().codePointAt(0), 0x10CA3); // OLD HUNGARIAN SMALL LETTER SHORT ER, OLD HUNGARIAN CAPITAL LETTER SHORT ER
assertEq(String.fromCodePoint(0x10CE4).toUpperCase().codePointAt(0), 0x10CA4); // OLD HUNGARIAN SMALL LETTER ES, OLD HUNGARIAN CAPITAL LETTER ES
assertEq(String.fromCodePoint(0x10CE5).toUpperCase().codePointAt(0), 0x10CA5); // OLD HUNGARIAN SMALL LETTER ESZ, OLD HUNGARIAN CAPITAL LETTER ESZ
assertEq(String.fromCodePoint(0x10CE6).toUpperCase().codePointAt(0), 0x10CA6); // OLD HUNGARIAN SMALL LETTER ET, OLD HUNGARIAN CAPITAL LETTER ET
assertEq(String.fromCodePoint(0x10CE7).toUpperCase().codePointAt(0), 0x10CA7); // OLD HUNGARIAN SMALL LETTER ENT, OLD HUNGARIAN CAPITAL LETTER ENT
assertEq(String.fromCodePoint(0x10CE8).toUpperCase().codePointAt(0), 0x10CA8); // OLD HUNGARIAN SMALL LETTER ETY, OLD HUNGARIAN CAPITAL LETTER ETY
assertEq(String.fromCodePoint(0x10CE9).toUpperCase().codePointAt(0), 0x10CA9); // OLD HUNGARIAN SMALL LETTER ECH, OLD HUNGARIAN CAPITAL LETTER ECH
assertEq(String.fromCodePoint(0x10CEA).toUpperCase().codePointAt(0), 0x10CAA); // OLD HUNGARIAN SMALL LETTER U, OLD HUNGARIAN CAPITAL LETTER U
assertEq(String.fromCodePoint(0x10CEB).toUpperCase().codePointAt(0), 0x10CAB); // OLD HUNGARIAN SMALL LETTER UU, OLD HUNGARIAN CAPITAL LETTER UU
assertEq(String.fromCodePoint(0x10CEC).toUpperCase().codePointAt(0), 0x10CAC); // OLD HUNGARIAN SMALL LETTER NIKOLSBURG UE, OLD HUNGARIAN CAPITAL LETTER NIKOLSBURG UE
assertEq(String.fromCodePoint(0x10CED).toUpperCase().codePointAt(0), 0x10CAD); // OLD HUNGARIAN SMALL LETTER RUDIMENTA UE, OLD HUNGARIAN CAPITAL LETTER RUDIMENTA UE
assertEq(String.fromCodePoint(0x10CEE).toUpperCase().codePointAt(0), 0x10CAE); // OLD HUNGARIAN SMALL LETTER EV, OLD HUNGARIAN CAPITAL LETTER EV
assertEq(String.fromCodePoint(0x10CEF).toUpperCase().codePointAt(0), 0x10CAF); // OLD HUNGARIAN SMALL LETTER EZ, OLD HUNGARIAN CAPITAL LETTER EZ
assertEq(String.fromCodePoint(0x10CF0).toUpperCase().codePointAt(0), 0x10CB0); // OLD HUNGARIAN SMALL LETTER EZS, OLD HUNGARIAN CAPITAL LETTER EZS
assertEq(String.fromCodePoint(0x10CF1).toUpperCase().codePointAt(0), 0x10CB1); // OLD HUNGARIAN SMALL LETTER ENT-SHAPED SIGN, OLD HUNGARIAN CAPITAL LETTER ENT-SHAPED SIGN
assertEq(String.fromCodePoint(0x10CF2).toUpperCase().codePointAt(0), 0x10CB2); // OLD HUNGARIAN SMALL LETTER US, OLD HUNGARIAN CAPITAL LETTER US
assertEq(String.fromCodePoint(0x118C0).toUpperCase().codePointAt(0), 0x118A0); // WARANG CITI SMALL LETTER NGAA, WARANG CITI CAPITAL LETTER NGAA
assertEq(String.fromCodePoint(0x118C1).toUpperCase().codePointAt(0), 0x118A1); // WARANG CITI SMALL LETTER A, WARANG CITI CAPITAL LETTER A
assertEq(String.fromCodePoint(0x118C2).toUpperCase().codePointAt(0), 0x118A2); // WARANG CITI SMALL LETTER WI, WARANG CITI CAPITAL LETTER WI
assertEq(String.fromCodePoint(0x118C3).toUpperCase().codePointAt(0), 0x118A3); // WARANG CITI SMALL LETTER YU, WARANG CITI CAPITAL LETTER YU
assertEq(String.fromCodePoint(0x118C4).toUpperCase().codePointAt(0), 0x118A4); // WARANG CITI SMALL LETTER YA, WARANG CITI CAPITAL LETTER YA
assertEq(String.fromCodePoint(0x118C5).toUpperCase().codePointAt(0), 0x118A5); // WARANG CITI SMALL LETTER YO, WARANG CITI CAPITAL LETTER YO
assertEq(String.fromCodePoint(0x118C6).toUpperCase().codePointAt(0), 0x118A6); // WARANG CITI SMALL LETTER II, WARANG CITI CAPITAL LETTER II
assertEq(String.fromCodePoint(0x118C7).toUpperCase().codePointAt(0), 0x118A7); // WARANG CITI SMALL LETTER UU, WARANG CITI CAPITAL LETTER UU
assertEq(String.fromCodePoint(0x118C8).toUpperCase().codePointAt(0), 0x118A8); // WARANG CITI SMALL LETTER E, WARANG CITI CAPITAL LETTER E
assertEq(String.fromCodePoint(0x118C9).toUpperCase().codePointAt(0), 0x118A9); // WARANG CITI SMALL LETTER O, WARANG CITI CAPITAL LETTER O
assertEq(String.fromCodePoint(0x118CA).toUpperCase().codePointAt(0), 0x118AA); // WARANG CITI SMALL LETTER ANG, WARANG CITI CAPITAL LETTER ANG
assertEq(String.fromCodePoint(0x118CB).toUpperCase().codePointAt(0), 0x118AB); // WARANG CITI SMALL LETTER GA, WARANG CITI CAPITAL LETTER GA
assertEq(String.fromCodePoint(0x118CC).toUpperCase().codePointAt(0), 0x118AC); // WARANG CITI SMALL LETTER KO, WARANG CITI CAPITAL LETTER KO
assertEq(String.fromCodePoint(0x118CD).toUpperCase().codePointAt(0), 0x118AD); // WARANG CITI SMALL LETTER ENY, WARANG CITI CAPITAL LETTER ENY
assertEq(String.fromCodePoint(0x118CE).toUpperCase().codePointAt(0), 0x118AE); // WARANG CITI SMALL LETTER YUJ, WARANG CITI CAPITAL LETTER YUJ
assertEq(String.fromCodePoint(0x118CF).toUpperCase().codePointAt(0), 0x118AF); // WARANG CITI SMALL LETTER UC, WARANG CITI CAPITAL LETTER UC
assertEq(String.fromCodePoint(0x118D0).toUpperCase().codePointAt(0), 0x118B0); // WARANG CITI SMALL LETTER ENN, WARANG CITI CAPITAL LETTER ENN
assertEq(String.fromCodePoint(0x118D1).toUpperCase().codePointAt(0), 0x118B1); // WARANG CITI SMALL LETTER ODD, WARANG CITI CAPITAL LETTER ODD
assertEq(String.fromCodePoint(0x118D2).toUpperCase().codePointAt(0), 0x118B2); // WARANG CITI SMALL LETTER TTE, WARANG CITI CAPITAL LETTER TTE
assertEq(String.fromCodePoint(0x118D3).toUpperCase().codePointAt(0), 0x118B3); // WARANG CITI SMALL LETTER NUNG, WARANG CITI CAPITAL LETTER NUNG
assertEq(String.fromCodePoint(0x118D4).toUpperCase().codePointAt(0), 0x118B4); // WARANG CITI SMALL LETTER DA, WARANG CITI CAPITAL LETTER DA
assertEq(String.fromCodePoint(0x118D5).toUpperCase().codePointAt(0), 0x118B5); // WARANG CITI SMALL LETTER AT, WARANG CITI CAPITAL LETTER AT
assertEq(String.fromCodePoint(0x118D6).toUpperCase().codePointAt(0), 0x118B6); // WARANG CITI SMALL LETTER AM, WARANG CITI CAPITAL LETTER AM
assertEq(String.fromCodePoint(0x118D7).toUpperCase().codePointAt(0), 0x118B7); // WARANG CITI SMALL LETTER BU, WARANG CITI CAPITAL LETTER BU
assertEq(String.fromCodePoint(0x118D8).toUpperCase().codePointAt(0), 0x118B8); // WARANG CITI SMALL LETTER PU, WARANG CITI CAPITAL LETTER PU
assertEq(String.fromCodePoint(0x118D9).toUpperCase().codePointAt(0), 0x118B9); // WARANG CITI SMALL LETTER HIYO, WARANG CITI CAPITAL LETTER HIYO
assertEq(String.fromCodePoint(0x118DA).toUpperCase().codePointAt(0), 0x118BA); // WARANG CITI SMALL LETTER HOLO, WARANG CITI CAPITAL LETTER HOLO
assertEq(String.fromCodePoint(0x118DB).toUpperCase().codePointAt(0), 0x118BB); // WARANG CITI SMALL LETTER HORR, WARANG CITI CAPITAL LETTER HORR
assertEq(String.fromCodePoint(0x118DC).toUpperCase().codePointAt(0), 0x118BC); // WARANG CITI SMALL LETTER HAR, WARANG CITI CAPITAL LETTER HAR
assertEq(String.fromCodePoint(0x118DD).toUpperCase().codePointAt(0), 0x118BD); // WARANG CITI SMALL LETTER SSUU, WARANG CITI CAPITAL LETTER SSUU
assertEq(String.fromCodePoint(0x118DE).toUpperCase().codePointAt(0), 0x118BE); // WARANG CITI SMALL LETTER SII, WARANG CITI CAPITAL LETTER SII
assertEq(String.fromCodePoint(0x118DF).toUpperCase().codePointAt(0), 0x118BF); // WARANG CITI SMALL LETTER VIYO, WARANG CITI CAPITAL LETTER VIYO
assertEq(String.fromCodePoint(0x1E922).toUpperCase().codePointAt(0), 0x1E900); // ADLAM SMALL LETTER ALIF, ADLAM CAPITAL LETTER ALIF
assertEq(String.fromCodePoint(0x1E923).toUpperCase().codePointAt(0), 0x1E901); // ADLAM SMALL LETTER DAALI, ADLAM CAPITAL LETTER DAALI
assertEq(String.fromCodePoint(0x1E924).toUpperCase().codePointAt(0), 0x1E902); // ADLAM SMALL LETTER LAAM, ADLAM CAPITAL LETTER LAAM
assertEq(String.fromCodePoint(0x1E925).toUpperCase().codePointAt(0), 0x1E903); // ADLAM SMALL LETTER MIIM, ADLAM CAPITAL LETTER MIIM
assertEq(String.fromCodePoint(0x1E926).toUpperCase().codePointAt(0), 0x1E904); // ADLAM SMALL LETTER BA, ADLAM CAPITAL LETTER BA
assertEq(String.fromCodePoint(0x1E927).toUpperCase().codePointAt(0), 0x1E905); // ADLAM SMALL LETTER SINNYIIYHE, ADLAM CAPITAL LETTER SINNYIIYHE
assertEq(String.fromCodePoint(0x1E928).toUpperCase().codePointAt(0), 0x1E906); // ADLAM SMALL LETTER PE, ADLAM CAPITAL LETTER PE
assertEq(String.fromCodePoint(0x1E929).toUpperCase().codePointAt(0), 0x1E907); // ADLAM SMALL LETTER BHE, ADLAM CAPITAL LETTER BHE
assertEq(String.fromCodePoint(0x1E92A).toUpperCase().codePointAt(0), 0x1E908); // ADLAM SMALL LETTER RA, ADLAM CAPITAL LETTER RA
assertEq(String.fromCodePoint(0x1E92B).toUpperCase().codePointAt(0), 0x1E909); // ADLAM SMALL LETTER E, ADLAM CAPITAL LETTER E
assertEq(String.fromCodePoint(0x1E92C).toUpperCase().codePointAt(0), 0x1E90A); // ADLAM SMALL LETTER FA, ADLAM CAPITAL LETTER FA
assertEq(String.fromCodePoint(0x1E92D).toUpperCase().codePointAt(0), 0x1E90B); // ADLAM SMALL LETTER I, ADLAM CAPITAL LETTER I
assertEq(String.fromCodePoint(0x1E92E).toUpperCase().codePointAt(0), 0x1E90C); // ADLAM SMALL LETTER O, ADLAM CAPITAL LETTER O
assertEq(String.fromCodePoint(0x1E92F).toUpperCase().codePointAt(0), 0x1E90D); // ADLAM SMALL LETTER DHA, ADLAM CAPITAL LETTER DHA
assertEq(String.fromCodePoint(0x1E930).toUpperCase().codePointAt(0), 0x1E90E); // ADLAM SMALL LETTER YHE, ADLAM CAPITAL LETTER YHE
assertEq(String.fromCodePoint(0x1E931).toUpperCase().codePointAt(0), 0x1E90F); // ADLAM SMALL LETTER WAW, ADLAM CAPITAL LETTER WAW
assertEq(String.fromCodePoint(0x1E932).toUpperCase().codePointAt(0), 0x1E910); // ADLAM SMALL LETTER NUN, ADLAM CAPITAL LETTER NUN
assertEq(String.fromCodePoint(0x1E933).toUpperCase().codePointAt(0), 0x1E911); // ADLAM SMALL LETTER KAF, ADLAM CAPITAL LETTER KAF
assertEq(String.fromCodePoint(0x1E934).toUpperCase().codePointAt(0), 0x1E912); // ADLAM SMALL LETTER YA, ADLAM CAPITAL LETTER YA
assertEq(String.fromCodePoint(0x1E935).toUpperCase().codePointAt(0), 0x1E913); // ADLAM SMALL LETTER U, ADLAM CAPITAL LETTER U
assertEq(String.fromCodePoint(0x1E936).toUpperCase().codePointAt(0), 0x1E914); // ADLAM SMALL LETTER JIIM, ADLAM CAPITAL LETTER JIIM
assertEq(String.fromCodePoint(0x1E937).toUpperCase().codePointAt(0), 0x1E915); // ADLAM SMALL LETTER CHI, ADLAM CAPITAL LETTER CHI
assertEq(String.fromCodePoint(0x1E938).toUpperCase().codePointAt(0), 0x1E916); // ADLAM SMALL LETTER HA, ADLAM CAPITAL LETTER HA
assertEq(String.fromCodePoint(0x1E939).toUpperCase().codePointAt(0), 0x1E917); // ADLAM SMALL LETTER QAAF, ADLAM CAPITAL LETTER QAAF
assertEq(String.fromCodePoint(0x1E93A).toUpperCase().codePointAt(0), 0x1E918); // ADLAM SMALL LETTER GA, ADLAM CAPITAL LETTER GA
assertEq(String.fromCodePoint(0x1E93B).toUpperCase().codePointAt(0), 0x1E919); // ADLAM SMALL LETTER NYA, ADLAM CAPITAL LETTER NYA
assertEq(String.fromCodePoint(0x1E93C).toUpperCase().codePointAt(0), 0x1E91A); // ADLAM SMALL LETTER TU, ADLAM CAPITAL LETTER TU
assertEq(String.fromCodePoint(0x1E93D).toUpperCase().codePointAt(0), 0x1E91B); // ADLAM SMALL LETTER NHA, ADLAM CAPITAL LETTER NHA
assertEq(String.fromCodePoint(0x1E93E).toUpperCase().codePointAt(0), 0x1E91C); // ADLAM SMALL LETTER VA, ADLAM CAPITAL LETTER VA
assertEq(String.fromCodePoint(0x1E93F).toUpperCase().codePointAt(0), 0x1E91D); // ADLAM SMALL LETTER KHA, ADLAM CAPITAL LETTER KHA
assertEq(String.fromCodePoint(0x1E940).toUpperCase().codePointAt(0), 0x1E91E); // ADLAM SMALL LETTER GBE, ADLAM CAPITAL LETTER GBE
assertEq(String.fromCodePoint(0x1E941).toUpperCase().codePointAt(0), 0x1E91F); // ADLAM SMALL LETTER ZAL, ADLAM CAPITAL LETTER ZAL
assertEq(String.fromCodePoint(0x1E942).toUpperCase().codePointAt(0), 0x1E920); // ADLAM SMALL LETTER KPO, ADLAM CAPITAL LETTER KPO
assertEq(String.fromCodePoint(0x1E943).toUpperCase().codePointAt(0), 0x1E921); // ADLAM SMALL LETTER SHA, ADLAM CAPITAL LETTER SHA
assertEq(String.fromCodePoint(0x10400).toLowerCase().codePointAt(0), 0x10428); // DESERET CAPITAL LETTER LONG I, DESERET SMALL LETTER LONG I
assertEq(String.fromCodePoint(0x10401).toLowerCase().codePointAt(0), 0x10429); // DESERET CAPITAL LETTER LONG E, DESERET SMALL LETTER LONG E
assertEq(String.fromCodePoint(0x10402).toLowerCase().codePointAt(0), 0x1042A); // DESERET CAPITAL LETTER LONG A, DESERET SMALL LETTER LONG A
assertEq(String.fromCodePoint(0x10403).toLowerCase().codePointAt(0), 0x1042B); // DESERET CAPITAL LETTER LONG AH, DESERET SMALL LETTER LONG AH
assertEq(String.fromCodePoint(0x10404).toLowerCase().codePointAt(0), 0x1042C); // DESERET CAPITAL LETTER LONG O, DESERET SMALL LETTER LONG O
assertEq(String.fromCodePoint(0x10405).toLowerCase().codePointAt(0), 0x1042D); // DESERET CAPITAL LETTER LONG OO, DESERET SMALL LETTER LONG OO
assertEq(String.fromCodePoint(0x10406).toLowerCase().codePointAt(0), 0x1042E); // DESERET CAPITAL LETTER SHORT I, DESERET SMALL LETTER SHORT I
assertEq(String.fromCodePoint(0x10407).toLowerCase().codePointAt(0), 0x1042F); // DESERET CAPITAL LETTER SHORT E, DESERET SMALL LETTER SHORT E
assertEq(String.fromCodePoint(0x10408).toLowerCase().codePointAt(0), 0x10430); // DESERET CAPITAL LETTER SHORT A, DESERET SMALL LETTER SHORT A
assertEq(String.fromCodePoint(0x10409).toLowerCase().codePointAt(0), 0x10431); // DESERET CAPITAL LETTER SHORT AH, DESERET SMALL LETTER SHORT AH
assertEq(String.fromCodePoint(0x1040A).toLowerCase().codePointAt(0), 0x10432); // DESERET CAPITAL LETTER SHORT O, DESERET SMALL LETTER SHORT O
assertEq(String.fromCodePoint(0x1040B).toLowerCase().codePointAt(0), 0x10433); // DESERET CAPITAL LETTER SHORT OO, DESERET SMALL LETTER SHORT OO
assertEq(String.fromCodePoint(0x1040C).toLowerCase().codePointAt(0), 0x10434); // DESERET CAPITAL LETTER AY, DESERET SMALL LETTER AY
assertEq(String.fromCodePoint(0x1040D).toLowerCase().codePointAt(0), 0x10435); // DESERET CAPITAL LETTER OW, DESERET SMALL LETTER OW
assertEq(String.fromCodePoint(0x1040E).toLowerCase().codePointAt(0), 0x10436); // DESERET CAPITAL LETTER WU, DESERET SMALL LETTER WU
assertEq(String.fromCodePoint(0x1040F).toLowerCase().codePointAt(0), 0x10437); // DESERET CAPITAL LETTER YEE, DESERET SMALL LETTER YEE
assertEq(String.fromCodePoint(0x10410).toLowerCase().codePointAt(0), 0x10438); // DESERET CAPITAL LETTER H, DESERET SMALL LETTER H
assertEq(String.fromCodePoint(0x10411).toLowerCase().codePointAt(0), 0x10439); // DESERET CAPITAL LETTER PEE, DESERET SMALL LETTER PEE
assertEq(String.fromCodePoint(0x10412).toLowerCase().codePointAt(0), 0x1043A); // DESERET CAPITAL LETTER BEE, DESERET SMALL LETTER BEE
assertEq(String.fromCodePoint(0x10413).toLowerCase().codePointAt(0), 0x1043B); // DESERET CAPITAL LETTER TEE, DESERET SMALL LETTER TEE
assertEq(String.fromCodePoint(0x10414).toLowerCase().codePointAt(0), 0x1043C); // DESERET CAPITAL LETTER DEE, DESERET SMALL LETTER DEE
assertEq(String.fromCodePoint(0x10415).toLowerCase().codePointAt(0), 0x1043D); // DESERET CAPITAL LETTER CHEE, DESERET SMALL LETTER CHEE
assertEq(String.fromCodePoint(0x10416).toLowerCase().codePointAt(0), 0x1043E); // DESERET CAPITAL LETTER JEE, DESERET SMALL LETTER JEE
assertEq(String.fromCodePoint(0x10417).toLowerCase().codePointAt(0), 0x1043F); // DESERET CAPITAL LETTER KAY, DESERET SMALL LETTER KAY
assertEq(String.fromCodePoint(0x10418).toLowerCase().codePointAt(0), 0x10440); // DESERET CAPITAL LETTER GAY, DESERET SMALL LETTER GAY
assertEq(String.fromCodePoint(0x10419).toLowerCase().codePointAt(0), 0x10441); // DESERET CAPITAL LETTER EF, DESERET SMALL LETTER EF
assertEq(String.fromCodePoint(0x1041A).toLowerCase().codePointAt(0), 0x10442); // DESERET CAPITAL LETTER VEE, DESERET SMALL LETTER VEE
assertEq(String.fromCodePoint(0x1041B).toLowerCase().codePointAt(0), 0x10443); // DESERET CAPITAL LETTER ETH, DESERET SMALL LETTER ETH
assertEq(String.fromCodePoint(0x1041C).toLowerCase().codePointAt(0), 0x10444); // DESERET CAPITAL LETTER THEE, DESERET SMALL LETTER THEE
assertEq(String.fromCodePoint(0x1041D).toLowerCase().codePointAt(0), 0x10445); // DESERET CAPITAL LETTER ES, DESERET SMALL LETTER ES
assertEq(String.fromCodePoint(0x1041E).toLowerCase().codePointAt(0), 0x10446); // DESERET CAPITAL LETTER ZEE, DESERET SMALL LETTER ZEE
assertEq(String.fromCodePoint(0x1041F).toLowerCase().codePointAt(0), 0x10447); // DESERET CAPITAL LETTER ESH, DESERET SMALL LETTER ESH
assertEq(String.fromCodePoint(0x10420).toLowerCase().codePointAt(0), 0x10448); // DESERET CAPITAL LETTER ZHEE, DESERET SMALL LETTER ZHEE
assertEq(String.fromCodePoint(0x10421).toLowerCase().codePointAt(0), 0x10449); // DESERET CAPITAL LETTER ER, DESERET SMALL LETTER ER
assertEq(String.fromCodePoint(0x10422).toLowerCase().codePointAt(0), 0x1044A); // DESERET CAPITAL LETTER EL, DESERET SMALL LETTER EL
assertEq(String.fromCodePoint(0x10423).toLowerCase().codePointAt(0), 0x1044B); // DESERET CAPITAL LETTER EM, DESERET SMALL LETTER EM
assertEq(String.fromCodePoint(0x10424).toLowerCase().codePointAt(0), 0x1044C); // DESERET CAPITAL LETTER EN, DESERET SMALL LETTER EN
assertEq(String.fromCodePoint(0x10425).toLowerCase().codePointAt(0), 0x1044D); // DESERET CAPITAL LETTER ENG, DESERET SMALL LETTER ENG
assertEq(String.fromCodePoint(0x10426).toLowerCase().codePointAt(0), 0x1044E); // DESERET CAPITAL LETTER OI, DESERET SMALL LETTER OI
assertEq(String.fromCodePoint(0x10427).toLowerCase().codePointAt(0), 0x1044F); // DESERET CAPITAL LETTER EW, DESERET SMALL LETTER EW
assertEq(String.fromCodePoint(0x104B0).toLowerCase().codePointAt(0), 0x104D8); // OSAGE CAPITAL LETTER A, OSAGE SMALL LETTER A
assertEq(String.fromCodePoint(0x104B1).toLowerCase().codePointAt(0), 0x104D9); // OSAGE CAPITAL LETTER AI, OSAGE SMALL LETTER AI
assertEq(String.fromCodePoint(0x104B2).toLowerCase().codePointAt(0), 0x104DA); // OSAGE CAPITAL LETTER AIN, OSAGE SMALL LETTER AIN
assertEq(String.fromCodePoint(0x104B3).toLowerCase().codePointAt(0), 0x104DB); // OSAGE CAPITAL LETTER AH, OSAGE SMALL LETTER AH
assertEq(String.fromCodePoint(0x104B4).toLowerCase().codePointAt(0), 0x104DC); // OSAGE CAPITAL LETTER BRA, OSAGE SMALL LETTER BRA
assertEq(String.fromCodePoint(0x104B5).toLowerCase().codePointAt(0), 0x104DD); // OSAGE CAPITAL LETTER CHA, OSAGE SMALL LETTER CHA
assertEq(String.fromCodePoint(0x104B6).toLowerCase().codePointAt(0), 0x104DE); // OSAGE CAPITAL LETTER EHCHA, OSAGE SMALL LETTER EHCHA
assertEq(String.fromCodePoint(0x104B7).toLowerCase().codePointAt(0), 0x104DF); // OSAGE CAPITAL LETTER E, OSAGE SMALL LETTER E
assertEq(String.fromCodePoint(0x104B8).toLowerCase().codePointAt(0), 0x104E0); // OSAGE CAPITAL LETTER EIN, OSAGE SMALL LETTER EIN
assertEq(String.fromCodePoint(0x104B9).toLowerCase().codePointAt(0), 0x104E1); // OSAGE CAPITAL LETTER HA, OSAGE SMALL LETTER HA
assertEq(String.fromCodePoint(0x104BA).toLowerCase().codePointAt(0), 0x104E2); // OSAGE CAPITAL LETTER HYA, OSAGE SMALL LETTER HYA
assertEq(String.fromCodePoint(0x104BB).toLowerCase().codePointAt(0), 0x104E3); // OSAGE CAPITAL LETTER I, OSAGE SMALL LETTER I
assertEq(String.fromCodePoint(0x104BC).toLowerCase().codePointAt(0), 0x104E4); // OSAGE CAPITAL LETTER KA, OSAGE SMALL LETTER KA
assertEq(String.fromCodePoint(0x104BD).toLowerCase().codePointAt(0), 0x104E5); // OSAGE CAPITAL LETTER EHKA, OSAGE SMALL LETTER EHKA
assertEq(String.fromCodePoint(0x104BE).toLowerCase().codePointAt(0), 0x104E6); // OSAGE CAPITAL LETTER KYA, OSAGE SMALL LETTER KYA
assertEq(String.fromCodePoint(0x104BF).toLowerCase().codePointAt(0), 0x104E7); // OSAGE CAPITAL LETTER LA, OSAGE SMALL LETTER LA
assertEq(String.fromCodePoint(0x104C0).toLowerCase().codePointAt(0), 0x104E8); // OSAGE CAPITAL LETTER MA, OSAGE SMALL LETTER MA
assertEq(String.fromCodePoint(0x104C1).toLowerCase().codePointAt(0), 0x104E9); // OSAGE CAPITAL LETTER NA, OSAGE SMALL LETTER NA
assertEq(String.fromCodePoint(0x104C2).toLowerCase().codePointAt(0), 0x104EA); // OSAGE CAPITAL LETTER O, OSAGE SMALL LETTER O
assertEq(String.fromCodePoint(0x104C3).toLowerCase().codePointAt(0), 0x104EB); // OSAGE CAPITAL LETTER OIN, OSAGE SMALL LETTER OIN
assertEq(String.fromCodePoint(0x104C4).toLowerCase().codePointAt(0), 0x104EC); // OSAGE CAPITAL LETTER PA, OSAGE SMALL LETTER PA
assertEq(String.fromCodePoint(0x104C5).toLowerCase().codePointAt(0), 0x104ED); // OSAGE CAPITAL LETTER EHPA, OSAGE SMALL LETTER EHPA
assertEq(String.fromCodePoint(0x104C6).toLowerCase().codePointAt(0), 0x104EE); // OSAGE CAPITAL LETTER SA, OSAGE SMALL LETTER SA
assertEq(String.fromCodePoint(0x104C7).toLowerCase().codePointAt(0), 0x104EF); // OSAGE CAPITAL LETTER SHA, OSAGE SMALL LETTER SHA
assertEq(String.fromCodePoint(0x104C8).toLowerCase().codePointAt(0), 0x104F0); // OSAGE CAPITAL LETTER TA, OSAGE SMALL LETTER TA
assertEq(String.fromCodePoint(0x104C9).toLowerCase().codePointAt(0), 0x104F1); // OSAGE CAPITAL LETTER EHTA, OSAGE SMALL LETTER EHTA
assertEq(String.fromCodePoint(0x104CA).toLowerCase().codePointAt(0), 0x104F2); // OSAGE CAPITAL LETTER TSA, OSAGE SMALL LETTER TSA
assertEq(String.fromCodePoint(0x104CB).toLowerCase().codePointAt(0), 0x104F3); // OSAGE CAPITAL LETTER EHTSA, OSAGE SMALL LETTER EHTSA
assertEq(String.fromCodePoint(0x104CC).toLowerCase().codePointAt(0), 0x104F4); // OSAGE CAPITAL LETTER TSHA, OSAGE SMALL LETTER TSHA
assertEq(String.fromCodePoint(0x104CD).toLowerCase().codePointAt(0), 0x104F5); // OSAGE CAPITAL LETTER DHA, OSAGE SMALL LETTER DHA
assertEq(String.fromCodePoint(0x104CE).toLowerCase().codePointAt(0), 0x104F6); // OSAGE CAPITAL LETTER U, OSAGE SMALL LETTER U
assertEq(String.fromCodePoint(0x104CF).toLowerCase().codePointAt(0), 0x104F7); // OSAGE CAPITAL LETTER WA, OSAGE SMALL LETTER WA
assertEq(String.fromCodePoint(0x104D0).toLowerCase().codePointAt(0), 0x104F8); // OSAGE CAPITAL LETTER KHA, OSAGE SMALL LETTER KHA
assertEq(String.fromCodePoint(0x104D1).toLowerCase().codePointAt(0), 0x104F9); // OSAGE CAPITAL LETTER GHA, OSAGE SMALL LETTER GHA
assertEq(String.fromCodePoint(0x104D2).toLowerCase().codePointAt(0), 0x104FA); // OSAGE CAPITAL LETTER ZA, OSAGE SMALL LETTER ZA
assertEq(String.fromCodePoint(0x104D3).toLowerCase().codePointAt(0), 0x104FB); // OSAGE CAPITAL LETTER ZHA, OSAGE SMALL LETTER ZHA
assertEq(String.fromCodePoint(0x10C80).toLowerCase().codePointAt(0), 0x10CC0); // OLD HUNGARIAN CAPITAL LETTER A, OLD HUNGARIAN SMALL LETTER A
assertEq(String.fromCodePoint(0x10C81).toLowerCase().codePointAt(0), 0x10CC1); // OLD HUNGARIAN CAPITAL LETTER AA, OLD HUNGARIAN SMALL LETTER AA
assertEq(String.fromCodePoint(0x10C82).toLowerCase().codePointAt(0), 0x10CC2); // OLD HUNGARIAN CAPITAL LETTER EB, OLD HUNGARIAN SMALL LETTER EB
assertEq(String.fromCodePoint(0x10C83).toLowerCase().codePointAt(0), 0x10CC3); // OLD HUNGARIAN CAPITAL LETTER AMB, OLD HUNGARIAN SMALL LETTER AMB
assertEq(String.fromCodePoint(0x10C84).toLowerCase().codePointAt(0), 0x10CC4); // OLD HUNGARIAN CAPITAL LETTER EC, OLD HUNGARIAN SMALL LETTER EC
assertEq(String.fromCodePoint(0x10C85).toLowerCase().codePointAt(0), 0x10CC5); // OLD HUNGARIAN CAPITAL LETTER ENC, OLD HUNGARIAN SMALL LETTER ENC
assertEq(String.fromCodePoint(0x10C86).toLowerCase().codePointAt(0), 0x10CC6); // OLD HUNGARIAN CAPITAL LETTER ECS, OLD HUNGARIAN SMALL LETTER ECS
assertEq(String.fromCodePoint(0x10C87).toLowerCase().codePointAt(0), 0x10CC7); // OLD HUNGARIAN CAPITAL LETTER ED, OLD HUNGARIAN SMALL LETTER ED
assertEq(String.fromCodePoint(0x10C88).toLowerCase().codePointAt(0), 0x10CC8); // OLD HUNGARIAN CAPITAL LETTER AND, OLD HUNGARIAN SMALL LETTER AND
assertEq(String.fromCodePoint(0x10C89).toLowerCase().codePointAt(0), 0x10CC9); // OLD HUNGARIAN CAPITAL LETTER E, OLD HUNGARIAN SMALL LETTER E
assertEq(String.fromCodePoint(0x10C8A).toLowerCase().codePointAt(0), 0x10CCA); // OLD HUNGARIAN CAPITAL LETTER CLOSE E, OLD HUNGARIAN SMALL LETTER CLOSE E
assertEq(String.fromCodePoint(0x10C8B).toLowerCase().codePointAt(0), 0x10CCB); // OLD HUNGARIAN CAPITAL LETTER EE, OLD HUNGARIAN SMALL LETTER EE
assertEq(String.fromCodePoint(0x10C8C).toLowerCase().codePointAt(0), 0x10CCC); // OLD HUNGARIAN CAPITAL LETTER EF, OLD HUNGARIAN SMALL LETTER EF
assertEq(String.fromCodePoint(0x10C8D).toLowerCase().codePointAt(0), 0x10CCD); // OLD HUNGARIAN CAPITAL LETTER EG, OLD HUNGARIAN SMALL LETTER EG
assertEq(String.fromCodePoint(0x10C8E).toLowerCase().codePointAt(0), 0x10CCE); // OLD HUNGARIAN CAPITAL LETTER EGY, OLD HUNGARIAN SMALL LETTER EGY
assertEq(String.fromCodePoint(0x10C8F).toLowerCase().codePointAt(0), 0x10CCF); // OLD HUNGARIAN CAPITAL LETTER EH, OLD HUNGARIAN SMALL LETTER EH
assertEq(String.fromCodePoint(0x10C90).toLowerCase().codePointAt(0), 0x10CD0); // OLD HUNGARIAN CAPITAL LETTER I, OLD HUNGARIAN SMALL LETTER I
assertEq(String.fromCodePoint(0x10C91).toLowerCase().codePointAt(0), 0x10CD1); // OLD HUNGARIAN CAPITAL LETTER II, OLD HUNGARIAN SMALL LETTER II
assertEq(String.fromCodePoint(0x10C92).toLowerCase().codePointAt(0), 0x10CD2); // OLD HUNGARIAN CAPITAL LETTER EJ, OLD HUNGARIAN SMALL LETTER EJ
assertEq(String.fromCodePoint(0x10C93).toLowerCase().codePointAt(0), 0x10CD3); // OLD HUNGARIAN CAPITAL LETTER EK, OLD HUNGARIAN SMALL LETTER EK
assertEq(String.fromCodePoint(0x10C94).toLowerCase().codePointAt(0), 0x10CD4); // OLD HUNGARIAN CAPITAL LETTER AK, OLD HUNGARIAN SMALL LETTER AK
assertEq(String.fromCodePoint(0x10C95).toLowerCase().codePointAt(0), 0x10CD5); // OLD HUNGARIAN CAPITAL LETTER UNK, OLD HUNGARIAN SMALL LETTER UNK
assertEq(String.fromCodePoint(0x10C96).toLowerCase().codePointAt(0), 0x10CD6); // OLD HUNGARIAN CAPITAL LETTER EL, OLD HUNGARIAN SMALL LETTER EL
assertEq(String.fromCodePoint(0x10C97).toLowerCase().codePointAt(0), 0x10CD7); // OLD HUNGARIAN CAPITAL LETTER ELY, OLD HUNGARIAN SMALL LETTER ELY
assertEq(String.fromCodePoint(0x10C98).toLowerCase().codePointAt(0), 0x10CD8); // OLD HUNGARIAN CAPITAL LETTER EM, OLD HUNGARIAN SMALL LETTER EM
assertEq(String.fromCodePoint(0x10C99).toLowerCase().codePointAt(0), 0x10CD9); // OLD HUNGARIAN CAPITAL LETTER EN, OLD HUNGARIAN SMALL LETTER EN
assertEq(String.fromCodePoint(0x10C9A).toLowerCase().codePointAt(0), 0x10CDA); // OLD HUNGARIAN CAPITAL LETTER ENY, OLD HUNGARIAN SMALL LETTER ENY
assertEq(String.fromCodePoint(0x10C9B).toLowerCase().codePointAt(0), 0x10CDB); // OLD HUNGARIAN CAPITAL LETTER O, OLD HUNGARIAN SMALL LETTER O
assertEq(String.fromCodePoint(0x10C9C).toLowerCase().codePointAt(0), 0x10CDC); // OLD HUNGARIAN CAPITAL LETTER OO, OLD HUNGARIAN SMALL LETTER OO
assertEq(String.fromCodePoint(0x10C9D).toLowerCase().codePointAt(0), 0x10CDD); // OLD HUNGARIAN CAPITAL LETTER NIKOLSBURG OE, OLD HUNGARIAN SMALL LETTER NIKOLSBURG OE
assertEq(String.fromCodePoint(0x10C9E).toLowerCase().codePointAt(0), 0x10CDE); // OLD HUNGARIAN CAPITAL LETTER RUDIMENTA OE, OLD HUNGARIAN SMALL LETTER RUDIMENTA OE
assertEq(String.fromCodePoint(0x10C9F).toLowerCase().codePointAt(0), 0x10CDF); // OLD HUNGARIAN CAPITAL LETTER OEE, OLD HUNGARIAN SMALL LETTER OEE
assertEq(String.fromCodePoint(0x10CA0).toLowerCase().codePointAt(0), 0x10CE0); // OLD HUNGARIAN CAPITAL LETTER EP, OLD HUNGARIAN SMALL LETTER EP
assertEq(String.fromCodePoint(0x10CA1).toLowerCase().codePointAt(0), 0x10CE1); // OLD HUNGARIAN CAPITAL LETTER EMP, OLD HUNGARIAN SMALL LETTER EMP
assertEq(String.fromCodePoint(0x10CA2).toLowerCase().codePointAt(0), 0x10CE2); // OLD HUNGARIAN CAPITAL LETTER ER, OLD HUNGARIAN SMALL LETTER ER
assertEq(String.fromCodePoint(0x10CA3).toLowerCase().codePointAt(0), 0x10CE3); // OLD HUNGARIAN CAPITAL LETTER SHORT ER, OLD HUNGARIAN SMALL LETTER SHORT ER
assertEq(String.fromCodePoint(0x10CA4).toLowerCase().codePointAt(0), 0x10CE4); // OLD HUNGARIAN CAPITAL LETTER ES, OLD HUNGARIAN SMALL LETTER ES
assertEq(String.fromCodePoint(0x10CA5).toLowerCase().codePointAt(0), 0x10CE5); // OLD HUNGARIAN CAPITAL LETTER ESZ, OLD HUNGARIAN SMALL LETTER ESZ
assertEq(String.fromCodePoint(0x10CA6).toLowerCase().codePointAt(0), 0x10CE6); // OLD HUNGARIAN CAPITAL LETTER ET, OLD HUNGARIAN SMALL LETTER ET
assertEq(String.fromCodePoint(0x10CA7).toLowerCase().codePointAt(0), 0x10CE7); // OLD HUNGARIAN CAPITAL LETTER ENT, OLD HUNGARIAN SMALL LETTER ENT
assertEq(String.fromCodePoint(0x10CA8).toLowerCase().codePointAt(0), 0x10CE8); // OLD HUNGARIAN CAPITAL LETTER ETY, OLD HUNGARIAN SMALL LETTER ETY
assertEq(String.fromCodePoint(0x10CA9).toLowerCase().codePointAt(0), 0x10CE9); // OLD HUNGARIAN CAPITAL LETTER ECH, OLD HUNGARIAN SMALL LETTER ECH
assertEq(String.fromCodePoint(0x10CAA).toLowerCase().codePointAt(0), 0x10CEA); // OLD HUNGARIAN CAPITAL LETTER U, OLD HUNGARIAN SMALL LETTER U
assertEq(String.fromCodePoint(0x10CAB).toLowerCase().codePointAt(0), 0x10CEB); // OLD HUNGARIAN CAPITAL LETTER UU, OLD HUNGARIAN SMALL LETTER UU
assertEq(String.fromCodePoint(0x10CAC).toLowerCase().codePointAt(0), 0x10CEC); // OLD HUNGARIAN CAPITAL LETTER NIKOLSBURG UE, OLD HUNGARIAN SMALL LETTER NIKOLSBURG UE
assertEq(String.fromCodePoint(0x10CAD).toLowerCase().codePointAt(0), 0x10CED); // OLD HUNGARIAN CAPITAL LETTER RUDIMENTA UE, OLD HUNGARIAN SMALL LETTER RUDIMENTA UE
assertEq(String.fromCodePoint(0x10CAE).toLowerCase().codePointAt(0), 0x10CEE); // OLD HUNGARIAN CAPITAL LETTER EV, OLD HUNGARIAN SMALL LETTER EV
assertEq(String.fromCodePoint(0x10CAF).toLowerCase().codePointAt(0), 0x10CEF); // OLD HUNGARIAN CAPITAL LETTER EZ, OLD HUNGARIAN SMALL LETTER EZ
assertEq(String.fromCodePoint(0x10CB0).toLowerCase().codePointAt(0), 0x10CF0); // OLD HUNGARIAN CAPITAL LETTER EZS, OLD HUNGARIAN SMALL LETTER EZS
assertEq(String.fromCodePoint(0x10CB1).toLowerCase().codePointAt(0), 0x10CF1); // OLD HUNGARIAN CAPITAL LETTER ENT-SHAPED SIGN, OLD HUNGARIAN SMALL LETTER ENT-SHAPED SIGN
assertEq(String.fromCodePoint(0x10CB2).toLowerCase().codePointAt(0), 0x10CF2); // OLD HUNGARIAN CAPITAL LETTER US, OLD HUNGARIAN SMALL LETTER US
assertEq(String.fromCodePoint(0x118A0).toLowerCase().codePointAt(0), 0x118C0); // WARANG CITI CAPITAL LETTER NGAA, WARANG CITI SMALL LETTER NGAA
assertEq(String.fromCodePoint(0x118A1).toLowerCase().codePointAt(0), 0x118C1); // WARANG CITI CAPITAL LETTER A, WARANG CITI SMALL LETTER A
assertEq(String.fromCodePoint(0x118A2).toLowerCase().codePointAt(0), 0x118C2); // WARANG CITI CAPITAL LETTER WI, WARANG CITI SMALL LETTER WI
assertEq(String.fromCodePoint(0x118A3).toLowerCase().codePointAt(0), 0x118C3); // WARANG CITI CAPITAL LETTER YU, WARANG CITI SMALL LETTER YU
assertEq(String.fromCodePoint(0x118A4).toLowerCase().codePointAt(0), 0x118C4); // WARANG CITI CAPITAL LETTER YA, WARANG CITI SMALL LETTER YA
assertEq(String.fromCodePoint(0x118A5).toLowerCase().codePointAt(0), 0x118C5); // WARANG CITI CAPITAL LETTER YO, WARANG CITI SMALL LETTER YO
assertEq(String.fromCodePoint(0x118A6).toLowerCase().codePointAt(0), 0x118C6); // WARANG CITI CAPITAL LETTER II, WARANG CITI SMALL LETTER II
assertEq(String.fromCodePoint(0x118A7).toLowerCase().codePointAt(0), 0x118C7); // WARANG CITI CAPITAL LETTER UU, WARANG CITI SMALL LETTER UU
assertEq(String.fromCodePoint(0x118A8).toLowerCase().codePointAt(0), 0x118C8); // WARANG CITI CAPITAL LETTER E, WARANG CITI SMALL LETTER E
assertEq(String.fromCodePoint(0x118A9).toLowerCase().codePointAt(0), 0x118C9); // WARANG CITI CAPITAL LETTER O, WARANG CITI SMALL LETTER O
assertEq(String.fromCodePoint(0x118AA).toLowerCase().codePointAt(0), 0x118CA); // WARANG CITI CAPITAL LETTER ANG, WARANG CITI SMALL LETTER ANG
assertEq(String.fromCodePoint(0x118AB).toLowerCase().codePointAt(0), 0x118CB); // WARANG CITI CAPITAL LETTER GA, WARANG CITI SMALL LETTER GA
assertEq(String.fromCodePoint(0x118AC).toLowerCase().codePointAt(0), 0x118CC); // WARANG CITI CAPITAL LETTER KO, WARANG CITI SMALL LETTER KO
assertEq(String.fromCodePoint(0x118AD).toLowerCase().codePointAt(0), 0x118CD); // WARANG CITI CAPITAL LETTER ENY, WARANG CITI SMALL LETTER ENY
assertEq(String.fromCodePoint(0x118AE).toLowerCase().codePointAt(0), 0x118CE); // WARANG CITI CAPITAL LETTER YUJ, WARANG CITI SMALL LETTER YUJ
assertEq(String.fromCodePoint(0x118AF).toLowerCase().codePointAt(0), 0x118CF); // WARANG CITI CAPITAL LETTER UC, WARANG CITI SMALL LETTER UC
assertEq(String.fromCodePoint(0x118B0).toLowerCase().codePointAt(0), 0x118D0); // WARANG CITI CAPITAL LETTER ENN, WARANG CITI SMALL LETTER ENN
assertEq(String.fromCodePoint(0x118B1).toLowerCase().codePointAt(0), 0x118D1); // WARANG CITI CAPITAL LETTER ODD, WARANG CITI SMALL LETTER ODD
assertEq(String.fromCodePoint(0x118B2).toLowerCase().codePointAt(0), 0x118D2); // WARANG CITI CAPITAL LETTER TTE, WARANG CITI SMALL LETTER TTE
assertEq(String.fromCodePoint(0x118B3).toLowerCase().codePointAt(0), 0x118D3); // WARANG CITI CAPITAL LETTER NUNG, WARANG CITI SMALL LETTER NUNG
assertEq(String.fromCodePoint(0x118B4).toLowerCase().codePointAt(0), 0x118D4); // WARANG CITI CAPITAL LETTER DA, WARANG CITI SMALL LETTER DA
assertEq(String.fromCodePoint(0x118B5).toLowerCase().codePointAt(0), 0x118D5); // WARANG CITI CAPITAL LETTER AT, WARANG CITI SMALL LETTER AT
assertEq(String.fromCodePoint(0x118B6).toLowerCase().codePointAt(0), 0x118D6); // WARANG CITI CAPITAL LETTER AM, WARANG CITI SMALL LETTER AM
assertEq(String.fromCodePoint(0x118B7).toLowerCase().codePointAt(0), 0x118D7); // WARANG CITI CAPITAL LETTER BU, WARANG CITI SMALL LETTER BU
assertEq(String.fromCodePoint(0x118B8).toLowerCase().codePointAt(0), 0x118D8); // WARANG CITI CAPITAL LETTER PU, WARANG CITI SMALL LETTER PU
assertEq(String.fromCodePoint(0x118B9).toLowerCase().codePointAt(0), 0x118D9); // WARANG CITI CAPITAL LETTER HIYO, WARANG CITI SMALL LETTER HIYO
assertEq(String.fromCodePoint(0x118BA).toLowerCase().codePointAt(0), 0x118DA); // WARANG CITI CAPITAL LETTER HOLO, WARANG CITI SMALL LETTER HOLO
assertEq(String.fromCodePoint(0x118BB).toLowerCase().codePointAt(0), 0x118DB); // WARANG CITI CAPITAL LETTER HORR, WARANG CITI SMALL LETTER HORR
assertEq(String.fromCodePoint(0x118BC).toLowerCase().codePointAt(0), 0x118DC); // WARANG CITI CAPITAL LETTER HAR, WARANG CITI SMALL LETTER HAR
assertEq(String.fromCodePoint(0x118BD).toLowerCase().codePointAt(0), 0x118DD); // WARANG CITI CAPITAL LETTER SSUU, WARANG CITI SMALL LETTER SSUU
assertEq(String.fromCodePoint(0x118BE).toLowerCase().codePointAt(0), 0x118DE); // WARANG CITI CAPITAL LETTER SII, WARANG CITI SMALL LETTER SII
assertEq(String.fromCodePoint(0x118BF).toLowerCase().codePointAt(0), 0x118DF); // WARANG CITI CAPITAL LETTER VIYO, WARANG CITI SMALL LETTER VIYO
assertEq(String.fromCodePoint(0x1E900).toLowerCase().codePointAt(0), 0x1E922); // ADLAM CAPITAL LETTER ALIF, ADLAM SMALL LETTER ALIF
assertEq(String.fromCodePoint(0x1E901).toLowerCase().codePointAt(0), 0x1E923); // ADLAM CAPITAL LETTER DAALI, ADLAM SMALL LETTER DAALI
assertEq(String.fromCodePoint(0x1E902).toLowerCase().codePointAt(0), 0x1E924); // ADLAM CAPITAL LETTER LAAM, ADLAM SMALL LETTER LAAM
assertEq(String.fromCodePoint(0x1E903).toLowerCase().codePointAt(0), 0x1E925); // ADLAM CAPITAL LETTER MIIM, ADLAM SMALL LETTER MIIM
assertEq(String.fromCodePoint(0x1E904).toLowerCase().codePointAt(0), 0x1E926); // ADLAM CAPITAL LETTER BA, ADLAM SMALL LETTER BA
assertEq(String.fromCodePoint(0x1E905).toLowerCase().codePointAt(0), 0x1E927); // ADLAM CAPITAL LETTER SINNYIIYHE, ADLAM SMALL LETTER SINNYIIYHE
assertEq(String.fromCodePoint(0x1E906).toLowerCase().codePointAt(0), 0x1E928); // ADLAM CAPITAL LETTER PE, ADLAM SMALL LETTER PE
assertEq(String.fromCodePoint(0x1E907).toLowerCase().codePointAt(0), 0x1E929); // ADLAM CAPITAL LETTER BHE, ADLAM SMALL LETTER BHE
assertEq(String.fromCodePoint(0x1E908).toLowerCase().codePointAt(0), 0x1E92A); // ADLAM CAPITAL LETTER RA, ADLAM SMALL LETTER RA
assertEq(String.fromCodePoint(0x1E909).toLowerCase().codePointAt(0), 0x1E92B); // ADLAM CAPITAL LETTER E, ADLAM SMALL LETTER E
assertEq(String.fromCodePoint(0x1E90A).toLowerCase().codePointAt(0), 0x1E92C); // ADLAM CAPITAL LETTER FA, ADLAM SMALL LETTER FA
assertEq(String.fromCodePoint(0x1E90B).toLowerCase().codePointAt(0), 0x1E92D); // ADLAM CAPITAL LETTER I, ADLAM SMALL LETTER I
assertEq(String.fromCodePoint(0x1E90C).toLowerCase().codePointAt(0), 0x1E92E); // ADLAM CAPITAL LETTER O, ADLAM SMALL LETTER O
assertEq(String.fromCodePoint(0x1E90D).toLowerCase().codePointAt(0), 0x1E92F); // ADLAM CAPITAL LETTER DHA, ADLAM SMALL LETTER DHA
assertEq(String.fromCodePoint(0x1E90E).toLowerCase().codePointAt(0), 0x1E930); // ADLAM CAPITAL LETTER YHE, ADLAM SMALL LETTER YHE
assertEq(String.fromCodePoint(0x1E90F).toLowerCase().codePointAt(0), 0x1E931); // ADLAM CAPITAL LETTER WAW, ADLAM SMALL LETTER WAW
assertEq(String.fromCodePoint(0x1E910).toLowerCase().codePointAt(0), 0x1E932); // ADLAM CAPITAL LETTER NUN, ADLAM SMALL LETTER NUN
assertEq(String.fromCodePoint(0x1E911).toLowerCase().codePointAt(0), 0x1E933); // ADLAM CAPITAL LETTER KAF, ADLAM SMALL LETTER KAF
assertEq(String.fromCodePoint(0x1E912).toLowerCase().codePointAt(0), 0x1E934); // ADLAM CAPITAL LETTER YA, ADLAM SMALL LETTER YA
assertEq(String.fromCodePoint(0x1E913).toLowerCase().codePointAt(0), 0x1E935); // ADLAM CAPITAL LETTER U, ADLAM SMALL LETTER U
assertEq(String.fromCodePoint(0x1E914).toLowerCase().codePointAt(0), 0x1E936); // ADLAM CAPITAL LETTER JIIM, ADLAM SMALL LETTER JIIM
assertEq(String.fromCodePoint(0x1E915).toLowerCase().codePointAt(0), 0x1E937); // ADLAM CAPITAL LETTER CHI, ADLAM SMALL LETTER CHI
assertEq(String.fromCodePoint(0x1E916).toLowerCase().codePointAt(0), 0x1E938); // ADLAM CAPITAL LETTER HA, ADLAM SMALL LETTER HA
assertEq(String.fromCodePoint(0x1E917).toLowerCase().codePointAt(0), 0x1E939); // ADLAM CAPITAL LETTER QAAF, ADLAM SMALL LETTER QAAF
assertEq(String.fromCodePoint(0x1E918).toLowerCase().codePointAt(0), 0x1E93A); // ADLAM CAPITAL LETTER GA, ADLAM SMALL LETTER GA
assertEq(String.fromCodePoint(0x1E919).toLowerCase().codePointAt(0), 0x1E93B); // ADLAM CAPITAL LETTER NYA, ADLAM SMALL LETTER NYA
assertEq(String.fromCodePoint(0x1E91A).toLowerCase().codePointAt(0), 0x1E93C); // ADLAM CAPITAL LETTER TU, ADLAM SMALL LETTER TU
assertEq(String.fromCodePoint(0x1E91B).toLowerCase().codePointAt(0), 0x1E93D); // ADLAM CAPITAL LETTER NHA, ADLAM SMALL LETTER NHA
assertEq(String.fromCodePoint(0x1E91C).toLowerCase().codePointAt(0), 0x1E93E); // ADLAM CAPITAL LETTER VA, ADLAM SMALL LETTER VA
assertEq(String.fromCodePoint(0x1E91D).toLowerCase().codePointAt(0), 0x1E93F); // ADLAM CAPITAL LETTER KHA, ADLAM SMALL LETTER KHA
assertEq(String.fromCodePoint(0x1E91E).toLowerCase().codePointAt(0), 0x1E940); // ADLAM CAPITAL LETTER GBE, ADLAM SMALL LETTER GBE
assertEq(String.fromCodePoint(0x1E91F).toLowerCase().codePointAt(0), 0x1E941); // ADLAM CAPITAL LETTER ZAL, ADLAM SMALL LETTER ZAL
assertEq(String.fromCodePoint(0x1E920).toLowerCase().codePointAt(0), 0x1E942); // ADLAM CAPITAL LETTER KPO, ADLAM SMALL LETTER KPO
assertEq(String.fromCodePoint(0x1E921).toLowerCase().codePointAt(0), 0x1E943); // ADLAM CAPITAL LETTER SHA, ADLAM SMALL LETTER SHA
if (typeof reportCompare === "function")
reportCompare(true, true);

Просмотреть файл

@ -44,6 +44,13 @@ skip-if(!Array.prototype.values) include test262/built-ins/Array/prototype/value
skip-if(release_or_beta) include test262/language/expressions/async-generators/jstests.list
skip-if(release_or_beta) include test262/language/statements/async-generator/jstests.list
# Requires ICU to detect Final_Sigma case mapping context
skip-if(!this.hasOwnProperty("Intl")) script test262/built-ins/String/prototype/toLowerCase/Final_Sigma_U180E.js
skip-if(!this.hasOwnProperty("Intl")) script test262/built-ins/String/prototype/toLowerCase/special_casing_conditional.js
skip-if(!this.hasOwnProperty("Intl")) script test262/built-ins/String/prototype/toLocaleLowerCase/Final_Sigma_U180E.js
skip-if(!this.hasOwnProperty("Intl")) script test262/built-ins/String/prototype/toLocaleLowerCase/special_casing_conditional.js
#####################################
# Test262 tests disabled on browser #
#####################################
@ -462,22 +469,6 @@ skip script test262/intl402/Collator/prototype/compare/compare-function-name.js
skip script test262/intl402/DateTimeFormat/prototype/format/format-function-name.js
skip script test262/intl402/NumberFormat/prototype/format/format-function-name.js
# https://bugzilla.mozilla.org/show_bug.cgi?id=394604
skip script test262/intl402/String/prototype/toLocaleLowerCase/capital_I_with_dot.js
skip script test262/intl402/String/prototype/toLocaleLowerCase/special_casing_Azeri.js
skip script test262/intl402/String/prototype/toLocaleLowerCase/special_casing_Lithuanian.js
skip script test262/intl402/String/prototype/toLocaleLowerCase/special_casing_Turkish.js
skip script test262/intl402/String/prototype/toLocaleUpperCase/special_casing_Azeri.js
skip script test262/intl402/String/prototype/toLocaleUpperCase/special_casing_Lithuanian.js
skip script test262/intl402/String/prototype/toLocaleUpperCase/special_casing_Turkish.js
skip script test262/built-ins/String/prototype/toLocaleLowerCase/Final_Sigma_U180E.js
skip script test262/built-ins/String/prototype/toLocaleLowerCase/special_casing_conditional.js
skip script test262/built-ins/String/prototype/toLocaleUpperCase/special_casing.js
skip script test262/built-ins/String/prototype/toLowerCase/Final_Sigma_U180E.js
skip script test262/built-ins/String/prototype/toLowerCase/special_casing.js
skip script test262/built-ins/String/prototype/toLowerCase/special_casing_conditional.js
skip script test262/built-ins/String/prototype/toUpperCase/special_casing.js
# https://bugzilla.mozilla.org/show_bug.cgi?id=1317373
skip script test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-exsting-global-init.js
skip script test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-exsting-global-init.js
@ -861,9 +852,6 @@ skip script test262/built-ins/SharedArrayBuffer/data-allocation-after-object-cre
skip script test262/intl402/NumberFormat/prototype/format/11.3.2_TRP.js
skip script test262/intl402/NumberFormat/prototype/format/11.3.2_TRF.js
# https://bugzilla.mozilla.org/show_bug.cgi?id=1346079
skip script test262/intl402/DateTimeFormat/prototype/format/12.3.2_1_a_L15.js
# https://bugzilla.mozilla.org/show_bug.cgi?id=1346080
skip script test262/intl402/PluralRules/prototype/select/tainting.js
@ -879,5 +867,8 @@ skip script test262/language/statements/async-generator/yield-star-async-next.js
skip script test262/language/statements/async-generator/yield-star-async-return.js
skip script test262/language/statements/async-generator/yield-star-async-throw.js
# https://github.com/tc39/test262/pull/947
skip script test262/intl402/DateTimeFormat/prototype/formatToParts/length.js
# https://github.com/tc39/test262/pull/947
skip script test262/intl402/PluralRules/this-not-ignored.js

Просмотреть файл

@ -0,0 +1,18 @@
// Copyright 2017 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: pending
description: >
Function.prototype.toString on an async generator created with the
AsyncGenerator constructor.
features: [async-iteration]
---*/
async function* f() {}
var AsyncGenerator = f.constructor;
var g = /* before */AsyncGenerator("a", " /* a */ b, c /* b */ //", "/* c */ ; /* d */ //")/* after */;
assert.sameValue(g.toString(), "async function* anonymous(a, /* a */ b, c /* b */ //\n) {\n/* c */ ; /* d */ //\n}");
reportCompare(0, 0);

Просмотреть файл

@ -0,0 +1,14 @@
// Copyright 2017 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: pending
description: Function.prototype.toString on an async generator declaration
features: [async-iteration]
---*/
/* before */async /* a */ function /* b */ * /* c */ f /* d */ ( /* e */ x /* f */ , /* g */ y /* h */ ) /* i */ { /* j */ ; /* k */ ; /* l */ }/* after */
assert.sameValue(f.toString(), "async /* a */ function /* b */ * /* c */ f /* d */ ( /* e */ x /* f */ , /* g */ y /* h */ ) /* i */ { /* j */ ; /* k */ ; /* l */ }");
reportCompare(0, 0);

Просмотреть файл

@ -0,0 +1,14 @@
// Copyright 2017 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: pending
description: Function.prototype.toString on an async generator expression
features: [async-iteration]
---*/
let f = /* before */async /* a */ function /* b */ * /* c */ f /* d */ ( /* e */ x /* f */ , /* g */ y /* h */ ) /* i */ { /* j */ ; /* k */ ; /* l */ }/* after */;
assert.sameValue(f.toString(), "async /* a */ function /* b */ * /* c */ f /* d */ ( /* e */ x /* f */ , /* g */ y /* h */ ) /* i */ { /* j */ ; /* k */ ; /* l */ }");
reportCompare(0, 0);

Просмотреть файл

@ -0,0 +1,16 @@
// Copyright 2017 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: pending
description: Function.prototype.toString on an async generator method
features: [async-iteration]
---*/
let f = { /* before */async /* a */ * /* b */ f /* c */ ( /* d */ ) /* e */ { /* f */ }/* after */ }.f;
let g = { /* before */async /* a */ * /* b */ [ /* c */ "g" /* d */ ] /* e */ ( /* f */ ) /* g */ { /* h */ }/* after */ }.g;
assert.sameValue(f.toString(), "async /* a */ * /* b */ f /* c */ ( /* d */ ) /* e */ { /* f */ }");
assert.sameValue(g.toString(), "async /* a */ * /* b */ [ /* c */ \"g\" /* d */ ] /* e */ ( /* f */ ) /* g */ { /* h */ }");
reportCompare(0, 0);

Просмотреть файл

Просмотреть файл

Просмотреть файл

@ -2351,15 +2351,15 @@ static const JSFunctionSpec intrinsic_functions[] = {
JS_FN("std_String_trim", str_trim, 0,0),
JS_FN("std_String_trimLeft", str_trimLeft, 0,0),
JS_FN("std_String_trimRight", str_trimRight, 0,0),
#if !EXPOSE_INTL_API
JS_FN("std_String_toLocaleLowerCase", str_toLocaleLowerCase, 0,0),
JS_FN("std_String_toLocaleUpperCase", str_toLocaleUpperCase, 0,0),
#if !EXPOSE_INTL_API
JS_FN("std_String_localeCompare", str_localeCompare, 1,0),
#else
JS_FN("std_String_normalize", str_normalize, 0,0),
#endif
JS_FN("std_String_concat", str_concat, 1,0),
JS_FN("std_TypedArray_buffer", js::TypedArray_bufferGetter, 1,0),
JS_FN("std_WeakMap_has", WeakMap_has, 1,0),
@ -2633,6 +2633,8 @@ static const JSFunctionSpec intrinsic_functions[] = {
JS_FN("intl_PluralRules_availableLocales", intl_PluralRules_availableLocales, 0,0),
JS_FN("intl_GetPluralCategories", intl_GetPluralCategories, 2, 0),
JS_FN("intl_SelectPluralRule", intl_SelectPluralRule, 2,0),
JS_FN("intl_toLocaleLowerCase", intl_toLocaleLowerCase, 2,0),
JS_FN("intl_toLocaleUpperCase", intl_toLocaleUpperCase, 2,0),
JS_INLINABLE_FN("IsCollator",
intrinsic_IsInstanceOfBuiltin<CollatorObject>, 1,0,

281
js/src/vm/SpecialCasing.txt Normal file
Просмотреть файл

@ -0,0 +1,281 @@
# SpecialCasing-9.0.0.txt
# Date: 2016-03-02, 18:55:13 GMT
# © 2016 Unicode®, Inc.
# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
# For terms of use, see http://www.unicode.org/terms_of_use.html
#
# Unicode Character Database
# For documentation, see http://www.unicode.org/reports/tr44/
#
# Special Casing
#
# This file is a supplement to the UnicodeData.txt file. It does not define any
# properties, but rather provides additional information about the casing of
# Unicode characters, for situations when casing incurs a change in string length
# or is dependent on context or locale. For compatibility, the UnicodeData.txt
# file only contains simple case mappings for characters where they are one-to-one
# and independent of context and language. The data in this file, combined with
# the simple case mappings in UnicodeData.txt, defines the full case mappings
# Lowercase_Mapping (lc), Titlecase_Mapping (tc), and Uppercase_Mapping (uc).
#
# Note that the preferred mechanism for defining tailored casing operations is
# the Unicode Common Locale Data Repository (CLDR). For more information, see the
# discussion of case mappings and case algorithms in the Unicode Standard.
#
# All code points not listed in this file that do not have a simple case mappings
# in UnicodeData.txt map to themselves.
# ================================================================================
# Format
# ================================================================================
# The entries in this file are in the following machine-readable format:
#
# <code>; <lower>; <title>; <upper>; (<condition_list>;)? # <comment>
#
# <code>, <lower>, <title>, and <upper> provide the respective full case mappings
# of <code>, expressed as character values in hex. If there is more than one character,
# they are separated by spaces. Other than as used to separate elements, spaces are
# to be ignored.
#
# The <condition_list> is optional. Where present, it consists of one or more language IDs
# or casing contexts, separated by spaces. In these conditions:
# - A condition list overrides the normal behavior if all of the listed conditions are true.
# - The casing context is always the context of the characters in the original string,
# NOT in the resulting string.
# - Case distinctions in the condition list are not significant.
# - Conditions preceded by "Not_" represent the negation of the condition.
# The condition list is not represented in the UCD as a formal property.
#
# A language ID is defined by BCP 47, with '-' and '_' treated equivalently.
#
# A casing context for a character is defined by Section 3.13 Default Case Algorithms
# of The Unicode Standard.
#
# Parsers of this file must be prepared to deal with future additions to this format:
# * Additional contexts
# * Additional fields
# ================================================================================
# ================================================================================
# Unconditional mappings
# ================================================================================
# The German es-zed is special--the normal mapping is to SS.
# Note: the titlecase should never occur in practice. It is equal to titlecase(uppercase(<es-zed>))
00DF; 00DF; 0053 0073; 0053 0053; # LATIN SMALL LETTER SHARP S
# Preserve canonical equivalence for I with dot. Turkic is handled below.
0130; 0069 0307; 0130; 0130; # LATIN CAPITAL LETTER I WITH DOT ABOVE
# Ligatures
FB00; FB00; 0046 0066; 0046 0046; # LATIN SMALL LIGATURE FF
FB01; FB01; 0046 0069; 0046 0049; # LATIN SMALL LIGATURE FI
FB02; FB02; 0046 006C; 0046 004C; # LATIN SMALL LIGATURE FL
FB03; FB03; 0046 0066 0069; 0046 0046 0049; # LATIN SMALL LIGATURE FFI
FB04; FB04; 0046 0066 006C; 0046 0046 004C; # LATIN SMALL LIGATURE FFL
FB05; FB05; 0053 0074; 0053 0054; # LATIN SMALL LIGATURE LONG S T
FB06; FB06; 0053 0074; 0053 0054; # LATIN SMALL LIGATURE ST
0587; 0587; 0535 0582; 0535 0552; # ARMENIAN SMALL LIGATURE ECH YIWN
FB13; FB13; 0544 0576; 0544 0546; # ARMENIAN SMALL LIGATURE MEN NOW
FB14; FB14; 0544 0565; 0544 0535; # ARMENIAN SMALL LIGATURE MEN ECH
FB15; FB15; 0544 056B; 0544 053B; # ARMENIAN SMALL LIGATURE MEN INI
FB16; FB16; 054E 0576; 054E 0546; # ARMENIAN SMALL LIGATURE VEW NOW
FB17; FB17; 0544 056D; 0544 053D; # ARMENIAN SMALL LIGATURE MEN XEH
# No corresponding uppercase precomposed character
0149; 0149; 02BC 004E; 02BC 004E; # LATIN SMALL LETTER N PRECEDED BY APOSTROPHE
0390; 0390; 0399 0308 0301; 0399 0308 0301; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
03B0; 03B0; 03A5 0308 0301; 03A5 0308 0301; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
01F0; 01F0; 004A 030C; 004A 030C; # LATIN SMALL LETTER J WITH CARON
1E96; 1E96; 0048 0331; 0048 0331; # LATIN SMALL LETTER H WITH LINE BELOW
1E97; 1E97; 0054 0308; 0054 0308; # LATIN SMALL LETTER T WITH DIAERESIS
1E98; 1E98; 0057 030A; 0057 030A; # LATIN SMALL LETTER W WITH RING ABOVE
1E99; 1E99; 0059 030A; 0059 030A; # LATIN SMALL LETTER Y WITH RING ABOVE
1E9A; 1E9A; 0041 02BE; 0041 02BE; # LATIN SMALL LETTER A WITH RIGHT HALF RING
1F50; 1F50; 03A5 0313; 03A5 0313; # GREEK SMALL LETTER UPSILON WITH PSILI
1F52; 1F52; 03A5 0313 0300; 03A5 0313 0300; # GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA
1F54; 1F54; 03A5 0313 0301; 03A5 0313 0301; # GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA
1F56; 1F56; 03A5 0313 0342; 03A5 0313 0342; # GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI
1FB6; 1FB6; 0391 0342; 0391 0342; # GREEK SMALL LETTER ALPHA WITH PERISPOMENI
1FC6; 1FC6; 0397 0342; 0397 0342; # GREEK SMALL LETTER ETA WITH PERISPOMENI
1FD2; 1FD2; 0399 0308 0300; 0399 0308 0300; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA
1FD3; 1FD3; 0399 0308 0301; 0399 0308 0301; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA
1FD6; 1FD6; 0399 0342; 0399 0342; # GREEK SMALL LETTER IOTA WITH PERISPOMENI
1FD7; 1FD7; 0399 0308 0342; 0399 0308 0342; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI
1FE2; 1FE2; 03A5 0308 0300; 03A5 0308 0300; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA
1FE3; 1FE3; 03A5 0308 0301; 03A5 0308 0301; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA
1FE4; 1FE4; 03A1 0313; 03A1 0313; # GREEK SMALL LETTER RHO WITH PSILI
1FE6; 1FE6; 03A5 0342; 03A5 0342; # GREEK SMALL LETTER UPSILON WITH PERISPOMENI
1FE7; 1FE7; 03A5 0308 0342; 03A5 0308 0342; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI
1FF6; 1FF6; 03A9 0342; 03A9 0342; # GREEK SMALL LETTER OMEGA WITH PERISPOMENI
# IMPORTANT-when iota-subscript (0345) is uppercased or titlecased,
# the result will be incorrect unless the iota-subscript is moved to the end
# of any sequence of combining marks. Otherwise, the accents will go on the capital iota.
# This process can be achieved by first transforming the text to NFC before casing.
# E.g. <alpha><iota_subscript><acute> is uppercased to <ALPHA><acute><IOTA>
# The following cases are already in the UnicodeData.txt file, so are only commented here.
# 0345; 0345; 0345; 0399; # COMBINING GREEK YPOGEGRAMMENI
# All letters with YPOGEGRAMMENI (iota-subscript) or PROSGEGRAMMENI (iota adscript)
# have special uppercases.
# Note: characters with PROSGEGRAMMENI are actually titlecase, not uppercase!
1F80; 1F80; 1F88; 1F08 0399; # GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI
1F81; 1F81; 1F89; 1F09 0399; # GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI
1F82; 1F82; 1F8A; 1F0A 0399; # GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI
1F83; 1F83; 1F8B; 1F0B 0399; # GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI
1F84; 1F84; 1F8C; 1F0C 0399; # GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI
1F85; 1F85; 1F8D; 1F0D 0399; # GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI
1F86; 1F86; 1F8E; 1F0E 0399; # GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
1F87; 1F87; 1F8F; 1F0F 0399; # GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
1F88; 1F80; 1F88; 1F08 0399; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI
1F89; 1F81; 1F89; 1F09 0399; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI
1F8A; 1F82; 1F8A; 1F0A 0399; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI
1F8B; 1F83; 1F8B; 1F0B 0399; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI
1F8C; 1F84; 1F8C; 1F0C 0399; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI
1F8D; 1F85; 1F8D; 1F0D 0399; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI
1F8E; 1F86; 1F8E; 1F0E 0399; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
1F8F; 1F87; 1F8F; 1F0F 0399; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
1F90; 1F90; 1F98; 1F28 0399; # GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI
1F91; 1F91; 1F99; 1F29 0399; # GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI
1F92; 1F92; 1F9A; 1F2A 0399; # GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI
1F93; 1F93; 1F9B; 1F2B 0399; # GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI
1F94; 1F94; 1F9C; 1F2C 0399; # GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI
1F95; 1F95; 1F9D; 1F2D 0399; # GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI
1F96; 1F96; 1F9E; 1F2E 0399; # GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
1F97; 1F97; 1F9F; 1F2F 0399; # GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
1F98; 1F90; 1F98; 1F28 0399; # GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI
1F99; 1F91; 1F99; 1F29 0399; # GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI
1F9A; 1F92; 1F9A; 1F2A 0399; # GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI
1F9B; 1F93; 1F9B; 1F2B 0399; # GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI
1F9C; 1F94; 1F9C; 1F2C 0399; # GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI
1F9D; 1F95; 1F9D; 1F2D 0399; # GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI
1F9E; 1F96; 1F9E; 1F2E 0399; # GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
1F9F; 1F97; 1F9F; 1F2F 0399; # GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
1FA0; 1FA0; 1FA8; 1F68 0399; # GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI
1FA1; 1FA1; 1FA9; 1F69 0399; # GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI
1FA2; 1FA2; 1FAA; 1F6A 0399; # GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI
1FA3; 1FA3; 1FAB; 1F6B 0399; # GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI
1FA4; 1FA4; 1FAC; 1F6C 0399; # GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI
1FA5; 1FA5; 1FAD; 1F6D 0399; # GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI
1FA6; 1FA6; 1FAE; 1F6E 0399; # GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
1FA7; 1FA7; 1FAF; 1F6F 0399; # GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
1FA8; 1FA0; 1FA8; 1F68 0399; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI
1FA9; 1FA1; 1FA9; 1F69 0399; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI
1FAA; 1FA2; 1FAA; 1F6A 0399; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI
1FAB; 1FA3; 1FAB; 1F6B 0399; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI
1FAC; 1FA4; 1FAC; 1F6C 0399; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI
1FAD; 1FA5; 1FAD; 1F6D 0399; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI
1FAE; 1FA6; 1FAE; 1F6E 0399; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
1FAF; 1FA7; 1FAF; 1F6F 0399; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
1FB3; 1FB3; 1FBC; 0391 0399; # GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI
1FBC; 1FB3; 1FBC; 0391 0399; # GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI
1FC3; 1FC3; 1FCC; 0397 0399; # GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI
1FCC; 1FC3; 1FCC; 0397 0399; # GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI
1FF3; 1FF3; 1FFC; 03A9 0399; # GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI
1FFC; 1FF3; 1FFC; 03A9 0399; # GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI
# Some characters with YPOGEGRAMMENI also have no corresponding titlecases
1FB2; 1FB2; 1FBA 0345; 1FBA 0399; # GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI
1FB4; 1FB4; 0386 0345; 0386 0399; # GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI
1FC2; 1FC2; 1FCA 0345; 1FCA 0399; # GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI
1FC4; 1FC4; 0389 0345; 0389 0399; # GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI
1FF2; 1FF2; 1FFA 0345; 1FFA 0399; # GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI
1FF4; 1FF4; 038F 0345; 038F 0399; # GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI
1FB7; 1FB7; 0391 0342 0345; 0391 0342 0399; # GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI
1FC7; 1FC7; 0397 0342 0345; 0397 0342 0399; # GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI
1FF7; 1FF7; 03A9 0342 0345; 03A9 0342 0399; # GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI
# ================================================================================
# Conditional Mappings
# The remainder of this file provides conditional casing data used to produce
# full case mappings.
# ================================================================================
# Language-Insensitive Mappings
# These are characters whose full case mappings do not depend on language, but do
# depend on context (which characters come before or after). For more information
# see the header of this file and the Unicode Standard.
# ================================================================================
# Special case for final form of sigma
03A3; 03C2; 03A3; 03A3; Final_Sigma; # GREEK CAPITAL LETTER SIGMA
# Note: the following cases for non-final are already in the UnicodeData.txt file.
# 03A3; 03C3; 03A3; 03A3; # GREEK CAPITAL LETTER SIGMA
# 03C3; 03C3; 03A3; 03A3; # GREEK SMALL LETTER SIGMA
# 03C2; 03C2; 03A3; 03A3; # GREEK SMALL LETTER FINAL SIGMA
# Note: the following cases are not included, since they would case-fold in lowercasing
# 03C3; 03C2; 03A3; 03A3; Final_Sigma; # GREEK SMALL LETTER SIGMA
# 03C2; 03C3; 03A3; 03A3; Not_Final_Sigma; # GREEK SMALL LETTER FINAL SIGMA
# ================================================================================
# Language-Sensitive Mappings
# These are characters whose full case mappings depend on language and perhaps also
# context (which characters come before or after). For more information
# see the header of this file and the Unicode Standard.
# ================================================================================
# Lithuanian
# Lithuanian retains the dot in a lowercase i when followed by accents.
# Remove DOT ABOVE after "i" with upper or titlecase
0307; 0307; ; ; lt After_Soft_Dotted; # COMBINING DOT ABOVE
# Introduce an explicit dot above when lowercasing capital I's and J's
# whenever there are more accents above.
# (of the accents used in Lithuanian: grave, acute, tilde above, and ogonek)
0049; 0069 0307; 0049; 0049; lt More_Above; # LATIN CAPITAL LETTER I
004A; 006A 0307; 004A; 004A; lt More_Above; # LATIN CAPITAL LETTER J
012E; 012F 0307; 012E; 012E; lt More_Above; # LATIN CAPITAL LETTER I WITH OGONEK
00CC; 0069 0307 0300; 00CC; 00CC; lt; # LATIN CAPITAL LETTER I WITH GRAVE
00CD; 0069 0307 0301; 00CD; 00CD; lt; # LATIN CAPITAL LETTER I WITH ACUTE
0128; 0069 0307 0303; 0128; 0128; lt; # LATIN CAPITAL LETTER I WITH TILDE
# ================================================================================
# Turkish and Azeri
# I and i-dotless; I-dot and i are case pairs in Turkish and Azeri
# The following rules handle those cases.
0130; 0069; 0130; 0130; tr; # LATIN CAPITAL LETTER I WITH DOT ABOVE
0130; 0069; 0130; 0130; az; # LATIN CAPITAL LETTER I WITH DOT ABOVE
# When lowercasing, remove dot_above in the sequence I + dot_above, which will turn into i.
# This matches the behavior of the canonically equivalent I-dot_above
0307; ; 0307; 0307; tr After_I; # COMBINING DOT ABOVE
0307; ; 0307; 0307; az After_I; # COMBINING DOT ABOVE
# When lowercasing, unless an I is before a dot_above, it turns into a dotless i.
0049; 0131; 0049; 0049; tr Not_Before_Dot; # LATIN CAPITAL LETTER I
0049; 0131; 0049; 0049; az Not_Before_Dot; # LATIN CAPITAL LETTER I
# When uppercasing, i turns into a dotted capital I
0069; 0069; 0130; 0130; tr; # LATIN SMALL LETTER I
0069; 0069; 0130; 0130; az; # LATIN SMALL LETTER I
# Note: the following case is already in the UnicodeData.txt file.
# 0131; 0131; 0049; 0049; tr; # LATIN SMALL LETTER DOTLESS I
# EOF

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -63,8 +63,16 @@ namespace CharFlag {
const uint8_t UNICODE_ID_CONTINUE = UNICODE_ID_START + UNICODE_ID_CONTINUE_ONLY;
}
const char16_t NO_BREAK_SPACE = 0x00A0;
const char16_t MICRO_SIGN = 0x00B5;
const char16_t LATIN_SMALL_LETTER_SHARP_S = 0x00DF;
const char16_t LATIN_SMALL_LETTER_Y_WITH_DIAERESIS = 0x00FF;
const char16_t LATIN_CAPITAL_LETTER_I_WITH_DOT_ABOVE = 0x0130;
const char16_t COMBINING_DOT_ABOVE = 0x0307;
const char16_t GREEK_CAPITAL_LETTER_SIGMA = 0x03A3;
const char16_t GREEK_SMALL_LETTER_FINAL_SIGMA = 0x03C2;
const char16_t GREEK_SMALL_LETTER_SIGMA = 0x03C3;
const char16_t BYTE_ORDER_MARK2 = 0xFFFE;
const char16_t NO_BREAK_SPACE = 0x00A0;
const char16_t LeadSurrogateMin = 0xD800;
const char16_t LeadSurrogateMax = 0xDBFF;
@ -239,6 +247,10 @@ IsSpaceOrBOM2(char16_t ch)
return CharInfo(ch).isSpace();
}
/*
* Returns the simple upper case mapping (see CanUpperCaseSpecialCasing for
* details) of the given UTF-16 code unit.
*/
inline char16_t
ToUpperCase(char16_t ch)
{
@ -253,6 +265,10 @@ ToUpperCase(char16_t ch)
return uint16_t(ch) + info.upperCase;
}
/*
* Returns the simple lower case mapping (see CanUpperCaseSpecialCasing for
* details) of the given UTF-16 code unit.
*/
inline char16_t
ToLowerCase(char16_t ch)
{
@ -329,6 +345,43 @@ ToLowerCaseNonBMPTrail(char16_t lead, char16_t trail)
return trail;
}
/*
* Returns true if the given UTF-16 code unit has a language-independent,
* unconditional or conditional special upper case mapping.
*
* Unicode defines two case mapping modes:
* 1. "simple case mappings" for one-to-one mappings which are independent of
* context and language (defined in UnicodeData.txt).
* 2. "special case mappings" for mappings which can increase or decrease the
* string length; or are dependent on context or locale (defined in
* SpecialCasing.txt).
*
* The CanUpperCase() method defined above only supports simple case mappings.
* In order to support the full case mappings of all Unicode characters,
* callers need to check this method in addition to CanUpperCase().
*
* NOTE: All special upper case mappings are unconditional in Unicode 9.
*/
bool
CanUpperCaseSpecialCasing(char16_t ch);
/*
* Returns the length of the upper case mapping of |ch|.
*
* This function asserts if |ch| doesn't have a special upper case mapping.
*/
size_t
LengthUpperCaseSpecialCasing(char16_t ch);
/*
* Appends the upper case mapping of |ch| to the given output buffer,
* starting at the provided index.
*
* This function asserts if |ch| doesn't have a special upper case mapping.
*/
void
AppendUpperCaseSpecialCasing(char16_t ch, char16_t* elements, size_t* index);
/*
* For a codepoint C, CodepointsWithSameUpperCaseInfo stores three offsets
* from C to up to three codepoints with same uppercase (no codepoint in
@ -491,7 +544,7 @@ UTF16Encode(uint32_t codePoint, char16_t* lead, char16_t* trail)
*trail = TrailSurrogate(codePoint);
}
static inline void
inline void
UTF16Encode(uint32_t codePoint, char16_t* elements, unsigned* index)
{
if (!IsSupplementary(codePoint)) {

Просмотреть файл

@ -20,6 +20,11 @@
// DIFF: the difference between the code point in the range and
// converted code point
// U+10400 DESERET CAPITAL LETTER LONG I .. U+10427 DESERET CAPITAL LETTER EW
// U+104B0 OSAGE CAPITAL LETTER A .. U+104D3 OSAGE CAPITAL LETTER ZHA
// U+10C80 OLD HUNGARIAN CAPITAL LETTER A .. U+10CB2 OLD HUNGARIAN CAPITAL LETTER US
// U+118A0 WARANG CITI CAPITAL LETTER NGAA .. U+118BF WARANG CITI CAPITAL LETTER VIYO
// U+1E900 ADLAM CAPITAL LETTER ALIF .. U+1E921 ADLAM CAPITAL LETTER SHA
#define FOR_EACH_NON_BMP_LOWERCASE(macro) \
macro(0x10400, 0x10427, 0xd801, 0xdc00, 0xdc27, 40) \
macro(0x104b0, 0x104d3, 0xd801, 0xdcb0, 0xdcd3, 40) \
@ -27,6 +32,11 @@
macro(0x118a0, 0x118bf, 0xd806, 0xdca0, 0xdcbf, 32) \
macro(0x1e900, 0x1e921, 0xd83a, 0xdd00, 0xdd21, 34)
// U+10428 DESERET SMALL LETTER LONG I .. U+1044F DESERET SMALL LETTER EW
// U+104D8 OSAGE SMALL LETTER A .. U+104FB OSAGE SMALL LETTER ZHA
// U+10CC0 OLD HUNGARIAN SMALL LETTER A .. U+10CF2 OLD HUNGARIAN SMALL LETTER US
// U+118C0 WARANG CITI SMALL LETTER NGAA .. U+118DF WARANG CITI SMALL LETTER VIYO
// U+1E922 ADLAM SMALL LETTER ALIF .. U+1E943 ADLAM SMALL LETTER SHA
#define FOR_EACH_NON_BMP_UPPERCASE(macro) \
macro(0x10428, 0x1044f, 0xd801, 0xdc28, 0xdc4f, -40) \
macro(0x104d8, 0x104fb, 0xd801, 0xdcd8, 0xdcfb, -40) \
@ -34,6 +44,11 @@
macro(0x118c0, 0x118df, 0xd806, 0xdcc0, 0xdcdf, -32) \
macro(0x1e922, 0x1e943, 0xd83a, 0xdd22, 0xdd43, -34)
// U+10400 DESERET CAPITAL LETTER LONG I .. U+10427 DESERET CAPITAL LETTER EW
// U+104B0 OSAGE CAPITAL LETTER A .. U+104D3 OSAGE CAPITAL LETTER ZHA
// U+10C80 OLD HUNGARIAN CAPITAL LETTER A .. U+10CB2 OLD HUNGARIAN CAPITAL LETTER US
// U+118A0 WARANG CITI CAPITAL LETTER NGAA .. U+118BF WARANG CITI CAPITAL LETTER VIYO
// U+1E900 ADLAM CAPITAL LETTER ALIF .. U+1E921 ADLAM CAPITAL LETTER SHA
#define FOR_EACH_NON_BMP_CASE_FOLDING(macro) \
macro(0x10400, 0x10427, 0xd801, 0xdc00, 0xdc27, 40) \
macro(0x104b0, 0x104d3, 0xd801, 0xdcb0, 0xdcd3, 40) \
@ -41,6 +56,11 @@
macro(0x118a0, 0x118bf, 0xd806, 0xdca0, 0xdcbf, 32) \
macro(0x1e900, 0x1e921, 0xd83a, 0xdd00, 0xdd21, 34)
// U+10428 DESERET SMALL LETTER LONG I .. U+1044F DESERET SMALL LETTER EW
// U+104D8 OSAGE SMALL LETTER A .. U+104FB OSAGE SMALL LETTER ZHA
// U+10CC0 OLD HUNGARIAN SMALL LETTER A .. U+10CF2 OLD HUNGARIAN SMALL LETTER US
// U+118C0 WARANG CITI SMALL LETTER NGAA .. U+118DF WARANG CITI SMALL LETTER VIYO
// U+1E922 ADLAM SMALL LETTER ALIF .. U+1E943 ADLAM SMALL LETTER SHA
#define FOR_EACH_NON_BMP_REV_CASE_FOLDING(macro) \
macro(0x10428, 0x1044f, 0xd801, 0xdc28, 0xdc4f, -40) \
macro(0x104d8, 0x104fb, 0xd801, 0xdcd8, 0xdcfb, -40) \

Просмотреть файл

@ -26,6 +26,18 @@ import re
import os
import sys
from contextlib import closing
from functools import partial
from itertools import chain, groupby, ifilter, imap, izip_longest, tee
from operator import is_not, itemgetter
class codepoint_dict(dict):
def name(self, code_point):
(_, _, name, alias) = self[code_point]
return '{}{}'.format(name, (' (' + alias + ')' if alias else ''))
def full_name(self, code_point):
(_, _, name, alias) = self[code_point]
return 'U+{:04X} {}{}'.format(code_point, name, (' (' + alias + ')' if alias else ''))
# ECMAScript 2016
# §11.2 White Space
@ -133,10 +145,32 @@ def read_derived_core_properties(derived_core_properties):
for char in range(int(start, 16), int(end, 16) + 1):
yield (char, char_property)
def read_special_casing(special_casing):
# Format:
# <code>; <lower>; <title>; <upper>; (<condition_list>;)? # <comment>
for line in special_casing:
if line == '\n' or line.startswith('#'):
continue
row = line.split('#')[0].split(';')
code = int(row[0].strip(), 16)
lower = row[1].strip()
lower = [int(c, 16) for c in lower.split(' ')] if lower else []
upper = row[3].strip()
upper = [int(c, 16) for c in upper.split(' ')] if upper else []
languages = []
contexts = []
condition = row[4].strip()
if condition:
for cond in condition.split(' '):
if cond[0].islower():
languages.append(cond)
else:
contexts.append(cond)
pass
yield (code, lower, upper, languages, contexts)
def int_ranges(ints):
""" Yields consecutive ranges (inclusive) from integer values. """
from itertools import tee, izip_longest
(a, b) = tee(sorted(ints))
start = next(b)
for (curr, succ) in izip_longest(a, b):
@ -154,7 +188,7 @@ def utf16_encode(code):
return lead, trail
def make_non_bmp_convert_macro(out_file, name, convert_map):
def make_non_bmp_convert_macro(out_file, name, convert_map, codepoint_table):
# Find continuous range in convert_map.
convert_list = []
entry = None
@ -179,6 +213,7 @@ def make_non_bmp_convert_macro(out_file, name, convert_map):
# Generate macro call for each range.
lines = []
comment = []
for entry in convert_list:
from_code = entry['code']
to_code = entry['code'] + entry['length'] - 1
@ -190,29 +225,15 @@ def make_non_bmp_convert_macro(out_file, name, convert_map):
lines.append(' macro(0x{:x}, 0x{:x}, 0x{:x}, 0x{:x}, 0x{:x}, {:d})'.format(
from_code, to_code, lead, from_trail, to_trail, diff))
comment.append('// {} .. {}'.format(codepoint_table.full_name(from_code),
codepoint_table.full_name(to_code)))
out_file.write('\n'.join(comment))
out_file.write('\n')
out_file.write('#define FOR_EACH_NON_BMP_{}(macro) \\\n'.format(name))
out_file.write(' \\\n'.join(lines))
out_file.write('\n')
def for_each_non_bmp_group(group_set):
# Find continuous range in group_set.
group_list = []
entry = None
for code in sorted(group_set.keys()):
if entry and code == entry['code'] + entry['length']:
entry['length'] += 1
continue
entry = {
'code': code,
'length': 1
}
group_list.append(entry)
for entry in group_list:
yield (entry['code'], entry['code'] + entry['length'] - 1)
def process_derived_core_properties(derived_core_properties):
id_start = set()
id_continue = set()
@ -236,7 +257,7 @@ def process_unicode_data(unicode_data, derived_core_properties):
same_upper_cache = {same_upper_dummy: 0}
same_upper_index = [0] * (MAX_BMP + 1)
test_table = {}
codepoint_table = codepoint_dict()
test_space_table = []
non_bmp_lower_map = {}
@ -254,15 +275,9 @@ def process_unicode_data(unicode_data, derived_core_properties):
alias = row[-5]
uppercase = row[-3]
lowercase = row[-2]
flags = 0
if uppercase:
upper = int(uppercase, 16)
if upper not in same_upper_map:
same_upper_map[upper] = [code]
else:
same_upper_map[upper].append(code)
else:
upper = code
@ -271,6 +286,8 @@ def process_unicode_data(unicode_data, derived_core_properties):
else:
lower = code
codepoint_table[code] = (upper, lower, name, alias)
if code > MAX_BMP:
if code != lower:
non_bmp_lower_map[code] = lower
@ -285,6 +302,16 @@ def process_unicode_data(unicode_data, derived_core_properties):
non_bmp_id_cont_set[code] = 1
continue
assert lower <= MAX_BMP and upper <= MAX_BMP
if code != upper:
if upper not in same_upper_map:
same_upper_map[upper] = [code]
else:
same_upper_map[upper].append(code)
flags = 0
# we combine whitespace and lineterminators because in pratice we don't need them separated
if category == 'Zs' or code in whitespace or code in line_terminator:
flags |= FLAG_SPACE
@ -298,8 +325,6 @@ def process_unicode_data(unicode_data, derived_core_properties):
elif code in id_continue or code in compatibility_identifier_part:
flags |= FLAG_UNICODE_ID_CONTINUE_ONLY
test_table[code] = (upper, lower, name, alias)
up_d = upper - code
low_d = lower - code
@ -319,12 +344,12 @@ def process_unicode_data(unicode_data, derived_core_properties):
index[code] = i
for code in range(0, MAX_BMP + 1):
entry = test_table.get(code)
entry = codepoint_table.get(code)
if not entry:
continue
(upper, lower, name, alias) = entry
(upper, _, _, _) = entry
if upper not in same_upper_map:
continue
@ -354,7 +379,7 @@ def process_unicode_data(unicode_data, derived_core_properties):
non_bmp_lower_map, non_bmp_upper_map,
non_bmp_space_set,
non_bmp_id_start_set, non_bmp_id_cont_set,
test_table, test_space_table,
codepoint_table, test_space_table,
)
def process_case_folding(case_folding):
@ -438,9 +463,149 @@ def process_case_folding(case_folding):
folding_tests
)
def process_special_casing(special_casing, table, index):
# Unconditional special casing.
unconditional_tolower = {}
unconditional_toupper = {}
# Conditional special casing, language independent.
conditional_tolower = {}
conditional_toupper = {}
# Conditional special casing, language dependent.
lang_conditional_tolower = {}
lang_conditional_toupper = {}
def caseInfo(code):
(upper, lower, flags) = table[index[code]]
return ((code + lower) & 0xffff, (code + upper) & 0xffff)
for (code, lower, upper, languages, contexts) in read_special_casing(special_casing):
assert code <= MAX_BMP, 'Unexpected character outside of BMP: %s' % code
assert len(languages) <= 1, 'Expected zero or one language ids: %s' % languages
assert len(contexts) <= 1, 'Expected zero or one casing contexts: %s' % languages
(default_lower, default_upper) = caseInfo(code)
special_lower = len(lower) != 1 or lower[0] != default_lower
special_upper = len(upper) != 1 or upper[0] != default_upper
# Invariant: If |code| has casing per UnicodeData.txt, then it also has
# casing rules in SpecialCasing.txt.
assert code == default_lower or len(lower) != 1 or code != lower[0]
assert code == default_upper or len(upper) != 1 or code != upper[0]
language = languages[0] if languages else None
context = contexts[0] if contexts else None
if not language and not context:
if special_lower:
unconditional_tolower[code] = lower
if special_upper:
unconditional_toupper[code] = upper
elif not language and context:
if special_lower:
conditional_tolower[code] = (lower, context)
if special_upper:
conditional_toupper[code] = (upper, context)
else:
if language not in lang_conditional_tolower:
lang_conditional_tolower[language] = {}
lang_conditional_toupper[language] = {}
if special_lower:
lang_conditional_tolower[language][code] = (lower, context)
if special_upper:
lang_conditional_toupper[language][code] = (upper, context)
# Certain special casing rules are inlined in jsstr.cpp, ensure these cases
# still match the current SpecialCasing.txt file.
def lowerCase(code):
(lower, _) = caseInfo(code)
return lower
def upperCase(code):
(_, upper) = caseInfo(code)
return upper
def ascii(char_dict):
return ifilter(lambda ch: ch <= 0x7f, char_dict.iterkeys())
def latin1(char_dict):
return ifilter(lambda ch: ch <= 0xff, char_dict.iterkeys())
def is_empty(iterable):
return not any(True for _ in iterable)
def is_equals(iter1, iter2):
return all(x == y for (x, y) in izip_longest(iter1, iter2))
# Ensure no ASCII characters have special case mappings.
assert is_empty(ascii(unconditional_tolower))
assert is_empty(ascii(unconditional_toupper))
assert is_empty(ascii(conditional_tolower))
assert is_empty(ascii(conditional_toupper))
# Ensure no Latin1 characters have special lower case mappings.
assert is_empty(latin1(unconditional_tolower))
assert is_empty(latin1(conditional_tolower))
# Ensure no Latin1 characters have conditional special upper case mappings.
assert is_empty(latin1(conditional_toupper))
# Ensure U+00DF is the only Latin1 character with a special upper case mapping.
assert is_equals([0x00DF], latin1(unconditional_toupper))
# Ensure U+0130 is the only character with a special lower case mapping.
assert is_equals([0x0130], unconditional_tolower)
# Ensure no characters have language independent conditional upper case mappings.
assert is_empty(conditional_toupper)
# Ensure U+03A3 is the only character with language independent conditional lower case mapping.
assert is_equals([0x03A3], conditional_tolower)
# Verify U+0130 and U+03A3 have simple lower case mappings.
assert all(ch != lowerCase(ch) for ch in [0x0130, 0x03A3])
# Ensure Azeri, Lithuanian, and Turkish are the only languages with conditional case mappings.
assert is_equals(["az", "lt", "tr"], sorted(lang_conditional_tolower.iterkeys()))
assert is_equals(["az", "lt", "tr"], sorted(lang_conditional_toupper.iterkeys()))
# Maximum case mapping length is three characters.
itervals = lambda d: d.itervalues()
assert max(imap(len, chain(
itervals(unconditional_tolower),
itervals(unconditional_toupper),
imap(itemgetter(0), itervals(conditional_tolower)),
imap(itemgetter(0), itervals(conditional_toupper)),
imap(itemgetter(0), chain.from_iterable(imap(itervals, itervals(lang_conditional_tolower)))),
imap(itemgetter(0), chain.from_iterable(imap(itervals, itervals(lang_conditional_toupper)))),
))) <= 3
# Ensure all case mapping contexts are known (see Unicode 9.0, §3.13 Default Case Algorithms).
assert set([
'After_I', 'After_Soft_Dotted', 'Final_Sigma', 'More_Above', 'Not_Before_Dot',
]).issuperset(set(ifilter(partial(is_not, None), chain(
imap(itemgetter(1), itervals(conditional_tolower)),
imap(itemgetter(1), itervals(conditional_toupper)),
imap(itemgetter(1), chain.from_iterable(imap(itervals, itervals(lang_conditional_tolower)))),
imap(itemgetter(1), chain.from_iterable(imap(itervals, itervals(lang_conditional_toupper)))),
))))
# Special casing for U+00DF (LATIN SMALL LETTER SHARP S).
assert upperCase(0x00DF) == 0x00DF and unconditional_toupper[0x00DF] == [0x0053, 0x0053];
# Special casing for U+0130 (LATIN CAPITAL LETTER I WITH DOT ABOVE).
assert unconditional_tolower[0x0130] == [0x0069, 0x0307]
# Special casing for U+03A3 (GREEK CAPITAL LETTER SIGMA).
assert lowerCase(0x03A3) == 0x03C3 and conditional_tolower[0x03A3] == ([0x03C2], 'Final_Sigma');
return (unconditional_tolower, unconditional_toupper)
def make_non_bmp_file(version,
non_bmp_lower_map, non_bmp_upper_map,
non_bmp_folding_map, non_bmp_rev_folding_map):
non_bmp_folding_map, non_bmp_rev_folding_map,
codepoint_table):
file_name = 'UnicodeNonBMP.h';
with io.open(file_name, mode='wb') as non_bmp_file:
non_bmp_file.write(mpl_license)
@ -463,77 +628,277 @@ def make_non_bmp_file(version,
""")
make_non_bmp_convert_macro(non_bmp_file, 'LOWERCASE', non_bmp_lower_map)
make_non_bmp_convert_macro(non_bmp_file, 'LOWERCASE', non_bmp_lower_map, codepoint_table)
non_bmp_file.write('\n')
make_non_bmp_convert_macro(non_bmp_file, 'UPPERCASE', non_bmp_upper_map)
make_non_bmp_convert_macro(non_bmp_file, 'UPPERCASE', non_bmp_upper_map, codepoint_table)
non_bmp_file.write('\n')
make_non_bmp_convert_macro(non_bmp_file, 'CASE_FOLDING', non_bmp_folding_map)
make_non_bmp_convert_macro(non_bmp_file, 'CASE_FOLDING', non_bmp_folding_map, codepoint_table)
non_bmp_file.write('\n')
make_non_bmp_convert_macro(non_bmp_file, 'REV_CASE_FOLDING', non_bmp_rev_folding_map)
make_non_bmp_convert_macro(non_bmp_file, 'REV_CASE_FOLDING', non_bmp_rev_folding_map, codepoint_table)
non_bmp_file.write("""
#endif /* vm_UnicodeNonBMP_h */
""")
def make_bmp_mapping_test(version, test_table):
def write_special_casing_methods(unconditional_toupper, codepoint_table, println):
def hexlit(n):
""" Returns C++ hex-literal for |n|. """
return '0x{:04X}'.format(n)
def describe_range(ranges, depth):
indent = depth * ' '
for (start, end) in ranges:
if start == end:
println(indent, '// {}'.format(codepoint_table.full_name(start)))
else:
println(indent, '// {} .. {}'.format(codepoint_table.full_name(start),
codepoint_table.full_name(end)))
def out_range(start, end):
""" Tests if the input character isn't a member of the set {x | start <= x <= end}. """
if (start == end):
return 'ch != {}'.format(hexlit(start))
return 'ch < {} || ch > {}'.format(hexlit(start), hexlit(end))
def in_range(start, end, parenthesize=False):
""" Tests if the input character is in the set {x | start <= x <= end}. """
if (start == end):
return 'ch == {}'.format(hexlit(start))
(left, right) = ('(', ')') if parenthesize else ('', '')
return '{}ch >= {} && ch <= {}{}'.format(left, hexlit(start), hexlit(end), right)
def in_any_range(ranges, spaces):
""" Tests if the input character is included in any of the given ranges. """
lines = [[]]
for (start, end) in ranges:
expr = in_range(start, end, parenthesize=True)
line = ' || '.join(lines[-1] + [expr])
if len(line) < (100 - len(spaces) - len(' ||')):
lines[-1].append(expr)
else:
lines.append([expr])
return ' ||\n{}'.format(spaces).join(imap(lambda t: ' || '.join(t), lines))
def write_range_accept(parent_list, child_list, depth):
""" Accepts the input character if it matches any code unit in |child_list|. """
(min_parent, max_parent) = (parent_list[0], parent_list[-1])
(min_child, max_child) = (child_list[0], child_list[-1])
assert min_child >= min_parent
assert max_child <= max_parent
indent = depth * ' '
child_ranges = list(int_ranges(child_list))
has_successor = max_child != max_parent
# If |child_list| is a contiguous list of code units, emit a simple
# range check: |min_child <= input <= max_child|.
if len(child_ranges) == 1:
describe_range(child_ranges, depth)
if has_successor:
println(indent, 'if (ch <= {})'.format(hexlit(max_child)))
println(indent, ' return ch >= {};'.format(hexlit(min_child)))
else:
println(indent, 'return {};'.format(in_range(min_child, max_child)))
return
# Otherwise create a disjunction over the subranges in |child_ranges|.
if not has_successor:
spaces = indent + len('return ') * ' '
else:
spaces = indent + len(' return ') * ' '
range_test_expr = in_any_range(child_ranges, spaces)
if min_child != min_parent:
println(indent, 'if (ch < {})'.format(hexlit(min_child)))
println(indent, ' return false;')
# If there's no successor block, we can omit the |input <= max_child| check,
# because it was already checked when we emitted the parent range test.
if not has_successor:
describe_range(child_ranges, depth)
println(indent, 'return {};'.format(range_test_expr))
else:
println(indent, 'if (ch <= {}) {{'.format(hexlit(max_child)))
describe_range(child_ranges, depth + 1)
println(indent, ' return {};'.format(range_test_expr))
println(indent, '}')
def write_CanUpperCaseSpecialCasing():
""" Checks if the input has a special upper case mapping. """
println('bool')
println('js::unicode::CanUpperCaseSpecialCasing(char16_t ch)')
println('{')
assert unconditional_toupper, "|unconditional_toupper| is not empty"
# Sorted list of code units with special upper case mappings.
code_list = sorted(unconditional_toupper.iterkeys())
# Fail-fast if the input character isn't a special casing character.
println(' if ({})'.format(out_range(code_list[0], code_list[-1])))
println(' return false;')
for i in range(0, 16):
# Check if the input characters is in the range:
# |start_point <= input < end_point|.
start_point = i << 12
end_point = (i + 1) << 12
matches = [cu for cu in code_list if start_point <= cu < end_point]
# Skip empty ranges.
if not matches:
continue
# If |matches| consists of only a few characters, directly check
# the input against the characters in |matches|.
if len(matches) <= 8:
write_range_accept(code_list, matches, depth=1)
continue
# Otherwise split into further subranges.
# Only enter the if-block if the input is less-or-equals to the
# largest value in the current range.
is_last_block = matches[-1] == code_list[-1]
if not is_last_block:
println(' if (ch <= {}) {{'.format(hexlit(matches[-1])))
else:
println(' if (ch < {})'.format(hexlit(matches[0])))
println(' return false;')
for j in range(0, 16):
inner_start = start_point + (j << 8)
inner_end = start_point + ((j + 1) << 8)
inner_matches = [cu for cu in matches if inner_start <= cu < inner_end]
if inner_matches:
d = 1 if is_last_block else 2
write_range_accept(matches, inner_matches, depth=d)
if not is_last_block:
println(' }')
println('}')
def write_LengthUpperCaseSpecialCasing():
""" Slow case: Special casing character was found, returns its mapping length. """
println('size_t')
println('js::unicode::LengthUpperCaseSpecialCasing(char16_t ch)')
println('{')
println(' switch(ch) {')
for (code, converted) in sorted(unconditional_toupper.iteritems(), key=itemgetter(0)):
println(' case {}: return {}; // {}'.format(hexlit(code), len(converted),
codepoint_table.name(code)))
println(' }')
println('')
println(' MOZ_ASSERT_UNREACHABLE("Bad character input.");')
println(' return 0;')
println('}')
def write_AppendUpperCaseSpecialCasing():
""" Slow case: Special casing character was found, append its mapping characters. """
println('void')
println('js::unicode::AppendUpperCaseSpecialCasing(char16_t ch, char16_t* elements, size_t* index)')
println('{')
println(' switch(ch) {')
for (code, converted) in sorted(unconditional_toupper.iteritems(), key=itemgetter(0)):
println(' case {}: // {}'.format(hexlit(code), codepoint_table.name(code)))
for ch in converted:
println(' elements[(*index)++] = {}; // {}'.format(hexlit(ch),
codepoint_table.name(ch)))
println(' return;')
println(' }')
println('')
println(' MOZ_ASSERT_UNREACHABLE("Bad character input.");')
println(' return;')
println('}')
write_CanUpperCaseSpecialCasing()
println('')
write_LengthUpperCaseSpecialCasing()
println('')
write_AppendUpperCaseSpecialCasing()
def make_bmp_mapping_test(version, codepoint_table, unconditional_tolower, unconditional_toupper):
def unicodeEsc(n):
return '\u{:04X}'.format(n)
file_name = '../tests/ecma_5/String/string-upper-lower-mapping.js'
with io.open(file_name, mode='wb') as test_mapping:
test_mapping.write(warning_message)
test_mapping.write(unicode_version_message.format(version))
test_mapping.write(public_domain)
test_mapping.write('var mapping = [\n')
with io.open(file_name, mode='wb') as output:
write = partial(print, file=output, sep='', end='')
println = partial(print, file=output, sep='', end='\n')
write(warning_message)
write(unicode_version_message.format(version))
write(public_domain)
println('var mapping = [')
for code in range(0, MAX_BMP + 1):
entry = test_table.get(code)
entry = codepoint_table.get(code)
if entry:
(upper, lower, name, alias) = entry
test_mapping.write(' [' + hex(upper) + ', ' + hex(lower) + '], /* ' +
name + (' (' + alias + ')' if alias else '') + ' */\n')
(upper, lower, _, _) = entry
upper = unconditional_toupper[code] if code in unconditional_toupper else [upper]
lower = unconditional_tolower[code] if code in unconditional_tolower else [lower]
println(' ["{}", "{}"], /* {} */'.format("".join(imap(unicodeEsc, upper)),
"".join(imap(unicodeEsc, lower)),
codepoint_table.name(code)))
else:
test_mapping.write(' [' + hex(code) + ', ' + hex(code) + '],\n')
test_mapping.write('];')
test_mapping.write("""
println(' ["{0}", "{0}"],'.format(unicodeEsc(code)))
println('];')
write("""
assertEq(mapping.length, 0x10000);
for (var i = 0; i <= 0xffff; i++) {
var char = String.fromCharCode(i);
var info = mapping[i];
assertEq(char.toUpperCase().charCodeAt(0), info[0]);
assertEq(char.toLowerCase().charCodeAt(0), info[1]);
assertEq(char.toUpperCase(), info[0]);
assertEq(char.toLowerCase(), info[1]);
}
if (typeof reportCompare === "function")
reportCompare(true, true);
""")
def make_non_bmp_mapping_test(version, non_bmp_upper_map, non_bmp_lower_map):
def make_non_bmp_mapping_test(version, non_bmp_upper_map, non_bmp_lower_map, codepoint_table):
file_name = '../tests/ecma_6/String/string-code-point-upper-lower-mapping.js'
with io.open(file_name, mode='wb') as test_non_bmp_mapping:
test_non_bmp_mapping.write(warning_message)
test_non_bmp_mapping.write(unicode_version_message.format(version))
test_non_bmp_mapping.write(public_domain)
for code in sorted(non_bmp_upper_map.keys()):
test_non_bmp_mapping.write("""\
assertEq(String.fromCodePoint(0x{:x}).toUpperCase().codePointAt(0), 0x{:x});
""".format(code, non_bmp_upper_map[code]))
assertEq(String.fromCodePoint(0x{:04X}).toUpperCase().codePointAt(0), 0x{:04X}); // {}, {}
""".format(code, non_bmp_upper_map[code],
codepoint_table.name(code), codepoint_table.name(non_bmp_upper_map[code])))
for code in sorted(non_bmp_lower_map.keys()):
test_non_bmp_mapping.write("""\
assertEq(String.fromCodePoint(0x{:x}).toLowerCase().codePointAt(0), 0x{:x});
""".format(code, non_bmp_lower_map[code]))
assertEq(String.fromCodePoint(0x{:04X}).toLowerCase().codePointAt(0), 0x{:04X}); // {}, {}
""".format(code, non_bmp_lower_map[code],
codepoint_table.name(code), codepoint_table.name(non_bmp_lower_map[code])))
test_non_bmp_mapping.write("""
if (typeof reportCompare === "function")
reportCompare(true, true);
""")
def make_space_test(version, test_space_table):
def make_space_test(version, test_space_table, codepoint_table):
def hex_and_name(c):
return ' 0x{:04X} /* {} */'.format(c, codepoint_table.name(c))
file_name = '../tests/ecma_5/String/string-space-trim.js'
with io.open(file_name, mode='wb') as test_space:
test_space.write(warning_message)
test_space.write(unicode_version_message.format(version))
test_space.write(public_domain)
test_space.write('var onlySpace = String.fromCharCode(' +
', '.join(map(lambda c: hex(c), test_space_table)) + ');\n')
test_space.write('var onlySpace = String.fromCharCode(\n')
test_space.write(',\n'.join(map(hex_and_name, test_space_table)))
test_space.write('\n);\n')
test_space.write("""
assertEq(onlySpace.trim(), "");
assertEq((onlySpace + 'aaaa').trim(), 'aaaa');
@ -544,14 +909,18 @@ if (typeof reportCompare === "function")
reportCompare(true, true);
""")
def make_regexp_space_test(version, test_space_table):
def make_regexp_space_test(version, test_space_table, codepoint_table):
def hex_and_name(c):
return ' 0x{:04X} /* {} */'.format(c, codepoint_table.name(c))
file_name = '../tests/ecma_6/RegExp/character-class-escape-s.js'
with io.open(file_name, mode='wb') as test_space:
test_space.write(warning_message)
test_space.write(unicode_version_message.format(version))
test_space.write(public_domain)
test_space.write('var onlySpace = String.fromCodePoint(' +
', '.join(map(lambda c: hex(c), test_space_table)) + ');\n')
test_space.write('var onlySpace = String.fromCodePoint(\n')
test_space.write(',\n'.join(map(hex_and_name, test_space_table)))
test_space.write('\n);\n')
test_space.write("""
assertEq(/^\s+$/.exec(onlySpace) !== null, true);
assertEq(/^[\s]+$/.exec(onlySpace) !== null, true);
@ -574,7 +943,10 @@ if (typeof reportCompare === "function")
reportCompare(true, true);
""")
def make_icase_test(version, folding_tests):
def make_icase_test(version, folding_tests, codepoint_table):
def char_hex(c):
return '0x{:04X}'.format(c)
file_name = '../tests/ecma_6/RegExp/unicode-ignoreCase.js'
with io.open(file_name, mode='wb') as test_icase:
test_icase.write(warning_message)
@ -595,7 +967,8 @@ function test(code, ...equivs) {
}
""")
for args in folding_tests:
test_icase.write('test(' + ','.join([hex(c) for c in args]) + ');\n')
test_icase.write('test({}); // {}\n'.format(', '.join(map(char_hex, args)),
', '.join(map(codepoint_table.name, args))))
test_icase.write("""
if (typeof reportCompare === "function")
reportCompare(true, true);
@ -606,7 +979,9 @@ def make_unicode_file(version,
same_upper_table, same_upper_index,
folding_table, folding_index,
non_bmp_space_set,
non_bmp_id_start_set, non_bmp_id_cont_set):
non_bmp_id_start_set, non_bmp_id_cont_set,
unconditional_toupper,
codepoint_table):
index1, index2, shift = splitbins(index)
# Don't forget to update CharInfo in Unicode.h if you need to change this
@ -695,8 +1070,8 @@ def make_unicode_file(version,
* stop if you found the best shift
*/
"""
def dump(data, name, file):
file.write('const uint8_t unicode::' + name + '[] = {\n')
def dump(data, name, println):
println('const uint8_t unicode::{}[] = {{'.format(name))
line = pad = ' ' * 4
lines = []
@ -712,93 +1087,79 @@ def make_unicode_file(version,
line = line + s + ', '
lines.append(line.rstrip())
file.write('\n'.join(lines))
file.write('\n};\n')
println('\n'.join(lines))
println('};')
def write_table(data_type, name, tbl, idx1_name, idx1, idx2_name, idx2, println):
println('const {} unicode::{}[] = {{'.format(data_type, name))
for d in tbl:
println(' {{ {} }},'.format(', '.join(str(e) for e in d)))
println('};')
println('')
dump(idx1, idx1_name, println)
println('')
dump(idx2, idx2_name, println)
println('')
def write_supplemental_identifier_method(name, group_set, println):
println('bool')
println('js::unicode::{}(uint32_t codePoint)'.format(name))
println('{')
for (from_code, to_code) in int_ranges(group_set.keys()):
println(' if (codePoint >= 0x{:X} && codePoint <= 0x{:X}) // {} .. {}'.format(from_code,
to_code,
codepoint_table.name(from_code),
codepoint_table.name(to_code)))
println(' return true;')
println(' return false;')
println('}')
println('')
file_name = 'Unicode.cpp'
with io.open(file_name, 'wb') as data_file:
data_file.write(warning_message)
data_file.write(unicode_version_message.format(version))
data_file.write(public_domain)
data_file.write('#include "vm/Unicode.h"\n\n')
data_file.write('using namespace js;\n');
data_file.write('using namespace js::unicode;\n')
data_file.write(comment)
data_file.write('const CharacterInfo unicode::js_charinfo[] = {\n')
for d in table:
data_file.write(' {')
data_file.write(', '.join((str(e) for e in d)))
data_file.write('},\n')
data_file.write('};\n')
data_file.write('\n')
write = partial(print, file=data_file, sep='', end='')
println = partial(print, file=data_file, sep='', end='\n')
dump(index1, 'index1', data_file)
data_file.write('\n')
dump(index2, 'index2', data_file)
data_file.write('\n')
write(warning_message)
write(unicode_version_message.format(version))
write(public_domain)
println('#include "vm/Unicode.h"')
println('')
println('using namespace js;')
println('using namespace js::unicode;')
write(comment)
data_file.write('const CodepointsWithSameUpperCaseInfo unicode::js_codepoints_with_same_upper_info[] = {\n')
for d in same_upper_table:
data_file.write(' {')
data_file.write(', '.join((str(e) for e in d)))
data_file.write('},\n')
data_file.write('};\n')
data_file.write('\n')
write_table('CharacterInfo',
'js_charinfo', table,
'index1', index1,
'index2', index2,
println)
dump(same_upper_index1, 'codepoints_with_same_upper_index1', data_file)
data_file.write('\n')
dump(same_upper_index2, 'codepoints_with_same_upper_index2', data_file)
data_file.write('\n')
write_table('CodepointsWithSameUpperCaseInfo',
'js_codepoints_with_same_upper_info', same_upper_table,
'codepoints_with_same_upper_index1', same_upper_index1,
'codepoints_with_same_upper_index2', same_upper_index2,
println)
data_file.write('const FoldingInfo unicode::js_foldinfo[] = {\n')
for d in folding_table:
data_file.write(' {')
data_file.write(', '.join((str(e) for e in d)))
data_file.write('},\n')
data_file.write('};\n')
data_file.write('\n')
dump(folding_index1, 'folding_index1', data_file)
data_file.write('\n')
dump(folding_index2, 'folding_index2', data_file)
data_file.write('\n')
write_table('FoldingInfo',
'js_foldinfo', folding_table,
'folding_index1', folding_index1,
'folding_index2', folding_index2,
println)
# If the following assert fails, it means space character is added to
# non-BMP area. In that case the following code should be uncommented
# and the corresponding code should be added to frontend.
assert len(non_bmp_space_set.keys()) == 0
data_file.write("""\
bool
js::unicode::IsIdentifierStartNonBMP(uint32_t codePoint)
{
""")
write_supplemental_identifier_method('IsIdentifierStartNonBMP', non_bmp_id_start_set,
println)
for (from_code, to_code) in for_each_non_bmp_group(non_bmp_id_start_set):
data_file.write("""\
if (codePoint >= 0x{:x} && codePoint <= 0x{:x})
return true;
""".format(from_code, to_code))
write_supplemental_identifier_method('IsIdentifierPartNonBMP', non_bmp_id_cont_set,
println)
data_file.write("""\
return false;
}
bool
js::unicode::IsIdentifierPartNonBMP(uint32_t codePoint)
{
""")
for (from_code, to_code) in for_each_non_bmp_group(non_bmp_id_cont_set):
data_file.write("""\
if (codePoint >= 0x{:x} && codePoint <= 0x{:x})
return true;
""".format(from_code, to_code))
data_file.write("""\
return false;
}
""")
write_special_casing_methods(unconditional_toupper, codepoint_table, println)
def getsize(data):
""" return smallest possible integer size for the given array """
@ -872,10 +1233,8 @@ def splitbins(t):
def make_irregexp_tables(version,
table, index,
folding_table, folding_index,
test_table):
codepoint_table):
import string
from functools import partial
from itertools import chain, ifilter, imap
MAX_ASCII = 0x7F
MAX_LATIN1 = 0xFF
@ -924,13 +1283,13 @@ def make_irregexp_tables(version,
def char_name(code):
assert 0 <= code and code <= MAX_BMP
if code not in test_table:
if code not in codepoint_table:
return '<Unused>'
if code == LEAD_SURROGATE_MIN:
return '<Lead Surrogate Min>'
if code == TRAIL_SURROGATE_MAX:
return '<Trail Surrogate Max>'
(_, _, name, alias) = test_table[code]
(_, _, name, alias) = codepoint_table[code]
return name if not name.startswith('<') else alias
def write_character_range(println, name, characters):
@ -1110,7 +1469,8 @@ def update_unicode(args):
with download_or_open('UnicodeData.txt') as unicode_data, \
download_or_open('CaseFolding.txt') as case_folding, \
download_or_open('DerivedCoreProperties.txt') as derived_core_properties:
download_or_open('DerivedCoreProperties.txt') as derived_core_properties, \
download_or_open('SpecialCasing.txt') as special_casing:
unicode_version = version_from_file(derived_core_properties, 'DerivedCoreProperties')
print('Processing...')
@ -1120,13 +1480,16 @@ def update_unicode(args):
non_bmp_lower_map, non_bmp_upper_map,
non_bmp_space_set,
non_bmp_id_start_set, non_bmp_id_cont_set,
test_table, test_space_table
codepoint_table, test_space_table
) = process_unicode_data(unicode_data, derived_core_properties)
(
folding_table, folding_index,
non_bmp_folding_map, non_bmp_rev_folding_map,
folding_tests
) = process_case_folding(case_folding)
(
unconditional_tolower, unconditional_toupper
) = process_special_casing(special_casing, table, index)
print('Generating...')
make_unicode_file(unicode_version,
@ -1134,20 +1497,24 @@ def update_unicode(args):
same_upper_table, same_upper_index,
folding_table, folding_index,
non_bmp_space_set,
non_bmp_id_start_set, non_bmp_id_cont_set)
non_bmp_id_start_set, non_bmp_id_cont_set,
unconditional_toupper,
codepoint_table)
make_non_bmp_file(unicode_version,
non_bmp_lower_map, non_bmp_upper_map,
non_bmp_folding_map, non_bmp_rev_folding_map)
non_bmp_folding_map, non_bmp_rev_folding_map,
codepoint_table)
make_irregexp_tables(unicode_version,
table, index,
folding_table, folding_index,
test_table)
codepoint_table)
make_bmp_mapping_test(unicode_version, test_table)
make_non_bmp_mapping_test(unicode_version, non_bmp_upper_map, non_bmp_lower_map)
make_space_test(unicode_version, test_space_table)
make_regexp_space_test(unicode_version, test_space_table)
make_icase_test(unicode_version, folding_tests)
make_bmp_mapping_test(unicode_version,
codepoint_table, unconditional_tolower, unconditional_toupper)
make_non_bmp_mapping_test(unicode_version, non_bmp_upper_map, non_bmp_lower_map, codepoint_table)
make_space_test(unicode_version, test_space_table, codepoint_table)
make_regexp_space_test(unicode_version, test_space_table, codepoint_table)
make_icase_test(unicode_version, folding_tests, codepoint_table)
if __name__ == '__main__':
import argparse

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,954 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/. */
//
//***************************************************************************
// This is an automatically generated file. It's used to maintain state for
// runs of genRootCAHashes.js; you should never need to manually edit it
//***************************************************************************
{
"roots": [
{
"label": "GTE_CyberTrust_Global_Root",
"binNumber": 1,
"sha256Fingerprint": "pTElGI0hEKqWSwLHt8baMgMXCJTl+3H/+2Zn1eaBCjY="
},
{
"label": "Thawte_Server_CA",
"binNumber": 2,
"sha256Fingerprint": "tEELc+Lm6spH+8Qvj6QBivQ4HcVM+qhEUEYe7QlFTek="
},
{
"label": "Thawte_Premium_Server_CA",
"binNumber": 3,
"sha256Fingerprint": "q3A2NlxxVKopwsKfXUGRFjsWKiIlARNX1W0H/6e8H3I="
},
{
"label": "OU_Equifax_Secure_Certificate_Authority_O_Equifax_C_US",
"binNumber": 4,
"sha256Fingerprint": "CCl6QEfbojaAxzHbbjF2U8p4SOG+vToLAXmnB/ks8Xg="
},
{
"label": "OU_VeriSign_Trust_Network_OU___c__1998_VeriSign__Inc____For_authorized_use_only__OU_Class_3_Public_Primary_Certification_Authority___G2_O__VeriSign__Inc___C_US",
"binNumber": 5,
"sha256Fingerprint": "g848Eiloilk9SF+BlzwPkZVDHto3zF42Qw55x6iIY4s="
},
{
"label": "GlobalSign_Root_CA",
"binNumber": 6,
"sha256Fingerprint": "69QQQOS7PsdCyeOB0x7ypBpItmhclufO88HfbNQzHJk="
},
{
"label": "GlobalSign",
"binNumber": 7,
"sha256Fingerprint": "ykLdQXRf0LgeuQI2LPnYv3Gdob0bHvyUb1tMmfQsG54="
},
{
"label": "VeriSign_Class_3_Public_Primary_Certification_Authority___G3",
"binNumber": 8,
"sha256Fingerprint": "6wTPXrHzmvp2LyuxIPKWy6Ugwbl9sViVZbgcuaF7ckQ="
},
{
"label": "VeriSign_Class_4_Public_Primary_Certification_Authority___G3",
"binNumber": 9,
"sha256Fingerprint": "44k2DQ/brrPSUFhLRzAxTiIvOcFWoCAUTo2WBWF5FQY="
},
{
"label": "Entrust_net_Certification_Authority__2048_",
"binNumber": 10,
"sha256Fingerprint": "bcRxcuAcvLC/YlgNiV/iuKya1PhzgB4MELnIN9IesXc="
},
{
"label": "Baltimore_CyberTrust_Root",
"binNumber": 11,
"sha256Fingerprint": "Fq9XqfZ2sKsSYJWqXrre8iqzERnWRKyVzUuT2/Pyaus="
},
{
"label": "Equifax_Secure_Global_eBusiness_CA_1",
"binNumber": 12,
"sha256Fingerprint": "Xwti6rXjU+plIWUWWPu2U1n0QygKSvvRBNd9EPnwTAc="
},
{
"label": "Equifax_Secure_eBusiness_CA_1",
"binNumber": 13,
"sha256Fingerprint": "z1b/RqShhhCd2WWEte61ilEMQnWw5flPQLuuhl4Z9nM="
},
{
"label": "AddTrust_Class_1_CA_Root",
"binNumber": 14,
"sha256Fingerprint": "jHIJJ5rATideFtB/07d16AFUtZaARuMfUt0ldmMk6ac="
},
{
"label": "AddTrust_External_CA_Root",
"binNumber": 15,
"sha256Fingerprint": "aH+kUTgieP/wyLEfjUPVdmccbrK86rQT+4PZZdBtL/I="
},
{
"label": "AddTrust_Public_CA_Root",
"binNumber": 16,
"sha256Fingerprint": "B5HKB0myB4Kq08fXvQzfyUhYNYQ+steZYAnOQ6tsaSc="
},
{
"label": "AddTrust_Qualified_CA_Root",
"binNumber": 17,
"sha256Fingerprint": "gJUhCAXbS7w1XkQo2P1uws3jq1+5eplCmI649NzQYBY="
},
{
"label": "Entrust_Root_Certification_Authority",
"binNumber": 18,
"sha256Fingerprint": "c8F2Q08bxtWt9FsOducnKHyN5XYWwebmFBorLLx9jkw="
},
{
"label": "OU_RSA_Security_2048_V3_O_RSA_Security_Inc",
"binNumber": 19,
"sha256Fingerprint": "r4tnYqHlKCKBYaldXFWe4mYnj3XXnoMBiaUDUGq9a0w="
},
{
"label": "GeoTrust_Global_CA",
"binNumber": 20,
"sha256Fingerprint": "/4VqLSUdzYjTZlb0UBJnmM+rqt5AeZxyLeTStds2pzo="
},
{
"label": "GeoTrust_Global_CA_2",
"binNumber": 21,
"sha256Fingerprint": "yi2CoIZ3By+KtnZP8DVnbP4+XjJeASFy3z+SCW23m4U="
},
{
"label": "GeoTrust_Universal_CA",
"binNumber": 22,
"sha256Fingerprint": "oEWbn2OyJVn1+l1MbbP59y/xk0IDNXjwc78dG0bLuRI="
},
{
"label": "GeoTrust_Universal_CA_2",
"binNumber": 23,
"sha256Fingerprint": "oCNPO8hSfKVijuyBrV1piV2laA3JHRy4R38z+Hi5Wws="
},
{
"label": "America_Online_Root_Certification_Authority_1",
"binNumber": 24,
"sha256Fingerprint": "d0BzEsY6FT1bwAtOUXWc39rCN9wqM7Z5RumOm/poCuM="
},
{
"label": "America_Online_Root_Certification_Authority_2",
"binNumber": 25,
"sha256Fingerprint": "fTtGWmAU5SbAr/zuISfSMRcnrYEcJoQtAGrzcwbMgL0="
},
{
"label": "Visa_eCommerce_Root",
"binNumber": 26,
"sha256Fingerprint": "afrJvVX7CseNU7vuXPHVl5if0KqrIKJRUb3xcz7n0SI="
},
{
"label": "Certum_CA",
"binNumber": 27,
"sha256Fingerprint": "2OD+vB2y440AlA830n1BNE2ZPnNLmdVlbZd41NgUNiQ="
},
{
"label": "AAA_Certificate_Services",
"binNumber": 28,
"sha256Fingerprint": "16eg+11+JzHXcelITrze9x1fDD4KKUh4K8g+4OppnvQ="
},
{
"label": "Secure_Certificate_Services",
"binNumber": 29,
"sha256Fingerprint": "vYHOO09lkdEaZ7X8ekf97yVSG/mqThi5498uNKeAO+g="
},
{
"label": "Trusted_Certificate_Services",
"binNumber": 30,
"sha256Fingerprint": "PwblVoHUlvW+Fp61OJ+fK4/2HhcI32iBckhJzV0ny2k="
},
{
"label": "QuoVadis_Root_Certification_Authority",
"binNumber": 31,
"sha256Fingerprint": "pF7eO7vwnIrhXHLvwHJo1pOiHJlv1R5nygeUYP1tiHM="
},
{
"label": "QuoVadis_Root_CA_2",
"binNumber": 32,
"sha256Fingerprint": "haDdfdcgrbf/Bfg9VCsgncf/RSj31nexg4n+peXEnoY="
},
{
"label": "QuoVadis_Root_CA_3",
"binNumber": 33,
"sha256Fingerprint": "GPH8fyBd+K3d63/gB91X4683WpxNjXNUa/Tx/tHhjTU="
},
{
"label": "OU_Security_Communication_RootCA1_O_SECOM_Trust_net_C_JP",
"binNumber": 34,
"sha256Fingerprint": "515y7Z9WDuxutIAAc6Q/w60ZGVo5IoIBeJWXSpkCa2w="
},
{
"label": "Sonera_Class2_CA",
"binNumber": 35,
"sha256Fingerprint": "eQi0AxTBOBALUY0HNYB/+/z4UYoAlTNxBbo4axU92Sc="
},
{
"label": "Staat_der_Nederlanden_Root_CA",
"binNumber": 36,
"sha256Fingerprint": "1B2CnowWWYIq+T/OYr/83iZPyE6LlQxf8nXQUjVGlaM="
},
{
"label": "UTN___DATACorp_SGC",
"binNumber": 37,
"sha256Fingerprint": "hfsvkd0SJ1oBRbY2U0+EAkrWi2m47ohoT/cRN1gFs0g="
},
{
"label": "UTN_USERFirst_Hardware",
"binNumber": 38,
"sha256Fingerprint": "bqVHQdAEZn7tG0gWY0qjp55uS5aVD4J52vyNm9iBITc="
},
{
"label": "Chambers_of_Commerce_Root",
"binNumber": 39,
"sha256Fingerprint": "DCWKEqVnSu8l8oun3Prs7qNI5UHm9cxO5jtxs2FgasM="
},
{
"label": "Global_Chambersign_Root",
"binNumber": 40,
"sha256Fingerprint": "7zy0F/yOv2+Xh2yeTs453h6l/mSRQdECi30RwLIpjO0="
},
{
"label": "NetLock_Kozjegyzoi__Class_A__Tanusitvanykiado",
"binNumber": 41,
"sha256Fingerprint": "fxLNX35eKQ7H2FF51bcsIKW+dQj/21v4GrloSn/J9mc="
},
{
"label": "XRamp_Global_Certification_Authority",
"binNumber": 42,
"sha256Fingerprint": "zs3ckFCZ2NrfxbHSCbc3y+LBjPssEMD/C88NMob8GqI="
},
{
"label": "OU_Go_Daddy_Class_2_Certification_Authority_O__The_Go_Daddy_Group__Inc___C_US",
"binNumber": 43,
"sha256Fingerprint": "w4Rr8kuek8pkJ0wOxnwezF4CT/ys0tdAGTUOgf5UauQ="
},
{
"label": "OU_Starfield_Class_2_Certification_Authority_O__Starfield_Technologies__Inc___C_US",
"binNumber": 44,
"sha256Fingerprint": "FGX6IFOXuHb6pvCplY5VkOQPzH+qT7fCyGd1Iftftlg="
},
{
"label": "StartCom_Certification_Authority",
"binNumber": 45,
"sha256Fingerprint": "x2apvvLUBxyGOjGqSSDoE7LRmGCMt7fP4hFDuDbfCeo="
},
{
"label": "O_Government_Root_Certification_Authority_C_TW",
"binNumber": 46,
"sha256Fingerprint": "dgApXu/oW54f1iTbdgYqqq5ZgYpU0ndM1MCywBEx4bM="
},
{
"label": "Swisscom_Root_CA_1",
"binNumber": 47,
"sha256Fingerprint": "IdsgEjZguy7UGCBdoR7nqFpl4rxuVbWvfniZyKJm2S4="
},
{
"label": "DigiCert_Assured_ID_Root_CA",
"binNumber": 48,
"sha256Fingerprint": "PpCZtQFej0hsALzqnREe5yH6ujVaibzx32lWHj3GMlw="
},
{
"label": "DigiCert_Global_Root_CA",
"binNumber": 49,
"sha256Fingerprint": "Q0ig6URMeMsmXgWNXolEtNhPlmK9Jtslf4k0pEPHAWE="
},
{
"label": "DigiCert_High_Assurance_EV_Root_CA",
"binNumber": 50,
"sha256Fingerprint": "dDHl9MPBzkaQd08LYeBUQIg7qaAe0Aumq9eAbtOxGM8="
},
{
"label": "Class_2_Primary_CA",
"binNumber": 51,
"sha256Fingerprint": "D5k8iu+Xuq9WhxQO1ZrRghu0r6zwqppYtdV6M4o6+8s="
},
{
"label": "DST_Root_CA_X3",
"binNumber": 52,
"sha256Fingerprint": "BocmAzGnJAPZCfEF5pvPDTLhvSST/8bZIG0RvNZ3Bzk="
},
{
"label": "DST_ACES_CA_X6",
"binNumber": 53,
"sha256Fingerprint": "dnyVWnZBLImvaI6QoccPVWz9a2Al2+oQQW1+toMfjEA="
},
{
"label": "T_RKTRUST_Elektronik_Sertifika_Hizmet_Sa_lay_c_s_",
"binNumber": 54,
"sha256Fingerprint": "RATjO14UDc+ZgFH9/IAox8gWFcXuc3sRG1iCM6m1NaA="
},
{
"label": "T_RKTRUST_Elektronik_Sertifika_Hizmet_Sa_lay_c_s_",
"binNumber": 55,
"sha256Fingerprint": "xHDPVH4jArl3+yndcaiae2wfYHd7Ayn1YBfzKL9Pa+Y="
},
{
"label": "SwissSign_Gold_CA___G2",
"binNumber": 56,
"sha256Fingerprint": "Yt0L6bn1ChY+oPjnXAU7HspX6lXIaI9kfGiB8sg1e5U="
},
{
"label": "SwissSign_Silver_CA___G2",
"binNumber": 57,
"sha256Fingerprint": "vmxNoru5ulm285OXaDdCRsPABZk/qY8CDR3tvtSKgdU="
},
{
"label": "GeoTrust_Primary_Certification_Authority",
"binNumber": 58,
"sha256Fingerprint": "N9UQBsUS6qtiZCHx7IySAT/F+CrpjuUz60YZuN600Gw="
},
{
"label": "thawte_Primary_Root_CA",
"binNumber": 59,
"sha256Fingerprint": "jXIvganBE8B5HfE2opZtsmyVCpcdtGtBmfTqVLeL+58="
},
{
"label": "VeriSign_Class_3_Public_Primary_Certification_Authority___G5",
"binNumber": 60,
"sha256Fingerprint": "ms+rfkPI2IDQayYqlN7u5LRlmYnD0Mrxm69kBeQat98="
},
{
"label": "SecureTrust_CA",
"binNumber": 61,
"sha256Fingerprint": "8cG1CuWiDdgDDsn2vCSCPdNntSVXWbTnG2H86fc3XXM="
},
{
"label": "Secure_Global_CA",
"binNumber": 62,
"sha256Fingerprint": "QgD1BDrIWQ67Un0gntFQMCn7y9QcobUG7CfxWt59rGk="
},
{
"label": "COMODO_Certification_Authority",
"binNumber": 63,
"sha256Fingerprint": "DCzWPfeAb6OZ7egJEWtXW/h5ifBlGPmAjIYFAxeLr2Y="
},
{
"label": "Network_Solutions_Certificate_Authority",
"binNumber": 64,
"sha256Fingerprint": "FfC6AKOsevOsiEwHKxARoHe9d8CX9AFksvhZir2Dhgw="
},
{
"label": "WellsSecure_Public_Root_Certificate_Authority",
"binNumber": 65,
"sha256Fingerprint": "pxJyrqqjz+hyf3+znw+z0eVCbpBgsG7m8T6aPFgzzUM="
},
{
"label": "COMODO_ECC_Certification_Authority",
"binNumber": 66,
"sha256Fingerprint": "F5OSegYUVJeJrc4vjzT38LZtDzrjo7hNIewV27pPrcc="
},
{
"label": "IGC_A",
"binNumber": 67,
"sha256Fingerprint": "ub6nhgqWLqNhHauXq22j4hwQaLl9VVde0OESecEciTI="
},
{
"label": "OU_Security_Communication_EV_RootCA1_O__SECOM_Trust_Systems_CO__LTD___C_JP",
"binNumber": 68,
"sha256Fingerprint": "oi26aB6XN24tOX1yiq46m2KWuf26YLwuEfZH8sZ1+zc="
},
{
"label": "OISTE_WISeKey_Global_Root_GA_CA",
"binNumber": 69,
"sha256Fingerprint": "Qckjhmq0yta3rVeAgVguAgeXpsvfT/94zoOWs4k31/U="
},
{
"label": "Microsec_e_Szigno_Root_CA",
"binNumber": 70,
"sha256Fingerprint": "Mno9dhq63qA065mEBidcsaR3bv2uL99tAWjqHE9VZ9A="
},
{
"label": "Certigna",
"binNumber": 71,
"sha256Fingerprint": "47ai2y7XzkiEL3rFMkHHtx1UFEv7QMEfPx0LQvXuoS0="
},
{
"label": "TC_TrustCenter_Class_2_CA_II",
"binNumber": 72,
"sha256Fingerprint": "5rj4dmSF+Aeuf42sFnBGHwfAoT7vOh/3F1ONerrTkbQ="
},
{
"label": "TC_TrustCenter_Class_3_CA_II",
"binNumber": 73,
"sha256Fingerprint": "jaCE/Pmc4Hci+JsyBZOYBvpcuBHhyBP2oQjH0zazQI4="
},
{
"label": "TC_TrustCenter_Universal_CA_I",
"binNumber": 74,
"sha256Fingerprint": "6/PAKoeJsft9URmV1mO3KQbZE84NXhBWiop34lhhZ+c="
},
{
"label": "Deutsche_Telekom_Root_CA_2",
"binNumber": 75,
"sha256Fingerprint": "thkaUNDDl399qZvNqshqIn2uuWeexwujsMnZInHBcNM="
},
{
"label": "ComSign_Secured_CA",
"binNumber": 76,
"sha256Fingerprint": "UHlBx0RgoLRwhiINTpkyVyq10bW7y4mAqxyxdlGoRNI="
},
{
"label": "Cybertrust_Global_Root",
"binNumber": 77,
"sha256Fingerprint": "lgrfAGPpY1Z1DCll3QoIZ9oLnL1ud3FK6vsjSas5PaM="
},
{
"label": "OU_ePKI_Root_Certification_Authority_O__Chunghwa_Telecom_Co___Ltd___C_TW",
"binNumber": 78,
"sha256Fingerprint": "wKb03GOiS/3PVO8qaggqCnLeNYA+L/X/Unrl2HIG39U="
},
{
"label": "T_B_TAK_UEKAE_K_k_Sertifika_Hizmet_Sa_lay_c_s____S_r_m_3",
"binNumber": 79,
"sha256Fingerprint": "5Mc0MNeltQkl30M3Cg0hbpp5udbbg3Ogxp6xzDHHxSo="
},
{
"label": "Buypass_Class_2_CA_1",
"binNumber": 80,
"sha256Fingerprint": "D06c3SZLAlVQ0XCAY0AhT+lENMmwL2l+xxD8X+r7Xjg="
},
{
"label": "Buypass_Class_3_CA_1",
"binNumber": 81,
"sha256Fingerprint": "t7ErFx+CHaqZDND+UIexKESLqOUYT4TFHgK1yPuWKyQ="
},
{
"label": "EBG_Elektronik_Sertifika_Hizmet_Sa_lay_c_s_",
"binNumber": 82,
"sha256Fingerprint": "Na5b3dj3rmNc/7pWgqjwC5X0hGLHEI7poOUpKwdKr7I="
},
{
"label": "OU_certSIGN_ROOT_CA_O_certSIGN_C_RO",
"binNumber": 83,
"sha256Fingerprint": "6qlixPpKa6/r5BUZbTUczYiNT1Pz+orm18RmqU5gQrs="
},
{
"label": "CNNIC_ROOT",
"binNumber": 84,
"sha256Fingerprint": "4oOTdz2oRaZ58ggMx/tEo7ehw3kst+t3Kf3Lao2Zrqc="
},
{
"label": "OU_ApplicationCA_O_Japanese_Government_C_JP",
"binNumber": 85,
"sha256Fingerprint": "LUdDfeF5USFaEvPFjlHHKaWAJu8fzApfs9ncAS9gDRk="
},
{
"label": "GeoTrust_Primary_Certification_Authority___G3",
"binNumber": 86,
"sha256Fingerprint": "tHi4EiUN+HhjXCqn7H0VXqpiXugpFuLNKUNhiGzR+9Q="
},
{
"label": "thawte_Primary_Root_CA___G2",
"binNumber": 87,
"sha256Fingerprint": "pDENUK8YpkRxkDcqhq+vi5Uf+0Mdg38eVoi0WXHtFVc="
},
{
"label": "thawte_Primary_Root_CA___G3",
"binNumber": 88,
"sha256Fingerprint": "SwP0WAetcPIb/Cyuccn95GBMBkz1/7aGuuXbqtf900w="
},
{
"label": "GeoTrust_Primary_Certification_Authority___G2",
"binNumber": 89,
"sha256Fingerprint": "Xtt6xDuCoGqHYejXvkl56/JhH33Xm/kcHGtWaiGe12Y="
},
{
"label": "VeriSign_Universal_Root_Certification_Authority",
"binNumber": 90,
"sha256Fingerprint": "I5lWESelcSXejO/qYQ3fL6B4tcgGf06CgpC/uGDoSzw="
},
{
"label": "VeriSign_Class_3_Public_Primary_Certification_Authority___G4",
"binNumber": 91,
"sha256Fingerprint": "ad3X6pC7V8k+E13IXqb81UgLYDI5vcRU/HWLKibPf3k="
},
{
"label": "NetLock_Arany__Class_Gold__F_tan_s_tv_ny",
"binNumber": 92,
"sha256Fingerprint": "bGHaw6Le8DFQa+A20qb+QBmU+9E9+cjUZlmSdMRG7Jg="
},
{
"label": "Staat_der_Nederlanden_Root_CA___G2",
"binNumber": 93,
"sha256Fingerprint": "ZoyDlH2mO3JL7OF0PDGg5q7Q247Fsxvjd7t4T5G2cW8="
},
{
"label": "CA_Disig",
"binNumber": 94,
"sha256Fingerprint": "kr9RGavsytCxMy3E4dBfunW1Z5BE7gyibpMfdE8vM88="
},
{
"label": "Juur_SK",
"binNumber": 95,
"sha256Fingerprint": "7MPpw0B1A77gkaqVL0E0j/iLqoY7ImS++sgHkBV06Tk="
},
{
"label": "Hongkong_Post_Root_CA_1",
"binNumber": 96,
"sha256Fingerprint": "+eZ9M2xRACrAVMYyAi1m3aLn4//xCtBh7THYu7QQz7I="
},
{
"label": "SecureSign_RootCA11",
"binNumber": 97,
"sha256Fingerprint": "vw/u+546WBrV+enbdYmYV0PSYQhcTTFPb11yWapCFhI="
},
{
"label": "ACEDICOM_Root",
"binNumber": 98,
"sha256Fingerprint": "A5UPtJpTHz4ZkZQjmN+p4Ooy17oc3ZvIXbV+2UALQ0o="
},
{
"label": "Microsec_e_Szigno_Root_CA_2009",
"binNumber": 99,
"sha256Fingerprint": "PF+B/qX6uCxkv6Lq7K/N6OB3/IYgp8rlNxY9827b83g="
},
{
"label": "e_Guven_Kok_Elektronik_Sertifika_Hizmet_Saglayicisi",
"binNumber": 100,
"sha256Fingerprint": "5gkHhGWkGXgMtqxMHAv7RlPZ2cxus5Rut/PWmZe61Zg="
},
{
"label": "GlobalSign",
"binNumber": 101,
"sha256Fingerprint": "y7Ui17fxJ61qAROGW98c1BAufQdZr2NafPRyDcljxTs="
},
{
"label": "Autoridad_de_Certificacion_Firmaprofesional_CIF_A62634068",
"binNumber": 102,
"sha256Fingerprint": "BASAKL8fKGTUj5rU2DKUNmqCiFZVPzsUMD+QFH9dQO8="
},
{
"label": "Izenpe_com",
"binNumber": 103,
"sha256Fingerprint": "JTDMjpgyFQK62W+bH7obCZ4tKZ4PRUi7kU82O8DUUx8="
},
{
"label": "Chambers_of_Commerce_Root___2008",
"binNumber": 104,
"sha256Fingerprint": "Bj5K+sSR39My8wibhULpRhfYk9f+lE4Qp5N+4p2Wk8A="
},
{
"label": "Global_Chambersign_Root___2008",
"binNumber": 105,
"sha256Fingerprint": "E2M1Q5M0p2mAFqDTJN5yKE4HnXtSILuPvXR4Fu6+uso="
},
{
"label": "Go_Daddy_Root_Certificate_Authority___G2",
"binNumber": 106,
"sha256Fingerprint": "RRQLMkfrnMjFtPDXtTCR9zKSCJ5uWmPidJ3TrKkZjto="
},
{
"label": "Starfield_Root_Certificate_Authority___G2",
"binNumber": 107,
"sha256Fingerprint": "LOHLC/nS+eECmT++IVFSw7LdDKveHGjlMZuDkVTbt/U="
},
{
"label": "Starfield_Services_Root_Certificate_Authority___G2",
"binNumber": 108,
"sha256Fingerprint": "Vo1pBaLIhwikswJRkO3P7bGXSmBqE8blKQ/LKuY+2rU="
},
{
"label": "AffirmTrust_Commercial",
"binNumber": 109,
"sha256Fingerprint": "A3arHVTF+YA85LLiAaDufu97V7Y26Kk8m41IYMlvX6c="
},
{
"label": "AffirmTrust_Networking",
"binNumber": 110,
"sha256Fingerprint": "CoHsWpKXd/FFkErzjV1Qn2a14sWPzbUxBYsOF/PwtBs="
},
{
"label": "AffirmTrust_Premium",
"binNumber": 111,
"sha256Fingerprint": "cKc/fzdrYAdCSJBFNLEUgtW/DmmOzEmN9SV36/LpO5o="
},
{
"label": "AffirmTrust_Premium_ECC",
"binNumber": 112,
"sha256Fingerprint": "vXH99tqX5M9i0WR63SWBsH15rfg5frTsupxehIiCFCM="
},
{
"label": "Certum_Trusted_Network_CA",
"binNumber": 113,
"sha256Fingerprint": "XFhGjVX1jkl+dDmC0rUAELbRZTdKz4On1KMtt2jEQI4="
},
{
"label": "Certinomis___Autorit__Racine",
"binNumber": 114,
"sha256Fingerprint": "/L/iiGIG9ysnWTyLBwKX4S12ntEO15MHBagJjv/BTRc="
},
{
"label": "Root_CA_Generalitat_Valenciana",
"binNumber": 115,
"sha256Fingerprint": "jE7f0ENI8yKWnn4ppM1NygBGVQYcFuGwdkIu80KtYw4="
},
{
"label": "A_Trust_nQual_03",
"binNumber": 116,
"sha256Fingerprint": "eTy/RVm5/eOKsi3xaGn2mIGuFMSwE5rHiKeKGvzKAvs="
},
{
"label": "TWCA_Root_Certification_Authority",
"binNumber": 117,
"sha256Fingerprint": "v9iP4RAcQa4+gBv4vlY1Dum60aa5vVFe3FxtW4cRrEQ="
},
{
"label": "OU_Security_Communication_RootCA2_O__SECOM_Trust_Systems_CO__LTD___C_JP",
"binNumber": 118,
"sha256Fingerprint": "UTss7LgQ1M3l3YU5Gt/Gwt1g2Hu3NtK1IUhKpHoOvvY="
},
{
"label": "EC_ACC",
"binNumber": 119,
"sha256Fingerprint": "iEl/AWAvMVQkauKMTVrvEPHYfrt2Ym9K4Lf5W6eWh5k="
},
{
"label": "Hellenic_Academic_and_Research_Institutions_RootCA_2011",
"binNumber": 120,
"sha256Fingerprint": "vBBPFaSL5wncpUKn4dS5328FRSfoAuqpLVlURCWK/nE="
},
{
"label": "Actalis_Authentication_Root_CA",
"binNumber": 121,
"sha256Fingerprint": "VZJghOyWOmS5biq+Ac4LqGpk+/68x6q1r8FVs3/XYGY="
},
{
"label": "OU_Trustis_FPS_Root_CA_O_Trustis_Limited_C_GB",
"binNumber": 122,
"sha256Fingerprint": "wbSCmaulII/pYwrOVcpooD7aWlGciAKg06Zzvo+OVX0="
},
{
"label": "StartCom_Certification_Authority",
"binNumber": 123,
"sha256Fingerprint": "4XiQ7gmj+/T0i5xBShfWN7elBkfpvHUjInJ/zBdCqRE="
},
{
"label": "StartCom_Certification_Authority_G2",
"binNumber": 124,
"sha256Fingerprint": "x7plZ96Tp5iuH6p5HnEtN4+uH5PEOX/qRBu3y+b9WZU="
},
{
"label": "Buypass_Class_2_Root_CA",
"binNumber": 125,
"sha256Fingerprint": "mhFAJRl8W7ldlOY9Vc1DeQhHtkayPN8RraSgDv8V+0g="
},
{
"label": "Buypass_Class_3_Root_CA",
"binNumber": 126,
"sha256Fingerprint": "7ffrvKJ6KjhNOHt9QBDGZuLttIQ+TCm0rh1bkzLmsk0="
},
{
"label": "T_TeleSec_GlobalRoot_Class_3",
"binNumber": 127,
"sha256Fingerprint": "/XPa0xxkT/G0O+8MzdqWcQuc2Ydeyn4xcHrz6W1SK70="
},
{
"label": "EE_Certification_Centre_Root_CA",
"binNumber": 128,
"sha256Fingerprint": "PoS6Q0KQhRbndXPAmS8JecoITkaFaB/xlcy6iiKbinY="
},
{
"label": "T_RKTRUST_Elektronik_Sertifika_Hizmet_Sa_lay_c_s_",
"binNumber": 129,
"sha256Fingerprint": "l4zZZvL6oHunqpUA2cAunXfyza2mrWunSvS5HGZZPFA="
},
{
"label": "D_TRUST_Root_Class_3_CA_2_2009",
"binNumber": 130,
"sha256Fingerprint": "SeekQqzw6mKHBQBUtSVktlDk9J5C40jWqjjgOelXscE="
},
{
"label": "D_TRUST_Root_Class_3_CA_2_EV_2009",
"binNumber": 131,
"sha256Fingerprint": "7sVJa5iM6YYluTQJLuwpCL7QsPMWwtRzDITq8fPTSIE="
},
{
"label": "PSCProcert",
"binNumber": 132,
"sha256Fingerprint": "PPw8FNH2hP8X44xDykQMALln7JM+i/4GTKHXLJDyrbA="
},
{
"label": "China_Internet_Network_Information_Center_EV_Certificates_Root",
"binNumber": 133,
"sha256Fingerprint": "HAHG9Nuy/vwiVYsryjJWP0mESs/DK3vksP9Zn56Mevc="
},
{
"label": "Swisscom_Root_CA_2",
"binNumber": 134,
"sha256Fingerprint": "8JsSLHEU9KCb1OpPSpnVWLRuTCXNgRQNKcBWE5FMOEE="
},
{
"label": "Swisscom_Root_EV_CA_2",
"binNumber": 135,
"sha256Fingerprint": "2V/qPKTu3OdM1251/G0f9ixEHw+ovHfwNLGeXbJYAV0="
},
{
"label": "CA_Disig_Root_R1",
"binNumber": 136,
"sha256Fingerprint": "+W8j9MPnnAd6RpiNWvWQBnag8DnLZF3RdUmyFsgkQM4="
},
{
"label": "CA_Disig_Root_R2",
"binNumber": 137,
"sha256Fingerprint": "4j1KA217cOn1lbFCIHnSuR7fux+2UaBjPqqKncX4BwM="
},
{
"label": "ACCVRAIZ1",
"binNumber": 138,
"sha256Fingerprint": "mm7AEuGn2p2+NBlNR4rXwNsYIvsHHfEpgUlu0QQ4QRM="
},
{
"label": "TWCA_Global_Root_CA",
"binNumber": 139,
"sha256Fingerprint": "WXaQB/doXQ/NUIcvn5XVdVpbK0V9gfNpK2EKmGcvDhs="
},
{
"label": "TeliaSonera_Root_CA_v1",
"binNumber": 140,
"sha256Fingerprint": "3Wk2/iH48HfBI6GlIcEiJPciVbc+A6cmBpPooksPo4k="
},
{
"label": "E_Tugra_Certification_Authority",
"binNumber": 141,
"sha256Fingerprint": "sL/VK7DX2b2Sv11NwT2iVcAsVC83g2XqiTkR9V5V8jw="
},
{
"label": "T_TeleSec_GlobalRoot_Class_2",
"binNumber": 142,
"sha256Fingerprint": "keL1eI1YEOunulhzfeFUio7KzQFFmLwLFD4EGxcFJVI="
},
{
"label": "Atos_TrustedRoot_2011",
"binNumber": 143,
"sha256Fingerprint": "81a+okS3qR6zXVPKmteGSs4Bji011fj5bd9opvQapHQ="
},
{
"label": "QuoVadis_Root_CA_1_G3",
"binNumber": 144,
"sha256Fingerprint": "ioZv0bJ2tX5XjpIcZYKKK+1Y6fLyiAVBNLfx9L/JzHQ="
},
{
"label": "QuoVadis_Root_CA_2_G3",
"binNumber": 145,
"sha256Fingerprint": "j+T7Cvk6TQ1n2wvrsj43xxvzJdy83SQOoE2vWLR+GEA="
},
{
"label": "QuoVadis_Root_CA_3_G3",
"binNumber": 146,
"sha256Fingerprint": "iO+B3iAusBhFLkP4ZHJc6l+9H8LZ0gVzBwnF2LhpD0Y="
},
{
"label": "DigiCert_Assured_ID_Root_G2",
"binNumber": 147,
"sha256Fingerprint": "fQXrtoIzn4yUUe4JTuv++nlToRTtsvRJSUUvq30vwYU="
},
{
"label": "DigiCert_Assured_ID_Root_G3",
"binNumber": 148,
"sha256Fingerprint": "fjfLi0xHCQyrNlUbpvRduEBoD7oWapUtsQBxf0MFP8I="
},
{
"label": "DigiCert_Global_Root_G2",
"binNumber": 149,
"sha256Fingerprint": "yzzLt2Ax5eATj43TmiP53kf/w15DwRRM6ifUalqxy18="
},
{
"label": "DigiCert_Global_Root_G3",
"binNumber": 150,
"sha256Fingerprint": "Ma1mSPgQQTjHOPOepDIBMzk+OhjMAilu+Xwqye9nMdA="
},
{
"label": "DigiCert_Trusted_Root_G4",
"binNumber": 151,
"sha256Fingerprint": "VS973PGnr55s5nIBf08Sq/dyQMeOdhrCA9HZ0grImYg="
},
{
"label": "Certification_Authority_of_WoSign",
"binNumber": 152,
"sha256Fingerprint": "SyLVpq7JnzzbeapewGg4R5zV7LpxZPfyLcHWX2PYVwg="
},
{
"label": "CA______",
"binNumber": 153,
"sha256Fingerprint": "1vA0vZSqIz8Cl+ykJFsoOXPkR6pZDzEMd/SP34MRIlQ="
},
{
"label": "COMODO_RSA_Certification_Authority",
"binNumber": 154,
"sha256Fingerprint": "UvDhxOWOxikpG2AxfwdGcbhdfqgNWwcnNGNTSzK0AjQ="
},
{
"label": "USERTrust_RSA_Certification_Authority",
"binNumber": 155,
"sha256Fingerprint": "55PJsC/YqhPiHDEiisywgRlkO3SciYlksXRtRsPUy9I="
},
{
"label": "USERTrust_ECC_Certification_Authority",
"binNumber": 156,
"sha256Fingerprint": "T/Rg1Uuchtq/vPxXEuBADSvtP7xNT72qhuBq3NKprXo="
},
{
"label": "GlobalSign",
"binNumber": 157,
"sha256Fingerprint": "vslJEcKVVnbbbApVCYbXbjugBWZ8RCyXYrT7t3PeIow="
},
{
"label": "GlobalSign",
"binNumber": 158,
"sha256Fingerprint": "F5+8FIo90A/STqE0WMxDv6f1nIGC14OlE/br7BAMiSQ="
},
{
"label": "Staat_der_Nederlanden_Root_CA___G3",
"binNumber": 159,
"sha256Fingerprint": "PE+wuVq4swAy9DK4b1Nf4XLBhdD9OYZYN882GH+m9Cg="
},
{
"label": "Staat_der_Nederlanden_EV_Root_CA",
"binNumber": 160,
"sha256Fingerprint": "TSSRQUz+lWdG7Ezvps9vcuKKEylDL52KkHrEy12twVo="
},
{
"label": "IdenTrust_Commercial_Root_CA_1",
"binNumber": 161,
"sha256Fingerprint": "XVZJm+TS4IvPytCKPjhyPVBQO95waUjkL1VgMBnlKK4="
},
{
"label": "IdenTrust_Public_Sector_Root_CA_1",
"binNumber": 162,
"sha256Fingerprint": "MNCJWppEiiYgkWNVItH1IBC1hnrK4Sx475WP1PQ4ny8="
},
{
"label": "Entrust_Root_Certification_Authority___G2",
"binNumber": 163,
"sha256Fingerprint": "Q99XdLA+f+9f5A2TGnvt8bsua0JzjE5tOEEQPTqn8zk="
},
{
"label": "Entrust_Root_Certification_Authority___EC1",
"binNumber": 164,
"sha256Fingerprint": "Au0OsowU2kUWXFZnkXANZFHX+1bwsqsdO46wcOVu3/U="
},
{
"label": "CFCA_EV_ROOT",
"binNumber": 165,
"sha256Fingerprint": "XMPXjk4dXkVUegTmhz5k+Qz5U20czC74APNVxMX9cP0="
},
{
"label": "T_RKTRUST_Elektronik_Sertifika_Hizmet_Sa_lay_c_s__H5",
"binNumber": 166,
"sha256Fingerprint": "STUbkDREwYXM3FxpPSTYVVyyCNaoFBMHaZ9K8GMZnXg="
},
{
"label": "T_RKTRUST_Elektronik_Sertifika_Hizmet_Sa_lay_c_s__H6",
"binNumber": 167,
"sha256Fingerprint": "jeeGVeG+f3hHgAuT9pTSHTaMwG4DPn+rBLteuZ2mtwA="
},
{
"label": "Certinomis___Root_CA",
"binNumber": 168,
"sha256Fingerprint": "Kpn1vBF0tzy7HWIIhOAcNOUcyzl42hJfDjMmiIO/QVg="
},
{
"label": "OISTE_WISeKey_Global_Root_GB_CA",
"binNumber": 169,
"sha256Fingerprint": "a5wI6G6w92fPrWXNmLYhSeVJSmf1hF570e0Bnye4a9Y="
},
{
"label": "Certification_Authority_of_WoSign_G2",
"binNumber": 170,
"sha256Fingerprint": "1Ielb4OwdILoXpYzlMHswsnlHQkD7pRrAsMBWB7ZnhY="
},
{
"label": "CA_WoSign_ECC_Root",
"binNumber": 171,
"sha256Fingerprint": "i0XaHAb3kesMq/Jr5Yj1+yMWXC5hS/iFVi0NzlCymwI="
},
{
"label": "SZAFIR_ROOT_CA2",
"binNumber": 172,
"sha256Fingerprint": "oTOdMygaC1blV9PTKxzn+TZ+sJS9X6cqflAEyN7Xyv4="
},
{
"label": "Certum_Trusted_Network_CA_2",
"binNumber": 173,
"sha256Fingerprint": "tnby7drod1zTbLD2PNHUYDlh9J5iZboBOi8DB7bQuAQ="
},
{
"label": "Hellenic_Academic_and_Research_Institutions_RootCA_2015",
"binNumber": 174,
"sha256Fingerprint": "oECSmgLOU7Ss9PL/xpgc5ElvdV5tRf4LKmkrzVJSPzY="
},
{
"label": "Hellenic_Academic_and_Research_Institutions_ECC_RootCA_2015",
"binNumber": 175,
"sha256Fingerprint": "RLVFqool5lpzyhXcJ/w20kwcuZU6BmU5sRWC3Eh7SDM="
},
{
"label": "Certplus_Root_CA_G1",
"binNumber": 176,
"sha256Fingerprint": "FSpAK/zfLNVIBU0idbOcf8o+wJeAeLDw6nblYabHQz4="
},
{
"label": "Certplus_Root_CA_G2",
"binNumber": 177,
"sha256Fingerprint": "bMBQQeZEXnRpbEz7yfgPVDt+q7tEtM5veHxqmXHELxc="
},
{
"label": "OpenTrust_Root_CA_G1",
"binNumber": 178,
"sha256Fingerprint": "VsdxKNmMGNkbTP3/vCXukQPUdY6iq62CapDzRX1GDrQ="
},
{
"label": "OpenTrust_Root_CA_G2",
"binNumber": 179,
"sha256Fingerprint": "J5lYKf5qdRXBv+hI+cR2HbFsIlkpJXv0DQiU8p6ouvI="
},
{
"label": "OpenTrust_Root_CA_G3",
"binNumber": 180,
"sha256Fingerprint": "t8NiMXBugQeMNny4lhmPHjII3ZJpSd2PVwmkEPdbYpI="
},
{
"label": "ISRG_Root_X1",
"binNumber": 181,
"sha256Fingerprint": "lrzsBiZJdvN0YHeazyjFp8/oo8Cq4RqP/O4FwL3fCMY="
},
{
"label": "OU_AC_RAIZ_FNMT_RCM_O_FNMT_RCM_C_ES",
"binNumber": 182,
"sha256Fingerprint": "68VXDCkBjE1nsaoSe68S9wO0YR68F7fatVc4lBebk/o="
},
{
"label": "Amazon_Root_CA_1",
"binNumber": 183,
"sha256Fingerprint": "js3miE89h7ESW6Maw/yxPXAW3n9XzJBP4cuXxq6YGW4="
},
{
"label": "Amazon_Root_CA_2",
"binNumber": 184,
"sha256Fingerprint": "G6WyqoxlQBqClgEY+AvsT2IwTYPOxHE6GcOcAR6kbbQ="
},
{
"label": "Amazon_Root_CA_3",
"binNumber": 185,
"sha256Fingerprint": "GM5s/nvxTmCy40e43+hoyzHQLrs62icVafUDQ7Rts6Q="
},
{
"label": "Amazon_Root_CA_4",
"binNumber": 186,
"sha256Fingerprint": "410oQZ7QICXPppA4zWI5YkWNpcaV+96jwisL+yWJcJI="
},
{
"label": "LuxTrust_Global_Root_2",
"binNumber": 187,
"sha256Fingerprint": "VEVfcSnCCxRHxBj5lxaPJMWPxQI79dpb4utuHdiQLtU="
},
{
"label": "TUBITAK_Kamu_SM_SSL_Kok_Sertifikasi___Surum_1",
"binNumber": 188,
"sha256Fingerprint": "Ru3DaJBG1TpFP7MQSrgNyuxliyZg6hYp3X6GeZBkhxY="
}
],
"maxBin": 188
}

Просмотреть файл

@ -1 +1 @@
1fb7e5f584de
7228445b43ac

Просмотреть файл

@ -980,8 +980,6 @@ AddNameConstraints(void *extHandle)
GEN_BREAK(SECFailure);
}
(void)SEC_ASN1EncodeInteger(arena, &current->min, 0);
if (!GetGeneralName(arena, &current->name, PR_TRUE)) {
GEN_BREAK(SECFailure);
}

Просмотреть файл

@ -1058,7 +1058,7 @@ main(int argc, char **argv)
certCipher = PKCS12U_MapCipherFromString(cipherString, certKeyLen);
/* If the user requested a cipher and we didn't find it, then
* don't just silently not encrypt. */
if (cipher == SEC_OID_UNKNOWN) {
if (certCipher == SEC_OID_UNKNOWN) {
PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
SECU_PrintError(progName, "Algorithm: \"%s\"", cipherString);
pk12uErrno = PK12UERR_INVALIDALGORITHM;

Просмотреть файл

@ -10,4 +10,3 @@
*/
#error "Do not include this header file."

Просмотреть файл

@ -1588,10 +1588,10 @@ done:
STRING_TO_SECITEM(CA##_NAME_CONSTRAINTS) \
}
/* Agence Nationale de la Securite des Systemes d'Information (ANSSI) */
/* clang-format off */
/* Agence Nationale de la Securite des Systemes d'Information (ANSSI) */
#define ANSSI_SUBJECT_DN \
"\x30\x81\x85" \
"\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02" "FR" /* C */ \
@ -1619,10 +1619,39 @@ done:
"\x30\x05\x82\x03" ".nc" \
"\x30\x05\x82\x03" ".tf"
/* TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 */
#define TUBITAK1_SUBJECT_DN \
"\x30\x81\xd2" \
"\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02" \
/* C */ "TR" \
"\x31\x18\x30\x16\x06\x03\x55\x04\x07\x13\x0f" \
/* L */ "Gebze - Kocaeli" \
"\x31\x42\x30\x40\x06\x03\x55\x04\x0a\x13\x39" \
/* O */ "Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK" \
"\x31\x2d\x30\x2b\x06\x03\x55\x04\x0b\x13\x24" \
/* OU */ "Kamu Sertifikasyon Merkezi - Kamu SM" \
"\x31\x36\x30\x34\x06\x03\x55\x04\x03\x13\x2d" \
/* CN */ "TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1"
#define TUBITAK1_NAME_CONSTRAINTS \
"\x30\x65\xa0\x63" \
"\x30\x09\x82\x07" ".gov.tr" \
"\x30\x09\x82\x07" ".k12.tr" \
"\x30\x09\x82\x07" ".pol.tr" \
"\x30\x09\x82\x07" ".mil.tr" \
"\x30\x09\x82\x07" ".tsk.tr" \
"\x30\x09\x82\x07" ".kep.tr" \
"\x30\x09\x82\x07" ".bel.tr" \
"\x30\x09\x82\x07" ".edu.tr" \
"\x30\x09\x82\x07" ".org.tr"
/* clang-format on */
static const SECItem builtInNameConstraints[][2] = { NAME_CONSTRAINTS_ENTRY(
ANSSI) };
static const SECItem builtInNameConstraints[][2] = {
NAME_CONSTRAINTS_ENTRY(ANSSI),
NAME_CONSTRAINTS_ENTRY(TUBITAK1)
};
SECStatus
CERT_GetImposedNameConstraints(const SECItem *derSubject, SECItem *extensions)

Просмотреть файл

@ -8245,168 +8245,6 @@ CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
#
# Certificate "WellsSecure Public Root Certificate Authority"
#
# Issuer: CN=WellsSecure Public Root Certificate Authority,OU=Wells Fargo Bank NA,O=Wells Fargo WellsSecure,C=US
# Serial Number: 1 (0x1)
# Subject: CN=WellsSecure Public Root Certificate Authority,OU=Wells Fargo Bank NA,O=Wells Fargo WellsSecure,C=US
# Not Valid Before: Thu Dec 13 17:07:54 2007
# Not Valid After : Wed Dec 14 00:07:54 2022
# Fingerprint (MD5): 15:AC:A5:C2:92:2D:79:BC:E8:7F:CB:67:ED:02:CF:36
# Fingerprint (SHA1): E7:B4:F6:9D:61:EC:90:69:DB:7E:90:A7:40:1A:3C:F4:7D:4F:E8:EE
CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
CKA_TOKEN CK_BBOOL CK_TRUE
CKA_PRIVATE CK_BBOOL CK_FALSE
CKA_MODIFIABLE CK_BBOOL CK_FALSE
CKA_LABEL UTF8 "WellsSecure Public Root Certificate Authority"
CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
CKA_SUBJECT MULTILINE_OCTAL
\060\201\205\061\013\060\011\006\003\125\004\006\023\002\125\123
\061\040\060\036\006\003\125\004\012\014\027\127\145\154\154\163
\040\106\141\162\147\157\040\127\145\154\154\163\123\145\143\165
\162\145\061\034\060\032\006\003\125\004\013\014\023\127\145\154
\154\163\040\106\141\162\147\157\040\102\141\156\153\040\116\101
\061\066\060\064\006\003\125\004\003\014\055\127\145\154\154\163
\123\145\143\165\162\145\040\120\165\142\154\151\143\040\122\157
\157\164\040\103\145\162\164\151\146\151\143\141\164\145\040\101
\165\164\150\157\162\151\164\171
END
CKA_ID UTF8 "0"
CKA_ISSUER MULTILINE_OCTAL
\060\201\205\061\013\060\011\006\003\125\004\006\023\002\125\123
\061\040\060\036\006\003\125\004\012\014\027\127\145\154\154\163
\040\106\141\162\147\157\040\127\145\154\154\163\123\145\143\165
\162\145\061\034\060\032\006\003\125\004\013\014\023\127\145\154
\154\163\040\106\141\162\147\157\040\102\141\156\153\040\116\101
\061\066\060\064\006\003\125\004\003\014\055\127\145\154\154\163
\123\145\143\165\162\145\040\120\165\142\154\151\143\040\122\157
\157\164\040\103\145\162\164\151\146\151\143\141\164\145\040\101
\165\164\150\157\162\151\164\171
END
CKA_SERIAL_NUMBER MULTILINE_OCTAL
\002\001\001
END
CKA_VALUE MULTILINE_OCTAL
\060\202\004\275\060\202\003\245\240\003\002\001\002\002\001\001
\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
\201\205\061\013\060\011\006\003\125\004\006\023\002\125\123\061
\040\060\036\006\003\125\004\012\014\027\127\145\154\154\163\040
\106\141\162\147\157\040\127\145\154\154\163\123\145\143\165\162
\145\061\034\060\032\006\003\125\004\013\014\023\127\145\154\154
\163\040\106\141\162\147\157\040\102\141\156\153\040\116\101\061
\066\060\064\006\003\125\004\003\014\055\127\145\154\154\163\123
\145\143\165\162\145\040\120\165\142\154\151\143\040\122\157\157
\164\040\103\145\162\164\151\146\151\143\141\164\145\040\101\165
\164\150\157\162\151\164\171\060\036\027\015\060\067\061\062\061
\063\061\067\060\067\065\064\132\027\015\062\062\061\062\061\064
\060\060\060\067\065\064\132\060\201\205\061\013\060\011\006\003
\125\004\006\023\002\125\123\061\040\060\036\006\003\125\004\012
\014\027\127\145\154\154\163\040\106\141\162\147\157\040\127\145
\154\154\163\123\145\143\165\162\145\061\034\060\032\006\003\125
\004\013\014\023\127\145\154\154\163\040\106\141\162\147\157\040
\102\141\156\153\040\116\101\061\066\060\064\006\003\125\004\003
\014\055\127\145\154\154\163\123\145\143\165\162\145\040\120\165
\142\154\151\143\040\122\157\157\164\040\103\145\162\164\151\146
\151\143\141\164\145\040\101\165\164\150\157\162\151\164\171\060
\202\001\042\060\015\006\011\052\206\110\206\367\015\001\001\001
\005\000\003\202\001\017\000\060\202\001\012\002\202\001\001\000
\356\157\264\275\171\342\217\010\041\236\070\004\101\045\357\253
\133\034\123\222\254\155\236\335\302\304\056\105\224\003\065\210
\147\164\127\343\337\214\270\247\166\217\073\367\250\304\333\051
\143\016\221\150\066\212\227\216\212\161\150\011\007\344\350\324
\016\117\370\326\053\114\244\026\371\357\103\230\217\263\236\122
\337\155\221\071\217\070\275\167\213\103\143\353\267\223\374\060
\114\034\001\223\266\023\373\367\241\037\277\045\341\164\067\054
\036\244\136\074\150\370\113\277\015\271\036\056\066\350\251\344
\247\370\017\313\202\165\174\065\055\042\326\302\277\013\363\264
\374\154\225\141\036\127\327\004\201\062\203\122\171\346\203\143
\317\267\313\143\213\021\342\275\136\353\366\215\355\225\162\050
\264\254\022\142\351\112\063\346\203\062\256\005\165\225\275\204
\225\333\052\134\233\216\056\014\270\201\053\101\346\070\126\237
\111\233\154\166\372\212\135\367\001\171\201\174\301\203\100\005
\376\161\375\014\077\314\116\140\011\016\145\107\020\057\001\300
\005\077\217\370\263\101\357\132\102\176\131\357\322\227\014\145
\002\003\001\000\001\243\202\001\064\060\202\001\060\060\017\006
\003\125\035\023\001\001\377\004\005\060\003\001\001\377\060\071
\006\003\125\035\037\004\062\060\060\060\056\240\054\240\052\206
\050\150\164\164\160\072\057\057\143\162\154\056\160\153\151\056
\167\145\154\154\163\146\141\162\147\157\056\143\157\155\057\167
\163\160\162\143\141\056\143\162\154\060\016\006\003\125\035\017
\001\001\377\004\004\003\002\001\306\060\035\006\003\125\035\016
\004\026\004\024\046\225\031\020\331\350\241\227\221\377\334\031
\331\265\004\076\322\163\012\152\060\201\262\006\003\125\035\043
\004\201\252\060\201\247\200\024\046\225\031\020\331\350\241\227
\221\377\334\031\331\265\004\076\322\163\012\152\241\201\213\244
\201\210\060\201\205\061\013\060\011\006\003\125\004\006\023\002
\125\123\061\040\060\036\006\003\125\004\012\014\027\127\145\154
\154\163\040\106\141\162\147\157\040\127\145\154\154\163\123\145
\143\165\162\145\061\034\060\032\006\003\125\004\013\014\023\127
\145\154\154\163\040\106\141\162\147\157\040\102\141\156\153\040
\116\101\061\066\060\064\006\003\125\004\003\014\055\127\145\154
\154\163\123\145\143\165\162\145\040\120\165\142\154\151\143\040
\122\157\157\164\040\103\145\162\164\151\146\151\143\141\164\145
\040\101\165\164\150\157\162\151\164\171\202\001\001\060\015\006
\011\052\206\110\206\367\015\001\001\005\005\000\003\202\001\001
\000\271\025\261\104\221\314\043\310\053\115\167\343\370\232\173
\047\015\315\162\273\231\000\312\174\146\031\120\306\325\230\355
\253\277\003\132\345\115\345\036\310\117\161\227\206\325\343\035
\375\220\311\074\165\167\127\172\175\370\336\364\324\325\367\225
\346\164\156\035\074\256\174\235\333\002\003\005\054\161\113\045
\076\007\343\136\232\365\146\027\051\210\032\070\237\317\252\101
\003\204\227\153\223\070\172\312\060\104\033\044\104\063\320\344
\321\334\050\070\364\023\103\065\065\051\143\250\174\242\265\255
\070\244\355\255\375\306\232\037\377\227\163\376\373\263\065\247
\223\206\306\166\221\000\346\254\121\026\304\047\062\134\333\163
\332\245\223\127\216\076\155\065\046\010\131\325\347\104\327\166
\040\143\347\254\023\147\303\155\261\160\106\174\325\226\021\075
\211\157\135\250\241\353\215\012\332\303\035\063\154\243\352\147
\031\232\231\177\113\075\203\121\052\035\312\057\206\014\242\176
\020\055\053\324\026\225\013\007\252\056\024\222\111\267\051\157
\330\155\061\175\365\374\241\020\007\207\316\057\131\334\076\130
\333
END
CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
# Trust for Certificate "WellsSecure Public Root Certificate Authority"
# Issuer: CN=WellsSecure Public Root Certificate Authority,OU=Wells Fargo Bank NA,O=Wells Fargo WellsSecure,C=US
# Serial Number: 1 (0x1)
# Subject: CN=WellsSecure Public Root Certificate Authority,OU=Wells Fargo Bank NA,O=Wells Fargo WellsSecure,C=US
# Not Valid Before: Thu Dec 13 17:07:54 2007
# Not Valid After : Wed Dec 14 00:07:54 2022
# Fingerprint (MD5): 15:AC:A5:C2:92:2D:79:BC:E8:7F:CB:67:ED:02:CF:36
# Fingerprint (SHA1): E7:B4:F6:9D:61:EC:90:69:DB:7E:90:A7:40:1A:3C:F4:7D:4F:E8:EE
CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
CKA_TOKEN CK_BBOOL CK_TRUE
CKA_PRIVATE CK_BBOOL CK_FALSE
CKA_MODIFIABLE CK_BBOOL CK_FALSE
CKA_LABEL UTF8 "WellsSecure Public Root Certificate Authority"
CKA_CERT_SHA1_HASH MULTILINE_OCTAL
\347\264\366\235\141\354\220\151\333\176\220\247\100\032\074\364
\175\117\350\356
END
CKA_CERT_MD5_HASH MULTILINE_OCTAL
\025\254\245\302\222\055\171\274\350\177\313\147\355\002\317\066
END
CKA_ISSUER MULTILINE_OCTAL
\060\201\205\061\013\060\011\006\003\125\004\006\023\002\125\123
\061\040\060\036\006\003\125\004\012\014\027\127\145\154\154\163
\040\106\141\162\147\157\040\127\145\154\154\163\123\145\143\165
\162\145\061\034\060\032\006\003\125\004\013\014\023\127\145\154
\154\163\040\106\141\162\147\157\040\102\141\156\153\040\116\101
\061\066\060\064\006\003\125\004\003\014\055\127\145\154\154\163
\123\145\143\165\162\145\040\120\165\142\154\151\143\040\122\157
\157\164\040\103\145\162\164\151\146\151\143\141\164\145\040\101
\165\164\150\157\162\151\164\171
END
CKA_SERIAL_NUMBER MULTILINE_OCTAL
\002\001\001
END
CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
#
# Certificate "COMODO ECC Certification Authority"
#
@ -8991,213 +8829,6 @@ CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
#
# Certificate "Microsec e-Szigno Root CA"
#
# Issuer: CN=Microsec e-Szigno Root CA,OU=e-Szigno CA,O=Microsec Ltd.,L=Budapest,C=HU
# Serial Number:00:cc:b8:e7:bf:4e:29:1a:fd:a2:dc:66:a5:1c:2c:0f:11
# Subject: CN=Microsec e-Szigno Root CA,OU=e-Szigno CA,O=Microsec Ltd.,L=Budapest,C=HU
# Not Valid Before: Wed Apr 06 12:28:44 2005
# Not Valid After : Thu Apr 06 12:28:44 2017
# Fingerprint (MD5): F0:96:B6:2F:C5:10:D5:67:8E:83:25:32:E8:5E:2E:E5
# Fingerprint (SHA1): 23:88:C9:D3:71:CC:9E:96:3D:FF:7D:3C:A7:CE:FC:D6:25:EC:19:0D
CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
CKA_TOKEN CK_BBOOL CK_TRUE
CKA_PRIVATE CK_BBOOL CK_FALSE
CKA_MODIFIABLE CK_BBOOL CK_FALSE
CKA_LABEL UTF8 "Microsec e-Szigno Root CA"
CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
CKA_SUBJECT MULTILINE_OCTAL
\060\162\061\013\060\011\006\003\125\004\006\023\002\110\125\061
\021\060\017\006\003\125\004\007\023\010\102\165\144\141\160\145
\163\164\061\026\060\024\006\003\125\004\012\023\015\115\151\143
\162\157\163\145\143\040\114\164\144\056\061\024\060\022\006\003
\125\004\013\023\013\145\055\123\172\151\147\156\157\040\103\101
\061\042\060\040\006\003\125\004\003\023\031\115\151\143\162\157
\163\145\143\040\145\055\123\172\151\147\156\157\040\122\157\157
\164\040\103\101
END
CKA_ID UTF8 "0"
CKA_ISSUER MULTILINE_OCTAL
\060\162\061\013\060\011\006\003\125\004\006\023\002\110\125\061
\021\060\017\006\003\125\004\007\023\010\102\165\144\141\160\145
\163\164\061\026\060\024\006\003\125\004\012\023\015\115\151\143
\162\157\163\145\143\040\114\164\144\056\061\024\060\022\006\003
\125\004\013\023\013\145\055\123\172\151\147\156\157\040\103\101
\061\042\060\040\006\003\125\004\003\023\031\115\151\143\162\157
\163\145\143\040\145\055\123\172\151\147\156\157\040\122\157\157
\164\040\103\101
END
CKA_SERIAL_NUMBER MULTILINE_OCTAL
\002\021\000\314\270\347\277\116\051\032\375\242\334\146\245\034
\054\017\021
END
CKA_VALUE MULTILINE_OCTAL
\060\202\007\250\060\202\006\220\240\003\002\001\002\002\021\000
\314\270\347\277\116\051\032\375\242\334\146\245\034\054\017\021
\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
\162\061\013\060\011\006\003\125\004\006\023\002\110\125\061\021
\060\017\006\003\125\004\007\023\010\102\165\144\141\160\145\163
\164\061\026\060\024\006\003\125\004\012\023\015\115\151\143\162
\157\163\145\143\040\114\164\144\056\061\024\060\022\006\003\125
\004\013\023\013\145\055\123\172\151\147\156\157\040\103\101\061
\042\060\040\006\003\125\004\003\023\031\115\151\143\162\157\163
\145\143\040\145\055\123\172\151\147\156\157\040\122\157\157\164
\040\103\101\060\036\027\015\060\065\060\064\060\066\061\062\062
\070\064\064\132\027\015\061\067\060\064\060\066\061\062\062\070
\064\064\132\060\162\061\013\060\011\006\003\125\004\006\023\002
\110\125\061\021\060\017\006\003\125\004\007\023\010\102\165\144
\141\160\145\163\164\061\026\060\024\006\003\125\004\012\023\015
\115\151\143\162\157\163\145\143\040\114\164\144\056\061\024\060
\022\006\003\125\004\013\023\013\145\055\123\172\151\147\156\157
\040\103\101\061\042\060\040\006\003\125\004\003\023\031\115\151
\143\162\157\163\145\143\040\145\055\123\172\151\147\156\157\040
\122\157\157\164\040\103\101\060\202\001\042\060\015\006\011\052
\206\110\206\367\015\001\001\001\005\000\003\202\001\017\000\060
\202\001\012\002\202\001\001\000\355\310\000\325\201\173\315\070
\000\107\314\333\204\301\041\151\054\164\220\014\041\331\123\207
\355\076\103\104\123\257\253\370\200\233\074\170\215\324\215\256
\270\357\323\021\334\201\346\317\073\226\214\326\157\025\306\167
\176\241\057\340\137\222\266\047\327\166\232\035\103\074\352\331
\354\057\356\071\363\152\147\113\213\202\317\042\370\145\125\376
\054\313\057\175\110\172\075\165\371\252\240\047\273\170\302\006
\312\121\302\176\146\113\257\315\242\247\115\002\202\077\202\254
\205\306\341\017\220\107\231\224\012\161\162\223\052\311\246\300
\276\074\126\114\163\222\047\361\153\265\365\375\374\060\005\140
\222\306\353\226\176\001\221\302\151\261\036\035\173\123\105\270
\334\101\037\311\213\161\326\124\024\343\213\124\170\077\276\364
\142\073\133\365\243\354\325\222\164\342\164\060\357\001\333\341
\324\253\231\233\052\153\370\275\246\034\206\043\102\137\354\111
\336\232\213\133\364\162\072\100\305\111\076\245\276\216\252\161
\353\154\372\365\032\344\152\375\173\175\125\100\357\130\156\346
\331\325\274\044\253\301\357\267\002\003\001\000\001\243\202\004
\067\060\202\004\063\060\147\006\010\053\006\001\005\005\007\001
\001\004\133\060\131\060\050\006\010\053\006\001\005\005\007\060
\001\206\034\150\164\164\160\163\072\057\057\162\143\141\056\145
\055\163\172\151\147\156\157\056\150\165\057\157\143\163\160\060
\055\006\010\053\006\001\005\005\007\060\002\206\041\150\164\164
\160\072\057\057\167\167\167\056\145\055\163\172\151\147\156\157
\056\150\165\057\122\157\157\164\103\101\056\143\162\164\060\017
\006\003\125\035\023\001\001\377\004\005\060\003\001\001\377\060
\202\001\163\006\003\125\035\040\004\202\001\152\060\202\001\146
\060\202\001\142\006\014\053\006\001\004\001\201\250\030\002\001
\001\001\060\202\001\120\060\050\006\010\053\006\001\005\005\007
\002\001\026\034\150\164\164\160\072\057\057\167\167\167\056\145
\055\163\172\151\147\156\157\056\150\165\057\123\132\123\132\057
\060\202\001\042\006\010\053\006\001\005\005\007\002\002\060\202
\001\024\036\202\001\020\000\101\000\040\000\164\000\141\000\156
\000\372\000\163\000\355\000\164\000\166\000\341\000\156\000\171
\000\040\000\351\000\162\000\164\000\145\000\154\000\155\000\145
\000\172\000\351\000\163\000\351\000\150\000\145\000\172\000\040
\000\351\000\163\000\040\000\145\000\154\000\146\000\157\000\147
\000\141\000\144\000\341\000\163\000\341\000\150\000\157\000\172
\000\040\000\141\000\040\000\123\000\172\000\157\000\154\000\147
\000\341\000\154\000\164\000\141\000\164\000\363\000\040\000\123
\000\172\000\157\000\154\000\147\000\341\000\154\000\164\000\141
\000\164\000\341\000\163\000\151\000\040\000\123\000\172\000\141
\000\142\000\341\000\154\000\171\000\172\000\141\000\164\000\141
\000\040\000\163\000\172\000\145\000\162\000\151\000\156\000\164
\000\040\000\153\000\145\000\154\000\154\000\040\000\145\000\154
\000\152\000\341\000\162\000\156\000\151\000\072\000\040\000\150
\000\164\000\164\000\160\000\072\000\057\000\057\000\167\000\167
\000\167\000\056\000\145\000\055\000\163\000\172\000\151\000\147
\000\156\000\157\000\056\000\150\000\165\000\057\000\123\000\132
\000\123\000\132\000\057\060\201\310\006\003\125\035\037\004\201
\300\060\201\275\060\201\272\240\201\267\240\201\264\206\041\150
\164\164\160\072\057\057\167\167\167\056\145\055\163\172\151\147
\156\157\056\150\165\057\122\157\157\164\103\101\056\143\162\154
\206\201\216\154\144\141\160\072\057\057\154\144\141\160\056\145
\055\163\172\151\147\156\157\056\150\165\057\103\116\075\115\151
\143\162\157\163\145\143\045\062\060\145\055\123\172\151\147\156
\157\045\062\060\122\157\157\164\045\062\060\103\101\054\117\125
\075\145\055\123\172\151\147\156\157\045\062\060\103\101\054\117
\075\115\151\143\162\157\163\145\143\045\062\060\114\164\144\056
\054\114\075\102\165\144\141\160\145\163\164\054\103\075\110\125
\077\143\145\162\164\151\146\151\143\141\164\145\122\145\166\157
\143\141\164\151\157\156\114\151\163\164\073\142\151\156\141\162
\171\060\016\006\003\125\035\017\001\001\377\004\004\003\002\001
\006\060\201\226\006\003\125\035\021\004\201\216\060\201\213\201
\020\151\156\146\157\100\145\055\163\172\151\147\156\157\056\150
\165\244\167\060\165\061\043\060\041\006\003\125\004\003\014\032
\115\151\143\162\157\163\145\143\040\145\055\123\172\151\147\156
\303\263\040\122\157\157\164\040\103\101\061\026\060\024\006\003
\125\004\013\014\015\145\055\123\172\151\147\156\303\263\040\110
\123\132\061\026\060\024\006\003\125\004\012\023\015\115\151\143
\162\157\163\145\143\040\113\146\164\056\061\021\060\017\006\003
\125\004\007\023\010\102\165\144\141\160\145\163\164\061\013\060
\011\006\003\125\004\006\023\002\110\125\060\201\254\006\003\125
\035\043\004\201\244\060\201\241\200\024\307\240\111\165\026\141
\204\333\061\113\204\322\361\067\100\220\357\116\334\367\241\166
\244\164\060\162\061\013\060\011\006\003\125\004\006\023\002\110
\125\061\021\060\017\006\003\125\004\007\023\010\102\165\144\141
\160\145\163\164\061\026\060\024\006\003\125\004\012\023\015\115
\151\143\162\157\163\145\143\040\114\164\144\056\061\024\060\022
\006\003\125\004\013\023\013\145\055\123\172\151\147\156\157\040
\103\101\061\042\060\040\006\003\125\004\003\023\031\115\151\143
\162\157\163\145\143\040\145\055\123\172\151\147\156\157\040\122
\157\157\164\040\103\101\202\021\000\314\270\347\277\116\051\032
\375\242\334\146\245\034\054\017\021\060\035\006\003\125\035\016
\004\026\004\024\307\240\111\165\026\141\204\333\061\113\204\322
\361\067\100\220\357\116\334\367\060\015\006\011\052\206\110\206
\367\015\001\001\005\005\000\003\202\001\001\000\323\023\234\146
\143\131\056\312\134\160\014\374\203\274\125\261\364\216\007\154
\146\047\316\301\073\040\251\034\273\106\124\160\356\132\314\240
\167\352\150\104\047\353\362\051\335\167\251\325\373\343\324\247
\004\304\225\270\013\341\104\150\140\007\103\060\061\102\141\345
\356\331\345\044\325\033\337\341\112\033\252\237\307\137\370\172
\021\352\023\223\000\312\212\130\261\356\355\016\115\264\327\250
\066\046\174\340\072\301\325\127\202\361\165\266\375\211\137\332
\363\250\070\237\065\006\010\316\042\225\276\315\325\374\276\133
\336\171\153\334\172\251\145\146\276\261\045\132\137\355\176\323
\254\106\155\114\364\062\207\264\040\004\340\154\170\260\167\321
\205\106\113\246\022\267\165\350\112\311\126\154\327\222\253\235
\365\111\070\322\117\123\343\125\220\021\333\230\226\306\111\362
\076\364\237\033\340\367\210\334\045\142\231\104\330\163\277\077
\060\363\014\067\076\324\302\050\200\163\261\001\267\235\132\226
\024\001\113\251\021\235\051\152\056\320\135\201\300\317\262\040
\103\307\003\340\067\116\135\012\334\131\040\045
END
CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
# Trust for Certificate "Microsec e-Szigno Root CA"
# Issuer: CN=Microsec e-Szigno Root CA,OU=e-Szigno CA,O=Microsec Ltd.,L=Budapest,C=HU
# Serial Number:00:cc:b8:e7:bf:4e:29:1a:fd:a2:dc:66:a5:1c:2c:0f:11
# Subject: CN=Microsec e-Szigno Root CA,OU=e-Szigno CA,O=Microsec Ltd.,L=Budapest,C=HU
# Not Valid Before: Wed Apr 06 12:28:44 2005
# Not Valid After : Thu Apr 06 12:28:44 2017
# Fingerprint (MD5): F0:96:B6:2F:C5:10:D5:67:8E:83:25:32:E8:5E:2E:E5
# Fingerprint (SHA1): 23:88:C9:D3:71:CC:9E:96:3D:FF:7D:3C:A7:CE:FC:D6:25:EC:19:0D
CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
CKA_TOKEN CK_BBOOL CK_TRUE
CKA_PRIVATE CK_BBOOL CK_FALSE
CKA_MODIFIABLE CK_BBOOL CK_FALSE
CKA_LABEL UTF8 "Microsec e-Szigno Root CA"
CKA_CERT_SHA1_HASH MULTILINE_OCTAL
\043\210\311\323\161\314\236\226\075\377\175\074\247\316\374\326
\045\354\031\015
END
CKA_CERT_MD5_HASH MULTILINE_OCTAL
\360\226\266\057\305\020\325\147\216\203\045\062\350\136\056\345
END
CKA_ISSUER MULTILINE_OCTAL
\060\162\061\013\060\011\006\003\125\004\006\023\002\110\125\061
\021\060\017\006\003\125\004\007\023\010\102\165\144\141\160\145
\163\164\061\026\060\024\006\003\125\004\012\023\015\115\151\143
\162\157\163\145\143\040\114\164\144\056\061\024\060\022\006\003
\125\004\013\023\013\145\055\123\172\151\147\156\157\040\103\101
\061\042\060\040\006\003\125\004\003\023\031\115\151\143\162\157
\163\145\143\040\145\055\123\172\151\147\156\157\040\122\157\157
\164\040\103\101
END
CKA_SERIAL_NUMBER MULTILINE_OCTAL
\002\021\000\314\270\347\277\116\051\032\375\242\334\146\245\034
\054\017\021
END
CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
#
# Certificate "Certigna"
#
@ -10815,138 +10446,6 @@ CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
#
# Certificate "ApplicationCA - Japanese Government"
#
# Issuer: OU=ApplicationCA,O=Japanese Government,C=JP
# Serial Number: 49 (0x31)
# Subject: OU=ApplicationCA,O=Japanese Government,C=JP
# Not Valid Before: Wed Dec 12 15:00:00 2007
# Not Valid After : Tue Dec 12 15:00:00 2017
# Fingerprint (MD5): 7E:23:4E:5B:A7:A5:B4:25:E9:00:07:74:11:62:AE:D6
# Fingerprint (SHA1): 7F:8A:B0:CF:D0:51:87:6A:66:F3:36:0F:47:C8:8D:8C:D3:35:FC:74
CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
CKA_TOKEN CK_BBOOL CK_TRUE
CKA_PRIVATE CK_BBOOL CK_FALSE
CKA_MODIFIABLE CK_BBOOL CK_FALSE
CKA_LABEL UTF8 "ApplicationCA - Japanese Government"
CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
CKA_SUBJECT MULTILINE_OCTAL
\060\103\061\013\060\011\006\003\125\004\006\023\002\112\120\061
\034\060\032\006\003\125\004\012\023\023\112\141\160\141\156\145
\163\145\040\107\157\166\145\162\156\155\145\156\164\061\026\060
\024\006\003\125\004\013\023\015\101\160\160\154\151\143\141\164
\151\157\156\103\101
END
CKA_ID UTF8 "0"
CKA_ISSUER MULTILINE_OCTAL
\060\103\061\013\060\011\006\003\125\004\006\023\002\112\120\061
\034\060\032\006\003\125\004\012\023\023\112\141\160\141\156\145
\163\145\040\107\157\166\145\162\156\155\145\156\164\061\026\060
\024\006\003\125\004\013\023\015\101\160\160\154\151\143\141\164
\151\157\156\103\101
END
CKA_SERIAL_NUMBER MULTILINE_OCTAL
\002\001\061
END
CKA_VALUE MULTILINE_OCTAL
\060\202\003\240\060\202\002\210\240\003\002\001\002\002\001\061
\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
\103\061\013\060\011\006\003\125\004\006\023\002\112\120\061\034
\060\032\006\003\125\004\012\023\023\112\141\160\141\156\145\163
\145\040\107\157\166\145\162\156\155\145\156\164\061\026\060\024
\006\003\125\004\013\023\015\101\160\160\154\151\143\141\164\151
\157\156\103\101\060\036\027\015\060\067\061\062\061\062\061\065
\060\060\060\060\132\027\015\061\067\061\062\061\062\061\065\060
\060\060\060\132\060\103\061\013\060\011\006\003\125\004\006\023
\002\112\120\061\034\060\032\006\003\125\004\012\023\023\112\141
\160\141\156\145\163\145\040\107\157\166\145\162\156\155\145\156
\164\061\026\060\024\006\003\125\004\013\023\015\101\160\160\154
\151\143\141\164\151\157\156\103\101\060\202\001\042\060\015\006
\011\052\206\110\206\367\015\001\001\001\005\000\003\202\001\017
\000\060\202\001\012\002\202\001\001\000\247\155\340\164\116\207
\217\245\006\336\150\242\333\206\231\113\144\015\161\360\012\005
\233\216\252\341\314\056\322\152\073\301\172\264\227\141\215\212
\276\306\232\234\006\264\206\121\344\067\016\164\170\176\137\212
\177\224\244\327\107\010\375\120\132\126\344\150\254\050\163\240
\173\351\177\030\222\100\117\055\235\365\256\104\110\163\066\006
\236\144\054\073\064\043\333\134\046\344\161\171\217\324\156\171
\042\271\223\301\312\315\301\126\355\210\152\327\240\071\041\004
\127\054\242\365\274\107\101\117\136\064\042\225\265\037\051\155
\136\112\363\115\162\276\101\126\040\207\374\351\120\107\327\060
\024\356\134\214\125\272\131\215\207\374\043\336\223\320\004\214
\375\357\155\275\320\172\311\245\072\152\162\063\306\112\015\005
\027\052\055\173\261\247\330\326\360\276\364\077\352\016\050\155
\101\141\043\166\170\303\270\145\244\363\132\256\314\302\252\331
\347\130\336\266\176\235\205\156\237\052\012\157\237\003\051\060
\227\050\035\274\267\317\124\051\116\121\061\371\047\266\050\046
\376\242\143\346\101\026\360\063\230\107\002\003\001\000\001\243
\201\236\060\201\233\060\035\006\003\125\035\016\004\026\004\024
\124\132\313\046\077\161\314\224\106\015\226\123\352\153\110\320
\223\376\102\165\060\016\006\003\125\035\017\001\001\377\004\004
\003\002\001\006\060\131\006\003\125\035\021\004\122\060\120\244
\116\060\114\061\013\060\011\006\003\125\004\006\023\002\112\120
\061\030\060\026\006\003\125\004\012\014\017\346\227\245\346\234
\254\345\233\275\346\224\277\345\272\234\061\043\060\041\006\003
\125\004\013\014\032\343\202\242\343\203\227\343\203\252\343\202
\261\343\203\274\343\202\267\343\203\247\343\203\263\103\101\060
\017\006\003\125\035\023\001\001\377\004\005\060\003\001\001\377
\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\003
\202\001\001\000\071\152\104\166\167\070\072\354\243\147\106\017
\371\213\006\250\373\152\220\061\316\176\354\332\321\211\174\172
\353\056\014\275\231\062\347\260\044\326\303\377\365\262\210\011
\207\054\343\124\341\243\246\262\010\013\300\205\250\310\322\234
\161\366\035\237\140\374\070\063\023\341\236\334\013\137\332\026
\120\051\173\057\160\221\017\231\272\064\064\215\225\164\305\176
\170\251\146\135\275\312\041\167\102\020\254\146\046\075\336\221
\253\375\025\360\157\355\154\137\020\370\363\026\366\003\212\217
\247\022\021\014\313\375\077\171\301\234\375\142\356\243\317\124
\014\321\053\137\027\076\343\076\277\300\053\076\011\233\376\210
\246\176\264\222\027\374\043\224\201\275\156\247\305\214\302\353
\021\105\333\370\101\311\226\166\352\160\137\171\022\153\344\243
\007\132\005\357\047\111\317\041\237\212\114\011\160\146\251\046
\301\053\021\116\063\322\016\374\326\154\322\016\062\144\150\377
\255\005\170\137\003\035\250\343\220\254\044\340\017\100\247\113
\256\213\050\267\202\312\030\007\346\267\133\164\351\040\031\177
\262\033\211\124
END
CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
# Trust for Certificate "ApplicationCA - Japanese Government"
# Issuer: OU=ApplicationCA,O=Japanese Government,C=JP
# Serial Number: 49 (0x31)
# Subject: OU=ApplicationCA,O=Japanese Government,C=JP
# Not Valid Before: Wed Dec 12 15:00:00 2007
# Not Valid After : Tue Dec 12 15:00:00 2017
# Fingerprint (MD5): 7E:23:4E:5B:A7:A5:B4:25:E9:00:07:74:11:62:AE:D6
# Fingerprint (SHA1): 7F:8A:B0:CF:D0:51:87:6A:66:F3:36:0F:47:C8:8D:8C:D3:35:FC:74
CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
CKA_TOKEN CK_BBOOL CK_TRUE
CKA_PRIVATE CK_BBOOL CK_FALSE
CKA_MODIFIABLE CK_BBOOL CK_FALSE
CKA_LABEL UTF8 "ApplicationCA - Japanese Government"
CKA_CERT_SHA1_HASH MULTILINE_OCTAL
\177\212\260\317\320\121\207\152\146\363\066\017\107\310\215\214
\323\065\374\164
END
CKA_CERT_MD5_HASH MULTILINE_OCTAL
\176\043\116\133\247\245\264\045\351\000\007\164\021\142\256\326
END
CKA_ISSUER MULTILINE_OCTAL
\060\103\061\013\060\011\006\003\125\004\006\023\002\112\120\061
\034\060\032\006\003\125\004\012\023\023\112\141\160\141\156\145
\163\145\040\107\157\166\145\162\156\155\145\156\164\061\026\060
\024\006\003\125\004\013\023\015\101\160\160\154\151\143\141\164
\151\157\156\103\101
END
CKA_SERIAL_NUMBER MULTILINE_OCTAL
\002\001\061
END
CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
#
# Certificate "GeoTrust Primary Certification Authority - G3"
#
@ -26424,167 +25923,6 @@ CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
#
# Certificate "TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H6"
#
# Issuer: CN=T..RKTRUST Elektronik Sertifika Hizmet Sa..lay..c..s.. H6,O=T..RKTRUST Bilgi ..leti..im ve Bili..im G..venli..i Hizmetleri A....,L=Ankara,C=TR
# Serial Number:7d:a1:f2:65:ec:8a
# Subject: CN=T..RKTRUST Elektronik Sertifika Hizmet Sa..lay..c..s.. H6,O=T..RKTRUST Bilgi ..leti..im ve Bili..im G..venli..i Hizmetleri A....,L=Ankara,C=TR
# Not Valid Before: Wed Dec 18 09:04:10 2013
# Not Valid After : Sat Dec 16 09:04:10 2023
# Fingerprint (SHA-256): 8D:E7:86:55:E1:BE:7F:78:47:80:0B:93:F6:94:D2:1D:36:8C:C0:6E:03:3E:7F:AB:04:BB:5E:B9:9D:A6:B7:00
# Fingerprint (SHA1): 8A:5C:8C:EE:A5:03:E6:05:56:BA:D8:1B:D4:F6:C9:B0:ED:E5:2F:E0
CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
CKA_TOKEN CK_BBOOL CK_TRUE
CKA_PRIVATE CK_BBOOL CK_FALSE
CKA_MODIFIABLE CK_BBOOL CK_FALSE
CKA_LABEL UTF8 "TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H6"
CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
CKA_SUBJECT MULTILINE_OCTAL
\060\201\261\061\013\060\011\006\003\125\004\006\023\002\124\122
\061\017\060\015\006\003\125\004\007\014\006\101\156\153\141\162
\141\061\115\060\113\006\003\125\004\012\014\104\124\303\234\122
\113\124\122\125\123\124\040\102\151\154\147\151\040\304\260\154
\145\164\151\305\237\151\155\040\166\145\040\102\151\154\151\305
\237\151\155\040\107\303\274\166\145\156\154\151\304\237\151\040
\110\151\172\155\145\164\154\145\162\151\040\101\056\305\236\056
\061\102\060\100\006\003\125\004\003\014\071\124\303\234\122\113
\124\122\125\123\124\040\105\154\145\153\164\162\157\156\151\153
\040\123\145\162\164\151\146\151\153\141\040\110\151\172\155\145
\164\040\123\141\304\237\154\141\171\304\261\143\304\261\163\304
\261\040\110\066
END
CKA_ID UTF8 "0"
CKA_ISSUER MULTILINE_OCTAL
\060\201\261\061\013\060\011\006\003\125\004\006\023\002\124\122
\061\017\060\015\006\003\125\004\007\014\006\101\156\153\141\162
\141\061\115\060\113\006\003\125\004\012\014\104\124\303\234\122
\113\124\122\125\123\124\040\102\151\154\147\151\040\304\260\154
\145\164\151\305\237\151\155\040\166\145\040\102\151\154\151\305
\237\151\155\040\107\303\274\166\145\156\154\151\304\237\151\040
\110\151\172\155\145\164\154\145\162\151\040\101\056\305\236\056
\061\102\060\100\006\003\125\004\003\014\071\124\303\234\122\113
\124\122\125\123\124\040\105\154\145\153\164\162\157\156\151\153
\040\123\145\162\164\151\146\151\153\141\040\110\151\172\155\145
\164\040\123\141\304\237\154\141\171\304\261\143\304\261\163\304
\261\040\110\066
END
CKA_SERIAL_NUMBER MULTILINE_OCTAL
\002\006\175\241\362\145\354\212
END
CKA_VALUE MULTILINE_OCTAL
\060\202\004\046\060\202\003\016\240\003\002\001\002\002\006\175
\241\362\145\354\212\060\015\006\011\052\206\110\206\367\015\001
\001\013\005\000\060\201\261\061\013\060\011\006\003\125\004\006
\023\002\124\122\061\017\060\015\006\003\125\004\007\014\006\101
\156\153\141\162\141\061\115\060\113\006\003\125\004\012\014\104
\124\303\234\122\113\124\122\125\123\124\040\102\151\154\147\151
\040\304\260\154\145\164\151\305\237\151\155\040\166\145\040\102
\151\154\151\305\237\151\155\040\107\303\274\166\145\156\154\151
\304\237\151\040\110\151\172\155\145\164\154\145\162\151\040\101
\056\305\236\056\061\102\060\100\006\003\125\004\003\014\071\124
\303\234\122\113\124\122\125\123\124\040\105\154\145\153\164\162
\157\156\151\153\040\123\145\162\164\151\146\151\153\141\040\110
\151\172\155\145\164\040\123\141\304\237\154\141\171\304\261\143
\304\261\163\304\261\040\110\066\060\036\027\015\061\063\061\062
\061\070\060\071\060\064\061\060\132\027\015\062\063\061\062\061
\066\060\071\060\064\061\060\132\060\201\261\061\013\060\011\006
\003\125\004\006\023\002\124\122\061\017\060\015\006\003\125\004
\007\014\006\101\156\153\141\162\141\061\115\060\113\006\003\125
\004\012\014\104\124\303\234\122\113\124\122\125\123\124\040\102
\151\154\147\151\040\304\260\154\145\164\151\305\237\151\155\040
\166\145\040\102\151\154\151\305\237\151\155\040\107\303\274\166
\145\156\154\151\304\237\151\040\110\151\172\155\145\164\154\145
\162\151\040\101\056\305\236\056\061\102\060\100\006\003\125\004
\003\014\071\124\303\234\122\113\124\122\125\123\124\040\105\154
\145\153\164\162\157\156\151\153\040\123\145\162\164\151\146\151
\153\141\040\110\151\172\155\145\164\040\123\141\304\237\154\141
\171\304\261\143\304\261\163\304\261\040\110\066\060\202\001\042
\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000\003
\202\001\017\000\060\202\001\012\002\202\001\001\000\235\260\150
\326\350\275\024\226\243\000\012\232\361\364\307\314\221\115\161
\170\167\271\367\041\046\025\163\121\026\224\011\107\005\342\063
\365\150\232\065\377\334\113\057\062\307\260\355\342\202\345\157
\332\332\352\254\306\006\317\045\015\101\201\366\301\070\042\275
\371\261\245\246\263\001\274\077\120\027\053\366\351\146\125\324
\063\263\134\370\103\040\170\223\125\026\160\031\062\346\211\327
\144\353\275\110\120\375\366\320\101\003\302\164\267\375\366\200
\317\133\305\253\244\326\225\022\233\347\227\023\062\003\351\324
\253\103\133\026\355\063\042\144\051\266\322\223\255\057\154\330
\075\266\366\035\016\064\356\322\175\251\125\017\040\364\375\051
\273\221\133\034\175\306\102\070\155\102\050\155\324\001\373\315
\210\227\111\176\270\363\203\370\265\230\057\263\047\013\110\136
\126\347\116\243\063\263\104\326\245\362\030\224\355\034\036\251
\225\134\142\112\370\015\147\121\251\257\041\325\370\062\235\171
\272\032\137\345\004\125\115\023\106\377\362\317\164\307\032\143
\155\303\037\027\022\303\036\020\076\140\010\263\061\002\003\001
\000\001\243\102\060\100\060\035\006\003\125\035\016\004\026\004
\024\335\125\027\023\366\254\350\110\041\312\357\265\257\321\000
\062\355\236\214\265\060\016\006\003\125\035\017\001\001\377\004
\004\003\002\001\006\060\017\006\003\125\035\023\001\001\377\004
\005\060\003\001\001\377\060\015\006\011\052\206\110\206\367\015
\001\001\013\005\000\003\202\001\001\000\157\130\015\227\103\252
\026\124\076\277\251\337\222\105\077\205\013\273\126\323\014\122
\314\310\277\166\147\136\346\252\263\247\357\271\254\264\020\024
\015\164\176\075\155\255\321\175\320\232\251\245\312\030\073\002
\100\056\052\234\120\024\213\376\127\176\127\134\021\011\113\066
\105\122\367\075\254\024\375\104\337\213\227\043\324\303\301\356
\324\123\225\376\054\112\376\015\160\252\273\213\057\055\313\062
\243\202\362\124\337\330\362\335\327\110\162\356\112\243\051\226
\303\104\316\156\265\222\207\166\244\273\364\222\154\316\054\024
\011\146\216\215\255\026\265\307\033\011\141\073\343\040\242\003
\200\216\255\176\121\000\116\307\226\206\373\103\230\167\175\050
\307\217\330\052\156\347\204\157\227\101\051\000\026\136\115\342
\023\352\131\300\143\147\072\104\373\230\374\004\323\060\162\246
\366\207\011\127\255\166\246\035\143\232\375\327\145\310\170\203
\053\165\073\245\133\270\015\135\177\276\043\256\126\125\224\130
\357\037\201\214\052\262\315\346\233\143\236\030\274\345\153\006
\264\013\230\113\050\136\257\210\130\313
END
CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
# Trust for "TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H6"
# Issuer: CN=T..RKTRUST Elektronik Sertifika Hizmet Sa..lay..c..s.. H6,O=T..RKTRUST Bilgi ..leti..im ve Bili..im G..venli..i Hizmetleri A....,L=Ankara,C=TR
# Serial Number:7d:a1:f2:65:ec:8a
# Subject: CN=T..RKTRUST Elektronik Sertifika Hizmet Sa..lay..c..s.. H6,O=T..RKTRUST Bilgi ..leti..im ve Bili..im G..venli..i Hizmetleri A....,L=Ankara,C=TR
# Not Valid Before: Wed Dec 18 09:04:10 2013
# Not Valid After : Sat Dec 16 09:04:10 2023
# Fingerprint (SHA-256): 8D:E7:86:55:E1:BE:7F:78:47:80:0B:93:F6:94:D2:1D:36:8C:C0:6E:03:3E:7F:AB:04:BB:5E:B9:9D:A6:B7:00
# Fingerprint (SHA1): 8A:5C:8C:EE:A5:03:E6:05:56:BA:D8:1B:D4:F6:C9:B0:ED:E5:2F:E0
CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
CKA_TOKEN CK_BBOOL CK_TRUE
CKA_PRIVATE CK_BBOOL CK_FALSE
CKA_MODIFIABLE CK_BBOOL CK_FALSE
CKA_LABEL UTF8 "TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H6"
CKA_CERT_SHA1_HASH MULTILINE_OCTAL
\212\134\214\356\245\003\346\005\126\272\330\033\324\366\311\260
\355\345\057\340
END
CKA_CERT_MD5_HASH MULTILINE_OCTAL
\370\305\356\052\153\276\225\215\010\367\045\112\352\161\076\106
END
CKA_ISSUER MULTILINE_OCTAL
\060\201\261\061\013\060\011\006\003\125\004\006\023\002\124\122
\061\017\060\015\006\003\125\004\007\014\006\101\156\153\141\162
\141\061\115\060\113\006\003\125\004\012\014\104\124\303\234\122
\113\124\122\125\123\124\040\102\151\154\147\151\040\304\260\154
\145\164\151\305\237\151\155\040\166\145\040\102\151\154\151\305
\237\151\155\040\107\303\274\166\145\156\154\151\304\237\151\040
\110\151\172\155\145\164\154\145\162\151\040\101\056\305\236\056
\061\102\060\100\006\003\125\004\003\014\071\124\303\234\122\113
\124\122\125\123\124\040\105\154\145\153\164\162\157\156\151\153
\040\123\145\162\164\151\146\151\153\141\040\110\151\172\155\145
\164\040\123\141\304\237\154\141\171\304\261\143\304\261\163\304
\261\040\110\066
END
CKA_SERIAL_NUMBER MULTILINE_OCTAL
\002\006\175\241\362\145\354\212
END
CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
#
# Certificate "Certinomis - Root CA"
#
@ -30027,3 +29365,313 @@ CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
#
# Certificate "D-TRUST Root CA 3 2013"
#
# Issuer: CN=D-TRUST Root CA 3 2013,O=D-Trust GmbH,C=DE
# Serial Number: 1039788 (0xfddac)
# Subject: CN=D-TRUST Root CA 3 2013,O=D-Trust GmbH,C=DE
# Not Valid Before: Fri Sep 20 08:25:51 2013
# Not Valid After : Wed Sep 20 08:25:51 2028
# Fingerprint (SHA-256): A1:A8:6D:04:12:1E:B8:7F:02:7C:66:F5:33:03:C2:8E:57:39:F9:43:FC:84:B3:8A:D6:AF:00:90:35:DD:94:57
# Fingerprint (SHA1): 6C:7C:CC:E7:D4:AE:51:5F:99:08:CD:3F:F6:E8:C3:78:DF:6F:EF:97
CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
CKA_TOKEN CK_BBOOL CK_TRUE
CKA_PRIVATE CK_BBOOL CK_FALSE
CKA_MODIFIABLE CK_BBOOL CK_FALSE
CKA_LABEL UTF8 "D-TRUST Root CA 3 2013"
CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
CKA_SUBJECT MULTILINE_OCTAL
\060\105\061\013\060\011\006\003\125\004\006\023\002\104\105\061
\025\060\023\006\003\125\004\012\014\014\104\055\124\162\165\163
\164\040\107\155\142\110\061\037\060\035\006\003\125\004\003\014
\026\104\055\124\122\125\123\124\040\122\157\157\164\040\103\101
\040\063\040\062\060\061\063
END
CKA_ID UTF8 "0"
CKA_ISSUER MULTILINE_OCTAL
\060\105\061\013\060\011\006\003\125\004\006\023\002\104\105\061
\025\060\023\006\003\125\004\012\014\014\104\055\124\162\165\163
\164\040\107\155\142\110\061\037\060\035\006\003\125\004\003\014
\026\104\055\124\122\125\123\124\040\122\157\157\164\040\103\101
\040\063\040\062\060\061\063
END
CKA_SERIAL_NUMBER MULTILINE_OCTAL
\002\003\017\335\254
END
CKA_VALUE MULTILINE_OCTAL
\060\202\004\016\060\202\002\366\240\003\002\001\002\002\003\017
\335\254\060\015\006\011\052\206\110\206\367\015\001\001\013\005
\000\060\105\061\013\060\011\006\003\125\004\006\023\002\104\105
\061\025\060\023\006\003\125\004\012\014\014\104\055\124\162\165
\163\164\040\107\155\142\110\061\037\060\035\006\003\125\004\003
\014\026\104\055\124\122\125\123\124\040\122\157\157\164\040\103
\101\040\063\040\062\060\061\063\060\036\027\015\061\063\060\071
\062\060\060\070\062\065\065\061\132\027\015\062\070\060\071\062
\060\060\070\062\065\065\061\132\060\105\061\013\060\011\006\003
\125\004\006\023\002\104\105\061\025\060\023\006\003\125\004\012
\014\014\104\055\124\162\165\163\164\040\107\155\142\110\061\037
\060\035\006\003\125\004\003\014\026\104\055\124\122\125\123\124
\040\122\157\157\164\040\103\101\040\063\040\062\060\061\063\060
\202\001\042\060\015\006\011\052\206\110\206\367\015\001\001\001
\005\000\003\202\001\017\000\060\202\001\012\002\202\001\001\000
\304\173\102\222\202\037\354\355\124\230\216\022\300\312\011\337
\223\156\072\223\134\033\344\020\167\236\116\151\210\154\366\341
\151\362\366\233\242\141\261\275\007\040\164\230\145\361\214\046
\010\315\250\065\312\200\066\321\143\155\350\104\172\202\303\154
\136\336\273\350\066\322\304\150\066\214\237\062\275\204\042\340
\334\302\356\020\106\071\155\257\223\071\256\207\346\303\274\011
\311\054\153\147\133\331\233\166\165\114\013\340\273\305\327\274
\076\171\362\137\276\321\220\127\371\256\366\146\137\061\277\323
\155\217\247\272\112\363\043\145\273\267\357\243\045\327\012\352
\130\266\357\210\372\372\171\262\122\130\325\360\254\214\241\121
\164\051\225\252\121\073\220\062\003\237\034\162\164\220\336\075
\355\141\322\345\343\375\144\107\345\271\267\112\251\367\037\256
\226\206\004\254\057\343\244\201\167\267\132\026\377\330\017\077
\366\267\170\314\244\257\372\133\074\022\133\250\122\211\162\357
\210\363\325\104\201\206\225\043\237\173\335\274\331\064\357\174
\224\074\252\300\101\302\343\235\120\032\300\344\031\042\374\263
\002\003\001\000\001\243\202\001\005\060\202\001\001\060\017\006
\003\125\035\023\001\001\377\004\005\060\003\001\001\377\060\035
\006\003\125\035\016\004\026\004\024\077\220\310\175\307\025\157
\363\044\217\251\303\057\113\242\017\041\262\057\347\060\016\006
\003\125\035\017\001\001\377\004\004\003\002\001\006\060\201\276
\006\003\125\035\037\004\201\266\060\201\263\060\164\240\162\240
\160\206\156\154\144\141\160\072\057\057\144\151\162\145\143\164
\157\162\171\056\144\055\164\162\165\163\164\056\156\145\164\057
\103\116\075\104\055\124\122\125\123\124\045\062\060\122\157\157
\164\045\062\060\103\101\045\062\060\063\045\062\060\062\060\061
\063\054\117\075\104\055\124\162\165\163\164\045\062\060\107\155
\142\110\054\103\075\104\105\077\143\145\162\164\151\146\151\143
\141\164\145\162\145\166\157\143\141\164\151\157\156\154\151\163
\164\060\073\240\071\240\067\206\065\150\164\164\160\072\057\057
\143\162\154\056\144\055\164\162\165\163\164\056\156\145\164\057
\143\162\154\057\144\055\164\162\165\163\164\137\162\157\157\164
\137\143\141\137\063\137\062\060\061\063\056\143\162\154\060\015
\006\011\052\206\110\206\367\015\001\001\013\005\000\003\202\001
\001\000\016\131\016\130\344\164\110\043\104\317\064\041\265\234
\024\032\255\232\113\267\263\210\155\134\251\027\160\360\052\237
\215\173\371\173\205\372\307\071\350\020\010\260\065\053\137\317
\002\322\323\234\310\013\036\356\005\124\256\067\223\004\011\175
\154\217\302\164\274\370\034\224\276\061\001\100\055\363\044\040
\267\204\125\054\134\310\365\164\112\020\031\213\243\307\355\065
\326\011\110\323\016\300\272\071\250\260\106\002\260\333\306\210
\131\302\276\374\173\261\053\317\176\142\207\125\226\314\001\157
\233\147\041\225\065\213\370\020\374\161\033\267\113\067\151\246
\073\326\354\213\356\301\260\363\045\311\217\222\175\241\352\303
\312\104\277\046\245\164\222\234\343\164\353\235\164\331\313\115
\207\330\374\264\151\154\213\240\103\007\140\170\227\351\331\223
\174\302\106\274\233\067\122\243\355\212\074\023\251\173\123\113
\111\232\021\005\054\013\156\126\254\037\056\202\154\340\151\147
\265\016\155\055\331\344\300\025\361\077\372\030\162\341\025\155
\047\133\055\060\050\053\237\110\232\144\053\231\357\362\165\111
\137\134
END
CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
# Trust for "D-TRUST Root CA 3 2013"
# Issuer: CN=D-TRUST Root CA 3 2013,O=D-Trust GmbH,C=DE
# Serial Number: 1039788 (0xfddac)
# Subject: CN=D-TRUST Root CA 3 2013,O=D-Trust GmbH,C=DE
# Not Valid Before: Fri Sep 20 08:25:51 2013
# Not Valid After : Wed Sep 20 08:25:51 2028
# Fingerprint (SHA-256): A1:A8:6D:04:12:1E:B8:7F:02:7C:66:F5:33:03:C2:8E:57:39:F9:43:FC:84:B3:8A:D6:AF:00:90:35:DD:94:57
# Fingerprint (SHA1): 6C:7C:CC:E7:D4:AE:51:5F:99:08:CD:3F:F6:E8:C3:78:DF:6F:EF:97
CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
CKA_TOKEN CK_BBOOL CK_TRUE
CKA_PRIVATE CK_BBOOL CK_FALSE
CKA_MODIFIABLE CK_BBOOL CK_FALSE
CKA_LABEL UTF8 "D-TRUST Root CA 3 2013"
CKA_CERT_SHA1_HASH MULTILINE_OCTAL
\154\174\314\347\324\256\121\137\231\010\315\077\366\350\303\170
\337\157\357\227
END
CKA_CERT_MD5_HASH MULTILINE_OCTAL
\267\042\146\230\176\326\003\340\301\161\346\165\315\126\105\277
END
CKA_ISSUER MULTILINE_OCTAL
\060\105\061\013\060\011\006\003\125\004\006\023\002\104\105\061
\025\060\023\006\003\125\004\012\014\014\104\055\124\162\165\163
\164\040\107\155\142\110\061\037\060\035\006\003\125\004\003\014
\026\104\055\124\122\125\123\124\040\122\157\157\164\040\103\101
\040\063\040\062\060\061\063
END
CKA_SERIAL_NUMBER MULTILINE_OCTAL
\002\003\017\335\254
END
CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
#
# Certificate "TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1"
#
# Issuer: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1,OU=Kamu Sertifikasyon Merkezi - Kamu SM,O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK,L=Gebze - Kocaeli,C=TR
# Serial Number: 1 (0x1)
# Subject: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1,OU=Kamu Sertifikasyon Merkezi - Kamu SM,O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK,L=Gebze - Kocaeli,C=TR
# Not Valid Before: Mon Nov 25 08:25:55 2013
# Not Valid After : Sun Oct 25 08:25:55 2043
# Fingerprint (SHA-256): 46:ED:C3:68:90:46:D5:3A:45:3F:B3:10:4A:B8:0D:CA:EC:65:8B:26:60:EA:16:29:DD:7E:86:79:90:64:87:16
# Fingerprint (SHA1): 31:43:64:9B:EC:CE:27:EC:ED:3A:3F:0B:8F:0D:E4:E8:91:DD:EE:CA
CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
CKA_TOKEN CK_BBOOL CK_TRUE
CKA_PRIVATE CK_BBOOL CK_FALSE
CKA_MODIFIABLE CK_BBOOL CK_FALSE
CKA_LABEL UTF8 "TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1"
CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
CKA_SUBJECT MULTILINE_OCTAL
\060\201\322\061\013\060\011\006\003\125\004\006\023\002\124\122
\061\030\060\026\006\003\125\004\007\023\017\107\145\142\172\145
\040\055\040\113\157\143\141\145\154\151\061\102\060\100\006\003
\125\004\012\023\071\124\165\162\153\151\171\145\040\102\151\154
\151\155\163\145\154\040\166\145\040\124\145\153\156\157\154\157
\152\151\153\040\101\162\141\163\164\151\162\155\141\040\113\165
\162\165\155\165\040\055\040\124\125\102\111\124\101\113\061\055
\060\053\006\003\125\004\013\023\044\113\141\155\165\040\123\145
\162\164\151\146\151\153\141\163\171\157\156\040\115\145\162\153
\145\172\151\040\055\040\113\141\155\165\040\123\115\061\066\060
\064\006\003\125\004\003\023\055\124\125\102\111\124\101\113\040
\113\141\155\165\040\123\115\040\123\123\114\040\113\157\153\040
\123\145\162\164\151\146\151\153\141\163\151\040\055\040\123\165
\162\165\155\040\061
END
CKA_ID UTF8 "0"
CKA_ISSUER MULTILINE_OCTAL
\060\201\322\061\013\060\011\006\003\125\004\006\023\002\124\122
\061\030\060\026\006\003\125\004\007\023\017\107\145\142\172\145
\040\055\040\113\157\143\141\145\154\151\061\102\060\100\006\003
\125\004\012\023\071\124\165\162\153\151\171\145\040\102\151\154
\151\155\163\145\154\040\166\145\040\124\145\153\156\157\154\157
\152\151\153\040\101\162\141\163\164\151\162\155\141\040\113\165
\162\165\155\165\040\055\040\124\125\102\111\124\101\113\061\055
\060\053\006\003\125\004\013\023\044\113\141\155\165\040\123\145
\162\164\151\146\151\153\141\163\171\157\156\040\115\145\162\153
\145\172\151\040\055\040\113\141\155\165\040\123\115\061\066\060
\064\006\003\125\004\003\023\055\124\125\102\111\124\101\113\040
\113\141\155\165\040\123\115\040\123\123\114\040\113\157\153\040
\123\145\162\164\151\146\151\153\141\163\151\040\055\040\123\165
\162\165\155\040\061
END
CKA_SERIAL_NUMBER MULTILINE_OCTAL
\002\001\001
END
CKA_VALUE MULTILINE_OCTAL
\060\202\004\143\060\202\003\113\240\003\002\001\002\002\001\001
\060\015\006\011\052\206\110\206\367\015\001\001\013\005\000\060
\201\322\061\013\060\011\006\003\125\004\006\023\002\124\122\061
\030\060\026\006\003\125\004\007\023\017\107\145\142\172\145\040
\055\040\113\157\143\141\145\154\151\061\102\060\100\006\003\125
\004\012\023\071\124\165\162\153\151\171\145\040\102\151\154\151
\155\163\145\154\040\166\145\040\124\145\153\156\157\154\157\152
\151\153\040\101\162\141\163\164\151\162\155\141\040\113\165\162
\165\155\165\040\055\040\124\125\102\111\124\101\113\061\055\060
\053\006\003\125\004\013\023\044\113\141\155\165\040\123\145\162
\164\151\146\151\153\141\163\171\157\156\040\115\145\162\153\145
\172\151\040\055\040\113\141\155\165\040\123\115\061\066\060\064
\006\003\125\004\003\023\055\124\125\102\111\124\101\113\040\113
\141\155\165\040\123\115\040\123\123\114\040\113\157\153\040\123
\145\162\164\151\146\151\153\141\163\151\040\055\040\123\165\162
\165\155\040\061\060\036\027\015\061\063\061\061\062\065\060\070
\062\065\065\065\132\027\015\064\063\061\060\062\065\060\070\062
\065\065\065\132\060\201\322\061\013\060\011\006\003\125\004\006
\023\002\124\122\061\030\060\026\006\003\125\004\007\023\017\107
\145\142\172\145\040\055\040\113\157\143\141\145\154\151\061\102
\060\100\006\003\125\004\012\023\071\124\165\162\153\151\171\145
\040\102\151\154\151\155\163\145\154\040\166\145\040\124\145\153
\156\157\154\157\152\151\153\040\101\162\141\163\164\151\162\155
\141\040\113\165\162\165\155\165\040\055\040\124\125\102\111\124
\101\113\061\055\060\053\006\003\125\004\013\023\044\113\141\155
\165\040\123\145\162\164\151\146\151\153\141\163\171\157\156\040
\115\145\162\153\145\172\151\040\055\040\113\141\155\165\040\123
\115\061\066\060\064\006\003\125\004\003\023\055\124\125\102\111
\124\101\113\040\113\141\155\165\040\123\115\040\123\123\114\040
\113\157\153\040\123\145\162\164\151\146\151\153\141\163\151\040
\055\040\123\165\162\165\155\040\061\060\202\001\042\060\015\006
\011\052\206\110\206\367\015\001\001\001\005\000\003\202\001\017
\000\060\202\001\012\002\202\001\001\000\257\165\060\063\252\273
\153\323\231\054\022\067\204\331\215\173\227\200\323\156\347\377
\233\120\225\076\220\225\126\102\327\031\174\046\204\215\222\372
\001\035\072\017\342\144\070\267\214\274\350\210\371\213\044\253
\056\243\365\067\344\100\216\030\045\171\203\165\037\073\377\154
\250\305\306\126\370\264\355\212\104\243\253\154\114\374\035\320
\334\357\150\275\317\344\252\316\360\125\367\242\064\324\203\153
\067\174\034\302\376\265\003\354\127\316\274\264\265\305\355\000
\017\123\067\052\115\364\117\014\203\373\206\317\313\376\214\116
\275\207\371\247\213\041\127\234\172\337\003\147\211\054\235\227
\141\247\020\270\125\220\177\016\055\047\070\164\337\347\375\332
\116\022\343\115\025\042\002\310\340\340\374\017\255\212\327\311
\124\120\314\073\017\312\026\200\204\320\121\126\303\216\126\177
\211\042\063\057\346\205\012\275\245\250\033\066\336\323\334\054
\155\073\307\023\275\131\043\054\346\345\244\367\330\013\355\352
\220\100\104\250\225\273\223\325\320\200\064\266\106\170\016\037
\000\223\106\341\356\351\371\354\117\027\002\003\001\000\001\243
\102\060\100\060\035\006\003\125\035\016\004\026\004\024\145\077
\307\212\206\306\074\335\074\124\134\065\370\072\355\122\014\107
\127\310\060\016\006\003\125\035\017\001\001\377\004\004\003\002
\001\006\060\017\006\003\125\035\023\001\001\377\004\005\060\003
\001\001\377\060\015\006\011\052\206\110\206\367\015\001\001\013
\005\000\003\202\001\001\000\052\077\341\361\062\216\256\341\230
\134\113\136\317\153\036\152\011\322\042\251\022\307\136\127\175
\163\126\144\200\204\172\223\344\011\271\020\315\237\052\047\341
\000\167\276\110\310\065\250\201\237\344\270\054\311\177\016\260
\322\113\067\135\352\271\325\013\136\064\275\364\163\051\303\355
\046\025\234\176\010\123\212\130\215\320\113\050\337\301\263\337
\040\363\371\343\343\072\337\314\234\224\330\116\117\303\153\027
\267\367\162\350\255\146\063\265\045\123\253\340\370\114\251\235
\375\362\015\272\256\271\331\252\306\153\371\223\273\256\253\270
\227\074\003\032\272\103\306\226\271\105\162\070\263\247\241\226
\075\221\173\176\300\041\123\114\207\355\362\013\124\225\121\223
\325\042\245\015\212\361\223\016\076\124\016\260\330\311\116\334
\362\061\062\126\352\144\371\352\265\235\026\146\102\162\363\177
\323\261\061\103\374\244\216\027\361\155\043\253\224\146\370\255
\373\017\010\156\046\055\177\027\007\011\262\214\373\120\300\237
\226\215\317\266\375\000\235\132\024\232\277\002\104\365\301\302
\237\042\136\242\017\241\343
END
CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
# Trust for "TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1"
# Issuer: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1,OU=Kamu Sertifikasyon Merkezi - Kamu SM,O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK,L=Gebze - Kocaeli,C=TR
# Serial Number: 1 (0x1)
# Subject: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1,OU=Kamu Sertifikasyon Merkezi - Kamu SM,O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK,L=Gebze - Kocaeli,C=TR
# Not Valid Before: Mon Nov 25 08:25:55 2013
# Not Valid After : Sun Oct 25 08:25:55 2043
# Fingerprint (SHA-256): 46:ED:C3:68:90:46:D5:3A:45:3F:B3:10:4A:B8:0D:CA:EC:65:8B:26:60:EA:16:29:DD:7E:86:79:90:64:87:16
# Fingerprint (SHA1): 31:43:64:9B:EC:CE:27:EC:ED:3A:3F:0B:8F:0D:E4:E8:91:DD:EE:CA
CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
CKA_TOKEN CK_BBOOL CK_TRUE
CKA_PRIVATE CK_BBOOL CK_FALSE
CKA_MODIFIABLE CK_BBOOL CK_FALSE
CKA_LABEL UTF8 "TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1"
CKA_CERT_SHA1_HASH MULTILINE_OCTAL
\061\103\144\233\354\316\047\354\355\072\077\013\217\015\344\350
\221\335\356\312
END
CKA_CERT_MD5_HASH MULTILINE_OCTAL
\334\000\201\334\151\057\076\057\260\073\366\075\132\221\216\111
END
CKA_ISSUER MULTILINE_OCTAL
\060\201\322\061\013\060\011\006\003\125\004\006\023\002\124\122
\061\030\060\026\006\003\125\004\007\023\017\107\145\142\172\145
\040\055\040\113\157\143\141\145\154\151\061\102\060\100\006\003
\125\004\012\023\071\124\165\162\153\151\171\145\040\102\151\154
\151\155\163\145\154\040\166\145\040\124\145\153\156\157\154\157
\152\151\153\040\101\162\141\163\164\151\162\155\141\040\113\165
\162\165\155\165\040\055\040\124\125\102\111\124\101\113\061\055
\060\053\006\003\125\004\013\023\044\113\141\155\165\040\123\145
\162\164\151\146\151\153\141\163\171\157\156\040\115\145\162\153
\145\172\151\040\055\040\113\141\155\165\040\123\115\061\066\060
\064\006\003\125\004\003\023\055\124\125\102\111\124\101\113\040
\113\141\155\165\040\123\115\040\123\123\114\040\113\157\153\040
\123\145\162\164\151\146\151\153\141\163\151\040\055\040\123\165
\162\165\155\040\061
END
CKA_SERIAL_NUMBER MULTILINE_OCTAL
\002\001\001
END
CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE

Просмотреть файл

@ -22,31 +22,32 @@
* to the list of trusted certificates.
*
* The NSS_BUILTINS_LIBRARY_VERSION_MINOR macro needs to be bumped
* for each NSS minor release AND whenever we change the list of
* trusted certificates. 10 minor versions are allocated for each
* NSS 3.x branch as follows, allowing us to change the list of
* trusted certificates up to 9 times on each branch.
* - NSS 3.5 branch: 3-9
* - NSS 3.6 branch: 10-19
* - NSS 3.7 branch: 20-29
* - NSS 3.8 branch: 30-39
* - NSS 3.9 branch: 40-49
* - NSS 3.10 branch: 50-59
* - NSS 3.11 branch: 60-69
* ...
* - NSS 3.12 branch: 70-89
* - NSS 3.13 branch: 90-99
* - NSS 3.14 branch: 100-109
* ...
* - NSS 3.29 branch: 250-255
* whenever we change the list of trusted certificates.
*
* Please use the following rules when increasing the version number:
*
* - starting with version 2.14, NSS_BUILTINS_LIBRARY_VERSION_MINOR
* must always be an EVEN number (e.g. 16, 18, 20 etc.)
*
* - whenever possible, if older branches require a modification to the
* list, these changes should be made on the main line of development (trunk),
* and the older branches should update to the most recent list.
*
* - ODD minor version numbers are reserved to indicate a snapshot that has
* deviated from the main line of development, e.g. if it was necessary
* to modify the list on a stable branch.
* Once the version has been changed to an odd number (e.g. 2.13) on a branch,
* it should remain unchanged on that branch, even if further changes are
* made on that branch.
*
* NSS_BUILTINS_LIBRARY_VERSION_MINOR is a CK_BYTE. It's not clear
* whether we may use its full range (0-255) or only 0-99 because
* of the comment in the CK_VERSION type definition.
* It's recommend to switch back to 0 after having reached version 98/99.
*/
#define NSS_BUILTINS_LIBRARY_VERSION_MAJOR 2
#define NSS_BUILTINS_LIBRARY_VERSION_MINOR 11
#define NSS_BUILTINS_LIBRARY_VERSION "2.11"
#define NSS_BUILTINS_LIBRARY_VERSION_MINOR 14
#define NSS_BUILTINS_LIBRARY_VERSION "2.14"
/* These version numbers detail the semantic changes to the ckfw engine. */
#define NSS_BUILTINS_HARDWARE_VERSION_MAJOR 1

Просмотреть файл

@ -510,7 +510,7 @@ sec_pkcs7_encoder_work_data(SEC_PKCS7EncoderContext *p7ecx, SECItem *dest,
* No output is expected, but the input data may be buffered
* so we still have to call Encrypt.
*/
rv = sec_PKCS7Encrypt(p7ecx->encryptobj, NULL, NULL, 0,
rv = sec_PKCS7Encrypt(p7ecx->encryptobj, NULL, &outlen, 0,
data, inlen, final);
if (final) {
len = 0;

Просмотреть файл

@ -29,7 +29,7 @@
"PKCS #12 V2 PBE With SHA-1 and 40 Bit RC4"
export pkcs12v2pbeWithSha1AndTripleDESCBC=\
"PKCS #12 V2 PBE With SHA-1 and Triple DES-CBC"
"PKCS #12 V2 PBE With SHA-1 and 3KEY Triple DES-CBC"
export pkcs12v2pbeWithSha1And128BitRc2Cbc=\
"PKCS #12 V2 PBE With SHA-1 and 128 Bit RC2 CBC"
@ -249,7 +249,7 @@ tools_p12_export_list_import_all_pkcs5pbe_ciphers()
"${pkcs5pbeWithMD5AndDEScbc}" \
"${pkcs5pbeWithSha1AndDEScbc}" \
"DEFAULT"\
"null"; do
"none"; do
export_list_import "${key_cipher}" "${cert_cipher}"
done
done
@ -287,7 +287,7 @@ tools_p12_export_list_import_all_pkcs5v2_ciphers()
AES-128-CBC \
AES-192-CBC \
AES-256-CBC \
null; do
none; do
export_list_import ${key_cipher} ${cert_cipher}
done
done
@ -324,8 +324,8 @@ tools_p12_export_list_import_all_pkcs12v2pbe_ciphers()
"${pkcs12v2pbeWithMd5AndDESCBC}" \
"${pkcs12v2pbeWithSha1AndDESCBC}" \
"DEFAULT"\
"null"; do
export_list_import "${key_cipher}" "${key_cipher}"
"none"; do
export_list_import "${key_cipher}" "${cert_cipher}"
done
#done
}
@ -333,34 +333,59 @@ tools_p12_export_list_import_all_pkcs12v2pbe_ciphers()
#########################################################################
# Export with no encryption on key should fail but on cert should pass
#########################################################################
tools_p12_export_with_null_ciphers()
tools_p12_export_with_none_ciphers()
{
# use null as the key encryption algorithm default for the cert one
# use none as the key encryption algorithm default for the cert one
# should fail
echo "pk12util -o Alice.p12 -n \"Alice\" -d ${P_R_ALICEDIR} \\"
echo " -k ${R_PWFILE} -w ${R_PWFILE} -c null"
echo " -k ${R_PWFILE} -w ${R_PWFILE} -c none"
${BINDIR}/pk12util -o Alice.p12 -n Alice -d ${P_R_ALICEDIR} \
-k ${R_PWFILE} -w ${R_PWFILE} \
-c null 2>&1
-c none 2>&1
ret=$?
html_msg $ret 30 "Exporting with [null:default] (pk12util -o)"
html_msg $ret 30 "Exporting with [none:default] (pk12util -o)"
check_tmpfile
# use default as the key encryption algorithm null for the cert one
# use default as the key encryption algorithm none for the cert one
# should pass
echo "pk12util -o Alice.p12 -n \"Alice\" -d ${P_R_ALICEDIR} \\"
echo " -k ${R_PWFILE} -w ${R_PWFILE} -C null"
echo " -k ${R_PWFILE} -w ${R_PWFILE} -C none"
${BINDIR}/pk12util -o Alice.p12 -n Alice -d ${P_R_ALICEDIR} \
-k ${R_PWFILE} -w ${R_PWFILE} \
-C null 2>&1
-C none 2>&1
ret=$?
html_msg $ret 0 "Exporting with [default:null] (pk12util -o)"
html_msg $ret 0 "Exporting with [default:none] (pk12util -o)"
check_tmpfile
}
#########################################################################
# Export with invalid cipher should fail
#########################################################################
tools_p12_export_with_invalid_ciphers()
{
echo "pk12util -o Alice.p12 -n \"Alice\" -d ${P_R_ALICEDIR} \\"
echo " -k ${R_PWFILE} -w ${R_PWFILE} -c INVALID_CIPHER"
${BINDIR}/pk12util -o Alice.p12 -n Alice -d ${P_R_ALICEDIR} \
-k ${R_PWFILE} -w ${R_PWFILE} \
-c INVALID_CIPHER 2>&1
ret=$?
html_msg $ret 30 "Exporting with [INVALID_CIPHER:default] (pk12util -o)"
check_tmpfile
echo "pk12util -o Alice.p12 -n \"Alice\" -d ${P_R_ALICEDIR} \\"
echo " -k ${R_PWFILE} -w ${R_PWFILE} -C INVALID_CIPHER"
${BINDIR}/pk12util -o Alice.p12 -n Alice -d ${P_R_ALICEDIR} \
-k ${R_PWFILE} -w ${R_PWFILE} \
-C INVALID_CIPHER 2>&1
ret=$?
html_msg $ret 30 "Exporting with [default:INVALID_CIPHER] (pk12util -o)"
check_tmpfile
}
#########################################################################
# Exports using the default key and certificate encryption ciphers.
# Imports from and lists the contents of the p12 file.
@ -407,7 +432,8 @@ tools_p12()
tools_p12_export_list_import_all_pkcs5v2_ciphers
tools_p12_export_list_import_all_pkcs5pbe_ciphers
tools_p12_export_list_import_all_pkcs12v2pbe_ciphers
tools_p12_export_with_null_ciphers
tools_p12_export_with_none_ciphers
tools_p12_export_with_invalid_ciphers
}
############################## tools_sign ##############################

Просмотреть файл

@ -986,6 +986,8 @@ class MochitestDesktop(object):
self.urlOpts.append("interactiveDebugger=true")
if options.jscov_dir_prefix:
self.urlOpts.append("jscovDirPrefix=%s" % options.jscov_dir_prefix)
if options.cleanupCrashes:
self.urlOpts.append("cleanupCrashes=true")
def normflavor(self, flavor):
"""

Просмотреть файл

@ -97,6 +97,7 @@ TestRunner.dumpDMDAfterTest = false;
TestRunner.slowestTestTime = 0;
TestRunner.slowestTestURL = "";
TestRunner.interactiveDebugger = false;
TestRunner.cleanupCrashes = false;
TestRunner._expectingProcessCrash = false;
TestRunner._structuredFormatter = new StructuredFormatter();
@ -561,6 +562,12 @@ TestRunner.testFinished = function(tests) {
aFilename + ".");
});
}
if (TestRunner.cleanupCrashes) {
if (SpecialPowers.removePendingCrashDumpFiles()) {
TestRunner.structuredLogger.info("This test left pending crash dumps");
}
}
}
function runNextTest() {

Просмотреть файл

@ -152,6 +152,10 @@ if (params.maxTimeouts) {
TestRunner.maxTimeouts = params.maxTimeouts;
}
if (params.cleanupCrashes) {
TestRunner.cleanupCrashes = true;
}
// Log things to the console if appropriate.
TestRunner.logger.addListener("dumpListener", consoleLevel + "", function(msg) {
dump(msg.info.join(' ') + "\n");

Просмотреть файл

@ -132,6 +132,15 @@ SpecialPowersObserverAPI.prototype = {
return this._crashDumpDir;
},
_getPendingCrashDumpDir: function() {
if (!this._pendingCrashDumpDir) {
this._pendingCrashDumpDir = Services.dirsvc.get("UAppData", Ci.nsIFile);
this._pendingCrashDumpDir.append("Crash Reports");
this._pendingCrashDumpDir.append("pending");
}
return this._pendingCrashDumpDir;
},
_getExtraData: function(dumpId) {
let extraFile = this._getCrashDumpDir().clone();
extraFile.append(dumpId + ".extra");
@ -178,6 +187,22 @@ SpecialPowersObserverAPI.prototype = {
return crashDumpFiles.concat();
},
_deletePendingCrashDumpFiles: function() {
var crashDumpDir = this._getPendingCrashDumpDir();
var removed = false;
if (crashDumpDir.exists()) {
let entries = crashDumpDir.directoryEntries;
while (entries.hasMoreElements()) {
let file = entries.getNext().QueryInterface(Ci.nsIFile);
if (file.isFile()) {
file.remove(false);
removed = true;
}
}
}
return removed;
},
_getURI: function (url) {
return Services.io.newURI(url);
},
@ -356,6 +381,8 @@ SpecialPowersObserverAPI.prototype = {
return this._deleteCrashDumpFiles(aMessage.json.filenames);
case "find-crash-dump-files":
return this._findCrashDumpFiles(aMessage.json.crashDumpFilesToIgnore);
case "delete-pending-crash-dump-files":
return this._deletePendingCrashDumpFiles();
default:
throw new SpecialPowersError("Invalid operation for SPProcessCrashService");
}

Просмотреть файл

@ -694,6 +694,14 @@ SpecialPowersAPI.prototype = {
return crashDumpFiles;
},
removePendingCrashDumpFiles: function() {
var message = {
op: "delete-pending-crash-dump-files"
};
var removed = this._sendSyncMessage("SPProcessCrashService", message)[0];
return removed;
},
_setTimeout: function(callback) {
// for mochitest-browser
if (typeof window != 'undefined')

Просмотреть файл

@ -20,20 +20,17 @@
#endif
ThreadInfo::ThreadInfo(const char* aName, int aThreadId, bool aIsMainThread,
mozilla::NotNull<PseudoStack*> aPseudoStack,
void* aStackTop)
: mName(strdup(aName))
, mThreadId(aThreadId)
, mIsMainThread(aIsMainThread)
, mPseudoStack(aPseudoStack)
, mPseudoStack(mozilla::WrapNotNull(new PseudoStack()))
, mPlatformData(AllocPlatformData(aThreadId))
, mStackTop(aStackTop)
, mPendingDelete(false)
, mHasProfile(false)
, mLastSample()
{
MOZ_COUNT_CTOR(ThreadInfo);
mThread = NS_GetCurrentThread();
// We don't have to guess on mac
#if defined(GP_OS_darwin)
@ -41,6 +38,10 @@ ThreadInfo::ThreadInfo(const char* aName, int aThreadId, bool aIsMainThread,
mStackTop = pthread_get_stackaddr_np(self);
#endif
if (aIsMainThread) {
mResponsiveness.emplace();
}
// I don't know if we can assert this. But we should warn.
MOZ_ASSERT(aThreadId >= 0, "native thread ID is < 0");
MOZ_ASSERT(aThreadId <= INT32_MAX, "native thread ID is > INT32_MAX");
@ -53,12 +54,6 @@ ThreadInfo::~ThreadInfo()
delete mPseudoStack;
}
void
ThreadInfo::SetPendingDelete()
{
mPendingDelete = true;
}
void
ThreadInfo::StreamJSON(ProfileBuffer* aBuffer, SpliceableJSONWriter& aWriter,
const TimeStamp& aStartTime, double aSinceTime)

Просмотреть файл

@ -17,7 +17,7 @@ class ThreadInfo final
{
public:
ThreadInfo(const char* aName, int aThreadId, bool aIsMainThread,
mozilla::NotNull<PseudoStack*> aPseudoStack, void* aStackTop);
void* aStackTop);
~ThreadInfo();
@ -25,6 +25,7 @@ public:
int ThreadId() const { return mThreadId; }
bool IsMainThread() const { return mIsMainThread; }
mozilla::NotNull<PseudoStack*> Stack() const { return mPseudoStack; }
void SetHasProfile() { mHasProfile = true; }
@ -32,9 +33,6 @@ public:
PlatformData* GetPlatformData() const { return mPlatformData.get(); }
void* StackTop() const { return mStackTop; }
void SetPendingDelete();
bool IsPendingDelete() const { return mPendingDelete; }
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
ProfileBuffer::LastSample& LastSample() { return mLastSample; }
@ -44,20 +42,15 @@ private:
int mThreadId;
const bool mIsMainThread;
// The thread's PseudoStack. This is an owning pointer.
// The thread's PseudoStack. This is an owning pointer. It could be an inline
// member, but we don't do that because PseudoStack is quite large, and we
// have ThreadInfo vectors and so we'd end up wasting a lot of space in those
// vectors for excess elements.
mozilla::NotNull<PseudoStack*> mPseudoStack;
UniquePlatformData mPlatformData;
void* mStackTop;
// May be null for the main thread if the profiler was started during startup.
nsCOMPtr<nsIThread> mThread;
// When a thread dies while the profiler is active we keep its ThreadInfo
// (and its PseudoStack) around for a while, and put it in a "pending delete"
// state.
bool mPendingDelete;
//
// The following code is only used for threads that are being profiled, i.e.
// for which SetHasProfile() has been called.
@ -74,10 +67,12 @@ public:
void FlushSamplesAndMarkers(ProfileBuffer* aBuffer,
const mozilla::TimeStamp& aStartTime);
ThreadResponsiveness* GetThreadResponsiveness() { return &mRespInfo; }
void UpdateThreadResponsiveness() {
mRespInfo.Update(mIsMainThread, mThread);
// Returns nullptr if this is not the main thread.
ThreadResponsiveness* GetThreadResponsiveness()
{
ThreadResponsiveness* responsiveness = mResponsiveness.ptrOr(nullptr);
MOZ_ASSERT(!!responsiveness == mIsMainThread);
return responsiveness;
}
private:
@ -91,7 +86,8 @@ private:
mozilla::UniquePtr<char[]> mSavedStreamedMarkers;
mozilla::Maybe<UniqueStacks> mUniqueStacks;
ThreadResponsiveness mRespInfo;
// This is only used for the main thread.
mozilla::Maybe<ThreadResponsiveness> mResponsiveness;
// When sampling, this holds the generation number and offset in
// ProfilerState::mBuffer of the most recent sample for this thread.

Просмотреть файл

@ -38,9 +38,9 @@
#include "nsProfilerStartParams.h"
#include "mozilla/Services.h"
#include "nsThreadUtils.h"
#include "ProfileGatherer.h"
#include "ProfilerMarkers.h"
#include "shared-libraries.h"
#include "prtime.h"
#ifdef MOZ_TASK_TRACER
#include "GeckoTaskTracer.h"
@ -129,7 +129,8 @@ class ProfilerState
{
public:
// Shorter names for local use.
typedef ProfilerStateMutex Mutex;
class Mutex : public mozilla::StaticMutex {};
typedef mozilla::BaseAutoLock<Mutex> AutoLock;
// Only functions that take a LockRef arg can modify this class's fields.
@ -153,7 +154,6 @@ public:
, mFeatureTaskTracer(false)
, mFeatureThreads(false)
, mBuffer(nullptr)
, mGatherer(nullptr)
, mIsPaused(false)
#if defined(GP_OS_linux) || defined(GP_OS_android)
, mWasPaused(false)
@ -196,9 +196,8 @@ public:
GET_AND_SET(ProfileBuffer*, Buffer)
GET_AND_SET(ProfileGatherer*, Gatherer)
ThreadVector& Threads(LockRef) { return mThreads; }
ThreadVector& LiveThreads(LockRef) { return mLiveThreads; }
ThreadVector& DeadThreads(LockRef) { return mDeadThreads; }
static bool IsActive(LockRef) { return sActivityGeneration > 0; }
static uint32_t ActivityGeneration(LockRef) { return sActivityGeneration; }
@ -266,15 +265,16 @@ private:
bool mFeatureThreads;
// The buffer into which all samples are recorded. Always used in conjunction
// with mThreads. Null when the profiler is inactive.
// with mLiveThreads and mDeadThreads. Null when the profiler is inactive.
ProfileBuffer* mBuffer;
// A helper class that is used when saving profiles. Null when the profiler
// is inactive.
RefPtr<mozilla::ProfileGatherer> mGatherer;
// All the registered threads.
ThreadVector mThreads;
// Info on all the registered threads, both live and dead. ThreadIds in
// mLiveThreads are unique. ThreadIds in mDeadThreads may not be, because
// ThreadIds can be reused. HasProfile() is true for all ThreadInfos in
// mDeadThreads because we don't hold onto ThreadInfos for non-profiled dead
// threads.
ThreadVector mLiveThreads;
ThreadVector mDeadThreads;
// Is the profiler active? The obvious way to track this is with a bool,
// sIsActive, but then we could have the following scenario.
@ -375,7 +375,7 @@ public:
, mStackTop(aThreadInfo->StackTop())
, mLastSample(&aThreadInfo->LastSample())
, mPlatformData(aThreadInfo->GetPlatformData())
, mRespInfo(aThreadInfo->GetThreadResponsiveness())
, mResponsiveness(aThreadInfo->GetThreadResponsiveness())
, mRSSMemory(aRSSMemory) // may be zero
, mUSSMemory(aUSSMemory) // may be zero
#if !defined(GP_OS_darwin)
@ -398,7 +398,7 @@ public:
, mStackTop(nullptr)
, mLastSample(nullptr)
, mPlatformData(aPlatformData)
, mRespInfo(nullptr)
, mResponsiveness(nullptr)
, mRSSMemory(0)
, mUSSMemory(0)
#if !defined(GP_OS_darwin)
@ -428,7 +428,7 @@ public:
PlatformData* const mPlatformData;
ThreadResponsiveness* const mRespInfo; // may be null
ThreadResponsiveness* const mResponsiveness; // may be null
const int64_t mRSSMemory; // may be zero
const int64_t mUSSMemory; // may be zero
@ -1077,9 +1077,9 @@ Tick(PS::LockRef aLock, ProfileBuffer* aBuffer, TickSample* aSample)
}
}
if (aSample->mRespInfo && aSample->mRespInfo->HasData()) {
if (aSample->mResponsiveness && aSample->mResponsiveness->HasData()) {
mozilla::TimeDuration delta =
aSample->mRespInfo->GetUnresponsiveDuration(aSample->mTimeStamp);
aSample->mResponsiveness->GetUnresponsiveDuration(aSample->mTimeStamp);
aBuffer->addTag(ProfileBufferEntry::Responsiveness(delta.ToMilliseconds()));
}
@ -1166,6 +1166,24 @@ AppendSharedLibraries(JSONWriter& aWriter)
}
}
#ifdef MOZ_TASK_TRACER
static void
StreamNameAndThreadId(const char* aName, int aThreadId)
{
aWriter.StartObjectElement();
{
if (XRE_GetProcessType() == GeckoProcessType_Plugin) {
// TODO Add the proper plugin name
aWriter.StringProperty("name", "Plugin");
} else {
aWriter.StringProperty("name", aName);
}
aWriter.IntProperty("tid", aThreadId);
}
aWriter.EndObject();
}
#endif
static void
StreamTaskTracer(PS::LockRef aLock, SpliceableJSONWriter& aWriter)
{
@ -1182,21 +1200,16 @@ StreamTaskTracer(PS::LockRef aLock, SpliceableJSONWriter& aWriter)
aWriter.StartArrayProperty("threads");
{
const PS::ThreadVector& threads = gPS->Threads(aLock);
for (size_t i = 0; i < threads.size(); i++) {
// Thread meta data
ThreadInfo* info = threads.at(i);
aWriter.StartObjectElement();
{
if (XRE_GetProcessType() == GeckoProcessType_Plugin) {
// TODO Add the proper plugin name
aWriter.StringProperty("name", "Plugin");
} else {
aWriter.StringProperty("name", info->Name());
}
aWriter.IntProperty("tid", static_cast<int>(info->ThreadId()));
}
aWriter.EndObject();
const PS::ThreadVector& liveThreads = gPS->LiveThreads(aLock);
for (size_t i = 0; i < liveThreads.size(); i++) {
ThreadInfo* info = liveThreads.at(i);
StreamNameAndThreadId(info->Name(), info->ThreadId());
}
const PS::ThreadVector& deadThreads = gPS->DeadThreads(aLock);
for (size_t i = 0; i < deadThreads.size(); i++) {
ThreadInfo* info = deadThreads.at(i);
StreamNameAndThreadId(info->Name(), info->ThreadId());
}
}
aWriter.EndArray();
@ -1391,21 +1404,22 @@ StreamJSON(PS::LockRef aLock, SpliceableJSONWriter& aWriter, double aSinceTime)
{
gPS->SetIsPaused(aLock, true);
{
const PS::ThreadVector& threads = gPS->Threads(aLock);
for (size_t i = 0; i < threads.size(); i++) {
// Thread not being profiled, skip it
ThreadInfo* info = threads.at(i);
if (!info->HasProfile()) {
continue;
}
// Note that we intentionally include thread profiles which
// have been marked for pending delete.
info->StreamJSON(gPS->Buffer(aLock), aWriter, gPS->StartTime(aLock),
aSinceTime);
const PS::ThreadVector& liveThreads = gPS->LiveThreads(aLock);
for (size_t i = 0; i < liveThreads.size(); i++) {
ThreadInfo* info = liveThreads.at(i);
if (!info->HasProfile()) {
continue;
}
info->StreamJSON(gPS->Buffer(aLock), aWriter, gPS->StartTime(aLock),
aSinceTime);
}
const PS::ThreadVector& deadThreads = gPS->DeadThreads(aLock);
for (size_t i = 0; i < deadThreads.size(); i++) {
ThreadInfo* info = deadThreads.at(i);
MOZ_ASSERT(info->HasProfile());
info->StreamJSON(gPS->Buffer(aLock), aWriter, gPS->StartTime(aLock),
aSinceTime);
}
// When notifying observers in other places in this file we are careful
@ -1446,19 +1460,6 @@ StreamJSON(PS::LockRef aLock, SpliceableJSONWriter& aWriter, double aSinceTime)
aWriter.End();
}
UniquePtr<char[]>
ToJSON(PS::LockRef aLock, double aSinceTime)
{
LOG("ToJSON");
MOZ_RELEASE_ASSERT(NS_IsMainThread());
MOZ_RELEASE_ASSERT(gPS && gPS->IsActive(aLock));
SpliceableChunkedJSONWriter b;
StreamJSON(aLock, b, aSinceTime);
return b.WriteFunc()->CopyData();
}
// END saving/streaming code
////////////////////////////////////////////////////////////////////////
@ -1661,11 +1662,11 @@ SamplerThread::Run()
gPS->Buffer(lock)->deleteExpiredStoredMarkers();
if (!gPS->IsPaused(lock)) {
const PS::ThreadVector& threads = gPS->Threads(lock);
for (uint32_t i = 0; i < threads.size(); i++) {
ThreadInfo* info = threads[i];
const PS::ThreadVector& liveThreads = gPS->LiveThreads(lock);
for (uint32_t i = 0; i < liveThreads.size(); i++) {
ThreadInfo* info = liveThreads[i];
if (!info->HasProfile() || info->IsPendingDelete()) {
if (!info->HasProfile()) {
// We are not interested in profiling this thread.
continue;
}
@ -1683,9 +1684,12 @@ SamplerThread::Run()
}
}
info->UpdateThreadResponsiveness();
// We only track responsiveness for the main thread.
if (info->IsMainThread()) {
info->GetThreadResponsiveness()->Update();
}
// We only get the memory measurements once for all threads.
// We only get the memory measurements once for all live threads.
int64_t rssMemory = 0;
int64_t ussMemory = 0;
if (i == 0 && gPS->FeatureMemory(lock)) {
@ -1780,9 +1784,15 @@ GeckoProfilerReporter::CollectReports(nsIHandleReportCallback* aHandleReport,
if (gPS) {
profSize = GeckoProfilerMallocSizeOf(gPS);
const PS::ThreadVector& threads = gPS->Threads(lock);
for (uint32_t i = 0; i < threads.size(); i++) {
ThreadInfo* info = threads.at(i);
const PS::ThreadVector& liveThreads = gPS->LiveThreads(lock);
for (uint32_t i = 0; i < liveThreads.size(); i++) {
ThreadInfo* info = liveThreads.at(i);
profSize += info->SizeOfIncludingThis(GeckoProfilerMallocSizeOf);
}
const PS::ThreadVector& deadThreads = gPS->DeadThreads(lock);
for (uint32_t i = 0; i < deadThreads.size(); i++) {
ThreadInfo* info = deadThreads.at(i);
profSize += info->SizeOfIncludingThis(GeckoProfilerMallocSizeOf);
}
@ -1795,8 +1805,8 @@ GeckoProfilerReporter::CollectReports(nsIHandleReportCallback* aHandleReport,
// is worthwhile:
// - gPS->mFeatures
// - gPS->mThreadNameFilters
// - gPS->mThreads itself (its elements' children are measured above)
// - gPS->mGatherer
// - gPS->mLiveThreads itself (its elements' children are measured above)
// - gPS->mDeadThreads itself (ditto)
// - gPS->mInterposeObserver
#if defined(USE_LUL_STACKWALK)
@ -1851,31 +1861,29 @@ ThreadSelected(PS::LockRef aLock, const char* aThreadName)
return false;
}
static void
MaybeSetProfile(PS::LockRef aLock, ThreadInfo* aInfo)
static bool
ShouldProfileThread(PS::LockRef aLock, ThreadInfo* aInfo)
{
// This function runs both on and off the main thread.
MOZ_RELEASE_ASSERT(gPS);
if ((aInfo->IsMainThread() || gPS->FeatureThreads(aLock)) &&
ThreadSelected(aLock, aInfo->Name())) {
aInfo->SetHasProfile();
}
return ((aInfo->IsMainThread() || gPS->FeatureThreads(aLock)) &&
ThreadSelected(aLock, aInfo->Name()));
}
// Find the ThreadInfo for the current thread. On success, *aIndexOut is set to
// the index if it is non-null.
static ThreadInfo*
FindThreadInfo(PS::LockRef aLock, int* aIndexOut = nullptr)
FindLiveThreadInfo(PS::LockRef aLock, int* aIndexOut = nullptr)
{
// This function runs both on and off the main thread.
Thread::tid_t id = Thread::GetCurrentId();
const PS::ThreadVector& threads = gPS->Threads(aLock);
for (uint32_t i = 0; i < threads.size(); i++) {
ThreadInfo* info = threads.at(i);
if (info->ThreadId() == id && !info->IsPendingDelete()) {
const PS::ThreadVector& liveThreads = gPS->LiveThreads(aLock);
for (uint32_t i = 0; i < liveThreads.size(); i++) {
ThreadInfo* info = liveThreads.at(i);
if (info->ThreadId() == id) {
if (aIndexOut) {
*aIndexOut = i;
}
@ -1892,28 +1900,30 @@ locked_register_thread(PS::LockRef aLock, const char* aName, void* stackTop)
MOZ_RELEASE_ASSERT(gPS);
MOZ_RELEASE_ASSERT(!FindThreadInfo(aLock));
MOZ_RELEASE_ASSERT(!FindLiveThreadInfo(aLock));
if (!tlsPseudoStack.init()) {
return;
}
NotNull<PseudoStack*> stack = WrapNotNull(new PseudoStack());
tlsPseudoStack.set(stack);
ThreadInfo* info = new ThreadInfo(aName, Thread::GetCurrentId(),
NS_IsMainThread(), stack, stackTop);
NS_IsMainThread(), stackTop);
NotNull<PseudoStack*> pseudoStack = info->Stack();
MaybeSetProfile(aLock, info);
tlsPseudoStack.set(pseudoStack.get());
// This must come after the MaybeSetProfile() call.
if (gPS->IsActive(aLock) && info->HasProfile() && gPS->FeatureJS(aLock)) {
// This startJSSampling() call is on-thread, so we can poll manually to
// start JS sampling immediately.
stack->startJSSampling();
stack->pollJSSampling();
if (ShouldProfileThread(aLock, info)) {
info->SetHasProfile();
if (gPS->IsActive(aLock) && gPS->FeatureJS(aLock)) {
// This startJSSampling() call is on-thread, so we can poll manually to
// start JS sampling immediately.
pseudoStack->startJSSampling();
pseudoStack->pollJSSampling();
}
}
gPS->Threads(aLock).push_back(info);
gPS->LiveThreads(aLock).push_back(info);
}
static void
@ -2095,10 +2105,16 @@ profiler_shutdown()
samplerThread = locked_profiler_stop(lock);
}
PS::ThreadVector& threads = gPS->Threads(lock);
while (threads.size() > 0) {
delete threads.back();
threads.pop_back();
PS::ThreadVector& liveThreads = gPS->LiveThreads(lock);
while (liveThreads.size() > 0) {
delete liveThreads.back();
liveThreads.pop_back();
}
PS::ThreadVector& deadThreads = gPS->DeadThreads(lock);
while (deadThreads.size() > 0) {
delete deadThreads.back();
deadThreads.pop_back();
}
#if defined(USE_LUL_STACKWALK)
@ -2144,81 +2160,9 @@ profiler_get_profile(double aSinceTime)
return nullptr;
}
return ToJSON(lock, aSinceTime);
}
JSObject*
profiler_get_profile_jsobject(JSContext *aCx, double aSinceTime)
{
LOG("profiler_get_profile_jsobject");
MOZ_RELEASE_ASSERT(NS_IsMainThread());
MOZ_RELEASE_ASSERT(gPS);
// |val| must outlive |lock| to avoid a GC hazard.
JS::RootedValue val(aCx);
UniquePtr<char[]> buf = nullptr;
{
PS::AutoLock lock(gPSMutex);
if (!gPS->IsActive(lock)) {
return nullptr;
}
buf = ToJSON(lock, aSinceTime);
}
NS_ConvertUTF8toUTF16 js_string(nsDependentCString(buf.get()));
auto buf16 = static_cast<const char16_t*>(js_string.get());
MOZ_ALWAYS_TRUE(JS_ParseJSON(aCx, buf16, js_string.Length(), &val));
return &val.toObject();
}
void
profiler_get_profile_jsobject_async(double aSinceTime,
mozilla::dom::Promise* aPromise)
{
LOG("profiler_get_profile_jsobject_async");
MOZ_RELEASE_ASSERT(NS_IsMainThread());
MOZ_RELEASE_ASSERT(gPS);
PS::AutoLock lock(gPSMutex);
if (!gPS->IsActive(lock)) {
LOG("END profiler_get_profile_jsobject_async: inactive");
return;
}
gPS->Gatherer(lock)->Start(lock, aSinceTime, aPromise);
}
void
profiler_save_profile_to_file_async(double aSinceTime, const char* aFileName)
{
LOG("BEGIN profiler_save_profile_to_file_async");
MOZ_RELEASE_ASSERT(NS_IsMainThread());
MOZ_RELEASE_ASSERT(gPS);
nsCString filename(aFileName);
NS_DispatchToMainThread(NS_NewRunnableFunction([=] () {
LOG("profiler_save_profile_to_file_async callback");
PS::AutoLock lock(gPSMutex);
// It's conceivable that profiler_stop() or profiler_shutdown() was called
// between the dispatch and running of this runnable, so check for those.
if (!gPS || !gPS->IsActive(lock)) {
LOG("END profiler_save_profile_to_file_async callback: inactive");
return;
}
gPS->Gatherer(lock)->Start(lock, aSinceTime, filename);
}));
SpliceableChunkedJSONWriter b;
StreamJSON(lock, b, aSinceTime);
return b.WriteFunc()->CopyData();
}
void
@ -2252,61 +2196,6 @@ profiler_get_start_params(int* aEntries, double* aInterval,
}
}
void
profiler_will_gather_OOP_profile()
{
MOZ_RELEASE_ASSERT(NS_IsMainThread());
MOZ_RELEASE_ASSERT(gPS);
// This function is called once per subprocess in response to the observation
// of a "profile-subprocess-gather" notification. That notification
// originates from ProfileGatherer::Start2(). The observers receive it and
// immediately call this function, all while Start2() holds gPSMutex locked.
// This is non-trivial, so we assert that gPSMutex is locked as expected...
gPSMutex.AssertCurrentThreadOwns();
// ...therefore we don't need to lock gPSMutex. But we need a PS::AutoLock to
// access gPS, so we make a fake one. This is gross but it's hard to get the
// "profile-subprocess-gather" observers to call back here any other way
// without exposing ProfileGatherer, which causes other difficulties.
static PS::Mutex sFakeMutex;
PS::AutoLock fakeLock(sFakeMutex);
MOZ_RELEASE_ASSERT(gPS->IsActive(fakeLock));
gPS->Gatherer(fakeLock)->WillGatherOOPProfile();
}
void
profiler_gathered_OOP_profile()
{
MOZ_RELEASE_ASSERT(NS_IsMainThread());
MOZ_RELEASE_ASSERT(gPS);
PS::AutoLock lock(gPSMutex);
if (!gPS->IsActive(lock)) {
return;
}
gPS->Gatherer(lock)->GatheredOOPProfile(lock);
}
void
profiler_OOP_exit_profile(const nsCString& aProfile)
{
MOZ_RELEASE_ASSERT(NS_IsMainThread());
MOZ_RELEASE_ASSERT(gPS);
PS::AutoLock lock(gPSMutex);
if (!gPS->IsActive(lock)) {
return;
}
gPS->Gatherer(lock)->OOPExitProfile(aProfile);
}
static void
locked_profiler_save_profile_to_file(PS::LockRef aLock, const char* aFilename)
{
@ -2449,14 +2338,14 @@ locked_profiler_start(PS::LockRef aLock, int aEntries, double aInterval,
double interval = aInterval > 0 ? aInterval : PROFILE_DEFAULT_INTERVAL;
gPS->SetInterval(aLock, interval);
// Deep copy aFeatures. Must precede the MaybeSetProfile() call below.
// Deep copy aFeatures. Must precede the ShouldProfileThread() call below.
Vector<std::string>& features = gPS->Features(aLock);
MOZ_ALWAYS_TRUE(features.resize(aFeatureCount));
for (uint32_t i = 0; i < aFeatureCount; ++i) {
features[i] = aFeatures[i];
}
// Deep copy aThreadNameFilters. Must precede the MaybeSetProfile() call
// Deep copy aThreadNameFilters. Must precede the ShouldProfileThread() call
// below.
Vector<std::string>& threadNameFilters = gPS->ThreadNameFilters(aLock);
MOZ_ALWAYS_TRUE(threadNameFilters.resize(aFilterCount));
@ -2486,36 +2375,37 @@ locked_profiler_start(PS::LockRef aLock, int aEntries, double aInterval,
#endif
// Profile non-main threads if we have a filter, because users sometimes ask
// to filter by a list of threads but forget to explicitly request.
// Must precede the MaybeSetProfile() call below.
// Must precede the ShouldProfileThread() call below.
gPS->SetFeatureThreads(aLock, HAS_FEATURE("threads") || aFilterCount > 0);
#undef HAS_FEATURE
gPS->SetBuffer(aLock, new ProfileBuffer(entries));
gPS->SetGatherer(aLock, new mozilla::ProfileGatherer());
// Set up profiling for each registered thread, if appropriate.
const PS::ThreadVector& threads = gPS->Threads(aLock);
for (uint32_t i = 0; i < threads.size(); i++) {
ThreadInfo* info = threads.at(i);
const PS::ThreadVector& liveThreads = gPS->LiveThreads(aLock);
for (uint32_t i = 0; i < liveThreads.size(); i++) {
ThreadInfo* info = liveThreads.at(i);
MaybeSetProfile(aLock, info);
if (info->HasProfile() && !info->IsPendingDelete()) {
if (ShouldProfileThread(aLock, info)) {
info->SetHasProfile();
info->Stack()->reinitializeOnResume();
if (featureJS) {
info->Stack()->startJSSampling();
}
}
}
// Dead ThreadInfos are deleted in profiler_stop(), and dead ThreadInfos
// aren't saved when the profiler is inactive. Therefore mDeadThreads should
// be empty here.
MOZ_RELEASE_ASSERT(gPS->DeadThreads(aLock).empty());
if (featureJS) {
// We just called startJSSampling() on all relevant threads. We can also
// manually poll the current thread so it starts sampling immediately.
if (PseudoStack* stack = tlsPseudoStack.get()) {
stack->pollJSSampling();
if (PseudoStack* pseudoStack = tlsPseudoStack.get()) {
pseudoStack->pollJSSampling();
}
}
@ -2625,20 +2515,24 @@ locked_profiler_stop(PS::LockRef aLock)
}
#endif
PS::ThreadVector& threads = gPS->Threads(aLock);
for (uint32_t i = 0; i < threads.size(); i++) {
ThreadInfo* info = threads.at(i);
if (info->IsPendingDelete()) {
// We've stopped profiling. Destroy ThreadInfo for dead threads.
delete info;
threads.erase(threads.begin() + i);
i--;
} else if (info->HasProfile() && gPS->FeatureJS(aLock)) {
// Stop JS sampling live threads.
info->Stack()->stopJSSampling();
// Stop JS sampling live threads.
if (gPS->FeatureJS(aLock)) {
PS::ThreadVector& liveThreads = gPS->LiveThreads(aLock);
for (uint32_t i = 0; i < liveThreads.size(); i++) {
ThreadInfo* info = liveThreads.at(i);
if (info->HasProfile()) {
info->Stack()->stopJSSampling();
}
}
}
// This is where we destroy the ThreadInfos for all dead threads.
PS::ThreadVector& deadThreads = gPS->DeadThreads(aLock);
while (deadThreads.size() > 0) {
delete deadThreads.back();
deadThreads.pop_back();
}
if (gPS->FeatureJS(aLock)) {
// We just called stopJSSampling() on all relevant threads. We can also
// manually poll the current thread so it stops profiling immediately.
@ -2647,10 +2541,6 @@ locked_profiler_stop(PS::LockRef aLock)
}
}
// Cancel any in-flight async profile gathering requests.
gPS->Gatherer(aLock)->Cancel();
gPS->SetGatherer(aLock, nullptr);
delete gPS->Buffer(aLock);
gPS->SetBuffer(aLock, nullptr);
@ -2854,26 +2744,23 @@ profiler_unregister_thread()
// that for a JS thread that is in the process of disappearing.
int i;
ThreadInfo* info = FindThreadInfo(lock, &i);
ThreadInfo* info = FindLiveThreadInfo(lock, &i);
if (info) {
DEBUG_LOG("profiler_unregister_thread: %s", info->Name());
if (gPS->IsActive(lock)) {
// We still want to show the results of this thread if you save the
// profile shortly after a thread is terminated. We defer the delete to
// profile stop.
info->SetPendingDelete();
if (gPS->IsActive(lock) && info->HasProfile()) {
gPS->DeadThreads(lock).push_back(info);
} else {
delete info;
PS::ThreadVector& threads = gPS->Threads(lock);
threads.erase(threads.begin() + i);
}
PS::ThreadVector& liveThreads = gPS->LiveThreads(lock);
liveThreads.erase(liveThreads.begin() + i);
// Whether or not we just destroyed the PseudoStack (via its owning
// ThreadInfo), we no longer need to access it via TLS.
tlsPseudoStack.set(nullptr);
} else {
// There are two ways FindThreadInfo() can fail.
// There are two ways FindLiveThreadInfo() can fail.
//
// - tlsPseudoStack.init() failed in locked_register_thread().
//
@ -3189,7 +3076,7 @@ profiler_clear_js_context()
gPS->SetIsPaused(lock, true);
// Flush this thread's ThreadInfo, if it is being profiled.
ThreadInfo* info = FindThreadInfo(lock);
ThreadInfo* info = FindLiveThreadInfo(lock);
MOZ_RELEASE_ASSERT(info);
if (info->HasProfile()) {
info->FlushSamplesAndMarkers(gPS->Buffer(lock), gPS->StartTime(lock));

Просмотреть файл

@ -111,23 +111,6 @@ public:
static tid_t GetCurrentId();
};
// ----------------------------------------------------------------------------
// ProfilerState auxiliaries
// There is a single instance of ProfilerState that holds the profiler's global
// state. Both the class and the instance are defined in platform.cpp.
// ProfilerStateMutex is the type of the mutex that guards all accesses to
// ProfilerState. We use a distinct type for it to make it hard to mix up with
// any other StaticMutex.
class ProfilerStateMutex : public mozilla::StaticMutex {};
// Values of this type are passed around as a kind of token indicating which
// functions are called while the global ProfilerStateMutex is held, i.e. while
// the ProfilerState can be modified. (All of ProfilerState's getters and
// setters require this token.) Some such functions are outside platform.cpp,
// so this type must be declared here.
typedef const mozilla::BaseAutoLock<ProfilerStateMutex>& PSLockRef;
// ----------------------------------------------------------------------------
// Miscellaneous
@ -143,9 +126,6 @@ typedef mozilla::UniquePtr<PlatformData, PlatformDataDestructor>
UniquePlatformData;
UniquePlatformData AllocPlatformData(int aThreadId);
mozilla::UniquePtr<char[]>
ToJSON(PSLockRef aLock, double aSinceTime);
namespace mozilla {
class JSONWriter;
}

Просмотреть файл

@ -10,6 +10,7 @@
#include "nsIProfileSaveEvent.h"
#include "nsISupports.h"
#include "nsIObserver.h"
#include "nsProfiler.h"
#include "ProfilerControllingProcess.h"
namespace mozilla {
@ -85,7 +86,7 @@ CrossProcessProfilerController::CrossProcessProfilerController(
CrossProcessProfilerController::~CrossProcessProfilerController()
{
if (!mProfile.IsEmpty()) {
profiler_OOP_exit_profile(mProfile);
nsProfiler::GetOrCreate()->OOPExitProfile(mProfile);
}
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
@ -124,7 +125,7 @@ CrossProcessProfilerController::Observe(nsISupports* aSubject,
// need to tell the other process that we're interested in its profile,
// and we tell the gatherer that we've forwarded the request, so that it
// can keep track of the number of pending profiles.
profiler_will_gather_OOP_profile();
nsProfiler::GetOrCreate()->WillGatherOOPProfile();
mProcess->SendGatherProfile();
}
else if (!strcmp(aTopic, "profiler-subprocess")) {
@ -169,7 +170,7 @@ CrossProcessProfilerController::RecvProfile(const nsCString& aProfile)
// don't actually give it the profile. It will request the profile once all
// processes have replied, through the "profiler-subprocess" observer
// notification.
profiler_gathered_OOP_profile();
nsProfiler::GetOrCreate()->GatheredOOPProfile();
}
} // namespace mozilla

Просмотреть файл

@ -11,7 +11,6 @@
#include "nsIProfileSaveEvent.h"
#include "nsLocalFile.h"
#include "nsIFileStreams.h"
#include "platform.h"
using mozilla::dom::AutoJSAPI;
using mozilla::dom::Promise;
@ -30,15 +29,19 @@ static const uint32_t MAX_SUBPROCESS_EXIT_PROFILES = 5;
NS_IMPL_ISUPPORTS(ProfileGatherer, nsIObserver)
ProfileGatherer::ProfileGatherer()
: mIsCancelled(false)
, mSinceTime(0)
: mSinceTime(0)
, mPendingProfiles(0)
, mGathering(false)
{
}
ProfileGatherer::~ProfileGatherer()
{
Cancel();
}
void
ProfileGatherer::GatheredOOPProfile(PSLockRef aLock)
ProfileGatherer::GatheredOOPProfile()
{
MOZ_RELEASE_ASSERT(NS_IsMainThread());
@ -60,7 +63,7 @@ ProfileGatherer::GatheredOOPProfile(PSLockRef aLock)
if (mPendingProfiles == 0) {
// We've got all of the async profiles now. Let's
// finish off the profile and resolve the Promise.
Finish(aLock);
Finish();
}
}
@ -71,7 +74,7 @@ ProfileGatherer::WillGatherOOPProfile()
}
void
ProfileGatherer::Start(PSLockRef aLock, double aSinceTime, Promise* aPromise)
ProfileGatherer::Start(double aSinceTime, Promise* aPromise)
{
MOZ_RELEASE_ASSERT(NS_IsMainThread());
@ -86,12 +89,11 @@ ProfileGatherer::Start(PSLockRef aLock, double aSinceTime, Promise* aPromise)
mPromise = aPromise;
Start2(aLock, aSinceTime);
Start2(aSinceTime);
}
void
ProfileGatherer::Start(PSLockRef aLock, double aSinceTime,
const nsACString& aFileName)
ProfileGatherer::Start(double aSinceTime, const nsACString& aFileName)
{
MOZ_RELEASE_ASSERT(NS_IsMainThread());
@ -107,12 +109,12 @@ ProfileGatherer::Start(PSLockRef aLock, double aSinceTime,
mFile = file;
Start2(aLock, aSinceTime);
Start2(aSinceTime);
}
// This is the common tail shared by both Start() methods.
void
ProfileGatherer::Start2(PSLockRef aLock, double aSinceTime)
ProfileGatherer::Start2(double aSinceTime)
{
MOZ_RELEASE_ASSERT(NS_IsMainThread());
@ -126,30 +128,38 @@ ProfileGatherer::Start2(PSLockRef aLock, double aSinceTime)
os->AddObserver(this, "profiler-subprocess", false);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "AddObserver failed");
// This notification triggers calls back to
// profiler_will_gather_OOP_profile(). See the comment in that function for
// the gory details of the connection between this function and that one.
rv = os->NotifyObservers(this, "profiler-subprocess-gather", nullptr);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "NotifyObservers failed");
}
if (!mPendingProfiles) {
Finish(aLock);
Finish();
}
}
void
ProfileGatherer::Finish(PSLockRef aLock)
ProfileGatherer::Finish()
{
MOZ_RELEASE_ASSERT(NS_IsMainThread());
if (mIsCancelled) {
// We somehow got called after we were cancelled! This shouldn't
// be possible, but doing a belt-and-suspenders check to be sure.
// It's unlikely but possible that profiler_stop() could be called while the
// profile gathering is in flight, but not via nsProfiler::StopProfiler().
// This check will detect that case.
//
// XXX: However, it won't detect the case where profiler_stop() *and*
// profiler_start() have both been called. (If that does happen, we'll end up
// with a franken-profile that includes a mix of data from the old and new
// profile activations.) We could include the activity generation to detect
// that, but it's not worth it for what should be an extremely unlikely case.
// It would be better if this class was rearranged so that
// profiler_get_profile() was called for the parent process in Start2()
// instead of in Finish(). Then we wouldn't have to worry about cancelling.
if (!profiler_is_active()) {
Cancel();
return;
}
UniquePtr<char[]> buf = ToJSON(aLock, mSinceTime);
UniquePtr<char[]> buf = profiler_get_profile(mSinceTime);
if (mFile) {
nsCOMPtr<nsIFileOutputStream> of =
@ -221,12 +231,10 @@ ProfileGatherer::Cancel()
}
mPromise = nullptr;
mFile = nullptr;
mIsCancelled = true;
}
void
ProfileGatherer::OOPExitProfile(const nsCString& aProfile)
ProfileGatherer::OOPExitProfile(const nsACString& aProfile)
{
if (mExitProfiles.Length() >= MAX_SUBPROCESS_EXIT_PROFILES) {
mExitProfiles.RemoveElementAt(0);

Просмотреть файл

@ -7,10 +7,10 @@
#include "mozilla/dom/Promise.h"
#include "nsIFile.h"
#include "platform.h"
namespace mozilla {
// This class holds the state for an async profile-gathering request.
class ProfileGatherer final : public nsIObserver
{
public:
@ -19,23 +19,21 @@ public:
explicit ProfileGatherer();
void WillGatherOOPProfile();
void GatheredOOPProfile(PSLockRef aLock);
void Start(PSLockRef aLock, double aSinceTime,
mozilla::dom::Promise* aPromise);
void Start(PSLockRef aLock, double aSinceTime, const nsACString& aFileName);
void GatheredOOPProfile();
void Start(double aSinceTime, mozilla::dom::Promise* aPromise);
void Start(double aSinceTime, const nsACString& aFileName);
void Cancel();
void OOPExitProfile(const nsCString& aProfile);
void OOPExitProfile(const nsACString& aProfile);
private:
~ProfileGatherer() {};
void Finish(PSLockRef aLock);
~ProfileGatherer();
void Finish();
void Reset();
void Start2(PSLockRef aLock, double aSinceTime);
void Start2(double aSinceTime);
nsTArray<nsCString> mExitProfiles;
RefPtr<mozilla::dom::Promise> mPromise;
nsCOMPtr<nsIFile> mFile;
bool mIsCancelled;
double mSinceTime;
uint32_t mPendingProfiles;
bool mGathering;

Просмотреть файл

@ -95,12 +95,8 @@ ThreadResponsiveness::~ThreadResponsiveness()
}
void
ThreadResponsiveness::Update(bool aIsMainThread, nsIThread* aThread)
ThreadResponsiveness::Update()
{
if (!aIsMainThread) {
return;
}
if (!mActiveTracerEvent) {
mActiveTracerEvent = new CheckResponsivenessTask();
NS_DispatchToMainThread(mActiveTracerEvent);

Просмотреть файл

@ -12,14 +12,14 @@
class CheckResponsivenessTask;
// This class should only be used for the main thread.
class ThreadResponsiveness {
public:
explicit ThreadResponsiveness();
~ThreadResponsiveness();
// Won't do anything on non-main threads for now.
void Update(bool aIsMainThread, nsIThread* aThread);
void Update();
mozilla::TimeDuration GetUnresponsiveDuration(const mozilla::TimeStamp& now) const {
return now - mLastTracerTime;

Просмотреть файл

@ -57,6 +57,9 @@ interface nsIProfiler : nsISupports
[implicit_jscontext]
nsISupports getProfileDataAsync([optional] in double aSinceTime);
void dumpProfileToFileAsync(in ACString aFilename,
[optional] in double aSinceTime);
boolean IsActive();
void GetFeatures(out uint32_t aCount, [retval, array, size_is(aCount)] out string aFeatures);

Просмотреть файл

@ -1,4 +1,5 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@ -20,6 +21,7 @@
#include "js/Value.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/Promise.h"
#include "ProfileGatherer.h"
using mozilla::ErrorResult;
using mozilla::dom::Promise;
@ -92,13 +94,21 @@ nsProfiler::StartProfiler(uint32_t aEntries, double aInterval,
profiler_start(aEntries, aInterval,
aFeatures, aFeatureCount,
aThreadNameFilters, aFilterCount);
// Do this after profiler_start().
mGatherer = new ProfileGatherer();
return NS_OK;
}
NS_IMETHODIMP
nsProfiler::StopProfiler()
{
// Do this before profiler_stop().
mGatherer = nullptr;
profiler_stop();
return NS_OK;
}
@ -190,11 +200,18 @@ NS_IMETHODIMP
nsProfiler::GetProfileData(double aSinceTime, JSContext* aCx,
JS::MutableHandle<JS::Value> aResult)
{
JS::RootedObject obj(aCx, profiler_get_profile_jsobject(aCx, aSinceTime));
if (!obj) {
mozilla::UniquePtr<char[]> profile = profiler_get_profile(aSinceTime);
if (!profile) {
return NS_ERROR_FAILURE;
}
aResult.setObject(*obj);
NS_ConvertUTF8toUTF16 js_string(nsDependentCString(profile.get()));
auto profile16 = static_cast<const char16_t*>(js_string.get());
JS::RootedValue val(aCx);
MOZ_ALWAYS_TRUE(JS_ParseJSON(aCx, profile16, js_string.Length(), &val));
aResult.set(val);
return NS_OK;
}
@ -204,6 +221,10 @@ nsProfiler::GetProfileDataAsync(double aSinceTime, JSContext* aCx,
{
MOZ_ASSERT(NS_IsMainThread());
if (!mGatherer) {
return NS_ERROR_FAILURE;
}
if (NS_WARN_IF(!aCx)) {
return NS_ERROR_FAILURE;
}
@ -220,12 +241,28 @@ nsProfiler::GetProfileDataAsync(double aSinceTime, JSContext* aCx,
return result.StealNSResult();
}
profiler_get_profile_jsobject_async(aSinceTime, promise);
mGatherer->Start(aSinceTime, promise);
promise.forget(aPromise);
return NS_OK;
}
NS_IMETHODIMP
nsProfiler::DumpProfileToFileAsync(const nsACString& aFilename,
double aSinceTime)
{
MOZ_ASSERT(NS_IsMainThread());
if (!mGatherer) {
return NS_ERROR_FAILURE;
}
mGatherer->Start(aSinceTime, aFilename);
return NS_OK;
}
NS_IMETHODIMP
nsProfiler::GetElapsedTime(double* aElapsedTime)
{
@ -311,3 +348,39 @@ nsProfiler::GetBufferInfo(uint32_t* aCurrentPosition, uint32_t* aTotalSize,
return NS_OK;
}
void
nsProfiler::WillGatherOOPProfile()
{
MOZ_RELEASE_ASSERT(NS_IsMainThread());
if (!mGatherer) {
return;
}
mGatherer->WillGatherOOPProfile();
}
void
nsProfiler::GatheredOOPProfile()
{
MOZ_RELEASE_ASSERT(NS_IsMainThread());
if (!mGatherer) {
return;
}
mGatherer->GatheredOOPProfile();
}
void
nsProfiler::OOPExitProfile(const nsACString& aProfile)
{
MOZ_RELEASE_ASSERT(NS_IsMainThread());
if (!mGatherer) {
return;
}
mGatherer->OOPExitProfile(aProfile);
}

Просмотреть файл

@ -10,6 +10,10 @@
#include "nsIObserver.h"
#include "mozilla/Attributes.h"
namespace mozilla {
class ProfileGatherer;
}
class nsProfiler final : public nsIProfiler, public nsIObserver
{
public:
@ -20,8 +24,22 @@ public:
NS_DECL_NSIPROFILER
nsresult Init();
static nsProfiler* GetOrCreate()
{
nsCOMPtr<nsIProfiler> iprofiler =
do_GetService("@mozilla.org/tools/profiler;1");
return static_cast<nsProfiler*>(iprofiler.get());
}
void WillGatherOOPProfile();
void GatheredOOPProfile();
void OOPExitProfile(const nsACString& aProfile);
private:
~nsProfiler();
RefPtr<ProfileGatherer> mGatherer;
bool mLockedForPrivateBrowsing;
};

Просмотреть файл

@ -215,17 +215,6 @@ PROFILER_FUNC_VOID(profiler_set_frame_number(int frameNumber))
PROFILER_FUNC(mozilla::UniquePtr<char[]> profiler_get_profile(double aSinceTime = 0),
nullptr)
// Get the profile encoded as a JSON object. A no-op (returning nullptr) if the
// profiler is inactive.
PROFILER_FUNC(JSObject* profiler_get_profile_jsobject(JSContext* aCx,
double aSinceTime = 0),
nullptr)
// Get the profile encoded as a JSON object, asynchronously. A no-op if the
// profiler is inactive.
PROFILER_FUNC_VOID(profiler_get_profile_jsobject_async(double aSinceTime = 0,
mozilla::dom::Promise* = 0))
// Get the params used to start the profiler. Returns 0 and empty vectors (via
// outparams) if the profile is inactive.
PROFILER_FUNC_VOID(profiler_get_start_params(int* aEntrySize,
@ -391,18 +380,6 @@ profiler_call_exit(void* aHandle)
void profiler_add_marker(const char *aMarker,
ProfilerMarkerPayload *aPayload = nullptr);
// Saves a profile asynchronously. A no-op if the profiler is inactive when the
// save operation begins.
MOZ_EXPORT // XXX: should this be 'extern "C"' as well?
void profiler_save_profile_to_file_async(double aSinceTime,
const char* aFileName);
// This function should only be called in response to the observation of a
// "profiler-subprocess-gather" notification.
void profiler_will_gather_OOP_profile();
void profiler_gathered_OOP_profile();
void profiler_OOP_exit_profile(const nsCString& aProfile);
#define SAMPLER_APPEND_LINE_NUMBER_PASTE(id, line) id ## line
#define SAMPLER_APPEND_LINE_NUMBER_EXPAND(id, line) SAMPLER_APPEND_LINE_NUMBER_PASTE(id, line)
#define SAMPLER_APPEND_LINE_NUMBER(id) SAMPLER_APPEND_LINE_NUMBER_EXPAND(id, __LINE__)

Просмотреть файл

@ -8,22 +8,17 @@
#include "ProfileBufferEntry.h"
#include "ThreadInfo.h"
using mozilla::NotNull;
using mozilla::WrapNotNull;
// Make sure we can initialize our thread profile
TEST(ThreadProfile, Initialization) {
Thread::tid_t tid = 1000;
ThreadInfo info("testThread", tid, true, WrapNotNull(new PseudoStack()),
nullptr);
ThreadInfo info("testThread", tid, true, nullptr);
info.SetHasProfile();
}
// Make sure we can record one tag and read it
TEST(ThreadProfile, InsertOneTag) {
Thread::tid_t tid = 1000;
ThreadInfo info("testThread", tid, true, WrapNotNull(new PseudoStack()),
nullptr);
ThreadInfo info("testThread", tid, true, nullptr);
ProfileBuffer* pb = new ProfileBuffer(10);
pb->addTag(ProfileBufferEntry::Time(123.1));
ASSERT_TRUE(pb->mEntries != nullptr);
@ -35,8 +30,7 @@ TEST(ThreadProfile, InsertOneTag) {
// See if we can insert some tags
TEST(ThreadProfile, InsertTagsNoWrap) {
Thread::tid_t tid = 1000;
ThreadInfo info("testThread", tid, true, WrapNotNull(new PseudoStack()),
nullptr);
ThreadInfo info("testThread", tid, true, nullptr);
ProfileBuffer* pb = new ProfileBuffer(100);
int test_size = 50;
for (int i = 0; i < test_size; i++) {
@ -58,8 +52,7 @@ TEST(ThreadProfile, InsertTagsWrap) {
// we can fit only 24 tags in this buffer because of the empty slot
int tags = 24;
int buffer_size = tags + 1;
ThreadInfo info("testThread", tid, true, WrapNotNull(new PseudoStack()),
nullptr);
ThreadInfo info("testThread", tid, true, nullptr);
ProfileBuffer* pb = new ProfileBuffer(buffer_size);
int test_size = 43;
for (int i = 0; i < test_size; i++) {