Merge mozilla-central to autoland. r=merge a=merge on a CLOSED TREE

This commit is contained in:
Bogdan Tara 2017-11-30 01:08:24 +02:00
Родитель a991a8ccee 7d5d1bc25f
Коммит a14227d83a
162 изменённых файлов: 2551 добавлений и 1696 удалений

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

@ -30,8 +30,12 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(AccessibleNode)
AccessibleNode::AccessibleNode(nsINode* aNode) : mDOMNode(aNode)
{
DocAccessible* doc =
GetOrCreateAccService()->GetDocAccessible(mDOMNode->OwnerDoc());
nsAccessibilityService* accService = GetOrCreateAccService();
if (!accService) {
return;
}
DocAccessible* doc = accService->GetDocAccessible(mDOMNode->OwnerDoc());
if (doc) {
mIntl = doc->GetAccessible(mDOMNode);
}
@ -57,8 +61,11 @@ void
AccessibleNode::GetRole(nsAString& aRole)
{
if (mIntl) {
GetOrCreateAccService()->GetStringRole(mIntl->Role(), aRole);
return;
nsAccessibilityService* accService = GetOrCreateAccService();
if (accService) {
accService->GetStringRole(mIntl->Role(), aRole);
return;
}
}
aRole.AssignLiteral("unknown");
@ -67,15 +74,19 @@ AccessibleNode::GetRole(nsAString& aRole)
void
AccessibleNode::GetStates(nsTArray<nsString>& aStates)
{
if (mIntl) {
if (!mStates) {
mStates = GetOrCreateAccService()->GetStringStates(mIntl->State());
}
nsAccessibilityService* accService = GetOrCreateAccService();
if (!mIntl || !accService) {
aStates.AppendElement(NS_LITERAL_STRING("defunct"));
return;
}
if (mStates) {
aStates = mStates->StringArray();
return;
}
aStates.AppendElement(NS_LITERAL_STRING("defunct"));
mStates = accService->GetStringStates(mIntl->State());
aStates = mStates->StringArray();
}
void
@ -106,7 +117,8 @@ AccessibleNode::GetAttributes(nsTArray<nsString>& aAttributes)
bool
AccessibleNode::Is(const Sequence<nsString>& aFlavors)
{
if (!mIntl) {
nsAccessibilityService* accService = GetOrCreateAccService();
if (!mIntl || !accService) {
for (const auto& flavor : aFlavors) {
if (!flavor.EqualsLiteral("unknown") && !flavor.EqualsLiteral("defunct")) {
return false;
@ -116,10 +128,10 @@ AccessibleNode::Is(const Sequence<nsString>& aFlavors)
}
nsAutoString role;
GetOrCreateAccService()->GetStringRole(mIntl->Role(), role);
accService->GetStringRole(mIntl->Role(), role);
if (!mStates) {
mStates = GetOrCreateAccService()->GetStringStates(mIntl->State());
mStates = accService->GetStringStates(mIntl->State());
}
for (const auto& flavor : aFlavors) {

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

@ -1904,6 +1904,11 @@ nsAccessibilityService::NotifyOfConsumersChange()
nsAccessibilityService*
GetOrCreateAccService(uint32_t aNewConsumer)
{
// Do not initialize accessibility if it is force disabled.
if (PlatformDisabledState() == ePlatformIsDisabled) {
return nullptr;
}
if (!nsAccessibilityService::gAccessibilityService) {
RefPtr<nsAccessibilityService> service = new nsAccessibilityService();
if (!service->Init()) {

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

@ -46,7 +46,7 @@ xpcAccessibilityService::AddRef(void)
// We want refcount to be > 1 because one reference is added in the XPCOM
// accessibility service getter.
if (mRefCnt > 1 && PlatformDisabledState() != ePlatformIsDisabled) {
if (mRefCnt > 1) {
GetOrCreateAccService(nsAccessibilityService::eXPCOM);
}
@ -280,13 +280,10 @@ NS_GetAccessibilityService(nsIAccessibilityService** aResult)
NS_ENSURE_TRUE(aResult, NS_ERROR_NULL_POINTER);
*aResult = nullptr;
// Do not initialize accessibility if it is force disabled.
if (PlatformDisabledState() == ePlatformIsDisabled) {
if (!GetOrCreateAccService(nsAccessibilityService::eXPCOM)) {
return NS_ERROR_SERVICE_NOT_AVAILABLE;
}
GetOrCreateAccService(nsAccessibilityService::eXPCOM);
xpcAccessibilityService* service = new xpcAccessibilityService();
NS_ENSURE_TRUE(service, NS_ERROR_OUT_OF_MEMORY);
xpcAccessibilityService::gXPCAccessibilityService = service;

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

@ -3284,72 +3284,27 @@
<certItem issuerName="MGYxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEgMB4GA1UEAxMXR2VvVHJ1c3QgRFYgU1NMIENBIC0gRzM=">
<serialNumber>L79XLVO2ZmtAu7FAG8Wmzw==</serialNumber>
</certItem>
<certItem issuerName="MFAxCzAJBgNVBAYTAkpQMRgwFgYDVQQKEw9TRUNPTSBUcnVzdC5uZXQxJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmljYXRpb24gUm9vdENBMQ==">
<serialNumber>Ermw0Q==</serialNumber>
</certItem>
<certItem issuerName="MIG8MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMTYwNAYDVQQDEy1WZXJpU2lnbiBDbGFzcyAzIEludGVybmF0aW9uYWwgU2VydmVyIENBIC0gRzM=">
<serialNumber>fWK0j/Vi8vNWg3VAGjc02w==</serialNumber>
</certItem>
<certItem issuerName="MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB">
<serialNumber>ESCLRVuhcUZaluIgIVlRJx+O</serialNumber>
</certItem>
<certItem issuerName="MEAxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5UcnVzdCBSb290IENBIEcx">
<serialNumber>ESDDtMgFFiaUfKo7HD9qImM7</serialNumber>
</certItem>
<certItem issuerName="MGoxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xOzA5BgNVBAMMMlN0YWF0IGRlciBOZWRlcmxhbmRlbiBPcmdhbmlzYXRpZSBTZXJ2aWNlcyBDQSAtIEcz">
<serialNumber>ATE5Ig==</serialNumber>
</certItem>
<certItem issuerName="MH4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEvMC0GA1UEAxMmU3ltYW50ZWMgQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzQ=">
<serialNumber>TurPPI6eivtNeGYdM0ZWXQ==</serialNumber>
</certItem>
<certItem issuerName="MFAxJDAiBgNVBAsTG0dsb2JhbFNpZ24gRUNDIFJvb3QgQ0EgLSBSNDETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbg==">
<serialNumber>Hwexgn/ZCJicZPcsIyI8zxQ=</serialNumber>
</certItem>
<certItem issuerName="MDQxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25h">
<serialNumber>Aw==</serialNumber>
</certItem>
<certItem issuerName="MFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxTaWduIFJvb3QgQ0E=">
<serialNumber>BAAAAAABL07hSVI=</serialNumber>
</certItem>
<certItem issuerName="MGYxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEgMB4GA1UEAxMXR2VvVHJ1c3QgRFYgU1NMIENBIC0gRzM=">
<serialNumber>YNOos6YJoPC77qwSGCpb7w==</serialNumber>
</certItem>
<certItem issuerName="MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=">
<serialNumber>Bydrxg==</serialNumber>
</certItem>
<certItem issuerName="MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=">
<serialNumber>DHmmaw==</serialNumber>
</certItem>
<certItem issuerName="MDIxCzAJBgNVBAYTAkNOMQ4wDAYDVQQKEwVDTk5JQzETMBEGA1UEAxMKQ05OSUMgUk9PVA==">
<serialNumber>STMAFQ==</serialNumber>
</certItem>
<certItem issuerName="MCgxCzAJBgNVBAYTAkJFMRkwFwYDVQQDExBCZWxnaXVtIFJvb3QgQ0Ey">
<serialNumber>Nbc68Q8EHza72P/hSWcddw==</serialNumber>
</certItem>
<certItem issuerName="MDQxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25h">
<serialNumber>Bw==</serialNumber>
</certItem>
<certItem issuerName="MH4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEvMC0GA1UEAxMmU3ltYW50ZWMgQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzQ=">
<serialNumber>a9/VeyVWrzFD7rM2PEHwQA==</serialNumber>
</certItem>
<certItem issuerName="MGYxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEgMB4GA1UEAxMXR2VvVHJ1c3QgRFYgU1NMIENBIC0gRzM=">
<serialNumber>dItWlz2V62Philqj9m6Pbg==</serialNumber>
</certItem>
<certItem issuerName="MDcxJDAiBgNVBAMTG1JDUyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEPMA0GA1UEChMGSFQgc3Js">
<serialNumber>AN9bfYOvlR1t</serialNumber>
</certItem>
<certItem issuerName="MDsxCzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTQ==">
<serialNumber>EA==</serialNumber>
</certItem>
<certItem issuerName="MEwxIDAeBgNVBAsTF0dsb2JhbFNpZ24gUm9vdCBDQSAtIFIyMRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu">
<serialNumber>BAAAAAABJ/v3ZwA=</serialNumber>
</certItem>
<certItem issuerName="MDIxCzAJBgNVBAYTAkNOMQ4wDAYDVQQKEwVDTk5JQzETMBEGA1UEAxMKQ05OSUMgUk9PVA==">
<serialNumber>STMAjg==</serialNumber>
</certItem>
<certItem issuerName="MCgxCzAJBgNVBAYTAkJFMRkwFwYDVQQDExBCZWxnaXVtIFJvb3QgQ0Ey">
<serialNumber>frj5jTuqBnQ4fljPvVU3KA==</serialNumber>
</certItem>
<certItem issuerName="MIGFMQswCQYDVQQGEwJVUzEgMB4GA1UECgwXV2VsbHMgRmFyZ28gV2VsbHNTZWN1cmUxHDAaBgNVBAsME1dlbGxzIEZhcmdvIEJhbmsgTkExNjA0BgNVBAMMLVdlbGxzU2VjdXJlIFB1YmxpYyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eQ==">
<serialNumber>AMs=</serialNumber>
</certItem>
@ -3365,9 +3320,6 @@
<certItem issuerName="MIGVMQswCQYDVQQGEwJHUjFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTE=">
<serialNumber>GN2Hrh9LtnM=</serialNumber>
</certItem>
<certItem issuerName="MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=">
<serialNumber>ByembA==</serialNumber>
</certItem>
<certItem issuerName="MH4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEvMC0GA1UEAxMmU3ltYW50ZWMgQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzQ=">
<serialNumber>45KI4WIxyXfNrdtdj7C6</serialNumber>
</certItem>
@ -3380,51 +3332,27 @@
<certItem issuerName="MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=">
<serialNumber>CeFU2w==</serialNumber>
</certItem>
<certItem issuerName="MGoxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xOzA5BgNVBAMMMlN0YWF0IGRlciBOZWRlcmxhbmRlbiBPcmdhbmlzYXRpZSBTZXJ2aWNlcyBDQSAtIEcz">
<serialNumber>LYTXWk7gMu8=</serialNumber>
</certItem>
<certItem issuerName="MFkxCzAJBgNVBAYTAk5MMR4wHAYDVQQKExVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xKjAoBgNVBAMTIVN0YWF0IGRlciBOZWRlcmxhbmRlbiBPdmVyaGVpZCBDQQ==">
<serialNumber>ATFEdg==</serialNumber>
<certItem issuerName="MIGcMQswCQYDVQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEkMCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxFzAVBgNVBAMMDlRydXN0Q29yIEVDQS0x">
<serialNumber>APB/jQRgyP8Q</serialNumber>
</certItem>
<certItem issuerName="MGYxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEgMB4GA1UEAxMXR2VvVHJ1c3QgRFYgU1NMIENBIC0gRzM=">
<serialNumber>KjoVfZ3by6+pL8fssyfM6A==</serialNumber>
</certItem>
<certItem issuerName="MFAxJDAiBgNVBAsTG0dsb2JhbFNpZ24gRUNDIFJvb3QgQ0EgLSBSNDETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbg==">
<serialNumber>RnQ3dg5KdDZs0nyFZk4=</serialNumber>
</certItem>
<certItem issuerName="MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQDExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMw==">
<serialNumber>A5oET6WBWx72ColKf0txoWyR</serialNumber>
</certItem>
<certItem issuerName="MEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDM=">
<serialNumber>BwImeaRkSZQLYwFREwKo3R1Jn+8=</serialNumber>
</certItem>
<certItem issuerName="MHYxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazEtMCsGA1UEAxMkVmVyaVNpZ24gQ2xhc3MgMyBTU1AgSW50ZXJtZWRpYXRlIENB">
<serialNumber>PmDn14AwWY28IlJeBXkDvA==</serialNumber>
</certItem>
<certItem issuerName="MHsxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazEyMDAGA1UEAxMpVmVyaVNpZ24gQ2xhc3MgMyBTU1AgSW50ZXJtZWRpYXRlIENBIC0gRzI=">
<serialNumber>NpsJHyt3o1U47AAgw3UNXA==</serialNumber>
</certItem>
<certItem issuerName="MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQDExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMw==">
<serialNumber>BONHqLIx/ibQE08IQIyoGaXg</serialNumber>
</certItem>
<certItem issuerName="MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB">
<serialNumber>ESCis569omrbb20yySF39+aE</serialNumber>
</certItem>
<certItem issuerName="MEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDM=">
<serialNumber>CLc=</serialNumber>
</certItem>
<certItem issuerName="MGoxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xOzA5BgNVBAMMMlN0YWF0IGRlciBOZWRlcmxhbmRlbiBPcmdhbmlzYXRpZSBTZXJ2aWNlcyBDQSAtIEcz">
<serialNumber>ATE6YA==</serialNumber>
</certItem>
<certItem issuerName="MCgxCzAJBgNVBAYTAkJFMRkwFwYDVQQDExBCZWxnaXVtIFJvb3QgQ0Ey">
<serialNumber>eLumDUO40KwnecZLJxFM2A==</serialNumber>
</certItem>
<certItem issuerName="MH0xCzAJBgNVBAYTAklMMRYwFAYDVQQKEw1TdGFydENvbSBMdGQuMSswKQYDVQQLEyJTZWN1cmUgRGlnaXRhbCBDZXJ0aWZpY2F0ZSBTaWduaW5nMSkwJwYDVQQDEyBTdGFydENvbSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQ==">
<serialNumber>eohOGeS5ZHJeptyBvCu/mQ==</serialNumber>
</certItem>
<certItem issuerName="MGYxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEgMB4GA1UEAxMXR2VvVHJ1c3QgRFYgU1NMIENBIC0gRzI=">
<serialNumber>XhcFm2g619rt8Sro+a4rHA==</serialNumber>
</certItem>
<certItem issuerName="MDwxGzAZBgNVBAMTEkNvbVNpZ24gU2VjdXJlZCBDQTEQMA4GA1UEChMHQ29tU2lnbjELMAkGA1UEBhMCSUw=">
<serialNumber>fbsHfUkagQtznc3rtY1uDg==</serialNumber>
</certItem>
@ -3548,12 +3476,18 @@
<certItem issuerName="MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=">
<serialNumber>F5Bg6C237Q==</serialNumber>
</certItem>
<certItem issuerName="MEcxCzAJBgNVBAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxITAfBgNVBAMTGFN3aXNzU2lnbiBTaWx2ZXIgQ0EgLSBHMg==">
<serialNumber>ANsAyDuSSs7Z83LfMZ+TDw==</serialNumber>
</certItem>
<certItem issuerName="MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB">
<serialNumber>ESByYNtAIfizf2L3NMzCH8zZ</serialNumber>
</certItem>
<certItem issuerName="MIG9MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5">
<serialNumber>Ai7cBJYqBE0I9NdyoZfRrw==</serialNumber>
</certItem>
<certItem issuerName="MHYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEnMCUGA1UEAxMeU3ltYW50ZWMgV2ViIFBLSSBFQ0MgUm9vdCAtIEcx">
<serialNumber>KNhgX8XuJduYciIyatpOQg==</serialNumber>
</certItem>
<certItem issuerName="MHExCzAJBgNVBAYTAkRFMRwwGgYDVQQKExNEZXV0c2NoZSBUZWxla29tIEFHMR8wHQYDVQQLExZULVRlbGVTZWMgVHJ1c3QgQ2VudGVyMSMwIQYDVQQDExpEZXV0c2NoZSBUZWxla29tIFJvb3QgQ0EgMg==">
<serialNumber>AImQERVYPoeb</serialNumber>
</certItem>
@ -3638,6 +3572,9 @@
<certItem issuerName="MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=">
<serialNumber>Bydp0g==</serialNumber>
</certItem>
<certItem issuerName="MHYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEnMCUGA1UEAxMeU3ltYW50ZWMgV2ViIFBLSSBSU0EgUm9vdCAtIEcx">
<serialNumber>SrQ125q7UcLfxVKepx+lRg==</serialNumber>
</certItem>
<certItem issuerName="MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==">
<serialNumber>BAAAAAABM6d3Z0s=</serialNumber>
</certItem>
@ -3671,6 +3608,9 @@
<certItem issuerName="MHsxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazEyMDAGA1UEAxMpVmVyaVNpZ24gQ2xhc3MgMyBTU1AgSW50ZXJtZWRpYXRlIENBIC0gRzI=">
<serialNumber>U3KGm6UTqJ/nsMyteiUa2g==</serialNumber>
</certItem>
<certItem issuerName="MHYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEnMCUGA1UEAxMeU3ltYW50ZWMgV2ViIFBLSSBFQ0MgUm9vdCAtIEcx">
<serialNumber>OIJdAvYxHmLb6YaaMmwmjg==</serialNumber>
</certItem>
<certItem issuerName="MFwxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xLTArBgNVBAMMJFN0YWF0IGRlciBOZWRlcmxhbmRlbiBCdXJnZXIgQ0EgLSBHMg==">
<serialNumber>ATE3ew==</serialNumber>
</certItem>
@ -3707,6 +3647,9 @@
<certItem issuerName="MIHKMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMw==">
<serialNumber>U4P1tUoxl/XkztlVHdtdgw==</serialNumber>
</certItem>
<certItem issuerName="MEUxCzAJBgNVBAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2lnbiBHb2xkIENBIC0gRzI=">
<serialNumber>AIQ8dLGqNIaxxMeg31W16Q==</serialNumber>
</certItem>
<certItem issuerName="MGMxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwx0aGF3dGUsIEluYy4xHTAbBgNVBAsTFERvbWFpbiBWYWxpZGF0ZWQgU1NMMR4wHAYDVQQDExV0aGF3dGUgRFYgU1NMIENBIC0gRzI=">
<serialNumber>TqfXw+FkhxfVgE9GVMgjWQ==</serialNumber>
</certItem>
@ -3785,6 +3728,9 @@
<certItem issuerName="MGcxCzAJBgNVBAYTAmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczEeMBwGA1UEAxMVU3dpc3Njb20gUm9vdCBFViBDQSAy">
<serialNumber>AL691kTvkemG9UQNa6McQg8=</serialNumber>
</certItem>
<certItem issuerName="MHYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEnMCUGA1UEAxMeU3ltYW50ZWMgV2ViIFBLSSBSU0EgUm9vdCAtIEcx">
<serialNumber>OeKv0wi+ATDxfQ6CWir1vA==</serialNumber>
</certItem>
<certItem issuerName="MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=">
<serialNumber>F5BhE0zbgQ==</serialNumber>
</certItem>
@ -3830,6 +3776,9 @@
<certItem issuerName="MF8xCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xhc3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQ==">
<serialNumber>Aj/CJN2QWZAF25GXPXADOA==</serialNumber>
</certItem>
<certItem issuerName="MHYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEnMCUGA1UEAxMeU3ltYW50ZWMgV2ViIFBLSSBFQ0MgUm9vdCAtIEcx">
<serialNumber>WU+jmMhGAumhewqVKrZBmg==</serialNumber>
</certItem>
<certItem issuerName="MGQxCzAJBgNVBAYTAmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAx">
<serialNumber>HxT1XSjIpzjMprp9Qu1gYQ==</serialNumber>
</certItem>
@ -3848,9 +3797,15 @@
<certItem issuerName="MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=">
<serialNumber>BydInw==</serialNumber>
</certItem>
<certItem issuerName="MHYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEnMCUGA1UEAxMeU3ltYW50ZWMgV2ViIFBLSSBSU0EgUm9vdCAtIEcx">
<serialNumber>d8ToN4Dfs5RqD2yfAp12yQ==</serialNumber>
</certItem>
<certItem issuerName="MFwxCzAJBgNVBAYTAkJFMRUwEwYDVQQLEwxUcnVzdGVkIFJvb3QxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExGzAZBgNVBAMTElRydXN0ZWQgUm9vdCBDQSBHMg==">
<serialNumber>F7PAjw2k0dTX5escPnyVOBo=</serialNumber>
</certItem>
<certItem issuerName="MHYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEnMCUGA1UEAxMeU3ltYW50ZWMgV2ViIFBLSSBSU0EgUm9vdCAtIEcx">
<serialNumber>DoP7aSdEs/3y+o2Gj9zgWA==</serialNumber>
</certItem>
<certItem issuerName="ME0xCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxJzAlBgNVBAMTHkRpZ2lDZXJ0IFNIQTIgU2VjdXJlIFNlcnZlciBDQQ==">
<serialNumber>Aa8e+91erglSMgsk/mtVaA==</serialNumber>
</certItem>
@ -3899,6 +3854,9 @@
<certItem issuerName="MIGVMQswCQYDVQQGEwJHUjFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTE=">
<serialNumber>GN2Hrh9LtnE=</serialNumber>
</certItem>
<certItem issuerName="MHYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEnMCUGA1UEAxMeU3ltYW50ZWMgV2ViIFBLSSBFQ0MgUm9vdCAtIEcx">
<serialNumber>UT6GtTGbEC6SXJteWAKy2g==</serialNumber>
</certItem>
<certItem issuerName="MGYxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEgMB4GA1UEAxMXR2VvVHJ1c3QgRFYgU1NMIENBIC0gRzI=">
<serialNumber>P6G7IYSL2RZxtzTh8I6qPA==</serialNumber>
</certItem>
@ -3911,6 +3869,9 @@
<certItem issuerName="MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=">
<serialNumber>ByfNeA==</serialNumber>
</certItem>
<certItem issuerName="MHYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEnMCUGA1UEAxMeU3ltYW50ZWMgV2ViIFBLSSBSU0EgUm9vdCAtIEcx">
<serialNumber>VIFPnH3Io2OmF0J5KK8gzA==</serialNumber>
</certItem>
<certItem issuerName="MIHKMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMw==">
<serialNumber>D/VlGqmz9Nai1ywCydT/RQ==</serialNumber>
</certItem>
@ -3923,6 +3884,9 @@
<certItem issuerName="MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=">
<serialNumber>Byd/Tw==</serialNumber>
</certItem>
<certItem issuerName="MHYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEnMCUGA1UEAxMeU3ltYW50ZWMgV2ViIFBLSSBSU0EgUm9vdCAtIEcx">
<serialNumber>XbPH0u4MjoIrWzN8QCilfg==</serialNumber>
</certItem>
<certItem issuerName="MIG8MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMTYwNAYDVQQDEy1WZXJpU2lnbiBDbGFzcyAzIEludGVybmF0aW9uYWwgU2VydmVyIENBIC0gRzM=">
<serialNumber>LdbnCbsA9sOgI4mkUpWXPw==</serialNumber>
</certItem>
@ -3959,18 +3923,27 @@
<certItem issuerName="MEwxIDAeBgNVBAsTF0dsb2JhbFNpZ24gUm9vdCBDQSAtIFIyMRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu">
<serialNumber>BAAAAAABL07hXdQ=</serialNumber>
</certItem>
<certItem issuerName="MHYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEnMCUGA1UEAxMeU3ltYW50ZWMgV2ViIFBLSSBSU0EgUm9vdCAtIEcx">
<serialNumber>CuUEKEJM4xhxlFXraPcSpQ==</serialNumber>
</certItem>
<certItem issuerName="MD8xJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLjEXMBUGA1UEAxMORFNUIFJvb3QgQ0EgWDM=">
<serialNumber>CgFBQQAAATjkOB1sAAAAAg==</serialNumber>
</certItem>
<certItem issuerName="MIG9MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5">
<serialNumber>QOu0a5Z9rCkw6Nk7Rg1/AQ==</serialNumber>
</certItem>
<certItem issuerName="MHYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEnMCUGA1UEAxMeU3ltYW50ZWMgV2ViIFBLSSBSU0EgUm9vdCAtIEcx">
<serialNumber>ElBUYv/f+6+gnbAJ23qnAA==</serialNumber>
</certItem>
<certItem issuerName="MIGVMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTEdMBsGA1UEAxMUVVROLVVTRVJGaXJzdC1PYmplY3Q=">
<serialNumber>a9rf7/BmG9JkKvRuy7J5QA==</serialNumber>
</certItem>
<certItem issuerName="MFwxCzAJBgNVBAYTAkJFMRUwEwYDVQQLEwxUcnVzdGVkIFJvb3QxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExGzAZBgNVBAMTElRydXN0ZWQgUm9vdCBDQSBHMg==">
<serialNumber>QM1zZ4GZ4gfwpQtUYye3Ne0=</serialNumber>
</certItem>
<certItem issuerName="MHYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEnMCUGA1UEAxMeU3ltYW50ZWMgV2ViIFBLSSBSU0EgUm9vdCAtIEcx">
<serialNumber>XOZMbPKQuJEw8Ib5neDVpQ==</serialNumber>
</certItem>
<certItem issuerName="MDwxHjAcBgNVBAMMFUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsGA1UECgwEQXRvczELMAkGA1UEBhMCREU=">
<serialNumber>M0VSOewW3WI=</serialNumber>
</certItem>
@ -4022,6 +3995,9 @@
<certItem issuerName="MGQxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMTowOAYDVQQDEzFHbG9iYWxTaWduIFBlcnNvbmFsU2lnbiBQYXJ0bmVycyBDQSAtIFNIQTI1NiAtIEcy">
<serialNumber>AeNmeF8oVpDp/4GPvA==</serialNumber>
</certItem>
<certItem issuerName="MHYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEnMCUGA1UEAxMeU3ltYW50ZWMgV2ViIFBLSSBSU0EgUm9vdCAtIEcx">
<serialNumber>UN78HLEKf7W9vQYkzYpJnw==</serialNumber>
</certItem>
<certItem issuerName="MIG+MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNRW50cnVzdCwgSW5jLjEoMCYGA1UECxMfU2VlIHd3dy5lbnRydXN0Lm5ldC9sZWdhbC10ZXJtczE5MDcGA1UECxMwKGMpIDIwMDkgRW50cnVzdCwgSW5jLiAtIGZvciBhdXRob3JpemVkIHVzZSBvbmx5MTIwMAYDVQQDEylFbnRydXN0IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMg==">
<serialNumber>UdNjvA==</serialNumber>
</certItem>
@ -4082,27 +4058,18 @@
<certItem issuerName="MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB">
<serialNumber>ESDItX4ruWiLnrlz0rk4/bmz</serialNumber>
</certItem>
<certItem issuerName="MEwxIDAeBgNVBAsTF0dsb2JhbFNpZ24gUm9vdCBDQSAtIFIyMRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu">
<serialNumber>BAAAAAABIg08D3U=</serialNumber>
</certItem>
<certItem issuerName="MIGVMQswCQYDVQQGEwJHUjFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTE=">
<serialNumber>GN2Hrh9LtnI=</serialNumber>
</certItem>
<certItem issuerName="MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==">
<serialNumber>BAAAAAABJ/ufQg8=</serialNumber>
</certItem>
<certItem issuerName="MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQDExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMw==">
<serialNumber>A8LV4zckxcwdttbQSk0EPnoA</serialNumber>
</certItem>
<certItem issuerName="MIGCMQswCQYDVQQGEwJVUzEeMBwGA1UECxMVd3d3LnhyYW1wc2VjdXJpdHkuY29tMSQwIgYDVQQKExtYUmFtcCBTZWN1cml0eSBTZXJ2aWNlcyBJbmMxLTArBgNVBAMTJFhSYW1wIEdsb2JhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQ==">
<serialNumber>QZCrvQ==</serialNumber>
</certItem>
<certItem issuerName="MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==">
<serialNumber>BAAAAAABMrS7t2g=</serialNumber>
</certItem>
<certItem issuerName="MIGQMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01PRE8gQ0EgTGltaXRlZDE2MDQGA1UEAxMtQ09NT0RPIFJTQSBEb21haW4gVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENB">
<serialNumber>D9UltDPl4XVfSSqQOvdiwQ==</serialNumber>
</certItem>
<certItem issuerName="MGExCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xMjAwBgNVBAMMKVN0YWF0IGRlciBOZWRlcmxhbmRlbiBPcmdhbmlzYXRpZSBDQSAtIEcy">
<serialNumber>LTRcDHabRHU=</serialNumber>
</certItem>
@ -4124,6 +4091,9 @@
<certItem issuerName="MIGFMQswCQYDVQQGEwJVUzEgMB4GA1UECgwXV2VsbHMgRmFyZ28gV2VsbHNTZWN1cmUxHDAaBgNVBAsME1dlbGxzIEZhcmdvIEJhbmsgTkExNjA0BgNVBAMMLVdlbGxzU2VjdXJlIFB1YmxpYyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eQ==">
<serialNumber>Aw==</serialNumber>
</certItem>
<certItem issuerName="MHYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEnMCUGA1UEAxMeU3ltYW50ZWMgV2ViIFBLSSBSU0EgUm9vdCAtIEcx">
<serialNumber>UfM8pWkcmmLGRiGIVydmoA==</serialNumber>
</certItem>
<certItem issuerName="MIGVMQswCQYDVQQGEwJHUjFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTE=">
<serialNumber>GN2Hrh9Ltms=</serialNumber>
</certItem>
@ -4157,6 +4127,9 @@
<certItem issuerName="MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==">
<serialNumber>BAAAAAABMxvC9bk=</serialNumber>
</certItem>
<certItem issuerName="MHYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEnMCUGA1UEAxMeU3ltYW50ZWMgV2ViIFBLSSBFQ0MgUm9vdCAtIEcx">
<serialNumber>EkoaKijVTGVYI5c604iweg==</serialNumber>
</certItem>
<certItem issuerName="MIHKMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMw==">
<serialNumber>TAA2G+UIK6mqznQKBT77NA==</serialNumber>
</certItem>
@ -4172,6 +4145,9 @@
<certItem issuerName="MIGRMQswCQYDVQQGEwJERTEQMA4GA1UECgwHU2llbWVuczERMA8GA1UEBRMIWlpaWlpaVjAxOjA4BgNVBAsMMUNvcHlyaWdodCAoQykgU2llbWVucyBBRyAyMDExIEFsbCBSaWdodHMgUmVzZXJ2ZWQxITAfBgNVBAMMGFNpZW1lbnMgSW50ZXJuZXQgQ0EgVjEuMA==">
<serialNumber>AaoZYg==</serialNumber>
</certItem>
<certItem issuerName="MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=">
<serialNumber>DNHqTQd9QC+JnMy6AWyhkg==</serialNumber>
</certItem>
<certItem issuerName="MGExCzAJBgNVBAYTAlVTMRIwEAYDVQQKEwlJZGVuVHJ1c3QxIDAeBgNVBAsTF0lkZW5UcnVzdCBQdWJsaWMgU2VjdG9yMRwwGgYDVQQDExNJZGVuVHJ1c3QgQUNFUyBDQSAx">
<serialNumber>fwAAAQAAAUrz/HmrAAAAAg==</serialNumber>
</certItem>
@ -4214,6 +4190,9 @@
<certItem issuerName="MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQDExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMw==">
<serialNumber>BOPwjyn5eqfeoxs7Z0y3vqNN</serialNumber>
</certItem>
<certItem issuerName="MHYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEnMCUGA1UEAxMeU3ltYW50ZWMgV2ViIFBLSSBFQ0MgUm9vdCAtIEcx">
<serialNumber>VNb2Hjai/t7dmCtOzRXXew==</serialNumber>
</certItem>
<certItem issuerName="MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQDExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMw==">
<serialNumber>BKobzjrOxa/6kCR0ImKoqaQW</serialNumber>
</certItem>
@ -4271,6 +4250,9 @@
<certItem issuerName="MFwxCzAJBgNVBAYTAkJFMRUwEwYDVQQLEwxUcnVzdGVkIFJvb3QxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExGzAZBgNVBAMTElRydXN0ZWQgUm9vdCBDQSBHMg==">
<serialNumber>LAVIFm0MWZYH+Sv8Vf+IqkM=</serialNumber>
</certItem>
<certItem issuerName="MHYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEnMCUGA1UEAxMeU3ltYW50ZWMgV2ViIFBLSSBSU0EgUm9vdCAtIEcx">
<serialNumber>RkNUwM80Jt7beb4ek+iI8w==</serialNumber>
</certItem>
<certItem issuerName="MDIxCzAJBgNVBAYTAkNOMQ4wDAYDVQQKEwVDTk5JQzETMBEGA1UEAxMKQ05OSUMgUk9PVA==">
<serialNumber>STMAeg==</serialNumber>
</certItem>
@ -4307,6 +4289,9 @@
<certItem issuerName="MGYxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEgMB4GA1UEAxMXR2VvVHJ1c3QgRFYgU1NMIENBIC0gRzM=">
<serialNumber>XLhHIg7vP+tWfRqvuKeAxw==</serialNumber>
</certItem>
<certItem issuerName="MIGkMQswCQYDVQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEkMCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRydXN0Q29yIFJvb3RDZXJ0IENBLTE=">
<serialNumber>AOVojQRgyPca</serialNumber>
</certItem>
<certItem issuerName="MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==">
<serialNumber>BAAAAAABJQdAjik=</serialNumber>
</certItem>
@ -4361,6 +4346,9 @@
<certItem issuerName="MEgxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdTZWN1cmVUcnVzdCBDb3Jwb3JhdGlvbjEXMBUGA1UEAxMOU2VjdXJlVHJ1c3QgQ0E=">
<serialNumber>R/j2qA==</serialNumber>
</certItem>
<certItem issuerName="MEUxCzAJBgNVBAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2lnbiBHb2xkIENBIC0gRzI=">
<serialNumber>AIQ8dLGqNIaxxMeg31W16Q==</serialNumber>
</certItem>
<certItem issuerName="MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQDExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMw==">
<serialNumber>A/7DHCczBnP5qUVh0jF2pvwB</serialNumber>
</certItem>
@ -4370,6 +4358,9 @@
<certItem issuerName="MEwxIDAeBgNVBAsTF0dsb2JhbFNpZ24gUm9vdCBDQSAtIFIyMRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu">
<serialNumber>BAAAAAABElatX7I=</serialNumber>
</certItem>
<certItem issuerName="MHYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEnMCUGA1UEAxMeU3ltYW50ZWMgV2ViIFBLSSBSU0EgUm9vdCAtIEcx">
<serialNumber>X4C5SJIG0BDeJvpQq4ngCw==</serialNumber>
</certItem>
<certItem issuerName="MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB">
<serialNumber>ESC8DawWRiAyEMd38UXbfgPR</serialNumber>
</certItem>
@ -4388,6 +4379,9 @@
<certItem issuerName="MFwxCzAJBgNVBAYTAkJFMRUwEwYDVQQLEwxUcnVzdGVkIFJvb3QxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExGzAZBgNVBAMTElRydXN0ZWQgUm9vdCBDQSBHMg==">
<serialNumber>O2S99lVUxErLSk56GvWRv+E=</serialNumber>
</certItem>
<certItem issuerName="MHYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEnMCUGA1UEAxMeU3ltYW50ZWMgV2ViIFBLSSBSU0EgUm9vdCAtIEcx">
<serialNumber>ODTGURr0vY14WkIt15hHrg==</serialNumber>
</certItem>
<certItem issuerName="MIG1MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMS8wLQYDVQQDEyZWZXJpU2lnbiBDbGFzcyAzIFNlY3VyZSBTZXJ2ZXIgQ0EgLSBHMw==">
<serialNumber>OqQ2rV0ISTc308Z/oQgzFw==</serialNumber>
</certItem>
@ -4397,6 +4391,9 @@
<certItem issuerName="MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=">
<serialNumber>BycpYA==</serialNumber>
</certItem>
<certItem issuerName="MHYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEnMCUGA1UEAxMeU3ltYW50ZWMgV2ViIFBLSSBSU0EgUm9vdCAtIEcx">
<serialNumber>FK+rVRFA0o0PnW+X6V60gQ==</serialNumber>
</certItem>
<certItem issuerName="MF8xCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xhc3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQ==">
<serialNumber>RMgdRGEBv0KzFCjgGFp0Hg==</serialNumber>
</certItem>
@ -4418,6 +4415,9 @@
<certItem issuerName="MHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlBUyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRyZSBSb290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWU=">
<serialNumber>LU4d0t7PAsZNgJGZcb+o/w==</serialNumber>
</certItem>
<certItem issuerName="MHYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEnMCUGA1UEAxMeU3ltYW50ZWMgV2ViIFBLSSBFQ0MgUm9vdCAtIEcx">
<serialNumber>c0ENPRDbRozjU83garZrdA==</serialNumber>
</certItem>
<certItem issuerName="MH4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEvMC0GA1UEAxMmU3ltYW50ZWMgQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzQ=">
<serialNumber>LnfcUaXG/pxV2CpXM5+YSg==</serialNumber>
</certItem>
@ -4433,6 +4433,9 @@
<certItem issuerName="MIG9MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5">
<serialNumber>RbG+tfPUe/vBRfTZF54i8g==</serialNumber>
</certItem>
<certItem issuerName="MIGwMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNRW50cnVzdCwgSW5jLjE5MDcGA1UECxMwd3d3LmVudHJ1c3QubmV0L0NQUyBpcyBpbmNvcnBvcmF0ZWQgYnkgcmVmZXJlbmNlMR8wHQYDVQQLExYoYykgMjAwNiBFbnRydXN0LCBJbmMuMS0wKwYDVQQDEyRFbnRydXN0IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHk=">
<serialNumber>cFbYT3bxd1sAAAAAUdNX8A==</serialNumber>
</certItem>
<certItem issuerName="MGgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEiMCAGA1UEAxMZR2VvVHJ1c3QgRFYgU1NMIFNIQTI1NiBDQQ==">
<serialNumber>ZgwfEqZnBsUNvNuZ77FbQA==</serialNumber>
</certItem>
@ -4493,6 +4496,9 @@
<certItem issuerName="MIG9MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5">
<serialNumber>MWzraR3LLhU9m/qKEhvVLQ==</serialNumber>
</certItem>
<certItem issuerName="MHYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEnMCUGA1UEAxMeU3ltYW50ZWMgV2ViIFBLSSBSU0EgUm9vdCAtIEcx">
<serialNumber>KvQ5AzK6tQy8eBy7NAD/lQ==</serialNumber>
</certItem>
<certItem issuerName="MEcxCzAJBgNVBAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxITAfBgNVBAMTGFN3aXNzU2lnbiBTaWx2ZXIgQ0EgLSBHMg==">
<serialNumber>APiyCXmwAUq+95DYa3DmGw==</serialNumber>
</certItem>
@ -4502,6 +4508,9 @@
<certItem issuerName="MH4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEvMC0GA1UEAxMmU3ltYW50ZWMgQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzQ=">
<serialNumber>AygWP2Fgd2T+iLbmAlKT6g==</serialNumber>
</certItem>
<certItem issuerName="MHYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEnMCUGA1UEAxMeU3ltYW50ZWMgV2ViIFBLSSBFQ0MgUm9vdCAtIEcx">
<serialNumber>dUIqmrcgq/261bRbo7fM1g==</serialNumber>
</certItem>
<certItem issuerName="MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=">
<serialNumber>BydSYg==</serialNumber>
</certItem>
@ -4583,6 +4592,9 @@
<certItem issuerName="MGExCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xMjAwBgNVBAMMKVN0YWF0IGRlciBOZWRlcmxhbmRlbiBPcmdhbmlzYXRpZSBDQSAtIEcy">
<serialNumber>ATE0vw==</serialNumber>
</certItem>
<certItem issuerName="MIGkMQswCQYDVQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEkMCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRydXN0Q29yIFJvb3RDZXJ0IENBLTI=">
<serialNumber>APB/jQRgyPca</serialNumber>
</certItem>
<certItem issuerName="MEoxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdTZWN1cmVUcnVzdCBDb3Jwb3JhdGlvbjEZMBcGA1UEAxMQU2VjdXJlIEdsb2JhbCBDQQ==">
<serialNumber>TXxtAQ==</serialNumber>
</certItem>
@ -4622,6 +4634,9 @@
<certItem issuerName="MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQDExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMw==">
<serialNumber>A1V4dX0tTb1rdTZxdWcuZ7YR</serialNumber>
</certItem>
<certItem issuerName="MIGkMQswCQYDVQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEkMCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRydXN0Q29yIFJvb3RDZXJ0IENBLTE=">
<serialNumber>AOVojQRgyPcY</serialNumber>
</certItem>
<certItem issuerName="MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==">
<serialNumber>BAAAAAABHkSHjz8=</serialNumber>
</certItem>
@ -4652,6 +4667,9 @@
<certItem issuerName="MEcxCzAJBgNVBAYTAkhLMRYwFAYDVQQKEw1Ib25na29uZyBQb3N0MSAwHgYDVQQDExdIb25na29uZyBQb3N0IFJvb3QgQ0EgMQ==">
<serialNumber>BHk=</serialNumber>
</certItem>
<certItem issuerName="MHYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEnMCUGA1UEAxMeU3ltYW50ZWMgV2ViIFBLSSBFQ0MgUm9vdCAtIEcx">
<serialNumber>EYfoVrySx7V3OUqs4xKvgA==</serialNumber>
</certItem>
<certItem issuerName="MIGQMQswCQYDVQQGEwJHUjFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxOzA5BgNVBAMTMkFyaXN0b3RsZSBVbml2ZXJzaXR5IG9mIFRoZXNzYWxvbmlraSBDZW50cmFsIENBIFI0">
<serialNumber>EqthLKdUgwI=</serialNumber>
</certItem>
@ -4778,6 +4796,9 @@
<certItem issuerName="MFAxJDAiBgNVBAsTG0dsb2JhbFNpZ24gRUNDIFJvb3QgQ0EgLSBSNDETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbg==">
<serialNumber>RnQ3dYovwvB0D5q2YGY=</serialNumber>
</certItem>
<certItem issuerName="MHYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEnMCUGA1UEAxMeU3ltYW50ZWMgV2ViIFBLSSBFQ0MgUm9vdCAtIEcx">
<serialNumber>CGo/+42e75JBJ2JcOEaMFw==</serialNumber>
</certItem>
<certItem issuerName="MGMxCzAJBgNVBAYTAkZSMRMwEQYDVQQKEwpDZXJ0aW5vbWlzMRcwFQYDVQQLEw4wMDAyIDQzMzk5ODkwMzEmMCQGA1UEAwwdQ2VydGlub21pcyAtIEF1dG9yaXTDqSBSYWNpbmU=">
<serialNumber>Eg==</serialNumber>
</certItem>
@ -4811,5 +4832,92 @@
<certItem issuerName="MF8xCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRQwEgYDVQQLEwtQYXJ0bmVycyBDQTEfMB0GA1UEAxMWR2xvYmFsU2lnbiBQYXJ0bmVycyBDQQ==">
<serialNumber>BAAAAAABHhw1vwc=</serialNumber>
</certItem>
<certItem issuerName="MEwxIDAeBgNVBAsTF0dsb2JhbFNpZ24gUm9vdCBDQSAtIFIyMRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu">
<serialNumber>BAAAAAABIg08D3U=</serialNumber>
</certItem>
<certItem issuerName="MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQDExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMw==">
<serialNumber>A8LV4zckxcwdttbQSk0EPnoA</serialNumber>
</certItem>
<certItem issuerName="MIGQMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01PRE8gQ0EgTGltaXRlZDE2MDQGA1UEAxMtQ09NT0RPIFJTQSBEb21haW4gVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENB">
<serialNumber>D9UltDPl4XVfSSqQOvdiwQ==</serialNumber>
</certItem>
<certItem issuerName="MFAxCzAJBgNVBAYTAkpQMRgwFgYDVQQKEw9TRUNPTSBUcnVzdC5uZXQxJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmljYXRpb24gUm9vdENBMQ==">
<serialNumber>Ermw0Q==</serialNumber>
</certItem>
<certItem issuerName="MIG8MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMTYwNAYDVQQDEy1WZXJpU2lnbiBDbGFzcyAzIEludGVybmF0aW9uYWwgU2VydmVyIENBIC0gRzM=">
<serialNumber>fWK0j/Vi8vNWg3VAGjc02w==</serialNumber>
</certItem>
<certItem issuerName="MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB">
<serialNumber>ESCLRVuhcUZaluIgIVlRJx+O</serialNumber>
</certItem>
<certItem issuerName="MGoxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xOzA5BgNVBAMMMlN0YWF0IGRlciBOZWRlcmxhbmRlbiBPcmdhbmlzYXRpZSBTZXJ2aWNlcyBDQSAtIEcz">
<serialNumber>ATE5Ig==</serialNumber>
</certItem>
<certItem issuerName="MDQxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25h">
<serialNumber>Aw==</serialNumber>
</certItem>
<certItem issuerName="MFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxTaWduIFJvb3QgQ0E=">
<serialNumber>BAAAAAABL07hSVI=</serialNumber>
</certItem>
<certItem issuerName="MHYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEnMCUGA1UEAxMeU3ltYW50ZWMgV2ViIFBLSSBFQ0MgUm9vdCAtIEcx">
<serialNumber>Q1r0dRkkG9miuHj/Y52izw==</serialNumber>
</certItem>
<certItem issuerName="MGYxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEgMB4GA1UEAxMXR2VvVHJ1c3QgRFYgU1NMIENBIC0gRzM=">
<serialNumber>YNOos6YJoPC77qwSGCpb7w==</serialNumber>
</certItem>
<certItem issuerName="MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=">
<serialNumber>DHmmaw==</serialNumber>
</certItem>
<certItem issuerName="MDIxCzAJBgNVBAYTAkNOMQ4wDAYDVQQKEwVDTk5JQzETMBEGA1UEAxMKQ05OSUMgUk9PVA==">
<serialNumber>STMAFQ==</serialNumber>
</certItem>
<certItem issuerName="MCgxCzAJBgNVBAYTAkJFMRkwFwYDVQQDExBCZWxnaXVtIFJvb3QgQ0Ey">
<serialNumber>Nbc68Q8EHza72P/hSWcddw==</serialNumber>
</certItem>
<certItem issuerName="MDQxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25h">
<serialNumber>Bw==</serialNumber>
</certItem>
<certItem issuerName="MGYxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEgMB4GA1UEAxMXR2VvVHJ1c3QgRFYgU1NMIENBIC0gRzM=">
<serialNumber>dItWlz2V62Philqj9m6Pbg==</serialNumber>
</certItem>
<certItem issuerName="MDcxJDAiBgNVBAMTG1JDUyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEPMA0GA1UEChMGSFQgc3Js">
<serialNumber>AN9bfYOvlR1t</serialNumber>
</certItem>
<certItem issuerName="MDsxCzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTQ==">
<serialNumber>EA==</serialNumber>
</certItem>
<certItem issuerName="MCgxCzAJBgNVBAYTAkJFMRkwFwYDVQQDExBCZWxnaXVtIFJvb3QgQ0Ey">
<serialNumber>frj5jTuqBnQ4fljPvVU3KA==</serialNumber>
</certItem>
<certItem issuerName="MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=">
<serialNumber>ByembA==</serialNumber>
</certItem>
<certItem issuerName="MGoxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xOzA5BgNVBAMMMlN0YWF0IGRlciBOZWRlcmxhbmRlbiBPcmdhbmlzYXRpZSBTZXJ2aWNlcyBDQSAtIEcz">
<serialNumber>LYTXWk7gMu8=</serialNumber>
</certItem>
<certItem issuerName="MFkxCzAJBgNVBAYTAk5MMR4wHAYDVQQKExVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xKjAoBgNVBAMTIVN0YWF0IGRlciBOZWRlcmxhbmRlbiBPdmVyaGVpZCBDQQ==">
<serialNumber>ATFEdg==</serialNumber>
</certItem>
<certItem issuerName="MFAxJDAiBgNVBAsTG0dsb2JhbFNpZ24gRUNDIFJvb3QgQ0EgLSBSNDETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbg==">
<serialNumber>RnQ3dg5KdDZs0nyFZk4=</serialNumber>
</certItem>
<certItem issuerName="MEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDM=">
<serialNumber>BwImeaRkSZQLYwFREwKo3R1Jn+8=</serialNumber>
</certItem>
<certItem issuerName="MHYxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazEtMCsGA1UEAxMkVmVyaVNpZ24gQ2xhc3MgMyBTU1AgSW50ZXJtZWRpYXRlIENB">
<serialNumber>PmDn14AwWY28IlJeBXkDvA==</serialNumber>
</certItem>
<certItem issuerName="MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQDExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMw==">
<serialNumber>BONHqLIx/ibQE08IQIyoGaXg</serialNumber>
</certItem>
<certItem issuerName="MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB">
<serialNumber>ESCis569omrbb20yySF39+aE</serialNumber>
</certItem>
<certItem issuerName="MGoxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xOzA5BgNVBAMMMlN0YWF0IGRlciBOZWRlcmxhbmRlbiBPcmdhbmlzYXRpZSBTZXJ2aWNlcyBDQSAtIEcz">
<serialNumber>ATE6YA==</serialNumber>
</certItem>
<certItem issuerName="MGYxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEgMB4GA1UEAxMXR2VvVHJ1c3QgRFYgU1NMIENBIC0gRzI=">
<serialNumber>XhcFm2g619rt8Sro+a4rHA==</serialNumber>
</certItem>
</certItems>
</blocklist>

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

@ -297,7 +297,9 @@ add_task(async function wrapped_text_in_dialog_should_have_expected_scrollHeight
Assert.ok(docEl.scrollHeight > contentOldHeight,
"Content height increased (from " + contentOldHeight + " to " + docEl.scrollHeight + ").");
Assert.equal(frame.style.height, docEl.scrollHeight + "px",
"Height on the frame should be higher now");
"Height on the frame should be higher now. " +
"This test may fail on certain screen resoluition. " +
"See bug 1420576 and bug 1205717.");
});
await close_subdialog_and_test_generic_end_state(tab.linkedBrowser,

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

@ -8,6 +8,8 @@ var initialPageZoom = ZoomManager.zoom;
const kTimeoutInMS = 20000;
async function testZoomButtonAppearsAndDisappearsBasedOnZoomChanges(zoomEventType) {
let tab = await BrowserTestUtils.openNewForegroundTab({ gBrowser, waitForStateStop: true });
info("Running this test with " + zoomEventType.substring(0, 9));
info("Confirm whether the browser zoom is set to the default level");
is(initialPageZoom, 1, "Page zoom is set to default (100%)");
@ -32,6 +34,8 @@ async function testZoomButtonAppearsAndDisappearsBasedOnZoomChanges(zoomEventTyp
expectedZoomLevel = 100;
is(pageZoomLevel, expectedZoomLevel, "Clicking zoom button successfully resets browser zoom to 100%");
is(zoomResetButton.hidden, true, "Zoom reset button returns to being hidden");
await BrowserTestUtils.removeTab(tab);
}
add_task(async function() {

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

@ -19,7 +19,7 @@ function test() {
"<script type='text/javascript'>",
"let b = 42;",
"</script>",
"<script type='text/javascript;version=1.8'>",
"<script type='text/javascript'>",
"let c = 42;",
"</script>",
"</head>"
@ -44,14 +44,14 @@ function test() {
"The first script was located correctly.");
is(parsed.getScriptInfo(source.indexOf("let b")).toSource(), "({start:85, length:13, index:1})",
"The second script was located correctly.");
is(parsed.getScriptInfo(source.indexOf("let c")).toSource(), "({start:151, length:13, index:2})",
is(parsed.getScriptInfo(source.indexOf("let c")).toSource(), "({start:139, length:13, index:2})",
"The third script was located correctly.");
is(parsed.getScriptInfo(source.indexOf("let a") - 1).toSource(), "({start:31, length:13, index:0})",
"The left edge of the first script was interpreted correctly.");
is(parsed.getScriptInfo(source.indexOf("let b") - 1).toSource(), "({start:85, length:13, index:1})",
"The left edge of the second script was interpreted correctly.");
is(parsed.getScriptInfo(source.indexOf("let c") - 1).toSource(), "({start:151, length:13, index:2})",
is(parsed.getScriptInfo(source.indexOf("let c") - 1).toSource(), "({start:139, length:13, index:2})",
"The left edge of the third script was interpreted correctly.");
is(parsed.getScriptInfo(source.indexOf("let a") - 2).toSource(), "({start:-1, length:-1, index:-1})",
@ -65,7 +65,7 @@ function test() {
"The right edge of the first script was interpreted correctly.");
is(parsed.getScriptInfo(source.indexOf("let b") + 12).toSource(), "({start:85, length:13, index:1})",
"The right edge of the second script was interpreted correctly.");
is(parsed.getScriptInfo(source.indexOf("let c") + 12).toSource(), "({start:151, length:13, index:2})",
is(parsed.getScriptInfo(source.indexOf("let c") + 12).toSource(), "({start:139, length:13, index:2})",
"The right edge of the third script was interpreted correctly.");
is(parsed.getScriptInfo(source.indexOf("let a") + 13).toSource(), "({start:-1, length:-1, index:-1})",

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

@ -19,7 +19,7 @@ function test() {
"a.push('<script type=\"text/javascript\">');",
"a.push('var b = 42;');",
"a.push('</script>');",
"a.push('<script type=\"text/javascript;version=1.8\">');",
"a.push('<script type=\"text/javascript\">');",
"a.push('var c = 42;');",
"a.push('</script>');"
].join("\n");
@ -34,11 +34,11 @@ function test() {
is(parsed.scriptCount, 1,
"There should be 1 script parsed in the parent source.");
is(parsed.getScriptInfo(source.indexOf("let a")).toSource(), "({start:0, length:261, index:0})",
is(parsed.getScriptInfo(source.indexOf("let a")).toSource(), "({start:0, length:249, index:0})",
"The script location is correct (1).");
is(parsed.getScriptInfo(source.indexOf("<script>")).toSource(), "({start:0, length:261, index:0})",
is(parsed.getScriptInfo(source.indexOf("<script>")).toSource(), "({start:0, length:249, index:0})",
"The script location is correct (2).");
is(parsed.getScriptInfo(source.indexOf("</script>")).toSource(), "({start:0, length:261, index:0})",
is(parsed.getScriptInfo(source.indexOf("</script>")).toSource(), "({start:0, length:249, index:0})",
"The script location is correct (3).");
finish();

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

@ -12,7 +12,7 @@ function test() {
let source = [
'<script type="text/javascript" src="chrome://foo.js"/>',
'<script type="application/javascript;version=1.8" src="chrome://baz.js"/>',
'<script type="application/javascript" src="chrome://baz.js"/>',
'<script async defer src="chrome://foobar.js"/>',
'<script type="application/javascript"/>"hello third"',
'<script type="application/javascript">"hello fourth"</script>',
@ -34,7 +34,7 @@ function test() {
is(parsed.getScriptInfo(source.indexOf("hello third!")).toSource(), "({start:-1, length:-1, index:-1})",
"Inline script on self-closing tag not considered a script");
is(parsed.getScriptInfo(source.indexOf("hello fourth")).toSource(), "({start:267, length:14, index:4})",
is(parsed.getScriptInfo(source.indexOf("hello fourth")).toSource(), "({start:255, length:14, index:4})",
"The fourth script was located correctly.");
finish();

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

@ -5,7 +5,7 @@
<title>Web Console test for bug 632347 - generators</title>
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<script type="application/javascript;version=1.8">
<script type="application/javascript">
(function(){
function genFunc() {
var a = 5;

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

@ -5,7 +5,7 @@
<title>Web Console test for bug 632347 - generators</title>
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<script type="application/javascript;version=1.8">
<script type="application/javascript">
(function(){
function* genFunc() {
var a = 5;

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

@ -28,7 +28,7 @@
#include "nsIUUIDGenerator.h"
#include "nsNetUtil.h"
#define RELEASING_TIMER 1000
#define RELEASING_TIMER 5000
using namespace mozilla;
using namespace mozilla::dom;
@ -48,18 +48,21 @@ struct DataInfo
: mObjectType(eBlobImpl)
, mBlobImpl(aBlobImpl)
, mPrincipal(aPrincipal)
, mRevoked(false)
{}
DataInfo(DOMMediaStream* aMediaStream, nsIPrincipal* aPrincipal)
: mObjectType(eMediaStream)
, mMediaStream(aMediaStream)
, mPrincipal(aPrincipal)
, mRevoked(false)
{}
DataInfo(MediaSource* aMediaSource, nsIPrincipal* aPrincipal)
: mObjectType(eMediaSource)
, mMediaSource(aMediaSource)
, mPrincipal(aPrincipal)
, mRevoked(false)
{}
ObjectType mObjectType;
@ -73,12 +76,17 @@ struct DataInfo
// WeakReferences of nsHostObjectURI objects.
nsTArray<nsWeakPtr> mURIs;
// When a blobURL is revoked, we keep it alive for RELEASING_TIMER
// milliseconds in order to support pending operations such as navigation,
// download and so on.
bool mRevoked;
};
static nsClassHashtable<nsCStringHashKey, DataInfo>* gDataTable;
static DataInfo*
GetDataInfo(const nsACString& aUri)
GetDataInfo(const nsACString& aUri, bool aAlsoIfRevoked = false)
{
if (!gDataTable) {
return nullptr;
@ -105,6 +113,10 @@ GetDataInfo(const nsACString& aUri)
gDataTable->Get(StringHead(aUri, pos), &res);
}
if (!aAlsoIfRevoked && res && res->mRevoked) {
return nullptr;
}
return res;
}
@ -154,9 +166,8 @@ BroadcastBlobURLRegistration(const nsACString& aURI,
}
void
BroadcastBlobURLUnregistration(const nsACString& aURI, DataInfo* aInfo)
BroadcastBlobURLUnregistration(const nsCString& aURI)
{
MOZ_ASSERT(aInfo);
MOZ_ASSERT(NS_IsMainThread());
if (XRE_IsParentProcess()) {
@ -165,8 +176,7 @@ BroadcastBlobURLUnregistration(const nsACString& aURI, DataInfo* aInfo)
}
dom::ContentChild* cc = dom::ContentChild::GetSingleton();
Unused << NS_WARN_IF(!cc->SendUnstoreAndBroadcastBlobURLUnregistration(
nsCString(aURI)));
Unused << NS_WARN_IF(!cc->SendUnstoreAndBroadcastBlobURLUnregistration(aURI));
}
class HostObjectURLsReporter final : public nsIMemoryReporter
@ -432,9 +442,10 @@ public:
NS_DECL_ISUPPORTS
static void
Create(nsTArray<nsWeakPtr>&& aArray)
Create(const nsACString& aURI, bool aBroadcastToOtherProcesses)
{
RefPtr<ReleasingTimerHolder> holder = new ReleasingTimerHolder(Move(aArray));
RefPtr<ReleasingTimerHolder> holder =
new ReleasingTimerHolder(aURI, aBroadcastToOtherProcesses);
nsresult rv = NS_NewTimerWithCallback(getter_AddRefs(holder->mTimer),
holder, RELEASING_TIMER,
nsITimer::TYPE_ONE_SHOT,
@ -445,13 +456,32 @@ public:
NS_IMETHOD
Notify(nsITimer* aTimer) override
{
for (uint32_t i = 0; i < mURIs.Length(); ++i) {
nsCOMPtr<nsIURI> uri = do_QueryReferent(mURIs[i]);
// If we have to broadcast the unregistration, let's do it now.
if (mBroadcastToOtherProcesses) {
BroadcastBlobURLUnregistration(mURI);
}
DataInfo* info = GetDataInfo(mURI, true /* We care about revoked dataInfo */);
if (!info) {
// Already gone!
return NS_OK;
}
MOZ_ASSERT(info->mRevoked);
for (uint32_t i = 0; i < info->mURIs.Length(); ++i) {
nsCOMPtr<nsIURI> uri = do_QueryReferent(info->mURIs[i]);
if (uri) {
static_cast<nsHostObjectURI*>(uri.get())->ForgetBlobImpl();
}
}
gDataTable->Remove(mURI);
if (gDataTable->Count() == 0) {
delete gDataTable;
gDataTable = nullptr;
}
return NS_OK;
}
@ -463,14 +493,17 @@ public:
}
private:
explicit ReleasingTimerHolder(nsTArray<nsWeakPtr>&& aArray)
: mURIs(aArray)
ReleasingTimerHolder(const nsACString& aURI, bool aBroadcastToOtherProcesses)
: mURI(aURI)
, mBroadcastToOtherProcesses(aBroadcastToOtherProcesses)
{}
~ReleasingTimerHolder()
{}
nsTArray<nsWeakPtr> mURIs;
nsCString mURI;
bool mBroadcastToOtherProcesses;
nsCOMPtr<nsITimer> mTimer;
};
@ -596,7 +629,8 @@ nsHostObjectProtocolHandler::GetAllBlobURLEntries(
}
aRegistrations.AppendElement(BlobURLRegistrationData(
nsCString(iter.Key()), ipcBlob, IPC::Principal(info->mPrincipal)));
nsCString(iter.Key()), ipcBlob, IPC::Principal(info->mPrincipal),
info->mRevoked));
}
return true;
@ -615,26 +649,19 @@ nsHostObjectProtocolHandler::RemoveDataEntry(const nsACString& aUri,
return;
}
if (aBroadcastToOtherProcesses && info->mObjectType == DataInfo::eBlobImpl) {
BroadcastBlobURLUnregistration(aUri, info);
}
info->mRevoked = true;
if (!info->mURIs.IsEmpty()) {
ReleasingTimerHolder::Create(Move(info->mURIs));
}
gDataTable->Remove(aUri);
if (gDataTable->Count() == 0) {
delete gDataTable;
gDataTable = nullptr;
}
// The timer will take care of removing the entry for real after
// RELEASING_TIMER milliseconds. In the meantime, the DataInfo, marked as
// revoked, will not be exposed.
ReleasingTimerHolder::Create(aUri,
aBroadcastToOtherProcesses &&
info->mObjectType == DataInfo::eBlobImpl);
}
/* static */ void
nsHostObjectProtocolHandler::RemoveDataEntries()
{
MOZ_ASSERT(XRE_IsContentProcess());
if (!gDataTable) {
return;
}

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

@ -77,7 +77,6 @@ public:
static void RemoveDataEntry(const nsACString& aUri,
bool aBroadcastToOTherProcesses = true);
// This is for IPC only.
static void RemoveDataEntries();
static bool HasDataEntry(const nsACString& aUri);

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

@ -2704,6 +2704,13 @@ ContentChild::RecvInitBlobURLs(nsTArray<BlobURLRegistrationData>&& aRegistration
nsHostObjectProtocolHandler::AddDataEntry(registration.url(),
registration.principal(),
blobImpl);
// If we have received an already-revoked blobURL, we have to keep it alive
// for a while (see nsHostObjectProtocolHandler) in order to support pending
// operations such as navigation, download and so on.
if (registration.revoked()) {
nsHostObjectProtocolHandler::RemoveDataEntry(registration.url(),
false);
}
}
return IPC_OK();

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

@ -2796,7 +2796,7 @@ ContentParent::Observe(nsISupports* aSubject,
// We know prefs are ASCII here.
NS_LossyConvertUTF16toASCII strData(aData);
Pref pref(strData, null_t(), null_t());
Pref pref(strData, /* isLocked */ false, null_t(), null_t());
Preferences::GetPreference(&pref);
if (!SendPreferenceUpdate(pref)) {
return NS_ERROR_NOT_AVAILABLE;

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

@ -156,7 +156,11 @@ ContentProcess::Init(int aArgc, char* aArgv[])
MaybePrefValue value(PrefValue(static_cast<int32_t>(strtol(str, &str, 10))));
MOZ_ASSERT(str[0] == '|');
str++;
Pref pref(nsCString(ContentPrefs::GetContentPref(index)), value, MaybePrefValue());
// XXX: we assume these values as default values, which may not be
// true. We also assume they are unlocked. Fortunately, these prefs
// get reset properly by the first IPC message.
Pref pref(nsCString(ContentPrefs::GetContentPref(index)),
/* isLocked */ false, value, MaybePrefValue());
prefsArray.AppendElement(pref);
}
SET_PREF_PHASE(END_INIT_PREFS);
@ -171,7 +175,8 @@ ContentProcess::Init(int aArgc, char* aArgv[])
MaybePrefValue value(PrefValue(!!strtol(str, &str, 10)));
MOZ_ASSERT(str[0] == '|');
str++;
Pref pref(nsCString(ContentPrefs::GetContentPref(index)), value, MaybePrefValue());
Pref pref(nsCString(ContentPrefs::GetContentPref(index)),
/* isLocked */ false, value, MaybePrefValue());
prefsArray.AppendElement(pref);
}
SET_PREF_PHASE(END_INIT_PREFS);
@ -187,7 +192,8 @@ ContentProcess::Init(int aArgc, char* aArgv[])
MOZ_ASSERT(str[0] == ';');
str++;
MaybePrefValue value(PrefValue(nsCString(str, length)));
Pref pref(nsCString(ContentPrefs::GetContentPref(index)), value, MaybePrefValue());
Pref pref(nsCString(ContentPrefs::GetContentPref(index)),
/* isLocked */ false, value, MaybePrefValue());
prefsArray.AppendElement(pref);
str += length + 1;
MOZ_ASSERT(*(str - 1) == '|');

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

@ -156,6 +156,7 @@ union MaybePrefValue {
struct Pref {
nsCString name;
bool isLocked;
MaybePrefValue defaultValue;
MaybePrefValue userValue;
};
@ -234,9 +235,10 @@ union FileCreationResult
struct BlobURLRegistrationData
{
nsCString url;
IPCBlob blob;
Principal principal;
nsCString url;
IPCBlob blob;
Principal principal;
bool revoked;
};
struct GMPAPITags

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

@ -52,7 +52,7 @@ ResolutionFeasibilityDistance(int32_t candidate, int32_t requested)
if (candidate >= requested) {
distance = (candidate - requested) * 1000 / std::max(candidate, requested);
} else {
distance = 10000 + (requested - candidate) *
distance = (UINT32_MAX / 2) + (requested - candidate) *
1000 / std::max(candidate, requested);
}
return distance;
@ -862,14 +862,14 @@ CamerasParent::RecvStartCapture(const CaptureEngine& aCapEngine,
capability.codecType = static_cast<webrtc::VideoCodecType>(ipcCaps.codecType());
capability.interlaced = ipcCaps.interlaced();
#ifdef DEBUG
auto deviceUniqueID = sDeviceUniqueIDs.find(capnum);
MOZ_ASSERT(deviceUniqueID == sDeviceUniqueIDs.end());
#endif
sDeviceUniqueIDs.emplace(capnum, cap.VideoCapture()->CurrentDeviceName());
sAllRequestedCapabilities.emplace(capnum, capability);
if (aCapEngine == CameraEngine) {
#ifdef DEBUG
auto deviceUniqueID = sDeviceUniqueIDs.find(capnum);
MOZ_ASSERT(deviceUniqueID == sDeviceUniqueIDs.end());
#endif
sDeviceUniqueIDs.emplace(capnum, cap.VideoCapture()->CurrentDeviceName());
sAllRequestedCapabilities.emplace(capnum, capability);
for (const auto &it : sDeviceUniqueIDs) {
if (strcmp(it.second, cap.VideoCapture()->CurrentDeviceName()) == 0) {
capability.width = std::max(
@ -908,16 +908,6 @@ CamerasParent::RecvStartCapture(const CaptureEngine& aCapEngine,
}
MOZ_ASSERT(minIdx != -1);
capability = candidateCapabilities->second[minIdx];
} else if (aCapEngine == ScreenEngine ||
aCapEngine == BrowserEngine ||
aCapEngine == WinEngine ||
aCapEngine == AppEngine) {
for (const auto &it : sDeviceUniqueIDs) {
if (strcmp(it.second, cap.VideoCapture()->CurrentDeviceName()) == 0) {
capability.maxFPS = std::max(
capability.maxFPS, sAllRequestedCapabilities[it.first].maxFPS);
}
}
}
error = cap.VideoCapture()->StartCapture(capability);
@ -959,14 +949,16 @@ CamerasParent::StopCapture(const CaptureEngine& aCapEngine,
mCallbacks[i - 1]->mStreamId == (uint32_t)capnum) {
CallbackHelper* cbh = mCallbacks[i-1];
engine->WithEntry(capnum,[cbh, &capnum](VideoEngine::CaptureEntry& cap){
engine->WithEntry(capnum,[cbh, &capnum, &aCapEngine](VideoEngine::CaptureEntry& cap){
if (cap.VideoCapture()) {
cap.VideoCapture()->DeRegisterCaptureDataCallback(
static_cast<rtc::VideoSinkInterface<webrtc::VideoFrame>*>(cbh));
cap.VideoCapture()->StopCaptureIfAllClientsClose();
sDeviceUniqueIDs.erase(capnum);
sAllRequestedCapabilities.erase(capnum);
if (aCapEngine == CameraEngine) {
sDeviceUniqueIDs.erase(capnum);
sAllRequestedCapabilities.erase(capnum);
}
}
});

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

@ -217,7 +217,6 @@ public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AllocationHandle);
protected:
~AllocationHandle() {}
static uint64_t sId;
public:
AllocationHandle(const dom::MediaTrackConstraints& aConstraints,
const mozilla::ipc::PrincipalInfo& aPrincipalInfo,
@ -227,15 +226,11 @@ public:
: mConstraints(aConstraints),
mPrincipalInfo(aPrincipalInfo),
mPrefs(aPrefs),
#ifdef MOZ_WEBRTC
mId(sId++),
#endif
mDeviceId(aDeviceId) {}
public:
NormalizedConstraints mConstraints;
mozilla::ipc::PrincipalInfo mPrincipalInfo;
MediaEnginePrefs mPrefs;
uint64_t mId;
nsString mDeviceId;
};
@ -371,7 +366,6 @@ protected:
virtual nsresult
UpdateSingleSource(const AllocationHandle* aHandle,
const NormalizedConstraints& aNetConstraints,
const NormalizedConstraints& aNewConstraint,
const MediaEnginePrefs& aPrefs,
const nsString& aDeviceId,
const char** aOutBadConstraint) {
@ -400,7 +394,6 @@ protected:
// aHandle and/or aConstraintsUpdate may be nullptr (see below)
AutoTArray<const NormalizedConstraints*, 10> allConstraints;
AutoTArray<const NormalizedConstraints*, 1> updatedConstraint;
for (auto& registered : mRegisteredHandles) {
if (aConstraintsUpdate && registered.get() == aHandle) {
continue; // Don't count old constraints
@ -409,13 +402,9 @@ protected:
}
if (aConstraintsUpdate) {
allConstraints.AppendElement(aConstraintsUpdate);
updatedConstraint.AppendElement(aConstraintsUpdate);
} else if (aHandle) {
// In the case of AddShareOfSingleSource, the handle isn't registered yet.
allConstraints.AppendElement(&aHandle->mConstraints);
updatedConstraint.AppendElement(&aHandle->mConstraints);
} else {
updatedConstraint.AppendElements(allConstraints);
}
NormalizedConstraints netConstraints(allConstraints);
@ -424,8 +413,7 @@ protected:
return NS_ERROR_FAILURE;
}
NormalizedConstraints newConstraint(updatedConstraint);
nsresult rv = UpdateSingleSource(aHandle, netConstraints, newConstraint, aPrefs, aDeviceId,
nsresult rv = UpdateSingleSource(aHandle, netConstraints, aPrefs, aDeviceId,
aOutBadConstraint);
if (NS_FAILED(rv)) {
return rv;

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

@ -25,20 +25,10 @@ bool MediaEngineCameraVideoSource::AppendToTrack(SourceMediaStream* aSource,
const PrincipalHandle& aPrincipalHandle)
{
MOZ_ASSERT(aSource);
MOZ_ASSERT(aImage);
if (!aImage) {
return 0;
}
VideoSegment segment;
RefPtr<layers::Image> image = aImage;
IntSize size = image->GetSize();
if (!size.width || !size.height) {
return 0;
}
IntSize size(image ? mWidth : 0, image ? mHeight : 0);
segment.AppendFrame(image.forget(), delta, size, aPrincipalHandle);
// This is safe from any thread, and is safe if the track is Finished
@ -64,19 +54,6 @@ MediaEngineCameraVideoSource::GetCapability(size_t aIndex,
aOut = mHardcodedCapabilities.SafeElementAt(aIndex, webrtc::CaptureCapability());
}
uint32_t
MediaEngineCameraVideoSource::GetDistance(
const webrtc::CaptureCapability& aCandidate,
const NormalizedConstraintSet &aConstraints,
const nsString& aDeviceId,
const DistanceCalculation aCalculate) const
{
if (aCalculate == kFeasibility) {
return GetFeasibilityDistance(aCandidate, aConstraints, aDeviceId);
}
return GetFitnessDistance(aCandidate, aConstraints, aDeviceId);
}
uint32_t
MediaEngineCameraVideoSource::GetFitnessDistance(
const webrtc::CaptureCapability& aCandidate,
@ -98,27 +75,6 @@ MediaEngineCameraVideoSource::GetFitnessDistance(
return uint32_t(std::min(distance, uint64_t(UINT32_MAX)));
}
uint32_t
MediaEngineCameraVideoSource::GetFeasibilityDistance(
const webrtc::CaptureCapability& aCandidate,
const NormalizedConstraintSet &aConstraints,
const nsString& aDeviceId) const
{
// Treat width|height|frameRate == 0 on capability as "can do any".
// This allows for orthogonal capabilities that are not in discrete steps.
uint64_t distance =
uint64_t(FitnessDistance(aDeviceId, aConstraints.mDeviceId)) +
uint64_t(FitnessDistance(mFacingMode, aConstraints.mFacingMode)) +
uint64_t(aCandidate.width? FeasibilityDistance(int32_t(aCandidate.width),
aConstraints.mWidth) : 0) +
uint64_t(aCandidate.height? FeasibilityDistance(int32_t(aCandidate.height),
aConstraints.mHeight) : 0) +
uint64_t(aCandidate.maxFPS? FeasibilityDistance(double(aCandidate.maxFPS),
aConstraints.mFrameRate) : 0);
return uint32_t(std::min(distance, uint64_t(UINT32_MAX)));
}
// Find best capability by removing inferiors. May leave >1 of equal distance
/* static */ void
@ -262,9 +218,7 @@ bool
MediaEngineCameraVideoSource::ChooseCapability(
const NormalizedConstraints &aConstraints,
const MediaEnginePrefs &aPrefs,
const nsString& aDeviceId,
webrtc::CaptureCapability& aCapability,
const DistanceCalculation aCalculate)
const nsString& aDeviceId)
{
if (MOZ_LOG_TEST(GetMediaManagerLog(), LogLevel::Debug)) {
LOG(("ChooseCapability: prefs: %dx%d @%dfps",
@ -292,7 +246,7 @@ MediaEngineCameraVideoSource::ChooseCapability(
auto& candidate = candidateSet[i];
webrtc::CaptureCapability cap;
GetCapability(candidate.mIndex, cap);
candidate.mDistance = GetDistance(cap, aConstraints, aDeviceId, aCalculate);
candidate.mDistance = GetFitnessDistance(cap, aConstraints, aDeviceId);
LogCapability("Capability", cap, candidate.mDistance);
if (candidate.mDistance == UINT32_MAX) {
candidateSet.RemoveElementAt(i);
@ -314,7 +268,7 @@ MediaEngineCameraVideoSource::ChooseCapability(
auto& candidate = candidateSet[i];
webrtc::CaptureCapability cap;
GetCapability(candidate.mIndex, cap);
if (GetDistance(cap, cs, aDeviceId, aCalculate) == UINT32_MAX) {
if (GetFitnessDistance(cap, cs, aDeviceId) == UINT32_MAX) {
rejects.AppendElement(candidate);
candidateSet.RemoveElementAt(i);
} else {
@ -345,7 +299,7 @@ MediaEngineCameraVideoSource::ChooseCapability(
for (auto& candidate : candidateSet) {
webrtc::CaptureCapability cap;
GetCapability(candidate.mIndex, cap);
candidate.mDistance = GetDistance(cap, normPrefs, aDeviceId, aCalculate);
candidate.mDistance = GetFitnessDistance(cap, normPrefs, aDeviceId);
}
TrimLessFitCandidates(candidateSet);
}
@ -361,13 +315,13 @@ MediaEngineCameraVideoSource::ChooseCapability(
if (cap.rawType == webrtc::RawVideoType::kVideoI420 ||
cap.rawType == webrtc::RawVideoType::kVideoYUY2 ||
cap.rawType == webrtc::RawVideoType::kVideoYV12) {
aCapability = cap;
mCapability = cap;
found = true;
break;
}
}
if (!found) {
GetCapability(candidateSet[0].mIndex, aCapability);
GetCapability(candidateSet[0].mIndex, mCapability);
}
LogCapability("Chosen capability", mCapability, sameDistance);

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

@ -24,19 +24,6 @@ namespace webrtc {
namespace mozilla {
// Fitness distance is defined in
// https://www.w3.org/TR/2017/CR-mediacapture-streams-20171003/#dfn-selectsettings
// The main difference of feasibility and fitness distance is that if the
// constraint is required ('max', or 'exact'), and the settings dictionary's value
// for the constraint does not satisfy the constraint, the fitness distance is
// positive infinity. Given a continuous space of settings dictionaries comprising
// all discrete combinations of dimension and frame-rate related properties,
// the feasibility distance is still in keeping with the constraints algorithm.
enum DistanceCalculation {
kFitness,
kFeasibility
};
class MediaEngineCameraVideoSource : public MediaEngineVideoSource
{
public:
@ -99,16 +86,9 @@ protected:
TrackID aID,
StreamTime delta,
const PrincipalHandle& aPrincipalHandle);
uint32_t GetDistance(const webrtc::CaptureCapability& aCandidate,
const NormalizedConstraintSet &aConstraints,
const nsString& aDeviceId,
const DistanceCalculation aCalculate) const;
uint32_t GetFitnessDistance(const webrtc::CaptureCapability& aCandidate,
const NormalizedConstraintSet &aConstraints,
const nsString& aDeviceId) const;
uint32_t GetFeasibilityDistance(const webrtc::CaptureCapability& aCandidate,
const NormalizedConstraintSet &aConstraints,
const nsString& aDeviceId) const;
static void TrimLessFitCandidates(CapabilitySet& set);
static void LogConstraints(const NormalizedConstraintSet& aConstraints);
static void LogCapability(const char* aHeader,
@ -116,13 +96,9 @@ protected:
uint32_t aDistance);
virtual size_t NumCapabilities() const;
virtual void GetCapability(size_t aIndex, webrtc::CaptureCapability& aOut) const;
virtual bool ChooseCapability(
const NormalizedConstraints &aConstraints,
const MediaEnginePrefs &aPrefs,
const nsString& aDeviceId,
webrtc::CaptureCapability& aCapability,
const DistanceCalculation aCalculate
);
virtual bool ChooseCapability(const NormalizedConstraints &aConstraints,
const MediaEnginePrefs &aPrefs,
const nsString& aDeviceId);
void SetName(nsString aName);
void SetUUID(const char* aUUID);
const nsCString& GetUUID() const; // protected access
@ -140,9 +116,6 @@ protected:
nsTArray<RefPtr<SourceMediaStream>> mSources; // When this goes empty, we shut down HW
nsTArray<PrincipalHandle> mPrincipalHandles; // Directly mapped to mSources.
RefPtr<layers::Image> mImage;
nsTArray<RefPtr<layers::Image>> mImages;
nsTArray<webrtc::CaptureCapability> mTargetCapabilities;
nsTArray<uint64_t> mHandleIds;
RefPtr<layers::ImageContainer> mImageContainer;
// end of data protected by mMonitor
@ -152,8 +125,6 @@ protected:
TrackID mTrackID;
webrtc::CaptureCapability mCapability;
webrtc::CaptureCapability mTargetCapability;
uint64_t mHandleId;
mutable nsTArray<webrtc::CaptureCapability> mHardcodedCapabilities;
private:

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

@ -10,9 +10,6 @@
#include "nsIPrefService.h"
#include "MediaTrackConstraints.h"
#include "CamerasChild.h"
#include "VideoFrameUtils.h"
#include "webrtc/api/video/i420_buffer.h"
#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
extern mozilla::LogModule* GetMediaManagerLog();
#define LOG(msg) MOZ_LOG(GetMediaManagerLog(), mozilla::LogLevel::Debug, msg)
@ -20,8 +17,6 @@ extern mozilla::LogModule* GetMediaManagerLog();
namespace mozilla {
uint64_t MediaEngineCameraVideoSource::AllocationHandle::sId = 0;
// These need a definition somewhere because template
// code is allowed to take their address, and they aren't
// guaranteed to have one without this.
@ -85,9 +80,6 @@ MediaEngineRemoteVideoSource::Shutdown()
empty = mSources.IsEmpty();
if (empty) {
MOZ_ASSERT(mPrincipalHandles.IsEmpty());
MOZ_ASSERT(mTargetCapabilities.IsEmpty());
MOZ_ASSERT(mHandleIds.IsEmpty());
MOZ_ASSERT(mImages.IsEmpty());
break;
}
source = mSources[0];
@ -134,9 +126,6 @@ MediaEngineRemoteVideoSource::Allocate(
MonitorAutoLock lock(mMonitor);
if (mSources.IsEmpty()) {
MOZ_ASSERT(mPrincipalHandles.IsEmpty());
MOZ_ASSERT(mTargetCapabilities.IsEmpty());
MOZ_ASSERT(mHandleIds.IsEmpty());
MOZ_ASSERT(mImages.IsEmpty());
LOG(("Video device %d reallocated", mCaptureIndex));
} else {
LOG(("Video device %d allocated shared", mCaptureIndex));
@ -179,21 +168,11 @@ MediaEngineRemoteVideoSource::Start(SourceMediaStream* aStream, TrackID aID,
return NS_ERROR_FAILURE;
}
mImageContainer =
layers::LayerManager::CreateImageContainer(layers::ImageContainer::ASYNCHRONOUS);
{
MonitorAutoLock lock(mMonitor);
mSources.AppendElement(aStream);
mPrincipalHandles.AppendElement(aPrincipalHandle);
mTargetCapabilities.AppendElement(mTargetCapability);
mHandleIds.AppendElement(mHandleId);
mImages.AppendElement(mImageContainer->CreatePlanarYCbCrImage());
MOZ_ASSERT(mSources.Length() == mPrincipalHandles.Length());
MOZ_ASSERT(mSources.Length() == mTargetCapabilities.Length());
MOZ_ASSERT(mSources.Length() == mHandleIds.Length());
MOZ_ASSERT(mSources.Length() == mImages.Length());
}
aStream->AddTrack(aID, 0, new VideoSegment(), SourceMediaStream::ADDTRACK_QUEUED);
@ -201,6 +180,8 @@ MediaEngineRemoteVideoSource::Start(SourceMediaStream* aStream, TrackID aID,
if (mState == kStarted) {
return NS_OK;
}
mImageContainer =
layers::LayerManager::CreateImageContainer(layers::ImageContainer::ASYNCHRONOUS);
mState = kStarted;
mTrackID = aID;
@ -237,14 +218,8 @@ MediaEngineRemoteVideoSource::Stop(mozilla::SourceMediaStream* aSource,
}
MOZ_ASSERT(mSources.Length() == mPrincipalHandles.Length());
MOZ_ASSERT(mSources.Length() == mTargetCapabilities.Length());
MOZ_ASSERT(mSources.Length() == mHandleIds.Length());
MOZ_ASSERT(mSources.Length() == mImages.Length());
mSources.RemoveElementAt(i);
mPrincipalHandles.RemoveElementAt(i);
mTargetCapabilities.RemoveElementAt(i);
mHandleIds.RemoveElementAt(i);
mImages.RemoveElementAt(i);
aSource->EndTrack(aID);
@ -287,21 +262,18 @@ nsresult
MediaEngineRemoteVideoSource::UpdateSingleSource(
const AllocationHandle* aHandle,
const NormalizedConstraints& aNetConstraints,
const NormalizedConstraints& aNewConstraint,
const MediaEnginePrefs& aPrefs,
const nsString& aDeviceId,
const char** aOutBadConstraint)
{
if (!ChooseCapability(aNetConstraints, aPrefs, aDeviceId)) {
*aOutBadConstraint = FindBadConstraint(aNetConstraints, *this, aDeviceId);
return NS_ERROR_FAILURE;
}
switch (mState) {
case kReleased:
MOZ_ASSERT(aHandle);
mHandleId = aHandle->mId;
if (!ChooseCapability(aNetConstraints, aPrefs, aDeviceId, mCapability, kFitness)) {
*aOutBadConstraint = FindBadConstraint(aNetConstraints, *this, aDeviceId);
return NS_ERROR_FAILURE;
}
mTargetCapability = mCapability;
if (camera::GetChildAndCall(&camera::CamerasChild::AllocateCaptureDevice,
mCapEngine, GetUUID().get(),
kMaxUniqueIdLength, mCaptureIndex,
@ -314,47 +286,18 @@ MediaEngineRemoteVideoSource::UpdateSingleSource(
break;
case kStarted:
{
size_t index = mHandleIds.NoIndex;
if (aHandle) {
mHandleId = aHandle->mId;
index = mHandleIds.IndexOf(mHandleId);
}
if (!ChooseCapability(aNewConstraint, aPrefs, aDeviceId, mTargetCapability,
kFitness)) {
*aOutBadConstraint = FindBadConstraint(aNewConstraint, *this, aDeviceId);
if (mCapability != mLastCapability) {
camera::GetChildAndCall(&camera::CamerasChild::StopCapture,
mCapEngine, mCaptureIndex);
if (camera::GetChildAndCall(&camera::CamerasChild::StartCapture,
mCapEngine, mCaptureIndex, mCapability,
this)) {
LOG(("StartCapture failed"));
return NS_ERROR_FAILURE;
}
if (index != mHandleIds.NoIndex) {
MonitorAutoLock lock(mMonitor);
mTargetCapabilities[index] = mTargetCapability;
MOZ_ASSERT(mSources.Length() == mPrincipalHandles.Length());
MOZ_ASSERT(mSources.Length() == mTargetCapabilities.Length());
MOZ_ASSERT(mSources.Length() == mHandleIds.Length());
MOZ_ASSERT(mSources.Length() == mImages.Length());
}
if (!ChooseCapability(aNetConstraints, aPrefs, aDeviceId, mCapability,
kFeasibility)) {
*aOutBadConstraint = FindBadConstraint(aNetConstraints, *this, aDeviceId);
return NS_ERROR_FAILURE;
}
if (mCapability != mLastCapability) {
camera::GetChildAndCall(&camera::CamerasChild::StopCapture,
mCapEngine, mCaptureIndex);
if (camera::GetChildAndCall(&camera::CamerasChild::StartCapture,
mCapEngine, mCaptureIndex, mCapability,
this)) {
LOG(("StartCapture failed"));
return NS_ERROR_FAILURE;
}
SetLastCapability(mCapability);
}
break;
SetLastCapability(mCapability);
}
break;
default:
LOG(("Video device %d in ignored state %d", mCaptureIndex, mState));
@ -400,22 +343,18 @@ MediaEngineRemoteVideoSource::NotifyPull(MediaStreamGraph* aGraph,
TrackID aID, StreamTime aDesiredTime,
const PrincipalHandle& aPrincipalHandle)
{
StreamTime delta = 0;
size_t i;
VideoSegment segment;
MonitorAutoLock lock(mMonitor);
if (mState != kStarted) {
return;
}
i = mSources.IndexOf(aSource);
if (i == mSources.NoIndex) {
return;
}
delta = aDesiredTime - aSource->GetEndOfAppendedData(aID);
StreamTime delta = aDesiredTime - aSource->GetEndOfAppendedData(aID);
if (delta > 0) {
AppendToTrack(aSource, mImages[i], aID, delta, aPrincipalHandle);
// nullptr images are allowed
AppendToTrack(aSource, mImage, aID, delta, aPrincipalHandle);
}
}
@ -438,12 +377,11 @@ MediaEngineRemoteVideoSource::FrameSizeChange(unsigned int w, unsigned int h)
}
int
MediaEngineRemoteVideoSource::DeliverFrame(uint8_t* aBuffer,
MediaEngineRemoteVideoSource::DeliverFrame(uint8_t* aBuffer ,
const camera::VideoFrameProperties& aProps)
{
MonitorAutoLock lock(mMonitor);
// Check for proper state.
if (mState != kStarted || !mImageContainer) {
if (mState != kStarted) {
LOG(("DeliverFrame: video not started"));
return 0;
}
@ -451,114 +389,51 @@ MediaEngineRemoteVideoSource::DeliverFrame(uint8_t* aBuffer,
// Update the dimensions
FrameSizeChange(aProps.width(), aProps.height());
MOZ_ASSERT(mSources.Length() == mPrincipalHandles.Length());
MOZ_ASSERT(mSources.Length() == mTargetCapabilities.Length());
MOZ_ASSERT(mSources.Length() == mHandleIds.Length());
MOZ_ASSERT(mSources.Length() == mImages.Length());
for (uint32_t i = 0; i < mTargetCapabilities.Length(); i++ ) {
int32_t req_max_width = mTargetCapabilities[i].width & 0xffff;
int32_t req_max_height = mTargetCapabilities[i].height & 0xffff;
int32_t req_ideal_width = (mTargetCapabilities[i].width >> 16) & 0xffff;
int32_t req_ideal_height = (mTargetCapabilities[i].height >> 16) & 0xffff;
int32_t dest_max_width = std::min(req_max_width, mWidth);
int32_t dest_max_height = std::min(req_max_height, mHeight);
// This logic works for both camera and screen sharing case.
// for camera case, req_ideal_width and req_ideal_height is 0.
// The following snippet will set dst_width to dest_max_width and dst_height to dest_max_height
int32_t dst_width = std::min(req_ideal_width > 0 ? req_ideal_width : mWidth, dest_max_width);
int32_t dst_height = std::min(req_ideal_height > 0 ? req_ideal_height : mHeight, dest_max_height);
int dst_stride_y = dst_width;
int dst_stride_uv = (dst_width + 1) / 2;
camera::VideoFrameProperties properties;
uint8_t* frame;
bool needReScale = !((dst_width == mWidth && dst_height == mHeight) ||
(dst_width > mWidth || dst_height > mHeight));
if (!needReScale) {
dst_width = mWidth;
dst_height = mHeight;
frame = aBuffer;
} else {
rtc::scoped_refptr<webrtc::I420Buffer> i420Buffer;
i420Buffer = webrtc::I420Buffer::Create(mWidth, mHeight, mWidth,
(mWidth + 1) / 2, (mWidth + 1) / 2);
const int conversionResult = webrtc::ConvertToI420(webrtc::kI420,
aBuffer,
0, 0, // No cropping
mWidth, mHeight,
mWidth * mHeight * 3 / 2,
webrtc::kVideoRotation_0,
i420Buffer.get());
webrtc::VideoFrame captureFrame(i420Buffer, 0, 0, webrtc::kVideoRotation_0);
if (conversionResult < 0) {
return 0;
}
rtc::scoped_refptr<webrtc::I420Buffer> scaledBuffer;
scaledBuffer = webrtc::I420Buffer::Create(dst_width, dst_height, dst_stride_y,
dst_stride_uv, dst_stride_uv);
scaledBuffer->CropAndScaleFrom(*captureFrame.video_frame_buffer().get());
webrtc::VideoFrame scaledFrame(scaledBuffer, 0, 0, webrtc::kVideoRotation_0);
VideoFrameUtils::InitFrameBufferProperties(scaledFrame, properties);
frame = new unsigned char[properties.bufferSize()];
if (!frame) {
return 0;
}
VideoFrameUtils::CopyVideoFrameBuffers(frame,
properties.bufferSize(), scaledFrame);
layers::PlanarYCbCrData data;
RefPtr<layers::PlanarYCbCrImage> image;
{
// We grab the lock twice, but don't hold it across the (long) CopyData
MonitorAutoLock lock(mMonitor);
if (!mImageContainer) {
LOG(("DeliverFrame() called after Stop()!"));
return 0;
}
// Create a video frame and append it to the track.
RefPtr<layers::PlanarYCbCrImage> image = mImageContainer->CreatePlanarYCbCrImage();
image = mImageContainer->CreatePlanarYCbCrImage();
uint8_t* frame = static_cast<uint8_t*> (aBuffer);
const uint8_t lumaBpp = 8;
const uint8_t chromaBpp = 4;
layers::PlanarYCbCrData data;
// Take lots of care to round up!
data.mYChannel = frame;
data.mYSize = IntSize(dst_width, dst_height);
data.mYStride = (dst_width * lumaBpp + 7) / 8;
data.mCbCrStride = (dst_width * chromaBpp + 7) / 8;
data.mCbChannel = frame + dst_height * data.mYStride;
data.mCrChannel = data.mCbChannel + ((dst_height + 1) / 2) * data.mCbCrStride;
data.mCbCrSize = IntSize((dst_width + 1) / 2, (dst_height + 1) / 2);
data.mYSize = IntSize(mWidth, mHeight);
data.mYStride = (mWidth * lumaBpp + 7)/ 8;
data.mCbCrStride = (mWidth * chromaBpp + 7) / 8;
data.mCbChannel = frame + mHeight * data.mYStride;
data.mCrChannel = data.mCbChannel + ((mHeight+1)/2) * data.mCbCrStride;
data.mCbCrSize = IntSize((mWidth+1)/ 2, (mHeight+1)/ 2);
data.mPicX = 0;
data.mPicY = 0;
data.mPicSize = IntSize(dst_width, dst_height);
data.mPicSize = IntSize(mWidth, mHeight);
data.mStereoMode = StereoMode::MONO;
}
if (!image->CopyData(data)) {
MOZ_ASSERT(false);
return 0;
}
if (needReScale && frame) {
delete frame;
frame = nullptr;
}
if (!image->CopyData(data)) {
MOZ_ASSERT(false);
return 0;
}
MonitorAutoLock lock(mMonitor);
#ifdef DEBUG
static uint32_t frame_num = 0;
LOGFRAME(("frame %d (%dx%d); timeStamp %u, ntpTimeMs %" PRIu64 ", renderTimeMs %" PRIu64,
frame_num++, mWidth, mHeight,
aProps.timeStamp(), aProps.ntpTimeMs(), aProps.renderTimeMs()));
static uint32_t frame_num = 0;
LOGFRAME(("frame %d (%dx%d); timeStamp %u, ntpTimeMs %" PRIu64 ", renderTimeMs %" PRIu64,
frame_num++, mWidth, mHeight,
aProps.timeStamp(), aProps.ntpTimeMs(), aProps.renderTimeMs()));
#endif
// implicitly releases last image
mImages[i] = image.forget();
}
// implicitly releases last image
mImage = image.forget();
// We'll push the frame into the MSG on the next NotifyPull. This will avoid
// swamping the MSG with frames should it be taking longer than normal to run
@ -589,9 +464,7 @@ bool
MediaEngineRemoteVideoSource::ChooseCapability(
const NormalizedConstraints &aConstraints,
const MediaEnginePrefs &aPrefs,
const nsString& aDeviceId,
webrtc::CaptureCapability& aCapability,
const DistanceCalculation aCalculate)
const nsString& aDeviceId)
{
AssertIsOnOwningThread();
@ -604,16 +477,15 @@ MediaEngineRemoteVideoSource::ChooseCapability(
// time (and may in fact change over time), so as a hack, we push ideal
// and max constraints down to desktop_capture_impl.cc and finish the
// algorithm there.
aCapability.width =
(c.mWidth.mIdeal.valueOr(0) & 0xffff) << 16 | (c.mWidth.mMax & 0xffff);
aCapability.height =
(c.mHeight.mIdeal.valueOr(0) & 0xffff) << 16 | (c.mHeight.mMax & 0xffff);
aCapability.maxFPS =
c.mFrameRate.Clamp(c.mFrameRate.mIdeal.valueOr(aPrefs.mFPS));
mCapability.width = (c.mWidth.mIdeal.valueOr(0) & 0xffff) << 16 |
(c.mWidth.mMax & 0xffff);
mCapability.height = (c.mHeight.mIdeal.valueOr(0) & 0xffff) << 16 |
(c.mHeight.mMax & 0xffff);
mCapability.maxFPS = c.mFrameRate.Clamp(c.mFrameRate.mIdeal.valueOr(aPrefs.mFPS));
return true;
}
default:
return MediaEngineCameraVideoSource::ChooseCapability(aConstraints, aPrefs, aDeviceId, aCapability, aCalculate);
return MediaEngineCameraVideoSource::ChooseCapability(aConstraints, aPrefs, aDeviceId);
}
}

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

@ -84,12 +84,9 @@ public:
return mMediaSource;
}
bool ChooseCapability(
const NormalizedConstraints &aConstraints,
const MediaEnginePrefs &aPrefs,
const nsString& aDeviceId,
webrtc::CaptureCapability& aCapability,
const DistanceCalculation aCalculate) override;
bool ChooseCapability(const NormalizedConstraints &aConstraints,
const MediaEnginePrefs &aPrefs,
const nsString& aDeviceId) override;
void Refresh(int aIndex);
@ -110,7 +107,6 @@ private:
nsresult
UpdateSingleSource(const AllocationHandle* aHandle,
const NormalizedConstraints& aNetConstraints,
const NormalizedConstraints& aNewConstraint,
const MediaEnginePrefs& aPrefs,
const nsString& aDeviceId,
const char** aOutBadConstraint) override;

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

@ -566,7 +566,6 @@ private:
nsresult
UpdateSingleSource(const AllocationHandle* aHandle,
const NormalizedConstraints& aNetConstraints,
const NormalizedConstraints& aNewConstraint,
const MediaEnginePrefs& aPrefs,
const nsString& aDeviceId,
const char** aOutBadConstraint) override;

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

@ -279,7 +279,6 @@ nsresult
MediaEngineWebRTCMicrophoneSource::UpdateSingleSource(
const AllocationHandle* aHandle,
const NormalizedConstraints& aNetConstraints,
const NormalizedConstraints& aNewConstraint, /* Ignored */
const MediaEnginePrefs& aPrefs,
const nsString& aDeviceId,
const char** aOutBadConstraint)

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

@ -417,28 +417,6 @@ MediaConstraintsHelper::FitnessDistance(ValueType aN,
std::max(std::abs(aN), std::abs(aRange.mIdeal.value()))));
}
template<class ValueType, class NormalizedRange>
/* static */ uint32_t
MediaConstraintsHelper::FeasibilityDistance(ValueType aN,
const NormalizedRange& aRange)
{
if (aRange.mMin > aN) {
return UINT32_MAX;
}
// We prefer larger resolution because now we support downscaling
if (aN == aRange.mIdeal.valueOr(aN)) {
return 0;
}
if (aN > aRange.mIdeal.value()) {
return uint32_t(ValueType((std::abs(aN - aRange.mIdeal.value()) * 1000) /
std::max(std::abs(aN), std::abs(aRange.mIdeal.value()))));
}
return 10000 + uint32_t(ValueType((std::abs(aN - aRange.mIdeal.value()) * 1000) /
std::max(std::abs(aN), std::abs(aRange.mIdeal.value()))));
}
// Fitness distance returned as integer math * 1000. Infinity = UINT32_MAX
/* static */ uint32_t

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

@ -85,19 +85,12 @@ public:
return mMax >= aOther.mMin && mMin <= aOther.mMax;
}
void Intersect(const Range& aOther) {
MOZ_ASSERT(Intersects(aOther));
mMin = std::max(mMin, aOther.mMin);
if (Intersects(aOther)) {
mMax = std::min(mMax, aOther.mMax);
} else {
// If there is no intersection, we will down-scale or drop frame
mMax = std::max(mMax, aOther.mMax);
}
mMax = std::min(mMax, aOther.mMax);
}
bool Merge(const Range& aOther) {
if (strcmp(mName, "width") != 0 &&
strcmp(mName, "height") != 0 &&
strcmp(mName, "frameRate") != 0 &&
!Intersects(aOther)) {
if (!Intersects(aOther)) {
return false;
}
Intersect(aOther);
@ -304,8 +297,6 @@ class MediaConstraintsHelper
protected:
template<class ValueType, class NormalizedRange>
static uint32_t FitnessDistance(ValueType aN, const NormalizedRange& aRange);
template<class ValueType, class NormalizedRange>
static uint32_t FeasibilityDistance(ValueType aN, const NormalizedRange& aRange);
static uint32_t FitnessDistance(nsString aN,
const NormalizedConstraintSet::StringRange& aConstraint);

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

@ -1207,12 +1207,22 @@ ParseTypeAttribute(const nsAString& aType, ValidJSVersion* aVersion)
nsAutoString versionName;
rv = parser.GetParameter("version", versionName);
if (NS_SUCCEEDED(rv)) {
*aVersion = ParseJavascriptVersion(versionName);
} else if (rv != NS_ERROR_INVALID_ARG) {
if (rv == NS_ERROR_INVALID_ARG) {
Telemetry::Accumulate(Telemetry::SCRIPT_LOADED_WITH_VERSION, false);
// Argument not set.
return true;
}
if (NS_FAILED(rv)) {
return false;
}
*aVersion = ParseJavascriptVersion(versionName);
if (*aVersion == ValidJSVersion::Valid) {
Telemetry::Accumulate(Telemetry::SCRIPT_LOADED_WITH_VERSION, true);
return true;
}
return true;
}

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

@ -419,11 +419,17 @@ U2F::Register(const nsAString& aAppId,
// Always blank for U2F
nsTArray<WebAuthnExtension> extensions;
WebAuthnTransactionInfo info(rpIdHash,
clientDataHash,
adjustedTimeoutMillis,
excludeList,
extensions);
// Default values for U2F.
WebAuthnAuthenticatorSelection authSelection(false /* requireResidentKey */,
false /* requireUserVerification */,
false /* requirePlatformAttachment */);
WebAuthnMakeCredentialInfo info(rpIdHash,
clientDataHash,
adjustedTimeoutMillis,
excludeList,
extensions,
authSelection);
MOZ_ASSERT(mTransaction.isNothing());
mTransaction = Some(U2FTransaction(clientData));
@ -548,11 +554,11 @@ U2F::Sign(const nsAString& aAppId,
// Always blank for U2F
nsTArray<WebAuthnExtension> extensions;
WebAuthnTransactionInfo info(rpIdHash,
clientDataHash,
adjustedTimeoutMillis,
permittedList,
extensions);
WebAuthnGetAssertionInfo info(rpIdHash,
clientDataHash,
adjustedTimeoutMillis,
permittedList,
extensions);
MOZ_ASSERT(mTransaction.isNothing());
mTransaction = Some(U2FTransaction(clientData));

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

@ -13,7 +13,7 @@ namespace dom {
mozilla::ipc::IPCResult
U2FTransactionParent::RecvRequestRegister(const uint64_t& aTransactionId,
const WebAuthnTransactionInfo& aTransactionInfo)
const WebAuthnMakeCredentialInfo& aTransactionInfo)
{
AssertIsOnBackgroundThread();
U2FTokenManager* mgr = U2FTokenManager::Get();
@ -23,7 +23,7 @@ U2FTransactionParent::RecvRequestRegister(const uint64_t& aTransactionId,
mozilla::ipc::IPCResult
U2FTransactionParent::RecvRequestSign(const uint64_t& aTransactionId,
const WebAuthnTransactionInfo& aTransactionInfo)
const WebAuthnGetAssertionInfo& aTransactionInfo)
{
AssertIsOnBackgroundThread();
U2FTokenManager* mgr = U2FTokenManager::Get();

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

@ -26,11 +26,11 @@ public:
virtual mozilla::ipc::IPCResult
RecvRequestRegister(const uint64_t& aTransactionId,
const WebAuthnTransactionInfo& aTransactionInfo) override;
const WebAuthnMakeCredentialInfo& aTransactionInfo) override;
virtual mozilla::ipc::IPCResult
RecvRequestSign(const uint64_t& aTransactionId,
const WebAuthnTransactionInfo& aTransactionInfo) override;
const WebAuthnGetAssertionInfo& aTransactionInfo) override;
virtual mozilla::ipc::IPCResult
RecvRequestCancel(const uint64_t& aTransactionId) override;

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

@ -19,6 +19,12 @@ include protocol PBackground;
namespace mozilla {
namespace dom {
struct WebAuthnAuthenticatorSelection {
bool requireResidentKey;
bool requireUserVerification;
bool requirePlatformAttachment;
};
struct WebAuthnScopedCredentialDescriptor {
uint8_t[] id;
};
@ -27,11 +33,20 @@ struct WebAuthnExtension {
/* TODO Fill in with predefined extensions */
};
struct WebAuthnTransactionInfo {
struct WebAuthnMakeCredentialInfo {
uint8_t[] RpIdHash;
uint8_t[] ClientDataHash;
uint32_t TimeoutMS;
WebAuthnScopedCredentialDescriptor[] Descriptors;
WebAuthnScopedCredentialDescriptor[] ExcludeList;
WebAuthnExtension[] Extensions;
WebAuthnAuthenticatorSelection AuthenticatorSelection;
};
struct WebAuthnGetAssertionInfo {
uint8_t[] RpIdHash;
uint8_t[] ClientDataHash;
uint32_t TimeoutMS;
WebAuthnScopedCredentialDescriptor[] AllowList;
WebAuthnExtension[] Extensions;
};
@ -39,8 +54,8 @@ async protocol PWebAuthnTransaction {
manager PBackground;
parent:
async __delete__();
async RequestRegister(uint64_t aTransactionId, WebAuthnTransactionInfo aTransactionInfo);
async RequestSign(uint64_t aTransactionId, WebAuthnTransactionInfo aTransactionInfo);
async RequestRegister(uint64_t aTransactionId, WebAuthnMakeCredentialInfo aTransactionInfo);
async RequestSign(uint64_t aTransactionId, WebAuthnGetAssertionInfo aTransactionInfo);
async RequestCancel(uint64_t aTransactionId);
child:
async ConfirmRegister(uint64_t aTransactionId, uint8_t[] RegBuffer);

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

@ -101,14 +101,29 @@ U2FHIDTokenManager::~U2FHIDTokenManager()
//
RefPtr<U2FRegisterPromise>
U2FHIDTokenManager::Register(const nsTArray<WebAuthnScopedCredentialDescriptor>& aDescriptors,
const WebAuthnAuthenticatorSelection &aAuthenticatorSelection,
const nsTArray<uint8_t>& aApplication,
const nsTArray<uint8_t>& aChallenge,
uint32_t aTimeoutMS)
{
MOZ_ASSERT(NS_GetCurrentThread() == gPBackgroundThread);
uint64_t registerFlags = 0;
// Set flags for credential creation.
if (aAuthenticatorSelection.requireResidentKey()) {
registerFlags |= U2F_FLAG_REQUIRE_RESIDENT_KEY;
}
if (aAuthenticatorSelection.requireUserVerification()) {
registerFlags |= U2F_FLAG_REQUIRE_USER_VERIFICATION;
}
if (aAuthenticatorSelection.requirePlatformAttachment()) {
registerFlags |= U2F_FLAG_REQUIRE_PLATFORM_ATTACHMENT;
}
ClearPromises();
mTransactionId = rust_u2f_mgr_register(mU2FManager,
registerFlags,
(uint64_t)aTimeoutMS,
u2f_register_callback,
aChallenge.Elements(),

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

@ -92,6 +92,7 @@ public:
virtual RefPtr<U2FRegisterPromise>
Register(const nsTArray<WebAuthnScopedCredentialDescriptor>& aDescriptors,
const WebAuthnAuthenticatorSelection &aAuthenticatorSelection,
const nsTArray<uint8_t>& aApplication,
const nsTArray<uint8_t>& aChallenge,
uint32_t aTimeoutMS) override;

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

@ -626,6 +626,7 @@ U2FSoftTokenManager::IsRegistered(const nsTArray<uint8_t>& aKeyHandle,
//
RefPtr<U2FRegisterPromise>
U2FSoftTokenManager::Register(const nsTArray<WebAuthnScopedCredentialDescriptor>& aDescriptors,
const WebAuthnAuthenticatorSelection &aAuthenticatorSelection,
const nsTArray<uint8_t>& aApplication,
const nsTArray<uint8_t>& aChallenge,
uint32_t aTimeoutMS)
@ -642,6 +643,14 @@ U2FSoftTokenManager::Register(const nsTArray<WebAuthnScopedCredentialDescriptor>
}
}
// The U2F softtoken neither supports resident keys or
// user verification, nor is it a platform authenticator.
if (aAuthenticatorSelection.requireResidentKey() ||
aAuthenticatorSelection.requireUserVerification() ||
aAuthenticatorSelection.requirePlatformAttachment()) {
return U2FRegisterPromise::CreateAndReject(NS_ERROR_DOM_NOT_ALLOWED_ERR, __func__);
}
// Optional exclusion list.
for (auto desc: aDescriptors) {
bool isRegistered = false;

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

@ -27,6 +27,7 @@ public:
virtual RefPtr<U2FRegisterPromise>
Register(const nsTArray<WebAuthnScopedCredentialDescriptor>& aDescriptors,
const WebAuthnAuthenticatorSelection &aAuthenticatorSelection,
const nsTArray<uint8_t>& aApplication,
const nsTArray<uint8_t>& aChallenge,
uint32_t aTimeoutMS) override;

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

@ -220,7 +220,7 @@ U2FTokenManager::GetTokenManagerImpl()
void
U2FTokenManager::Register(PWebAuthnTransactionParent* aTransactionParent,
const uint64_t& aTransactionId,
const WebAuthnTransactionInfo& aTransactionInfo)
const WebAuthnMakeCredentialInfo& aTransactionInfo)
{
MOZ_LOG(gU2FTokenManagerLog, LogLevel::Debug, ("U2FAuthRegister"));
@ -245,7 +245,8 @@ U2FTokenManager::Register(PWebAuthnTransactionParent* aTransactionParent,
uint64_t tid = mLastTransactionId = aTransactionId;
mozilla::TimeStamp startTime = mozilla::TimeStamp::Now();
mTokenManagerImpl->Register(aTransactionInfo.Descriptors(),
mTokenManagerImpl->Register(aTransactionInfo.ExcludeList(),
aTransactionInfo.AuthenticatorSelection(),
aTransactionInfo.RpIdHash(),
aTransactionInfo.ClientDataHash(),
aTransactionInfo.TimeoutMS())
@ -297,7 +298,7 @@ U2FTokenManager::MaybeAbortRegister(const uint64_t& aTransactionId,
void
U2FTokenManager::Sign(PWebAuthnTransactionParent* aTransactionParent,
const uint64_t& aTransactionId,
const WebAuthnTransactionInfo& aTransactionInfo)
const WebAuthnGetAssertionInfo& aTransactionInfo)
{
MOZ_LOG(gU2FTokenManagerLog, LogLevel::Debug, ("U2FAuthSign"));
@ -318,7 +319,7 @@ U2FTokenManager::Sign(PWebAuthnTransactionParent* aTransactionParent,
uint64_t tid = mLastTransactionId = aTransactionId;
mozilla::TimeStamp startTime = mozilla::TimeStamp::Now();
mTokenManagerImpl->Sign(aTransactionInfo.Descriptors(),
mTokenManagerImpl->Sign(aTransactionInfo.AllowList(),
aTransactionInfo.RpIdHash(),
aTransactionInfo.ClientDataHash(),
aTransactionInfo.TimeoutMS())

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

@ -32,10 +32,10 @@ public:
static U2FTokenManager* Get();
void Register(PWebAuthnTransactionParent* aTransactionParent,
const uint64_t& aTransactionId,
const WebAuthnTransactionInfo& aTransactionInfo);
const WebAuthnMakeCredentialInfo& aTransactionInfo);
void Sign(PWebAuthnTransactionParent* aTransactionParent,
const uint64_t& aTransactionId,
const WebAuthnTransactionInfo& aTransactionInfo);
const WebAuthnGetAssertionInfo& aTransactionInfo);
void Cancel(PWebAuthnTransactionParent* aTransactionParent,
const uint64_t& aTransactionId);
void MaybeClearTransaction(PWebAuthnTransactionParent* aParent);

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

@ -64,6 +64,7 @@ public:
virtual RefPtr<U2FRegisterPromise>
Register(const nsTArray<WebAuthnScopedCredentialDescriptor>& aDescriptors,
const WebAuthnAuthenticatorSelection &aAuthenticatorSelection,
const nsTArray<uint8_t>& aApplication,
const nsTArray<uint8_t>& aChallenge,
uint32_t aTimeoutMS) = 0;

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

@ -475,11 +475,28 @@ WebAuthnManager::MakeCredential(nsPIDOMWindowInner* aParent,
// TODO: Add extension list building
nsTArray<WebAuthnExtension> extensions;
WebAuthnTransactionInfo info(rpIdHash,
clientDataHash,
adjustedTimeout,
excludeList,
extensions);
const auto& selection = aOptions.mAuthenticatorSelection;
const auto& attachment = selection.mAuthenticatorAttachment;
// Does the RP require attachment == "platform"?
bool requirePlatformAttachment =
attachment.WasPassed() && attachment.Value() == AuthenticatorAttachment::Platform;
// Does the RP require user verification?
bool requireUserVerification =
selection.mUserVerification == UserVerificationRequirement::Required;
// Create and forward authenticator selection criteria.
WebAuthnAuthenticatorSelection authSelection(selection.mRequireResidentKey,
requireUserVerification,
requirePlatformAttachment);
WebAuthnMakeCredentialInfo info(rpIdHash,
clientDataHash,
adjustedTimeout,
excludeList,
extensions,
authSelection);
ListenForVisibilityEvents(aParent, this);
@ -492,11 +509,11 @@ WebAuthnManager::MakeCredential(nsPIDOMWindowInner* aParent,
MOZ_ASSERT(mTransaction.isNothing());
mTransaction = Some(WebAuthnTransaction(aParent,
promise,
Move(info),
Move(clientDataJSON),
rpIdHash,
clientDataJSON,
signal));
mChild->SendRequestRegister(mTransaction.ref().mId, mTransaction.ref().mInfo);
mChild->SendRequestRegister(mTransaction.ref().mId, info);
return promise.forget();
}
@ -638,11 +655,11 @@ WebAuthnManager::GetAssertion(nsPIDOMWindowInner* aParent,
// result of this processing clientExtensions.
nsTArray<WebAuthnExtension> extensions;
WebAuthnTransactionInfo info(rpIdHash,
clientDataHash,
adjustedTimeout,
allowList,
extensions);
WebAuthnGetAssertionInfo info(rpIdHash,
clientDataHash,
adjustedTimeout,
allowList,
extensions);
ListenForVisibilityEvents(aParent, this);
@ -655,11 +672,11 @@ WebAuthnManager::GetAssertion(nsPIDOMWindowInner* aParent,
MOZ_ASSERT(mTransaction.isNothing());
mTransaction = Some(WebAuthnTransaction(aParent,
promise,
Move(info),
Move(clientDataJSON),
rpIdHash,
clientDataJSON,
signal));
mChild->SendRequestSign(mTransaction.ref().mId, mTransaction.ref().mInfo);
mChild->SendRequestSign(mTransaction.ref().mId, info);
return promise.forget();
}
@ -743,7 +760,7 @@ WebAuthnManager::FinishMakeCredential(const uint64_t& aTransactionId,
}
CryptoBuffer rpIdHashBuf;
if (!rpIdHashBuf.Assign(mTransaction.ref().mInfo.RpIdHash())) {
if (!rpIdHashBuf.Assign(mTransaction.ref().mRpIdHash)) {
RejectTransaction(NS_ERROR_OUT_OF_MEMORY);
return;
}
@ -840,7 +857,7 @@ WebAuthnManager::FinishGetAssertion(const uint64_t& aTransactionId,
}
CryptoBuffer rpIdHashBuf;
if (!rpIdHashBuf.Assign(mTransaction.ref().mInfo.RpIdHash())) {
if (!rpIdHashBuf.Assign(mTransaction.ref().mRpIdHash)) {
RejectTransaction(NS_ERROR_OUT_OF_MEMORY);
return;
}

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

@ -65,12 +65,12 @@ class WebAuthnTransaction
public:
WebAuthnTransaction(nsPIDOMWindowInner* aParent,
const RefPtr<Promise>& aPromise,
const WebAuthnTransactionInfo&& aInfo,
const nsAutoCString&& aClientData,
const nsTArray<uint8_t>& aRpIdHash,
const nsCString& aClientData,
AbortSignal* aSignal)
: mParent(aParent)
, mPromise(aPromise)
, mInfo(aInfo)
, mRpIdHash(aRpIdHash)
, mClientData(aClientData)
, mSignal(aSignal)
, mId(NextId())
@ -84,9 +84,8 @@ public:
// JS Promise representing the transaction status.
RefPtr<Promise> mPromise;
// Holds the parameters of the current transaction, as we need them both
// before the transaction request is sent, and on successful return.
WebAuthnTransactionInfo mInfo;
// The RP ID hash.
nsTArray<uint8_t> mRpIdHash;
// Client data used to assemble reply objects.
nsCString mClientData;

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

@ -13,7 +13,7 @@ namespace dom {
mozilla::ipc::IPCResult
WebAuthnTransactionParent::RecvRequestRegister(const uint64_t& aTransactionId,
const WebAuthnTransactionInfo& aTransactionInfo)
const WebAuthnMakeCredentialInfo& aTransactionInfo)
{
AssertIsOnBackgroundThread();
U2FTokenManager* mgr = U2FTokenManager::Get();
@ -23,7 +23,7 @@ WebAuthnTransactionParent::RecvRequestRegister(const uint64_t& aTransactionId,
mozilla::ipc::IPCResult
WebAuthnTransactionParent::RecvRequestSign(const uint64_t& aTransactionId,
const WebAuthnTransactionInfo& aTransactionInfo)
const WebAuthnGetAssertionInfo& aTransactionInfo)
{
AssertIsOnBackgroundThread();
U2FTokenManager* mgr = U2FTokenManager::Get();

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

@ -26,11 +26,11 @@ public:
virtual mozilla::ipc::IPCResult
RecvRequestRegister(const uint64_t& aTransactionId,
const WebAuthnTransactionInfo& aTransactionInfo) override;
const WebAuthnMakeCredentialInfo& aTransactionInfo) override;
virtual mozilla::ipc::IPCResult
RecvRequestSign(const uint64_t& aTransactionId,
const WebAuthnTransactionInfo& aTransactionInfo) override;
const WebAuthnGetAssertionInfo& aTransactionInfo) override;
virtual mozilla::ipc::IPCResult
RecvRequestCancel(const uint64_t& aTransactionId) override;

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

@ -7,6 +7,7 @@ skip-if = !e10s
scheme = https
[test_webauthn_abort_signal.html]
[test_webauthn_authenticator_selection.html]
[test_webauthn_loopback.html]
[test_webauthn_no_token.html]
[test_webauthn_make_credential.html]

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

@ -0,0 +1,101 @@
<!DOCTYPE html>
<meta charset=utf-8>
<head>
<title>W3C Web Authentication - Authenticator Selection Criteria</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
<script type="text/javascript" src="u2futil.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<h1>W3C Web Authentication - Authenticator Selection Criteria</h1>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1406462">Mozilla Bug 1406462</a>
<script class="testbody" type="text/javascript">
"use strict";
function arrivingHereIsGood(aResult) {
ok(true, "Good result! Received a: " + aResult);
}
function arrivingHereIsBad(aResult) {
ok(false, "Bad result! Received a: " + aResult);
}
function expectNotAllowedError(aResult) {
ok(aResult.toString().startsWith("NotAllowedError"), "Expecting a NotAllowedError, got " + aResult);
}
add_task(() => {
// Enable the softtoken.
return SpecialPowers.pushPrefEnv({"set": [
["security.webauth.webauthn", true],
["security.webauth.webauthn_enable_softtoken", true],
["security.webauth.webauthn_enable_usbtoken", false],
]});
});
// Start a new MakeCredential() request.
function requestMakeCredential(authenticatorSelection) {
let publicKey = {
rp: {id: document.domain, name: "none", icon: "none"},
user: {id: new Uint8Array(), name: "none", icon: "none", displayName: "none"},
challenge: crypto.getRandomValues(new Uint8Array(16)),
timeout: 5000, // the minimum timeout is actually 15 seconds
pubKeyCredParams: [{type: "public-key", alg: cose_alg_ECDSA_w_SHA256}],
authenticatorSelection,
};
return navigator.credentials.create({publicKey});
}
// Test success cases.
add_task(async () => {
// No selection criteria.
await requestMakeCredential({})
.then(arrivingHereIsGood)
.catch(arrivingHereIsBad);
// Request a cross-platform authenticator.
await requestMakeCredential({authenticatorAttachment: "cross-platform"})
.then(arrivingHereIsGood)
.catch(arrivingHereIsBad);
// Don't require a resident key.
await requestMakeCredential({requireResidentKey: false})
.then(arrivingHereIsGood)
.catch(arrivingHereIsBad);
// Prefer user verification.
await requestMakeCredential({userVerification: "preferred"})
.then(arrivingHereIsGood)
.catch(arrivingHereIsBad);
// Discourage user verification.
await requestMakeCredential({userVerification: "discouraged"})
.then(arrivingHereIsGood)
.catch(arrivingHereIsBad);
});
// Test the failure cases.
add_task(async () => {
// Request a platform authenticator.
await requestMakeCredential({authenticatorAttachment: "platform"})
.then(arrivingHereIsBad)
.catch(expectNotAllowedError);
// Require a resident key.
await requestMakeCredential({requireResidentKey: true})
.then(arrivingHereIsBad)
.catch(expectNotAllowedError);
// Require user verification.
await requestMakeCredential({userVerification: "required"})
.then(arrivingHereIsBad)
.catch(expectNotAllowedError);
});
</script>
</body>
</html>

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

@ -19,6 +19,7 @@ env_logger = "0.4.1"
libc = "^0.2"
boxfnonce = "0.0.3"
runloop = "0.1.0"
bitflags = "1.0"
[dev-dependencies]
rust-crypto = "^0.2"

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

@ -9,7 +9,7 @@ use crypto::digest::Digest;
use crypto::sha2::Sha256;
use std::io;
use std::sync::mpsc::channel;
use u2fhid::U2FManager;
use u2fhid::{RegisterFlags, U2FManager};
extern crate log;
extern crate env_logger;
@ -49,10 +49,12 @@ fn main() {
application.result(&mut app_bytes);
let manager = U2FManager::new().unwrap();
let flags = RegisterFlags::empty();
let (tx, rx) = channel();
manager
.register(
flags,
15_000,
chall_bytes.clone(),
app_bytes.clone(),

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

@ -109,6 +109,7 @@ pub unsafe extern "C" fn rust_u2f_res_free(res: *mut U2FResult) {
#[no_mangle]
pub unsafe extern "C" fn rust_u2f_mgr_register(
mgr: *mut U2FManager,
flags: u64,
timeout: u64,
callback: U2FCallback,
challenge_ptr: *const u8,
@ -126,20 +127,28 @@ pub unsafe extern "C" fn rust_u2f_mgr_register(
return 0;
}
let flags = ::RegisterFlags::from_bits_truncate(flags);
let challenge = from_raw(challenge_ptr, challenge_len);
let application = from_raw(application_ptr, application_len);
let key_handles = (*khs).clone();
let tid = new_tid();
let res = (*mgr).register(timeout, challenge, application, key_handles, move |rv| {
if let Ok(registration) = rv {
let mut result = U2FResult::new();
result.insert(RESBUF_ID_REGISTRATION, registration);
callback(tid, Box::into_raw(Box::new(result)));
} else {
callback(tid, ptr::null_mut());
};
});
let res = (*mgr).register(
flags,
timeout,
challenge,
application,
key_handles,
move |rv| {
if let Ok(registration) = rv {
let mut result = U2FResult::new();
result.insert(RESBUF_ID_REGISTRATION, registration);
callback(tid, Box::into_raw(Box::new(result)));
} else {
callback(tid, ptr::null_mut());
};
},
);
if res.is_ok() { tid } else { 0 }
}

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

@ -34,6 +34,9 @@ extern crate libc;
extern crate boxfnonce;
extern crate runloop;
#[macro_use]
extern crate bitflags;
mod consts;
mod statemachine;
mod u2ftypes;
@ -45,6 +48,15 @@ pub use manager::U2FManager;
mod capi;
pub use capi::*;
// Keep this in sync with the constants in u2fhid-capi.h.
bitflags! {
pub struct RegisterFlags: u64 {
const REQUIRE_RESIDENT_KEY = 1;
const REQUIRE_USER_VERIFICATION = 2;
const REQUIRE_PLATFORM_ATTACHMENT = 4;
}
}
#[cfg(fuzzing)]
pub use u2fprotocol::*;
#[cfg(fuzzing)]

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

@ -11,8 +11,9 @@ use statemachine::StateMachine;
use runloop::RunLoop;
use util::{to_io_err, OnceCallback};
pub enum QueueAction {
enum QueueAction {
Register {
flags: ::RegisterFlags,
timeout: u64,
challenge: Vec<u8>,
application: Vec<u8>,
@ -45,6 +46,7 @@ impl U2FManager {
while alive() {
match rx.recv_timeout(Duration::from_millis(50)) {
Ok(QueueAction::Register {
flags,
timeout,
challenge,
application,
@ -52,7 +54,14 @@ impl U2FManager {
callback,
}) => {
// This must not block, otherwise we can't cancel.
sm.register(timeout, challenge, application, key_handles, callback);
sm.register(
flags,
timeout,
challenge,
application,
key_handles,
callback,
);
}
Ok(QueueAction::Sign {
timeout,
@ -88,6 +97,7 @@ impl U2FManager {
pub fn register<F>(
&self,
flags: ::RegisterFlags,
timeout: u64,
challenge: Vec<u8>,
application: Vec<u8>,
@ -116,6 +126,7 @@ impl U2FManager {
let callback = OnceCallback::new(callback);
let action = QueueAction::Register {
flags,
timeout,
challenge,
application,

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

@ -22,6 +22,7 @@ impl StateMachine {
pub fn register(
&mut self,
flags: ::RegisterFlags,
timeout: u64,
challenge: Vec<u8>,
application: Vec<u8>,
@ -45,6 +46,17 @@ impl StateMachine {
return;
}
// We currently support none of the authenticator selection
// criteria because we can't ask tokens whether they do support
// those features. If flags are set, ignore all tokens for now.
//
// Technically, this is a ConstraintError because we shouldn't talk
// to this authenticator in the first place. But the result is the
// same anyway.
if !flags.is_empty() {
return;
}
// Iterate the exclude list and see if there are any matches.
// Abort the state machine if we found a valid key handle.
if key_handles.iter().any(|key_handle| {

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

@ -15,6 +15,10 @@ const uint8_t U2F_RESBUF_ID_REGISTRATION = 0;
const uint8_t U2F_RESBUF_ID_KEYHANDLE = 1;
const uint8_t U2F_RESBUF_ID_SIGNATURE = 2;
const uint64_t U2F_FLAG_REQUIRE_RESIDENT_KEY = 1;
const uint64_t U2F_FLAG_REQUIRE_USER_VERIFICATION = 2;
const uint64_t U2F_FLAG_REQUIRE_PLATFORM_ATTACHMENT = 4;
// NOTE: Preconditions
// * All rust_u2f_mgr* pointers must refer to pointers which are returned
// by rust_u2f_mgr_new, and must be freed with rust_u2f_mgr_free.
@ -42,6 +46,7 @@ rust_u2f_manager* rust_u2f_mgr_new();
/* unsafe */ void rust_u2f_mgr_free(rust_u2f_manager* mgr);
uint64_t rust_u2f_mgr_register(rust_u2f_manager* mgr,
uint64_t flags,
uint64_t timeout,
rust_u2f_callback,
const uint8_t* challenge_ptr,

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

@ -75,7 +75,7 @@ dictionary PublicKeyCredentialUserEntity : PublicKeyCredentialEntity {
dictionary AuthenticatorSelectionCriteria {
AuthenticatorAttachment authenticatorAttachment;
boolean requireResidentKey = false;
boolean requireUserVerification = false;
UserVerificationRequirement userVerification = "preferred";
};
enum AuthenticatorAttachment {
@ -83,6 +83,12 @@ enum AuthenticatorAttachment {
"cross-platform" // Cross-platform attachment
};
enum UserVerificationRequirement {
"required",
"preferred",
"discouraged"
};
dictionary PublicKeyCredentialRequestOptions {
required BufferSource challenge;
unsigned long timeout;

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

@ -1,6 +1,6 @@
<html><body>
<iframe id="frame" sandbox="allow-scripts allow-popups"></iframe>
<script type="application/javascript;version=1.8">
<script type="application/javascript">
onmessage = function(e) {
parent.postMessage(e.data, '*');
}

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

@ -8,7 +8,7 @@
<body>
<div id="container"></div>
<iframe id="frame"></iframe>
<script type="application/javascript;version=1.8">
<script type="application/javascript">
var urls = [ "https://example.com/tests/dom/websocket/tests/iframe_webSocket_sandbox.html",
"https://example.com/tests/dom/websocket/tests/iframe_webSocket_sandbox.html?nested",
"https://example.com/tests/dom/websocket/tests/iframe_webSocket_sandbox.html?popup" ];

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

@ -113,15 +113,16 @@ ConvolutionFilter::ComputeResizeFilter(ResizeMethod aResizeMethod, int32_t aSrcS
// filter values for each one. Those values will tell us how to blend the
// source pixels to compute the destination pixel.
// This is the pixel in the source directly under the pixel in the dest.
// Note that we base computations on the "center" of the pixels. To see
// why, observe that the destination pixel at coordinates (0, 0) in a 5.0x
// downscale should "cover" the pixels around the pixel with *its center*
// at coordinates (2.5, 2.5) in the source, not those around (0, 0).
// Hence we need to scale coordinates (0.5, 0.5), not (0, 0).
float srcPixel = 0.5f * invScale;
mFilter->reserveAdditional(aDstSize, int32_t(ceil(aDstSize * srcSupport * 2)));
for (int32_t destI = 0; destI < aDstSize; destI++) {
// This is the pixel in the source directly under the pixel in the dest.
// Note that we base computations on the "center" of the pixels. To see
// why, observe that the destination pixel at coordinates (0, 0) in a 5.0x
// downscale should "cover" the pixels around the pixel with *its center*
// at coordinates (2.5, 2.5) in the source, not those around (0, 0).
// Hence we need to scale coordinates (0.5, 0.5), not (0, 0).
float srcPixel = (static_cast<float>(destI) + 0.5f) * invScale;
// Compute the (inclusive) range of source pixels the filter covers.
float srcBegin = std::max(0.0f, floorf(srcPixel - srcSupport));
float srcEnd = std::min(aSrcSize - 1.0f, ceilf(srcPixel + srcSupport));
@ -165,8 +166,6 @@ ConvolutionFilter::ComputeResizeFilter(ResizeMethod aResizeMethod, int32_t aSrcS
fixedFilterValues[filterCount / 2] += leftovers;
mFilter->AddFilter(int32_t(srcBegin), fixedFilterValues.begin(), filterCount);
srcPixel += invScale;
}
return mFilter->maxFilter() > 0 && mFilter->numValues() == aDstSize;

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

@ -50,7 +50,7 @@ parent:
sync Create(IntSize aSize);
async DeleteCompositorAnimations(uint64_t[] aIds);
async SetDisplayList(IntSize aSize, WebRenderParentCommand[] commands, OpDestroy[] toDestroy, uint64_t fwdTransactionId, uint64_t transactionId,
LayoutSize aContentSize, ByteBuffer aDL, BuiltDisplayListDescriptor aDLDesc,
LayoutSize aContentSize, ByteBuf aDL, BuiltDisplayListDescriptor aDLDesc,
WebRenderScrollData aScrollData,
OpUpdateResource[] aResourceUpdates, Shmem[] aSmallShmems, Shmem[] aLargeShmems,
IdNamespace aIdNamespace, TimeStamp txnStartTime, TimeStamp fwdTime);

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

@ -144,7 +144,9 @@ WebRenderBridgeChild::EndTransaction(const wr::LayoutSize& aContentSize,
MOZ_ASSERT(!mDestroyed);
MOZ_ASSERT(mIsInTransaction);
ByteBuffer dlData(Move(aDL.dl));
ByteBuf dlData(aDL.dl.inner.data, aDL.dl.inner.length, aDL.dl.inner.capacity);
aDL.dl.inner.capacity = 0;
aDL.dl.inner.data = nullptr;
TimeStamp fwdTime;
#if defined(ENABLE_FRAME_LATENCY_LOG)

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

@ -561,7 +561,7 @@ WebRenderBridgeParent::RecvSetDisplayList(const gfx::IntSize& aSize,
const uint64_t& aFwdTransactionId,
const uint64_t& aTransactionId,
const wr::LayoutSize& aContentSize,
const wr::ByteBuffer& dl,
ipc::ByteBuf&& dl,
const wr::BuiltDisplayListDescriptor& dlDesc,
const WebRenderScrollData& aScrollData,
nsTArray<OpUpdateResource>&& aResourceUpdates,
@ -609,7 +609,7 @@ WebRenderBridgeParent::RecvSetDisplayList(const gfx::IntSize& aSize,
gfx::Color clearColor(0.f, 0.f, 0.f, 0.f);
mApi->SetDisplayList(clearColor, wr::NewEpoch(wrEpoch), LayerSize(aSize.width, aSize.height),
mPipelineId, aContentSize,
dlDesc, dl.mData, dl.mLength,
dlDesc, dl.mData, dl.mLen,
resources);
ScheduleComposition();

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

@ -82,7 +82,7 @@ public:
const uint64_t& aFwdTransactionId,
const uint64_t& aTransactionId,
const wr::LayoutSize& aContentSize,
const wr::ByteBuffer& dl,
ipc::ByteBuf&& dl,
const wr::BuiltDisplayListDescriptor& dlDesc,
const WebRenderScrollData& aScrollData,
nsTArray<OpUpdateResource>&& aResourceUpdates,

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

@ -209,6 +209,7 @@ void TestSchedulerChain(uint32_t aNumThreads, uint32_t aNumCmdBuffers)
} // namespace test_scheduler
#if !defined(MOZ_CODE_COVERAGE) || !defined(XP_WIN)
TEST(Moz2D, JobScheduler_Shutdown) {
srand(time(nullptr));
for (uint32_t threads = 1; threads < 16; ++threads) {
@ -218,6 +219,7 @@ TEST(Moz2D, JobScheduler_Shutdown) {
}
}
}
#endif
TEST(Moz2D, JobScheduler_Join) {
srand(time(nullptr));

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

@ -0,0 +1,20 @@
<html reftest-zoom="1.6">
<head>
<style>
#xx {
background-image: url("1421191-1.png");
background-position: -61px -797px;
background-position-x: -61px;
background-position-y: -797px;
background-repeat: no-repeat;
background-size: 82px auto;
display: block;
height: 24px;
width: 22px;
}
</style>
</head>
<body>
<span id="xx"></span>
</body>
</html>

Двоичные данные
image/test/reftest/downscaling/1421191-1.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 90 KiB

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

@ -205,3 +205,6 @@ fuzzy(18,128) == downscale-32px.html?-png-in.ico downscale-32px-ref.html
== huge-1.html?100x32768.jpg,100,32768 huge-1.html?100x100.jpg,100,32768
== huge-1.html?32768x100.jpg,100,100 huge-1.html?100x100.jpg,100,100
== huge-1.html?32768x100.jpg,32768,100 huge-1.html?100x100.jpg,32768,100
# Only need to run this with downscaling on
!= 1421191-1.html about:blank

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

@ -627,6 +627,16 @@ bool Pickle::WriteUnsignedChar(unsigned char value) {
return WriteBytes(&value, sizeof(value));
}
bool Pickle::WriteBytesZeroCopy(void* data, uint32_t data_len, uint32_t capacity) {
BeginWrite(data_len, sizeof(memberAlignmentType));
buffers_.WriteBytesZeroCopy(reinterpret_cast<char*>(data), data_len, capacity);
EndWrite(data_len);
return true;
}
bool Pickle::WriteBytes(const void* data, uint32_t data_len, uint32_t alignment) {
DCHECK(alignment == 4 || alignment == 8);
DCHECK(intptr_t(header_) % alignment == 0);

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

@ -162,6 +162,8 @@ class Pickle {
bool WriteData(const char* data, uint32_t length);
bool WriteBytes(const void* data, uint32_t data_len,
uint32_t alignment = sizeof(memberAlignmentType));
// Takes ownership of data
bool WriteBytesZeroCopy(void* data, uint32_t data_len, uint32_t capacity);
bool WriteSentinel(uint32_t sentinel)
#ifdef MOZ_PICKLE_SENTINEL_CHECKING

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

@ -111,6 +111,11 @@ static inline void WriteParam(Message* m, const P& p) {
ParamTraits<P>::Write(m, p);
}
template <class P>
static inline void WriteParam(Message* m, P& p) {
ParamTraits<P>::Write(m, p);
}
template <class P>
static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m, PickleIterator* iter,
P* p) {

116
ipc/glue/ByteBuf.h Normal file
Просмотреть файл

@ -0,0 +1,116 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/. */
/* A type that can be sent without needing to make a copy during
* serialization. In addition the receiver can take ownership of the
* data to avoid having to make an additional copy. */
#ifndef mozilla_ipc_ByteBuf_h
#define mozilla_ipc_ByteBuf_h
#include "ipc/IPCMessageUtils.h"
namespace mozilla {
namespace ipc {
class ByteBuf final
{
friend struct IPC::ParamTraits<mozilla::ipc::ByteBuf>;
public:
bool
Allocate(size_t aLength)
{
MOZ_ASSERT(mData == nullptr);
mData = (uint8_t*)malloc(aLength);
if (!mData) {
return false;
}
mLen = aLength;
mCapacity = aLength;
return true;
}
ByteBuf()
: mData(nullptr)
, mLen(0)
, mCapacity(0)
{}
ByteBuf(uint8_t *aData, size_t aLen, size_t aCapacity)
: mData(aData)
, mLen(aLen)
, mCapacity(aCapacity)
{}
ByteBuf(const ByteBuf& aFrom) = delete;
ByteBuf(ByteBuf&& aFrom)
: mData(aFrom.mData)
, mLen(aFrom.mLen)
, mCapacity(aFrom.mCapacity)
{
aFrom.mData = nullptr;
aFrom.mLen = 0;
aFrom.mCapacity = 0;
}
~ByteBuf()
{
free(mData);
}
uint8_t* mData;
size_t mLen;
size_t mCapacity;
};
} // namespace ipc
} // namespace mozilla
namespace IPC {
template<>
struct ParamTraits<mozilla::ipc::ByteBuf>
{
typedef mozilla::ipc::ByteBuf paramType;
// this is where we transfer the memory from the ByteBuf to IPDL, avoiding a copy
static void Write(Message* aMsg, paramType& aParam)
{
WriteParam(aMsg, aParam.mLen);
// hand over ownership of the buffer to the Message
aMsg->WriteBytesZeroCopy(aParam.mData, aParam.mLen, aParam.mCapacity);
aParam.mData = nullptr;
aParam.mCapacity = 0;
aParam.mLen = 0;
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
// We make a copy from the BufferList so that we get a contigous result.
// For users the can handle a non-contiguous result using ExtractBuffers
// is an option, alternatively if the users don't need to take ownership of
// the data they can use the removed FlattenBytes (bug 1297981)
size_t length;
return ReadParam(aMsg, aIter, &length)
&& aResult->Allocate(length)
&& aMsg->ReadBytesInto(aIter, aResult->mData, length);
}
static void Log(const paramType& aParam, std::wstring* aLog)
{
aLog->append(L"(byte buf)");
}
};
} // namespace IPC
#endif // ifndef mozilla_ipc_Shmem_h

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

@ -18,6 +18,7 @@
#include "IPCMessageStart.h"
#include "mozilla/AlreadyAddRefed.h"
#include "mozilla/Attributes.h"
#include "mozilla/ipc/ByteBuf.h"
#include "mozilla/ipc/FileDescriptor.h"
#include "mozilla/ipc/Shmem.h"
#include "mozilla/ipc/Transport.h"

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

@ -15,6 +15,7 @@ EXPORTS.mozilla.ipc += [
'BackgroundParent.h',
'BackgroundUtils.h',
'BrowserProcessSubThread.h',
'ByteBuf.h',
'CrashReporterClient.h',
'CrashReporterHost.h',
'CrashReporterMetadataShmem.h',

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

@ -39,6 +39,7 @@ Types = (
'nsDependentSubstring',
'nsDependentCSubstring',
'mozilla::ipc::Shmem',
'mozilla::ipc::ByteBuf',
'mozilla::ipc::FileDescriptor'
)

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

@ -560,6 +560,9 @@ class _ConvertToCxxType(TypeVisitor):
def visitShmemType(self, s):
return Type(self.typename(s))
def visitByteBufType(self, s):
return Type(self.typename(s))
def visitFDType(self, s):
return Type(self.typename(s))
@ -586,6 +589,9 @@ def _cxxConstRefType(ipdltype, side):
if ipdltype.isIPDL() and ipdltype.isShmem():
t.ref = 1
return t
if ipdltype.isIPDL() and ipdltype.isByteBuf():
t.ref = 1
return t
t.const = 1
t.ref = 1
return t
@ -593,6 +599,7 @@ def _cxxConstRefType(ipdltype, side):
def _cxxTypeNeedsMove(ipdltype):
return ipdltype.isIPDL() and (ipdltype.isArray() or
ipdltype.isShmem() or
ipdltype.isByteBuf() or
ipdltype.isEndpoint())
def _cxxMoveRefType(ipdltype, side):
@ -768,6 +775,8 @@ class _StructField(_CompoundTypeComponent):
refexpr = self.refExpr(thisexpr)
if 'Shmem' == self.ipdltype.name():
refexpr = ExprCast(refexpr, Type('Shmem', ref=1), const=1)
if 'ByteBuf' == self.ipdltype.name():
refexpr = ExprCast(refexpr, Type('ByteBuf', ref=1), const=1)
if 'FileDescriptor' == self.ipdltype.name():
refexpr = ExprCast(refexpr, Type('FileDescriptor', ref=1), const=1)
return refexpr
@ -931,6 +940,8 @@ IPDL union type."""
def getConstValue(self):
v = ExprDeref(self.callGetConstPtr())
# sigh
if 'ByteBuf' == self.ipdltype.name():
v = ExprCast(v, Type('ByteBuf', ref=1), const=1)
if 'Shmem' == self.ipdltype.name():
v = ExprCast(v, Type('Shmem', ref=1), const=1)
if 'FileDescriptor' == self.ipdltype.name():
@ -1870,6 +1881,11 @@ stmt. Some types generate both kinds.'''
self.visited.add(s)
self.maybeTypedef('mozilla::ipc::Shmem', 'Shmem')
def visitByteBufType(self, s):
if s in self.visited: return
self.visited.add(s)
self.maybeTypedef('mozilla::ipc::ByteBuf', 'ByteBuf')
def visitFDType(self, s):
if s in self.visited: return
self.visited.add(s)
@ -3384,6 +3400,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
class findSpecialTypes(TypeVisitor):
def visitActorType(self, a): specialtypes.add(a)
def visitShmemType(self, s): specialtypes.add(s)
def visitByteBufType(self, s): specialtypes.add(s)
def visitFDType(self, s): specialtypes.add(s)
def visitStructType(self, s):
specialtypes.add(s)
@ -3408,12 +3425,13 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
ret.ipdltype.accept(findSpecialTypes())
for t in specialtypes:
if t.isActor(): self.implementActorPickling(t)
elif t.isArray(): self.implementSpecialArrayPickling(t)
elif t.isShmem(): self.implementShmemPickling(t)
elif t.isFD(): self.implementFDPickling(t)
elif t.isStruct(): self.implementStructPickling(t)
elif t.isUnion(): self.implementUnionPickling(t)
if t.isActor(): self.implementActorPickling(t)
elif t.isArray(): self.implementSpecialArrayPickling(t)
elif t.isShmem(): self.implementShmemPickling(t)
elif t.isByteBuf(): self.implementByteBufPickling(t)
elif t.isFD(): self.implementFDPickling(t)
elif t.isStruct(): self.implementStructPickling(t)
elif t.isUnion(): self.implementUnionPickling(t)
else:
assert 0 and 'unknown special type'
@ -3434,6 +3452,19 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
self.cls.addstmts([ write, Whitespace.NL, read, Whitespace.NL ])
def implementByteBufPickling(self, bytebuftype):
var = self.var
msgvar = self.msgvar
itervar = self.itervar
intype = _cxxRefType(bytebuftype, self.side)
write = MethodDefn(self.writeMethodDecl(intype, var))
write.addstmt(StmtExpr(ExprCall(ExprVar('IPC::WriteParam'),
args=[ msgvar, var ])))
self.cls.addstmts([ write, Whitespace.NL ])
# the rest of generic pickling will work fine for us
def implementActorPickling(self, actortype):
# Note that we pickle based on *protocol* type and *not* actor
# type. The actor type includes a |nullable| qualifier, but

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

@ -67,6 +67,9 @@ class TypeVisitor:
def visitShmemType(self, s, *args):
pass
def visitByteBufType(self, s, *args):
pass
def visitShmemChmodType(self, c, *args):
c.shmem.accept(self)
@ -147,6 +150,7 @@ class IPDLType(Type):
def isAtom(self): return True
def isCompound(self): return False
def isShmem(self): return False
def isByteBuf(self): return False
def isFD(self): return False
def isEndpoint(self): return False
@ -368,6 +372,16 @@ class ShmemType(IPDLType):
def fullname(self):
return str(self.qname)
class ByteBufType(IPDLType):
def __init__(self, qname):
self.qname = qname
def isByteBuf(self): return True
def name(self):
return self.qname.baseid
def fullname(self):
return str(self.qname)
class FDType(IPDLType):
def __init__(self, qname):
self.qname = qname
@ -725,6 +739,8 @@ class GatherDecls(TcheckVisitor):
fullname = None
if fullname == 'mozilla::ipc::Shmem':
ipdltype = ShmemType(using.type.spec)
elif fullname == 'mozilla::ipc::ByteBuf':
ipdltype = ByteBufType(using.type.spec)
elif fullname == 'mozilla::ipc::FileDescriptor':
ipdltype = FDType(using.type.spec)
else:

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

@ -7434,11 +7434,9 @@ BytecodeEmitter::emitForIn(ParseNode* forInLoop, EmitterScope* headLexicalEmitte
if (!emitTreeInBranch(expr)) // EXPR
return false;
// Convert the value to the appropriate sort of iterator object for the
// loop variant (for-in, for-each-in, or destructuring for-in).
unsigned iflags = forInLoop->pn_iflags;
MOZ_ASSERT(0 == (iflags & ~JSITER_ENUMERATE));
if (!emit2(JSOP_ITER, AssertedCast<uint8_t>(iflags))) // ITER
MOZ_ASSERT(forInLoop->pn_iflags == 0);
if (!emit1(JSOP_ITER)) // ITER
return false;
// For-in loops have both the iterator and the value on the stack. Push
@ -7491,10 +7489,8 @@ BytecodeEmitter::emitForIn(ParseNode* forInLoop, EmitterScope* headLexicalEmitte
#endif
MOZ_ASSERT(loopDepth >= 2);
if (iflags == JSITER_ENUMERATE) {
if (!emit1(JSOP_ITERNEXT)) // ITER ITERVAL
return false;
}
if (!emit1(JSOP_ITERNEXT)) // ITER ITERVAL
return false;
if (!emitInitializeForInOrOfTarget(forInHead)) // ITER ITERVAL
return false;

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

@ -6306,12 +6306,10 @@ Parser<ParseHandler, CharT>::forStatement(YieldHandling yieldHandling)
Node target = startNode;
// Parse the rest of the for-in/of head.
if (headKind == PNK_FORIN) {
if (headKind == PNK_FORIN)
stmt.refineForKind(StatementKind::ForInLoop);
iflags |= JSITER_ENUMERATE;
} else {
else
stmt.refineForKind(StatementKind::ForOfLoop);
}
// Parser::declaration consumed everything up to the closing ')'. That
// token follows an {Assignment,}Expression and so must be interpreted

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

@ -237,15 +237,14 @@ AtomMarkingRuntime::atomIsMarked(Zone* zone, TenuredCell* thing)
if (!thing)
return true;
JS::TraceKind kind = thing->getTraceKind();
if (kind == JS::TraceKind::String) {
JSString* str = static_cast<JSString*>(thing);
if (str->isAtom())
return atomIsMarked(zone, &str->asAtom());
return true;
if (thing->is<JSString>()) {
JSString* str = thing->as<JSString>();
return str->isAtom() ? atomIsMarked(zone, &str->asAtom()) : true;
}
if (kind == JS::TraceKind::Symbol)
return atomIsMarked(zone, static_cast<JS::Symbol*>(thing));
if (thing->is<JS::Symbol>())
return atomIsMarked(zone, thing->as<JS::Symbol>());
return true;
}

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

@ -138,6 +138,23 @@ class TenuredCell : public Cell
return JS::shadow::Zone::asShadowZone(zoneFromAnyThread());
}
template <class T>
inline bool is() const {
return getTraceKind() == JS::MapTypeToTraceKind<T>::kind;
}
template<class T>
inline T* as() {
MOZ_ASSERT(is<T>());
return static_cast<T*>(this);
}
template <class T>
inline const T* as() const {
MOZ_ASSERT(is<T>());
return static_cast<const T*>(this);
}
static MOZ_ALWAYS_INLINE void readBarrier(TenuredCell* thing);
static MOZ_ALWAYS_INLINE void writeBarrierPre(TenuredCell* thing);

79
js/src/gc/DeletePolicy.h Normal file
Просмотреть файл

@ -0,0 +1,79 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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/. */
#ifndef gc_DeletePolicy_h
#define gc_DeletePolicy_h
#include "js/TracingAPI.h"
namespace js {
namespace gc {
struct ClearEdgesTracer : public JS::CallbackTracer
{
ClearEdgesTracer();
#ifdef DEBUG
TracerKind getTracerKind() const override { return TracerKind::ClearEdges; }
#endif
template <typename T>
inline void clearEdge(T** thingp);
void onObjectEdge(JSObject** objp) override;
void onStringEdge(JSString** strp) override;
void onSymbolEdge(JS::Symbol** symp) override;
void onScriptEdge(JSScript** scriptp) override;
void onShapeEdge(js::Shape** shapep) override;
void onObjectGroupEdge(js::ObjectGroup** groupp) override;
void onBaseShapeEdge(js::BaseShape** basep) override;
void onJitCodeEdge(js::jit::JitCode** codep) override;
void onLazyScriptEdge(js::LazyScript** lazyp) override;
void onScopeEdge(js::Scope** scopep) override;
void onRegExpSharedEdge(js::RegExpShared** sharedp) override;
void onChild(const JS::GCCellPtr& thing) override;
};
#ifdef DEBUG
inline bool
IsClearEdgesTracer(JSTracer *trc)
{
return trc->isCallbackTracer() &&
trc->asCallbackTracer()->getTracerKind() == JS::CallbackTracer::TracerKind::ClearEdges;
}
#endif
} // namespace gc
/*
* Provides a delete policy that can be used for objects which have their
* lifetime managed by the GC so they can be safely destroyed outside of GC.
*
* This is necessary for example when initializing such an object may fail after
* the initial allocation. The partially-initialized object must be destroyed,
* but it may not be safe to do so at the current time as the store buffer may
* contain pointers into it.
*
* This policy traces GC pointers in the object and clears them, making sure to
* trigger barriers while doing so. This will remove any store buffer pointers
* into the object and make it safe to delete.
*/
template <typename T>
struct GCManagedDeletePolicy
{
void operator()(const T* constPtr) {
if (constPtr) {
auto ptr = const_cast<T*>(constPtr);
gc::ClearEdgesTracer trc;
ptr->trace(&trc);
js_delete(ptr);
}
}
};
} // namespace js
#endif // gc_DeletePolicy_h

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

@ -2016,7 +2016,8 @@ inline T*
MarkStack::TaggedPtr::as() const
{
MOZ_ASSERT(tag() == MapTypeToMarkStackTag<T*>::value);
MOZ_ASSERT(ptr()->asTenured().getTraceKind() == MapTypeToTraceKind<T>::kind);
MOZ_ASSERT(ptr()->isTenured());
MOZ_ASSERT(ptr()->is<T>());
return static_cast<T*>(ptr());
}
@ -2024,7 +2025,8 @@ inline JSObject*
MarkStack::TaggedPtr::asValueArrayObject() const
{
MOZ_ASSERT(tag() == ValueArrayTag);
MOZ_ASSERT(ptr()->asTenured().getTraceKind() == JS::TraceKind::Object);
MOZ_ASSERT(ptr()->isTenured());
MOZ_ASSERT(ptr()->is<JSObject>());
return static_cast<JSObject*>(ptr());
}
@ -2032,7 +2034,8 @@ inline JSObject*
MarkStack::TaggedPtr::asSavedValueArrayObject() const
{
MOZ_ASSERT(tag() == SavedValueArrayTag);
MOZ_ASSERT(ptr()->asTenured().getTraceKind() == JS::TraceKind::Object);
MOZ_ASSERT(ptr()->isTenured());
MOZ_ASSERT(ptr()->is<JSObject>());
return static_cast<JSObject*>(ptr());
}
@ -2040,7 +2043,8 @@ inline JSRope*
MarkStack::TaggedPtr::asTempRope() const
{
MOZ_ASSERT(tag() == TempRopeTag);
MOZ_ASSERT(ptr()->asTenured().getTraceKind() == JS::TraceKind::String);
MOZ_ASSERT(ptr()->isTenured());
MOZ_ASSERT(ptr()->is<JSString>());
return static_cast<JSRope*>(ptr());
}

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

@ -9,21 +9,20 @@
#include "mozilla/Atomics.h"
#include "mozilla/HashFunctions.h"
#include "mozilla/MemoryReporting.h"
#include "jscntxt.h"
#include "ds/SplayTree.h"
#include "gc/FindSCCs.h"
#include "gc/GCRuntime.h"
#include "js/GCHashTable.h"
#include "js/TracingAPI.h"
#include "vm/MallocProvider.h"
#include "vm/RegExpShared.h"
#include "vm/TypeInference.h"
#include "vm/Runtime.h"
struct JSContext;
namespace js {
class Debugger;
namespace jit {
class JitZone;
} // namespace jit
@ -987,92 +986,6 @@ ZoneAllocPolicy::pod_realloc(T* p, size_t oldSize, size_t newSize)
return zone->pod_realloc<T>(p, oldSize, newSize);
}
/*
* Provides a delete policy that can be used for objects which have their
* lifetime managed by the GC so they can be safely destroyed outside of GC.
*
* This is necessary for example when initializing such an object may fail after
* the initial allocation. The partially-initialized object must be destroyed,
* but it may not be safe to do so at the current time as the store buffer may
* contain pointers into it.
*
* This policy traces GC pointers in the object and clears them, making sure to
* trigger barriers while doing so. This will remove any store buffer pointers
* into the object and make it safe to delete.
*/
template <typename T>
struct GCManagedDeletePolicy
{
struct ClearEdgesTracer : public JS::CallbackTracer
{
explicit ClearEdgesTracer(JSContext* cx) : CallbackTracer(cx, TraceWeakMapKeysValues) {}
#ifdef DEBUG
TracerKind getTracerKind() const override { return TracerKind::ClearEdges; }
#endif
template <typename S>
void clearEdge(S** thingp) {
InternalBarrierMethods<S*>::preBarrier(*thingp);
InternalBarrierMethods<S*>::postBarrier(thingp, *thingp, nullptr);
*thingp = nullptr;
}
void onObjectEdge(JSObject** objp) override { clearEdge(objp); }
void onStringEdge(JSString** strp) override { clearEdge(strp); }
void onSymbolEdge(JS::Symbol** symp) override { clearEdge(symp); }
void onScriptEdge(JSScript** scriptp) override { clearEdge(scriptp); }
void onShapeEdge(js::Shape** shapep) override { clearEdge(shapep); }
void onObjectGroupEdge(js::ObjectGroup** groupp) override { clearEdge(groupp); }
void onBaseShapeEdge(js::BaseShape** basep) override { clearEdge(basep); }
void onJitCodeEdge(js::jit::JitCode** codep) override { clearEdge(codep); }
void onLazyScriptEdge(js::LazyScript** lazyp) override { clearEdge(lazyp); }
void onScopeEdge(js::Scope** scopep) override { clearEdge(scopep); }
void onRegExpSharedEdge(js::RegExpShared** sharedp) override { clearEdge(sharedp); }
void onChild(const JS::GCCellPtr& thing) override { MOZ_CRASH(); }
};
void operator()(const T* constPtr) {
if (constPtr) {
auto ptr = const_cast<T*>(constPtr);
ClearEdgesTracer trc(TlsContext.get());
ptr->trace(&trc);
js_delete(ptr);
}
}
};
#ifdef DEBUG
inline bool
IsClearEdgesTracer(JSTracer *trc)
{
return trc->isCallbackTracer() &&
trc->asCallbackTracer()->getTracerKind() == JS::CallbackTracer::TracerKind::ClearEdges;
}
#endif
} // namespace js
namespace JS {
// Scope data that contain GCPtrs must use the correct DeletePolicy.
//
// This is defined here because vm/Scope.h cannot #include "vm/Runtime.h"
template <>
struct DeletePolicy<js::FunctionScope::Data>
: public js::GCManagedDeletePolicy<js::FunctionScope::Data>
{ };
template <>
struct DeletePolicy<js::ModuleScope::Data>
: public js::GCManagedDeletePolicy<js::ModuleScope::Data>
{ };
template <>
struct DeletePolicy<js::WasmInstanceScope::Data>
: public js::GCManagedDeletePolicy<js::WasmInstanceScope::Data>
{ };
} // namespace JS
#endif // gc_Zone_h

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

@ -0,0 +1,5 @@
var g = newGlobal();
g.eval("azx918 = 1");
for (var x in g) {
assertEq(x, x);
}

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

@ -0,0 +1,12 @@
function g(s) {
for (var i = s; ; i--) {
if (s[i] !== ' ')
return;
}
}
function f() {
var s = "foo".match(/(.*)$/)[0];
return g(s);
}
for (var i = 0; i < 10; i++)
f();

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

@ -4087,7 +4087,6 @@ static bool
DoGetIteratorFallback(JSContext* cx, BaselineFrame* frame, ICGetIterator_Fallback* stub,
HandleValue value, MutableHandleValue res)
{
jsbytecode* pc = stub->icEntry()->pc(frame->script());
FallbackICSpew(cx, stub, "GetIterator");
if (stub->state().maybeTransition())
@ -4111,8 +4110,7 @@ DoGetIteratorFallback(JSContext* cx, BaselineFrame* frame, ICGetIterator_Fallbac
stub->state().trackNotAttached();
}
uint8_t flags = GET_UINT8(pc);
JSObject* iterobj = ValueToIterator(cx, flags, value);
JSObject* iterobj = ValueToIterator(cx, value);
if (!iterobj)
return false;

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

@ -4009,9 +4009,6 @@ GetIteratorIRGenerator::tryAttachNativeIterator(ObjOperandId objId, HandleObject
{
MOZ_ASSERT(JSOp(*pc_) == JSOP_ITER);
if (GET_UINT8(pc_) != JSITER_ENUMERATE)
return false;
PropertyIteratorObject* iterobj = LookupInIteratorCache(cx_, obj);
if (!iterobj)
return false;

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

@ -470,8 +470,6 @@ CacheRegisterAllocator::fixupAliasedInputs(MacroAssembler& masm)
// PayloadReg: spilling the ValueReg instead would leave its type
// register unallocated on 32-bit platforms.
if (loc1.kind() == OperandLocation::ValueReg) {
MOZ_ASSERT_IF(loc2.kind() == OperandLocation::ValueReg,
loc1 == loc2);
spillOperandToStack(masm, &loc2);
} else {
MOZ_ASSERT(loc1.kind() == OperandLocation::PayloadReg);

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

@ -9291,9 +9291,6 @@ CodeGenerator::visitIteratorEnd(LIteratorEnd* lir)
LoadNativeIterator(masm, obj, temp1, ool->entry());
masm.branchTest32(Assembler::Zero, Address(temp1, offsetof(NativeIterator, flags)),
Imm32(JSITER_ENUMERATE), ool->entry());
// Clear active bit.
masm.and32(Imm32(~JSITER_ACTIVE), Address(temp1, offsetof(NativeIterator, flags)));

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

@ -2305,7 +2305,7 @@ IonBuilder::inspectOpcode(JSOp op)
return jsop_copylexicalenv(false);
case JSOP_ITER:
return jsop_iter(GET_INT8(pc));
return jsop_iter();
case JSOP_MOREITER:
return jsop_itermore();
@ -12577,7 +12577,7 @@ IonBuilder::jsop_toid()
}
AbortReasonOr<Ok>
IonBuilder::jsop_iter(uint8_t flags)
IonBuilder::jsop_iter()
{
MDefinition* obj = current->pop();
MInstruction* ins = MGetIteratorCache::New(alloc(), obj);

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

@ -578,7 +578,7 @@ class IonBuilder
AbortReasonOr<Ok> jsop_toasyncgen();
AbortReasonOr<Ok> jsop_toasynciter();
AbortReasonOr<Ok> jsop_toid();
AbortReasonOr<Ok> jsop_iter(uint8_t flags);
AbortReasonOr<Ok> jsop_iter();
AbortReasonOr<Ok> jsop_itermore();
AbortReasonOr<Ok> jsop_isnoiter();
AbortReasonOr<Ok> jsop_iterend();

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

@ -402,7 +402,6 @@ IonGetIteratorIC::update(JSContext* cx, HandleScript outerScript, IonGetIterator
HandleValue value)
{
IonScript* ionScript = outerScript->ionScript();
jsbytecode* pc = ic->pc();
if (ic->state().maybeTransition())
ic->discardStubs(cx->zone());
@ -410,7 +409,7 @@ IonGetIteratorIC::update(JSContext* cx, HandleScript outerScript, IonGetIterator
if (ic->state().canAttachStub()) {
bool attached = false;
RootedScript script(cx, ic->script());
GetIteratorIRGenerator gen(cx, script, pc, ic->state().mode(), value);
GetIteratorIRGenerator gen(cx, script, ic->pc(), ic->state().mode(), value);
if (gen.tryAttachStub())
ic->attachCacheIRStub(cx, gen.writerRef(), gen.cacheKind(), ionScript, &attached);
@ -418,8 +417,7 @@ IonGetIteratorIC::update(JSContext* cx, HandleScript outerScript, IonGetIterator
ic->state().trackNotAttached();
}
uint8_t flags = GET_UINT8(pc);
return ValueToIterator(cx, flags, value);
return ValueToIterator(cx, value);
}
/* static */ bool

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

@ -18,6 +18,7 @@
#include "js/Vector.h"
#include "threading/ProtectedData.h"
#include "vm/ErrorReporting.h"
#include "vm/MallocProvider.h"
#include "vm/Runtime.h"
#ifdef _MSC_VER

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

@ -1000,9 +1000,8 @@ IsObjectInContextCompartment(JSObject* obj, const JSContext* cx);
/*
* NB: keep these in sync with the copy in builtin/SelfHostingDefines.h.
* The first two are omitted because they shouldn't be used in new code.
*/
#define JSITER_ENUMERATE 0x1 /* for-in compatible hidden default iterator */
/* 0x1 is no longer used */
/* 0x2 is no longer used */
/* 0x4 is no longer used */
#define JSITER_OWNONLY 0x8 /* iterate over obj's own properties only */

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

@ -9047,3 +9047,29 @@ js::gc::detail::CellIsNotGray(const Cell* cell)
return false;
}
#endif
js::gc::ClearEdgesTracer::ClearEdgesTracer()
: CallbackTracer(TlsContext.get(), TraceWeakMapKeysValues)
{}
template <typename S>
inline void
js::gc::ClearEdgesTracer::clearEdge(S** thingp)
{
InternalBarrierMethods<S*>::preBarrier(*thingp);
InternalBarrierMethods<S*>::postBarrier(thingp, *thingp, nullptr);
*thingp = nullptr;
}
void js::gc::ClearEdgesTracer::onObjectEdge(JSObject** objp) { clearEdge(objp); }
void js::gc::ClearEdgesTracer::onStringEdge(JSString** strp) { clearEdge(strp); }
void js::gc::ClearEdgesTracer::onSymbolEdge(JS::Symbol** symp) { clearEdge(symp); }
void js::gc::ClearEdgesTracer::onScriptEdge(JSScript** scriptp) { clearEdge(scriptp); }
void js::gc::ClearEdgesTracer::onShapeEdge(js::Shape** shapep) { clearEdge(shapep); }
void js::gc::ClearEdgesTracer::onObjectGroupEdge(js::ObjectGroup** groupp) { clearEdge(groupp); }
void js::gc::ClearEdgesTracer::onBaseShapeEdge(js::BaseShape** basep) { clearEdge(basep); }
void js::gc::ClearEdgesTracer::onJitCodeEdge(js::jit::JitCode** codep) { clearEdge(codep); }
void js::gc::ClearEdgesTracer::onLazyScriptEdge(js::LazyScript** lazyp) { clearEdge(lazyp); }
void js::gc::ClearEdgesTracer::onScopeEdge(js::Scope** scopep) { clearEdge(scopep); }
void js::gc::ClearEdgesTracer::onRegExpSharedEdge(js::RegExpShared** sharedp) { clearEdge(sharedp); }
void js::gc::ClearEdgesTracer::onChild(const JS::GCCellPtr& thing) { MOZ_CRASH(); }

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

@ -537,36 +537,32 @@ js::GetPropertyKeys(JSContext* cx, HandleObject obj, unsigned flags, AutoIdVecto
}
static inline PropertyIteratorObject*
NewPropertyIteratorObject(JSContext* cx, unsigned flags)
NewPropertyIteratorObject(JSContext* cx)
{
if (flags & JSITER_ENUMERATE) {
RootedObjectGroup group(cx, ObjectGroup::defaultNewGroup(cx, &PropertyIteratorObject::class_,
TaggedProto(nullptr)));
if (!group)
return nullptr;
RootedObjectGroup group(cx, ObjectGroup::defaultNewGroup(cx, &PropertyIteratorObject::class_,
TaggedProto(nullptr)));
if (!group)
return nullptr;
const Class* clasp = &PropertyIteratorObject::class_;
RootedShape shape(cx, EmptyShape::getInitialShape(cx, clasp, TaggedProto(nullptr),
ITERATOR_FINALIZE_KIND));
if (!shape)
return nullptr;
const Class* clasp = &PropertyIteratorObject::class_;
RootedShape shape(cx, EmptyShape::getInitialShape(cx, clasp, TaggedProto(nullptr),
ITERATOR_FINALIZE_KIND));
if (!shape)
return nullptr;
JSObject* obj;
JS_TRY_VAR_OR_RETURN_NULL(cx, obj, NativeObject::create(cx, ITERATOR_FINALIZE_KIND,
GetInitialHeap(GenericObject, clasp),
shape, group));
JSObject* obj;
JS_TRY_VAR_OR_RETURN_NULL(cx, obj, NativeObject::create(cx, ITERATOR_FINALIZE_KIND,
GetInitialHeap(GenericObject, clasp),
shape, group));
PropertyIteratorObject* res = &obj->as<PropertyIteratorObject>();
PropertyIteratorObject* res = &obj->as<PropertyIteratorObject>();
// CodeGenerator::visitIteratorStartO assumes the iterator object is not
// inside the nursery when deciding whether a barrier is necessary.
MOZ_ASSERT(!js::gc::IsInsideNursery(res));
// CodeGenerator::visitIteratorStartO assumes the iterator object is not
// inside the nursery when deciding whether a barrier is necessary.
MOZ_ASSERT(!js::gc::IsInsideNursery(res));
MOZ_ASSERT(res->numFixedSlots() == JSObject::ITER_CLASS_NFIXED_SLOTS);
return res;
}
return NewBuiltinClassInstance<PropertyIteratorObject>(cx);
MOZ_ASSERT(res->numFixedSlots() == JSObject::ITER_CLASS_NFIXED_SLOTS);
return res;
}
NativeIterator*
@ -607,11 +603,11 @@ NativeIterator::allocateSentinel(JSContext* maybecx)
}
inline void
NativeIterator::init(JSObject* obj, JSObject* iterObj, unsigned flags, uint32_t numGuards, uint32_t key)
NativeIterator::init(JSObject* obj, JSObject* iterObj, uint32_t numGuards, uint32_t key)
{
this->obj.init(obj);
this->iterObj_ = iterObj;
this->flags = flags;
this->flags = 0;
this->guard_array = (HeapReceiverGuard*) this->props_end;
this->guard_length = numGuards;
this->guard_key = key;
@ -642,23 +638,20 @@ static inline void
RegisterEnumerator(JSContext* cx, PropertyIteratorObject* iterobj, NativeIterator* ni)
{
/* Register non-escaping native enumerators (for-in) with the current context. */
if (ni->flags & JSITER_ENUMERATE) {
ni->link(cx->compartment()->enumerators);
ni->link(cx->compartment()->enumerators);
MOZ_ASSERT(!(ni->flags & JSITER_ACTIVE));
ni->flags |= JSITER_ACTIVE;
}
MOZ_ASSERT(!(ni->flags & JSITER_ACTIVE));
ni->flags |= JSITER_ACTIVE;
}
static inline PropertyIteratorObject*
VectorToKeyIterator(JSContext* cx, HandleObject obj, unsigned flags, AutoIdVector& keys,
uint32_t numGuards)
VectorToKeyIterator(JSContext* cx, HandleObject obj, AutoIdVector& keys, uint32_t numGuards)
{
if (obj->isSingleton() && !JSObject::setIteratedSingleton(cx, obj))
return nullptr;
MarkObjectGroupFlags(cx, obj, OBJECT_FLAG_ITERATED);
Rooted<PropertyIteratorObject*> iterobj(cx, NewPropertyIteratorObject(cx, flags));
Rooted<PropertyIteratorObject*> iterobj(cx, NewPropertyIteratorObject(cx));
if (!iterobj)
return nullptr;
@ -667,7 +660,7 @@ VectorToKeyIterator(JSContext* cx, HandleObject obj, unsigned flags, AutoIdVecto
return nullptr;
iterobj->setNativeIterator(ni);
ni->init(obj, iterobj, flags, numGuards, 0);
ni->init(obj, iterobj, numGuards, 0);
if (!ni->initProperties(cx, iterobj, keys))
return nullptr;
@ -699,17 +692,16 @@ VectorToKeyIterator(JSContext* cx, HandleObject obj, unsigned flags, AutoIdVecto
JSObject*
js::EnumeratedIdVectorToIterator(JSContext* cx, HandleObject obj, unsigned flags,
AutoIdVector& props)
js::EnumeratedIdVectorToIterator(JSContext* cx, HandleObject obj, AutoIdVector& props)
{
return VectorToKeyIterator(cx, obj, flags, props, 0);
return VectorToKeyIterator(cx, obj, props, 0);
}
// Mainly used for .. in over null/undefined
JSObject*
js::NewEmptyPropertyIterator(JSContext* cx, unsigned flags)
js::NewEmptyPropertyIterator(JSContext* cx)
{
Rooted<PropertyIteratorObject*> iterobj(cx, NewPropertyIteratorObject(cx, flags));
Rooted<PropertyIteratorObject*> iterobj(cx, NewPropertyIteratorObject(cx));
if (!iterobj)
return nullptr;
@ -719,7 +711,7 @@ js::NewEmptyPropertyIterator(JSContext* cx, unsigned flags)
return nullptr;
iterobj->setNativeIterator(ni);
ni->init(nullptr, iterobj, flags, 0, 0);
ni->init(nullptr, iterobj, 0, 0);
if (!ni->initProperties(cx, iterobj, keys))
return nullptr;
@ -766,10 +758,6 @@ LookupInIteratorCache(JSContext* cx, JSObject* obj, uint32_t* numGuards)
{
MOZ_ASSERT(*numGuards == 0);
// The iterator object for JSITER_ENUMERATE never escapes, so we don't
// care that the "proper" prototype is set. This also lets us reuse an
// old, inactive iterator object.
ReceiverGuardVector guards(cx);
uint32_t key = 0;
JSObject* pobj = obj;
@ -861,39 +849,29 @@ StoreInIteratorCache(JSContext* cx, JSObject* obj, PropertyIteratorObject* itero
}
JSObject*
js::GetIterator(JSContext* cx, HandleObject obj, unsigned flags)
js::GetIterator(JSContext* cx, HandleObject obj)
{
uint32_t numGuards = 0;
if (flags == JSITER_ENUMERATE) {
if (PropertyIteratorObject* iterobj = LookupInIteratorCache(cx, obj, &numGuards)) {
NativeIterator* ni = iterobj->getNativeIterator();
UpdateNativeIterator(ni, obj);
RegisterEnumerator(cx, iterobj, ni);
return iterobj;
}
if (numGuards > 0 && !CanStoreInIteratorCache(cx, obj))
numGuards = 0;
if (PropertyIteratorObject* iterobj = LookupInIteratorCache(cx, obj, &numGuards)) {
NativeIterator* ni = iterobj->getNativeIterator();
UpdateNativeIterator(ni, obj);
RegisterEnumerator(cx, iterobj, ni);
return iterobj;
}
if (MOZ_UNLIKELY(obj->is<PropertyIteratorObject>()))
return obj;
if (numGuards > 0 && !CanStoreInIteratorCache(cx, obj))
numGuards = 0;
// We should only call the enumerate trap for "for-in".
// Or when we call GetIterator from the Proxy [[Enumerate]] hook.
// JSITER_ENUMERATE is just an optimization and the same
// as flags == 0 otherwise.
if (flags == 0 || flags == JSITER_ENUMERATE) {
if (MOZ_UNLIKELY(obj->is<ProxyObject>()))
return Proxy::enumerate(cx, obj);
}
MOZ_ASSERT(!obj->is<PropertyIteratorObject>());
if (MOZ_UNLIKELY(obj->is<ProxyObject>()))
return Proxy::enumerate(cx, obj);
AutoIdVector keys(cx);
if (!Snapshot(cx, obj, flags, &keys))
if (!Snapshot(cx, obj, 0, &keys))
return nullptr;
JSObject* res = VectorToKeyIterator(cx, obj, flags, keys, numGuards);
JSObject* res = VectorToKeyIterator(cx, obj, keys, numGuards);
if (!res)
return nullptr;
@ -997,17 +975,15 @@ JSCompartment::getOrCreateIterResultTemplateObject(JSContext* cx)
/*** Iterator objects ****************************************************************************/
MOZ_ALWAYS_INLINE bool
NativeIteratorNext(JSContext* cx, NativeIterator* ni, MutableHandleValue rval)
MOZ_ALWAYS_INLINE void
NativeIteratorNext(NativeIterator* ni, MutableHandleValue rval)
{
if (ni->props_cursor >= ni->props_end) {
rval.setMagic(JS_NO_ITER_VALUE);
return true;
} else {
rval.setString(*ni->current());
ni->incCursor();
}
rval.setString(*ni->current());
ni->incCursor();
return true;
}
bool
@ -1122,26 +1098,26 @@ js::NewStringIteratorObject(JSContext* cx, NewObjectKind newKind)
}
JSObject*
js::ValueToIterator(JSContext* cx, unsigned flags, HandleValue vp)
js::ValueToIterator(JSContext* cx, HandleValue vp)
{
RootedObject obj(cx);
if (vp.isObject()) {
/* Common case. */
obj = &vp.toObject();
} else if ((flags & JSITER_ENUMERATE) && vp.isNullOrUndefined()) {
} else if (vp.isNullOrUndefined()) {
/*
* Enumerating over null and undefined gives an empty enumerator, so
* that |for (var p in <null or undefined>) <loop>;| never executes
* <loop>, per ES5 12.6.4.
*/
return NewEmptyPropertyIterator(cx, flags);
return NewEmptyPropertyIterator(cx);
} else {
obj = ToObject(cx, vp);
if (!obj)
return nullptr;
}
return GetIterator(cx, obj, flags);
return GetIterator(cx, obj);
}
void
@ -1151,18 +1127,16 @@ js::CloseIterator(JSObject* obj)
/* Remove enumerators from the active list, which is a stack. */
NativeIterator* ni = obj->as<PropertyIteratorObject>().getNativeIterator();
if (ni->flags & JSITER_ENUMERATE) {
ni->unlink();
ni->unlink();
MOZ_ASSERT(ni->flags & JSITER_ACTIVE);
ni->flags &= ~JSITER_ACTIVE;
MOZ_ASSERT(ni->flags & JSITER_ACTIVE);
ni->flags &= ~JSITER_ACTIVE;
/*
* Reset the enumerator; it may still be in the cached iterators
* for this thread, and can be reused.
*/
ni->props_cursor = ni->props_array;
}
/*
* Reset the enumerator; it may still be in the cached iterators
* for this thread, and can be reused.
*/
ni->props_cursor = ni->props_array;
}
}
@ -1221,8 +1195,7 @@ js::UnwindIteratorForUncatchableException(JSContext* cx, JSObject* obj)
{
if (obj->is<PropertyIteratorObject>()) {
NativeIterator* ni = obj->as<PropertyIteratorObject>().getNativeIterator();
if (ni->flags & JSITER_ENUMERATE)
ni->unlink();
ni->unlink();
}
}
@ -1371,7 +1344,8 @@ js::IteratorMore(JSContext* cx, HandleObject iterobj, MutableHandleValue rval)
// Fast path for native iterators.
if (MOZ_LIKELY(iterobj->is<PropertyIteratorObject>())) {
NativeIterator* ni = iterobj->as<PropertyIteratorObject>().getNativeIterator();
return NativeIteratorNext(cx, ni, rval);
NativeIteratorNext(ni, rval);
return true;
}
if (JS_IsDeadWrapper(iterobj)) {
@ -1389,8 +1363,7 @@ js::IteratorMore(JSContext* cx, HandleObject iterobj, MutableHandleValue rval)
{
AutoCompartment ac(cx, obj);
NativeIterator* ni = obj->as<PropertyIteratorObject>().getNativeIterator();
if (!NativeIteratorNext(cx, ni, rval))
return false;
NativeIteratorNext(ni, rval);
}
return cx->compartment()->wrap(cx, rval);
}

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

@ -85,7 +85,6 @@ struct NativeIterator
void link(NativeIterator* other) {
/* A NativeIterator cannot appear in the enumerator list twice. */
MOZ_ASSERT(!next_ && !prev_);
MOZ_ASSERT(flags & JSITER_ENUMERATE);
this->next_ = other;
this->prev_ = other->prev_;
@ -93,8 +92,6 @@ struct NativeIterator
other->prev_ = this;
}
void unlink() {
MOZ_ASSERT(flags & JSITER_ENUMERATE);
next_->prev_ = prev_;
prev_->next_ = next_;
next_ = nullptr;
@ -103,7 +100,7 @@ struct NativeIterator
static NativeIterator* allocateSentinel(JSContext* maybecx);
static NativeIterator* allocateIterator(JSContext* cx, uint32_t slength, uint32_t plength);
void init(JSObject* obj, JSObject* iterObj, unsigned flags, uint32_t slength, uint32_t key);
void init(JSObject* obj, JSObject* iterObj, uint32_t slength, uint32_t key);
bool initProperties(JSContext* cx, Handle<PropertyIteratorObject*> obj,
const js::AutoIdVector& props);
@ -154,29 +151,19 @@ StringIteratorObject*
NewStringIteratorObject(JSContext* cx, NewObjectKind newKind = GenericObject);
JSObject*
GetIterator(JSContext* cx, HandleObject obj, unsigned flags);
GetIterator(JSContext* cx, HandleObject obj);
PropertyIteratorObject*
LookupInIteratorCache(JSContext* cx, HandleObject obj);
/*
* Creates either a key or value iterator, depending on flags. For a value
* iterator, performs value-lookup to convert the given list of jsids.
*/
JSObject*
EnumeratedIdVectorToIterator(JSContext* cx, HandleObject obj, unsigned flags, AutoIdVector& props);
EnumeratedIdVectorToIterator(JSContext* cx, HandleObject obj, AutoIdVector& props);
JSObject*
NewEmptyPropertyIterator(JSContext* cx, unsigned flags);
NewEmptyPropertyIterator(JSContext* cx);
/*
* Convert the value stored in *vp to its iteration object. The flags should
* contain JSITER_ENUMERATE if js::ValueToIterator is called when enumerating
* for-in semantics are required, and when the caller can guarantee that the
* iterator will never be exposed to scripts.
*/
JSObject*
ValueToIterator(JSContext* cx, unsigned flags, HandleValue vp);
ValueToIterator(JSContext* cx, HandleValue vp);
void
CloseIterator(JSObject* obj);

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

@ -14,6 +14,7 @@
#include "jsfriendapi.h"
#include "jsobj.h"
#include "gc/DeletePolicy.h"
#include "gc/StoreBuffer.h"
#include "js/HashTable.h"

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

@ -284,7 +284,7 @@ BaseProxyHandler::enumerate(JSContext* cx, HandleObject proxy) const
if (!GetPropertyKeys(cx, proxy, 0, &props))
return nullptr;
return EnumeratedIdVectorToIterator(cx, proxy, 0, props);
return EnumeratedIdVectorToIterator(cx, proxy, props);
}
bool

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

@ -260,8 +260,7 @@ CrossCompartmentWrapper::getOwnEnumerablePropertyKeys(JSContext* cx, HandleObjec
static bool
CanReify(HandleObject obj)
{
return obj->is<PropertyIteratorObject>() &&
(obj->as<PropertyIteratorObject>().getNativeIterator()->flags & JSITER_ENUMERATE);
return obj->is<PropertyIteratorObject>();
}
struct AutoCloseIterator
@ -303,11 +302,13 @@ Reify(JSContext* cx, JSCompartment* origin, HandleObject objp)
if (length > 0) {
if (!keys.reserve(length))
return nullptr;
RootedId id(cx);
RootedValue v(cx);
for (size_t i = 0; i < length; ++i) {
RootedId id(cx);
RootedValue v(cx, StringValue(ni->begin()[i]));
v.setString(ni->begin()[i]);
if (!ValueToId<CanGC>(cx, v, &id))
return nullptr;
cx->markId(id);
keys.infallibleAppend(id);
}
}
@ -315,7 +316,7 @@ Reify(JSContext* cx, JSCompartment* origin, HandleObject objp)
close.clear();
CloseIterator(iterObj);
obj = EnumeratedIdVectorToIterator(cx, obj, ni->flags, keys);
obj = EnumeratedIdVectorToIterator(cx, obj, keys);
}
return obj;
}

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

@ -467,7 +467,7 @@ Proxy::enumerate(JSContext* cx, HandleObject proxy)
if (!GetPrototype(cx, proxy, &proto))
return nullptr;
if (!proto)
return EnumeratedIdVectorToIterator(cx, proxy, 0, props);
return EnumeratedIdVectorToIterator(cx, proxy, props);
assertSameCompartment(cx, proxy, proto);
AutoIdVector protoProps(cx);
@ -475,7 +475,7 @@ Proxy::enumerate(JSContext* cx, HandleObject proxy)
return nullptr;
if (!AppendUnique(cx, props, protoProps))
return nullptr;
return EnumeratedIdVectorToIterator(cx, proxy, 0, props);
return EnumeratedIdVectorToIterator(cx, proxy, props);
}
AutoEnterPolicy policy(cx, handler, proxy, JSID_VOIDHANDLE,
@ -486,7 +486,7 @@ Proxy::enumerate(JSContext* cx, HandleObject proxy)
if (!policy.allowed()) {
if (!policy.returnValue())
return nullptr;
return NewEmptyPropertyIterator(cx, 0);
return NewEmptyPropertyIterator(cx);
}
return handler->enumerate(cx, proxy);
}

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

@ -86,7 +86,7 @@ ForwardingProxyHandler::enumerate(JSContext* cx, HandleObject proxy) const
assertEnteredPolicy(cx, proxy, JSID_VOID, ENUMERATE);
MOZ_ASSERT(!hasPrototype()); // Should never be called if there's a prototype.
RootedObject target(cx, proxy->as<ProxyObject>().target());
return GetIterator(cx, target, 0);
return GetIterator(cx, target);
}
bool

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

@ -2276,10 +2276,8 @@ END_CASE(JSOP_HASOWN)
CASE(JSOP_ITER)
{
MOZ_ASSERT(REGS.stackDepth() >= 1);
uint8_t flags = GET_UINT8(REGS.pc);
HandleValue val = REGS.stackHandleAt(-1);
ReservedRooted<JSObject*> iter(&rootObject0);
iter.set(ValueToIterator(cx, flags, val));
JSObject* iter = ValueToIterator(cx, val);
if (!iter)
goto error;
REGS.sp[-1].setObject(*iter);

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше