From 19aa672b13aaae34656f4ac227cf0fc28494eff6 Mon Sep 17 00:00:00 2001 From: Mason Chang Date: Fri, 17 Jul 2015 13:52:38 -0700 Subject: [PATCH 01/69] Bug 1172841. Set number of WMF decoder threads based on CPU count. r=cpearce --- dom/media/platforms/wmf/WMFDecoderModule.cpp | 29 +++++++++++++++++++ dom/media/platforms/wmf/WMFDecoderModule.h | 3 ++ .../platforms/wmf/WMFVideoMFTManager.cpp | 14 +++++---- modules/libpref/init/all.js | 1 + 4 files changed, 41 insertions(+), 6 deletions(-) diff --git a/dom/media/platforms/wmf/WMFDecoderModule.cpp b/dom/media/platforms/wmf/WMFDecoderModule.cpp index ca25fafb3d1e..6f814633f899 100644 --- a/dom/media/platforms/wmf/WMFDecoderModule.cpp +++ b/dom/media/platforms/wmf/WMFDecoderModule.cpp @@ -19,11 +19,13 @@ #include "GfxDriverInfo.h" #include "gfxWindowsPlatform.h" #include "MediaInfo.h" +#include "prsystem.h" namespace mozilla { static bool sIsWMFEnabled = false; static bool sDXVAEnabled = false; +static int sNumDecoderThreads = -1; WMFDecoderModule::WMFDecoderModule() : mWMFInitialized(false) @@ -44,6 +46,25 @@ WMFDecoderModule::DisableHardwareAcceleration() sDXVAEnabled = false; } +static void +SetNumOfDecoderThreads() +{ + MOZ_ASSERT(NS_IsMainThread(), "Preferences can only be read on main thread"); + int32_t numCores = PR_GetNumberOfProcessors(); + + // If we have more than 4 cores, let the decoder decide how many threads. + // On an 8 core machine, WMF chooses 4 decoder threads + const int WMF_DECODER_DEFAULT = -1; + int32_t prefThreadCount = Preferences::GetInt("media.wmf.decoder.thread-count", -1); + if (prefThreadCount != WMF_DECODER_DEFAULT) { + sNumDecoderThreads = std::max(prefThreadCount, 1); + } else if (numCores > 4) { + sNumDecoderThreads = WMF_DECODER_DEFAULT; + } else { + sNumDecoderThreads = std::max(numCores - 1, 1); + } +} + /* static */ void WMFDecoderModule::Init() @@ -51,6 +72,14 @@ WMFDecoderModule::Init() MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread."); sIsWMFEnabled = Preferences::GetBool("media.windows-media-foundation.enabled", false); sDXVAEnabled = gfxPlatform::GetPlatform()->CanUseHardwareVideoDecoding(); + SetNumOfDecoderThreads(); +} + +/* static */ +int +WMFDecoderModule::GetNumDecoderThreads() +{ + return sNumDecoderThreads; } nsresult diff --git a/dom/media/platforms/wmf/WMFDecoderModule.h b/dom/media/platforms/wmf/WMFDecoderModule.h index 5cbc5fa7d60b..3b713168f865 100644 --- a/dom/media/platforms/wmf/WMFDecoderModule.h +++ b/dom/media/platforms/wmf/WMFDecoderModule.h @@ -48,6 +48,9 @@ public: // Called on main thread. static void Init(); + + // Called from any thread, must call init first + static int GetNumDecoderThreads(); private: bool ShouldUseDXVA(const VideoInfo& aConfig) const; bool mWMFInitialized; diff --git a/dom/media/platforms/wmf/WMFVideoMFTManager.cpp b/dom/media/platforms/wmf/WMFVideoMFTManager.cpp index 828961f7a076..f031f9d5c99a 100644 --- a/dom/media/platforms/wmf/WMFVideoMFTManager.cpp +++ b/dom/media/platforms/wmf/WMFVideoMFTManager.cpp @@ -198,13 +198,15 @@ WMFVideoMFTManager::InitInternal(bool aForceD3D9) HRESULT hr = decoder->Create(GetMFTGUID()); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); - if (useDxva) { - RefPtr attr(decoder->GetAttributes()); - - UINT32 aware = 0; - if (attr) { + RefPtr attr(decoder->GetAttributes()); + UINT32 aware = 0; + if (attr) { attr->GetUINT32(MF_SA_D3D_AWARE, &aware); - } + attr->SetUINT32(CODECAPI_AVDecNumWorkerThreads, + WMFDecoderModule::GetNumDecoderThreads()); + } + + if (useDxva) { if (aware) { // TODO: Test if I need this anywhere... Maybe on Vista? //hr = attr->SetUINT32(CODECAPI_AVDecVideoAcceleration_H264, TRUE); diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 0a0684ca92ea..0011dbe539ad 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -290,6 +290,7 @@ pref("media.decoder.heuristic.dormant.timeout", 60000); #ifdef MOZ_WMF pref("media.windows-media-foundation.enabled", true); +pref("media.wmf.decoder.thread-count", -1); #endif #ifdef MOZ_DIRECTSHOW pref("media.directshow.enabled", true); From 9b96df5045141ff8a1430847369292c1cbe28c36 Mon Sep 17 00:00:00 2001 From: David Keeler Date: Tue, 30 Jun 2015 14:35:42 -0700 Subject: [PATCH 02/69] bug 1178988 - refactor key-specific parts of pycert.py into pykey.py r=Cykesiopka,mgoodwin --- security/manager/ssl/tests/unit/pycert.py | 153 ++-------------- security/manager/ssl/tests/unit/pykey.py | 210 ++++++++++++++++++++++ 2 files changed, 224 insertions(+), 139 deletions(-) create mode 100755 security/manager/ssl/tests/unit/pykey.py diff --git a/security/manager/ssl/tests/unit/pycert.py b/security/manager/ssl/tests/unit/pycert.py index bf8b7c8734d1..daf85f7d16c3 100755 --- a/security/manager/ssl/tests/unit/pycert.py +++ b/security/manager/ssl/tests/unit/pycert.py @@ -48,14 +48,14 @@ or as the subject public key information field, respectively. from pyasn1.codec.der import decoder from pyasn1.codec.der import encoder -from pyasn1.type import constraint, namedtype, tag, univ, useful +from pyasn1.type import constraint, tag, univ, useful from pyasn1_modules import rfc2459 import base64 -import binascii import datetime import hashlib import sys -import rsa + +import pykey class UnknownBaseError(Exception): """Base class for handling unexpected input in this module.""" @@ -99,14 +99,6 @@ class UnknownKeyPurposeTypeError(UnknownBaseError): self.category = 'keyPurpose' -class UnknownKeySpecificationError(UnknownBaseError): - """Helper exception type to handle unknown key specifications.""" - - def __init__(self, value): - UnknownBaseError.__init__(self, value) - self.category = 'key specification' - - class UnknownKeyTargetError(UnknownBaseError): """Helper exception type to handle unknown key targets.""" @@ -166,97 +158,10 @@ def datetimeToTime(dt): time.setComponentByName('generalTime', useful.GeneralizedTime(dt.strftime('%Y%m%d%H%M%SZ'))) return time -def byteStringToHexifiedBitString(string): - """Takes a string of bytes and returns a hex string representing - those bytes for use with pyasn1.type.univ.BitString. It must be of - the form "''H", where the trailing 'H' indicates to - pyasn1 that the input is a hex string.""" - return "'%s'H" % binascii.hexlify(string) - -class RSAPublicKey(univ.Sequence): - """Helper type for encoding an RSA public key""" - componentType = namedtype.NamedTypes( - namedtype.NamedType('N', univ.Integer()), - namedtype.NamedType('E', univ.Integer())) - - class Certificate: """Utility class for reading a certificate specification and generating a signed x509 certificate""" - # For reference, when encoded as a subject public key info, the - # base64-encoded sha-256 hash of this key is - # VCIlmPM9NkgFQtrs4Oa5TeFcDu6MWRTKSNdePEhOgD8= - sharedRSA_N = long( - '00ba8851a8448e16d641fd6eb6880636103d3c13d9eae4354ab4ecf56857' - '6c247bc1c725a8e0d81fbdb19c069b6e1a86f26be2af5a756b6a6471087a' - 'a55aa74587f71cd5249c027ecd43fc1e69d038202993ab20c349e4dbb94c' - 'c26b6c0eed15820ff17ead691ab1d3023a8b2a41eea770e00f0d8dfd660b' - '2bb02492a47db988617990b157903dd23bc5e0b8481fa837d38843ef2716' - 'd855b7665aaa7e02902f3a7b10800624cc1c6c97ad96615bb7e29612c075' - '31a30c91ddb4caf7fcad1d25d309efb9170ea768e1b37b2f226f69e3b48a' - '95611dee26d6259dab91084e36cb1c24042cbf168b2fe5f18f991731b8b3' - 'fe4923fa7251c431d503acda180a35ed8d', 16) - sharedRSA_E = 65537L - sharedRSA_D = long( - '009ecbce3861a454ecb1e0fe8f85dd43c92f5825ce2e997884d0e1a949da' - 'a2c5ac559b240450e5ac9fe0c3e31c0eefa6525a65f0c22194004ee1ab46' - '3dde9ee82287cc93e746a91929c5e6ac3d88753f6c25ba5979e73e5d8fb2' - '39111a3cdab8a4b0cdf5f9cab05f1233a38335c64b5560525e7e3b92ad7c' - '7504cf1dc7cb005788afcbe1e8f95df7402a151530d5808346864eb370aa' - '79956a587862cb533791307f70d91c96d22d001a69009b923c683388c9f3' - '6cb9b5ebe64302041c78d908206b87009cb8cabacad3dbdb2792fb911b2c' - 'f4db6603585be9ae0ca3b8e6417aa04b06e470ea1a3b581ca03a6781c931' - '5b62b30e6011f224725946eec57c6d9441', 16) - sharedRSA_P = long( - '00dd6e1d4fffebf68d889c4d114cdaaa9caa63a59374286c8a5c29a717bb' - 'a60375644d5caa674c4b8bc7326358646220e4550d7608ac27d55b6db74f' - '8d8127ef8fa09098b69147de065573447e183d22fe7d885aceb513d9581d' - 'd5e07c1a90f5ce0879de131371ecefc9ce72e9c43dc127d238190de81177' - '3ca5d19301f48c742b', 16) - sharedRSA_Q = long( - '00d7a773d9ebc380a767d2fec0934ad4e8b5667240771acdebb5ad796f47' - '8fec4d45985efbc9532968289c8d89102fadf21f34e2dd4940eba8c09d6d' - '1f16dcc29729774c43275e9251ddbe4909e1fd3bf1e4bedf46a39b8b3833' - '28ef4ae3b95b92f2070af26c9e7c5c9b587fedde05e8e7d86ca57886fb16' - '5810a77b9845bc3127', 16) - # For reference, when encoded as a subject public key info, the - # base64-encoded sha-256 hash of this key is - # K+uamI+1JmrxMsBxEfGOoydEDJVMa5MY/eaTj+43Lzc= - alternateRSA_N = long( - '00cd6e66a71b9a104c7c5f270b5869da966a52e547f8a026eef128c4d51f' - 'a7d949b1df8a1e342c59cbad0fb6ef867427bd9e76f2e9bf0b582745c646' - '4446db7bdd4d0f2f361da724ff206d070b3d75ad87d690fa307dcccc2ad1' - '4283921f9621f2a564e7e9f708a98556194df12fb4b0a2f0b89f76ac7e59' - '668285aa50f14f310b6ebd8f001d0c115393bd27f3334f67780abfe0b19e' - '5ac3414c5b4a3819fbed39198050e1c660e44cacaf108cbe1671d5a14602' - '6090f371b2873d419eeb6de982fb493c3d4d33fb8a12bd65f1c59a3494dd' - 'd7e1131aa45e896d817bbb28e6fd4c2323ed17a26dc8e4e49281decc641e' - 'f7b7acfe65e7c0e5212fb2a9d472902c35', 16) - alternateRSA_E = 65537L - alternateRSA_D = long( - '6ae6e0946550aeda9e7e059b69ceebe90a3b490542e4545e53309bfd2c13' - 'f486dd012ea6b90fbb4aba2c4b4e29f1981c9cb1d986b9dbf56bba6b8b75' - '4c4a3b12d65ee87a88c3ca04d9a2e2df7e84166171cecfe31c13cecb194a' - '3b9d76c271b80b498f45b93fd0b78a2e70d8e9b26598e51bae1fdb7384a2' - '4b99b31f9bf351d9692c00d6f05c30424be4b4de55331ac77532c3fdaf74' - '95dbf7aef601b517ed227d0efa3de443d56d8b29e556f6be938eabf4c0e4' - '2e2fe38bec60cba5b5ff9192b68620ee4b629b9d0b64b9a8810809813b0b' - '04e485d97fdad2961c0982a589863643974e3900dd8a75112a0fffc59f4b' - '24c31307901dd04a848b02db32f61a01', 16) - alternateRSA_P = long( - '00feeacc987c0494cb5e9550eefb9dc56f9d957022a11539dae04c6361ab' - 'd5081dce2a6aec0905450886f5bb7e56e8bd2bef37cfa16fbda5ffc268ca' - 'e0499017552c37fa4a041341d67d4d69d093d8950f50672fb085b636560e' - '2446689474b29be7abeba358ab7bc4cde3fd065d46f762adeb5c4b54ccca' - '651a14b498311615b1', 16) - alternateRSA_Q = long( - '00ce4dca3fdda86b8c800c268082446633c8aaf0f20c729878092198585b' - 'd2ed134a7bdb2c93f829f99e6e9070db6598b3113627fd87bf6bc46cb2e5' - '121777cbea9c41e74c9c2c248931dbccb5ae8a1dccfad284784cc35b8329' - 'abc420ce95640085dbf325fa7f6a2a567d487c1ef67d07a56c6beade9404' - 'd039ba01adf328ebc5', 16) - def __init__(self, paramStream, now=datetime.datetime.utcnow()): self.versionValue = 2 # a value of 2 is X509v3 self.signature = 'sha256WithRSAEncryption' @@ -267,13 +172,8 @@ class Certificate: self.subject = 'Default Subject' self.signatureAlgorithm = 'sha256WithRSAEncryption' self.extensions = None - self.subjectRSA_N = self.sharedRSA_N - self.subjectRSA_E = self.sharedRSA_E - self.issuerRSA_N = self.sharedRSA_N - self.issuerRSA_E = self.sharedRSA_E - self.issuerRSA_D = self.sharedRSA_D - self.issuerRSA_P = self.sharedRSA_P - self.issuerRSA_Q = self.sharedRSA_Q + self.subjectKey = pykey.RSAKey() + self.issuerKey = pykey.RSAKey() self.decodeParams(paramStream) self.serialNumber = self.generateSerialNumber() @@ -351,20 +251,12 @@ class Certificate: raise UnknownExtensionTypeError(extensionType) def setupKey(self, subjectOrIssuer, value): - if value == 'alternate': - if subjectOrIssuer == 'subject': - self.subjectRSA_N = self.alternateRSA_N - self.subjectRSA_E = self.alternateRSA_E - elif subjectOrIssuer == 'issuer': - self.issuerRSA_N = self.alternateRSA_N - self.issuerRSA_E = self.alternateRSA_E - self.issuerRSA_D = self.alternateRSA_D - self.issuerRSA_P = self.alternateRSA_P - self.issuerRSA_Q = self.alternateRSA_Q - else: - raise UnknownKeyTargetError(subjectOrIssuer) + if subjectOrIssuer == 'subject': + self.subjectKey = pykey.RSAKey(value) + elif subjectOrIssuer == 'issuer': + self.issuerKey = pykey.RSAKey(value) else: - raise UnknownKeySpecificationError(value) + raise UnknownKeyTargetError(subjectOrIssuer) def addExtension(self, extensionType, extensionValue): if not self.extensions: @@ -460,21 +352,6 @@ class Certificate: def getSignatureAlgorithm(self): return stringToAlgorithmIdentifier(self.signature) - def getSubjectPublicKey(self): - rsaKey = RSAPublicKey() - rsaKey.setComponentByName('N', univ.Integer(self.subjectRSA_N)) - rsaKey.setComponentByName('E', univ.Integer(self.subjectRSA_E)) - return univ.BitString(byteStringToHexifiedBitString(encoder.encode(rsaKey))) - - def getSubjectPublicKeyInfo(self): - algorithmIdentifier = rfc2459.AlgorithmIdentifier() - algorithmIdentifier.setComponentByName('algorithm', rfc2459.rsaEncryption) - algorithmIdentifier.setComponentByName('parameters', univ.Null()) - spki = rfc2459.SubjectPublicKeyInfo() - spki.setComponentByName('algorithm', algorithmIdentifier) - spki.setComponentByName('subjectPublicKey', self.getSubjectPublicKey()) - return spki - def toDER(self): tbsCertificate = rfc2459.TBSCertificate() tbsCertificate.setComponentByName('version', self.getVersion()) @@ -483,7 +360,8 @@ class Certificate: tbsCertificate.setComponentByName('issuer', self.getIssuer()) tbsCertificate.setComponentByName('validity', self.getValidity()) tbsCertificate.setComponentByName('subject', self.getSubject()) - tbsCertificate.setComponentByName('subjectPublicKeyInfo', self.getSubjectPublicKeyInfo()) + tbsCertificate.setComponentByName('subjectPublicKeyInfo', + self.subjectKey.asSubjectPublicKeyInfo()) if self.extensions: extensions = rfc2459.Extensions().subtype( explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3)) @@ -492,14 +370,11 @@ class Certificate: extensions.setComponentByPosition(count, extension) count += 1 tbsCertificate.setComponentByName('extensions', extensions) - tbsDER = encoder.encode(tbsCertificate) - rsaPrivateKey = rsa.PrivateKey(self.issuerRSA_N, self.issuerRSA_E, self.issuerRSA_D, - self.issuerRSA_P, self.issuerRSA_Q) - signature = rsa.sign(tbsDER, rsaPrivateKey, 'SHA-256') certificate = rfc2459.Certificate() certificate.setComponentByName('tbsCertificate', tbsCertificate) certificate.setComponentByName('signatureAlgorithm', self.getSignatureAlgorithm()) - certificate.setComponentByName('signatureValue', byteStringToHexifiedBitString(signature)) + tbsDER = encoder.encode(tbsCertificate) + certificate.setComponentByName('signatureValue', self.issuerKey.sign(tbsDER)) return encoder.encode(certificate) def toPEM(self): diff --git a/security/manager/ssl/tests/unit/pykey.py b/security/manager/ssl/tests/unit/pykey.py new file mode 100755 index 000000000000..862c67c5a8b1 --- /dev/null +++ b/security/manager/ssl/tests/unit/pykey.py @@ -0,0 +1,210 @@ +#!/usr/bin/env python +# +# 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/. + +""" +Provides methods for signing data and representing a key as a +subject public key info for use with pyasn1. + +The key specification format is currently very simple. If it is +empty, one RSA key is used. If it consists of the string +'alternate', a different RSA key is used. In the future it will +be possible to specify other properties of the key (type, +strength, signature algorithm, etc.). +""" + +from pyasn1.codec.der import encoder +from pyasn1.type import univ, namedtype +from pyasn1_modules import rfc2459 +import binascii +import rsa + +def byteStringToHexifiedBitString(string): + """Takes a string of bytes and returns a hex string representing + those bytes for use with pyasn1.type.univ.BitString. It must be of + the form "''H", where the trailing 'H' indicates to + pyasn1 that the input is a hex string.""" + return "'%s'H" % binascii.hexlify(string) + +class UnknownBaseError(Exception): + """Base class for handling unexpected input in this module.""" + def __init__(self, value): + self.value = value + self.category = 'input' + + def __str__(self): + return 'Unknown %s type "%s"' % (self.category, repr(self.value)) + + +class UnknownKeySpecificationError(UnknownBaseError): + """Helper exception type to handle unknown key specifications.""" + + def __init__(self, value): + UnknownBaseError.__init__(self, value) + self.category = 'key specification' + + +class RSAPublicKey(univ.Sequence): + """Helper type for encoding an RSA public key""" + componentType = namedtype.NamedTypes( + namedtype.NamedType('N', univ.Integer()), + namedtype.NamedType('E', univ.Integer())) + + +class RSAKey: + # For reference, when encoded as a subject public key info, the + # base64-encoded sha-256 hash of this key is + # VCIlmPM9NkgFQtrs4Oa5TeFcDu6MWRTKSNdePEhOgD8= + sharedRSA_N = long( + '00ba8851a8448e16d641fd6eb6880636103d3c13d9eae4354ab4ecf56857' + '6c247bc1c725a8e0d81fbdb19c069b6e1a86f26be2af5a756b6a6471087a' + 'a55aa74587f71cd5249c027ecd43fc1e69d038202993ab20c349e4dbb94c' + 'c26b6c0eed15820ff17ead691ab1d3023a8b2a41eea770e00f0d8dfd660b' + '2bb02492a47db988617990b157903dd23bc5e0b8481fa837d38843ef2716' + 'd855b7665aaa7e02902f3a7b10800624cc1c6c97ad96615bb7e29612c075' + '31a30c91ddb4caf7fcad1d25d309efb9170ea768e1b37b2f226f69e3b48a' + '95611dee26d6259dab91084e36cb1c24042cbf168b2fe5f18f991731b8b3' + 'fe4923fa7251c431d503acda180a35ed8d', 16) + sharedRSA_E = 65537L + sharedRSA_D = long( + '009ecbce3861a454ecb1e0fe8f85dd43c92f5825ce2e997884d0e1a949da' + 'a2c5ac559b240450e5ac9fe0c3e31c0eefa6525a65f0c22194004ee1ab46' + '3dde9ee82287cc93e746a91929c5e6ac3d88753f6c25ba5979e73e5d8fb2' + '39111a3cdab8a4b0cdf5f9cab05f1233a38335c64b5560525e7e3b92ad7c' + '7504cf1dc7cb005788afcbe1e8f95df7402a151530d5808346864eb370aa' + '79956a587862cb533791307f70d91c96d22d001a69009b923c683388c9f3' + '6cb9b5ebe64302041c78d908206b87009cb8cabacad3dbdb2792fb911b2c' + 'f4db6603585be9ae0ca3b8e6417aa04b06e470ea1a3b581ca03a6781c931' + '5b62b30e6011f224725946eec57c6d9441', 16) + sharedRSA_P = long( + '00dd6e1d4fffebf68d889c4d114cdaaa9caa63a59374286c8a5c29a717bb' + 'a60375644d5caa674c4b8bc7326358646220e4550d7608ac27d55b6db74f' + '8d8127ef8fa09098b69147de065573447e183d22fe7d885aceb513d9581d' + 'd5e07c1a90f5ce0879de131371ecefc9ce72e9c43dc127d238190de81177' + '3ca5d19301f48c742b', 16) + sharedRSA_Q = long( + '00d7a773d9ebc380a767d2fec0934ad4e8b5667240771acdebb5ad796f47' + '8fec4d45985efbc9532968289c8d89102fadf21f34e2dd4940eba8c09d6d' + '1f16dcc29729774c43275e9251ddbe4909e1fd3bf1e4bedf46a39b8b3833' + '28ef4ae3b95b92f2070af26c9e7c5c9b587fedde05e8e7d86ca57886fb16' + '5810a77b9845bc3127', 16) + sharedRSA_exp1 = long( + '0096472b41a610c0ade1af2266c1600e3671355ba42d4b5a0eb4e9d7eb35' + '81400ba5dd132cdb1a5e9328c7bbc0bbb0155ea192972edf97d12751d8fc' + 'f6ae572a30b1ea309a8712dd4e33241db1ee455fc093f5bc9b592d756e66' + '21474f32c07af22fb275d340792b32ba2590bbb261aefb95a258eea53765' + '5315be9c24d191992d', 16) + sharedRSA_exp2 = long( + '28b450a7a75a856413b2bda6f7a63e3d964fb9ecf50e3823ef6cc8e8fa26' + 'ee413f8b9d1205540f12bbe7a0c76828b7ba65ad83cca4d0fe2a220114e1' + 'b35d03d5a85bfe2706bd50fce6cfcdd571b46ca621b8ed47d605bbe765b0' + 'aa4a0665ac25364da20154032e1204b8559d3e34fb5b177c9a56ff93510a' + '5a4a6287c151de2d', 16) + sharedRSA_coef = long( + '28067b9355801d2ef52dfa96d8adb589673cf8ee8a9c6ff72aeeabe9ef6b' + 'e58a4f4abf05f788947dc851fdaa34542147a71a246bfb054ee76aa346ab' + 'cd2692cfc9e44c51e6f069c735e073ba019f6a7214961c91b26871caeabf' + '8f064418a02690e39a8d5ff3067b7cdb7f50b1f53418a703966c4fc774bf' + '7402af6c43247f43', 16) + + # For reference, when encoded as a subject public key info, the + # base64-encoded sha-256 hash of this key is + # MQj2tt1yGAfwFpWETYUCVrZxk2CD2705NKBQUlAaKJI= + alternateRSA_N = long( + '00c175c65266099f77082a6791f1b876c37f5ce538b06c4acd22b1cbd46f' + 'a65ada2add41c8c2498ac4a3b3c1f61487f41b698941bd80a51c3c120244' + 'c584a4c4483305e5138c0106cf08be9a862760bae6a2e8f36f23c5d98313' + 'b9dfaf378345dace51d4d6dcd2a6cb3cc706ebcd3070ec98cce40aa591d7' + '295a7f71c5be66691d2b2dfec84944590bc5a3ea49fd93b1d753405f1773' + '7699958666254797ed426908880811422069988a43fee48ce68781dd22b6' + 'a69cd28375131f932b128ce286fa7d251c062ad27ef016f187cdd54e832b' + '35b8930f74ba90aa8bc76167242ab1fd6d62140d18c4c0b8c68fc3748457' + '324ad7de86e6552f1d1e191d712168d3bb', 16) + alternateRSA_E = 65537L + alternateRSA_D = long( + '7e3f6d7cb839ef66ae5d7dd92ff5410bb341dc14728d39034570e1a37079' + '0f30f0681355fff41e2ad4e9a9d9fcebfbd127bdfab8c00affb1f3cea732' + '7ead47aa1621f2ac1ee14ca02f04b3b2786017980b181a449d03b03e69d1' + '12b83571e55434f012056575d2832ed6731dce799e37c83f6d51c55ab71e' + 'b58015af05e1af15c747603ef7f27d03a6ff049d96bbf854c1e4e50ef5b0' + '58d0fb08180e0ac7f7be8f2ff1673d97fc9e55dba838077bbf8a7cff2962' + '857785269cd9d5bad2b57469e4afcd33c4ca2d2f699f11e7c8fbdcd484f0' + '8d8efb8a3cb8a972eb24bed972efaae4bb712093e48fe94a46eb629a8750' + '78c4021a9a2c93c9a70390e9d0a54401', 16) + alternateRSA_P = long( + '00e63fc725a6ba76925a7ff8cb59c4f56dd7ec83fe85bf1f53e11cac9a81' + '258bcfc0ae819077b0f2d1477aaf868de6a8ecbeaf7bb22b196f2a9ad82d' + '3286f0d0cc29de719e5f2be8e509b7284d5963edd362f927887a4c4a8979' + '9d340d51b301ac7601ab27179024fcaadd38bf6522af63eb16461ec02a7f' + '27b06fe09ddda7c0a1', 16) + alternateRSA_Q = long( + '00d718b1fe9f8f99f00e832ae1fbdc6fe2ab27f34e049c498010fa0eb708' + '4852182346083b5c96c3eee5592c014a410c6b930b165c13b5c26aa32eac' + '6e7c925a8551c25134f2f4a72c6421f19a73148a0edfaba5d3a6888b35cb' + 'a18c00fd38ee5aaf0b545731d720761bbccdee744a52ca415e98e4de01cd' + 'fe764c1967b3e8cadb', 16) + alternateRSA_exp1 = long( + '01e5aca266c94a88d22e13c2b92ea247116c657a076817bdfd30db4b3a9d' + '3095b9a4b6749647e2f84e7a784fc7838b08c85971cf7a036fa30e3b91c3' + 'c4d0df278f80c1b6e859d8456adb137defaa9f1f0ac5bac9a9184fd4ea27' + '9d722ea626f160d78aad7bc83845ccb29df115c83f61b7622b99bd439c60' + '9b5790a63c595181', 16) + alternateRSA_exp2 = long( + '0080cc45d10d2484ee0d1297fc07bf80b3beff461ea27e1f38f371789c3a' + 'f66b4a0edd2192c227791db4f1c77ae246bf342f31856b0f56581b58a95b' + '1131c0c5396db2a8c3c6f39ea2e336bc205ae6a2a0b36869fca98cbba733' + 'cf01319a6f9bb26b7ca23d3017fc551cd8da8afdd17f6fa2e30d34868798' + '1cd6234d571e90b7df', 16) + alternateRSA_coef = long( + '6f77c0c1f2ae7ac169561cca499c52bdfbe04cddccdbdc12aec5a85691e8' + '594b7ee29908f30e7b96aa6254b80ed4aeec9b993782bdfc79b69d8d58c6' + '8870fa4be1bc0c3527288c5c82bb4aebaf15edff110403fc78e6ace6a828' + '27bf42f0cfa751e507651c5638db9393dd23dd1f6b295151de44b77fe55a' + '7b0df271e19a65c0', 16) + + def __init__(self, specification = None): + if not specification: + self.RSA_N = self.sharedRSA_N + self.RSA_E = self.sharedRSA_E + self.RSA_D = self.sharedRSA_D + self.RSA_P = self.sharedRSA_P + self.RSA_Q = self.sharedRSA_Q + self.RSA_exp1 = self.sharedRSA_exp1 + self.RSA_exp2 = self.sharedRSA_exp2 + self.RSA_coef = self.sharedRSA_coef + elif specification == 'alternate': + self.RSA_N = self.alternateRSA_N + self.RSA_E = self.alternateRSA_E + self.RSA_D = self.alternateRSA_D + self.RSA_P = self.alternateRSA_P + self.RSA_Q = self.alternateRSA_Q + self.RSA_exp1 = self.alternateRSA_exp1 + self.RSA_exp2 = self.alternateRSA_exp2 + self.RSA_coef = self.alternateRSA_coef + else: + raise UnknownKeySpecificationError(specification) + + def asSubjectPublicKeyInfo(self): + """Returns a subject public key info representing + this key for use by pyasn1.""" + algorithmIdentifier = rfc2459.AlgorithmIdentifier() + algorithmIdentifier.setComponentByName('algorithm', rfc2459.rsaEncryption) + algorithmIdentifier.setComponentByName('parameters', univ.Null()) + spki = rfc2459.SubjectPublicKeyInfo() + spki.setComponentByName('algorithm', algorithmIdentifier) + rsaKey = RSAPublicKey() + rsaKey.setComponentByName('N', univ.Integer(self.RSA_N)) + rsaKey.setComponentByName('E', univ.Integer(self.RSA_E)) + subjectPublicKey = univ.BitString(byteStringToHexifiedBitString(encoder.encode(rsaKey))) + spki.setComponentByName('subjectPublicKey', subjectPublicKey) + return spki + + def sign(self, data): + """Returns a hexified bit string representing a + signature by this key over the specified data. + Intended for use with pyasn1.type.univ.BitString""" + rsaPrivateKey = rsa.PrivateKey(self.RSA_N, self.RSA_E, self.RSA_D, self.RSA_P, self.RSA_Q) + signature = rsa.sign(data, rsaPrivateKey, 'SHA-256') + return byteStringToHexifiedBitString(signature) From 9e28b0964fb68f886f09b1d4c952eaf0dca3bb4e Mon Sep 17 00:00:00 2001 From: David Keeler Date: Thu, 4 Jun 2015 17:03:48 -0700 Subject: [PATCH 03/69] bug 1178988 - convert test_ocsp_url to generate certificates at build time r=Cykesiopka Also enable loading of certificates and private keys into GenerateOCSPResponse --- security/manager/ssl/tests/unit/moz.build | 1 + security/manager/ssl/tests/unit/pycert.py | 21 ++ security/manager/ssl/tests/unit/pykey.py | 76 ++++++- .../manager/ssl/tests/unit/test_ocsp_url.js | 8 +- .../tests/unit/test_ocsp_url/bad-scheme.der | Bin 895 -> 0 bytes .../test_ocsp_url/bad-scheme.pem.certspec | 3 + .../ssl/tests/unit/test_ocsp_url/ca.der | Bin 845 -> 0 bytes .../tests/unit/test_ocsp_url/ca.pem.certspec | 4 + .../ssl/tests/unit/test_ocsp_url/cert9.db | Bin 43008 -> 0 bytes .../tests/unit/test_ocsp_url/empty-port.der | Bin 904 -> 0 bytes .../test_ocsp_url/empty-port.pem.certspec | 3 + .../unit/test_ocsp_url/empty-scheme-url.der | Bin 910 -> 0 bytes .../empty-scheme-url.pem.certspec | 3 + .../ssl/tests/unit/test_ocsp_url/ftp-url.der | Bin 903 -> 0 bytes .../unit/test_ocsp_url/ftp-url.pem.certspec | 3 + .../ssl/tests/unit/test_ocsp_url/generate.py | 40 ---- .../ssl/tests/unit/test_ocsp_url/hTTp-url.der | Bin 914 -> 0 bytes .../unit/test_ocsp_url/hTTp-url.pem.certspec | 3 + .../tests/unit/test_ocsp_url/https-url.der | Bin 917 -> 0 bytes .../unit/test_ocsp_url/https-url.pem.certspec | 3 + .../ssl/tests/unit/test_ocsp_url/int.der | Bin 845 -> 0 bytes .../tests/unit/test_ocsp_url/int.key.keyspec | 0 .../tests/unit/test_ocsp_url/int.pem.certspec | 4 + .../ssl/tests/unit/test_ocsp_url/key4.db | Bin 72704 -> 0 bytes .../ssl/tests/unit/test_ocsp_url/moz.build | 42 ++++ .../unit/test_ocsp_url/negative-port.der | Bin 908 -> 0 bytes .../test_ocsp_url/negative-port.pem.certspec | 3 + .../tests/unit/test_ocsp_url/no-host-url.der | Bin 894 -> 0 bytes .../test_ocsp_url/no-host-url.pem.certspec | 3 + .../tests/unit/test_ocsp_url/no-path-url.der | Bin 908 -> 0 bytes .../test_ocsp_url/no-path-url.pem.certspec | 3 + .../test_ocsp_url/no-scheme-host-port.der | Bin 889 -> 0 bytes .../no-scheme-host-port.pem.certspec | 3 + .../unit/test_ocsp_url/no-scheme-url.der | Bin 904 -> 0 bytes .../test_ocsp_url/no-scheme-url.pem.certspec | 3 + .../ssl/tests/unit/test_ocsp_url/pkcs11.txt | 5 - .../unit/test_ocsp_url/unknown-scheme.der | Bin 905 -> 0 bytes .../test_ocsp_url/unknown-scheme.pem.certspec | 3 + .../tlsserver/cmd/GenerateOCSPResponse.cpp | 212 +++++++++++++++++- 39 files changed, 388 insertions(+), 61 deletions(-) delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/bad-scheme.der create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/bad-scheme.pem.certspec delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/ca.der create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/ca.pem.certspec delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/cert9.db delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/empty-port.der create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/empty-port.pem.certspec delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/empty-scheme-url.der create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/empty-scheme-url.pem.certspec delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/ftp-url.der create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/ftp-url.pem.certspec delete mode 100755 security/manager/ssl/tests/unit/test_ocsp_url/generate.py delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/hTTp-url.der create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/hTTp-url.pem.certspec delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/https-url.der create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/https-url.pem.certspec delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/int.der create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/int.key.keyspec create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/int.pem.certspec delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/key4.db create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/moz.build delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/negative-port.der create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/negative-port.pem.certspec delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/no-host-url.der create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/no-host-url.pem.certspec delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/no-path-url.der create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/no-path-url.pem.certspec delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-host-port.der create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-host-port.pem.certspec delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-url.der create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-url.pem.certspec delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/pkcs11.txt delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/unknown-scheme.der create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/unknown-scheme.pem.certspec diff --git a/security/manager/ssl/tests/unit/moz.build b/security/manager/ssl/tests/unit/moz.build index 85bea2f51150..2433f5b843f2 100644 --- a/security/manager/ssl/tests/unit/moz.build +++ b/security/manager/ssl/tests/unit/moz.build @@ -12,6 +12,7 @@ TEST_DIRS += [ 'test_cert_version', 'test_intermediate_basic_usage_constraints', 'test_pinning_dynamic', + 'test_ocsp_url', ] if not CONFIG['MOZ_NO_SMART_CARDS']: diff --git a/security/manager/ssl/tests/unit/pycert.py b/security/manager/ssl/tests/unit/pycert.py index daf85f7d16c3..0da1e71b5516 100755 --- a/security/manager/ssl/tests/unit/pycert.py +++ b/security/manager/ssl/tests/unit/pycert.py @@ -26,6 +26,7 @@ extKeyUsage:[serverAuth,clientAuth,codeSigning,emailProtection nsSGC, # Netscape Server Gated Crypto OCSPSigning,timeStamping] subjectAlternativeName:[,...] +authorityInformationAccess: Where: [] indicates an optional field or component of a field @@ -120,6 +121,18 @@ def getASN1Tag(asn1Type): type from the pyasn1 package""" return asn1Type.baseTagSet.getBaseTag().asTuple()[2] +def stringToAccessDescription(string): + """Helper function that takes a string representing a URI + presumably identifying an OCSP authority information access + location. Returns an AccessDescription usable by pyasn1.""" + accessMethod = rfc2459.id_ad_ocsp + accessLocation = rfc2459.GeneralName() + accessLocation.setComponentByName('uniformResourceIdentifier', string) + sequence = univ.Sequence() + sequence.setComponentByPosition(0, accessMethod) + sequence.setComponentByPosition(1, accessLocation) + return sequence + def stringToAlgorithmIdentifier(string): """Helper function that converts a description of an algorithm to a representation usable by the pyasn1 package""" @@ -247,6 +260,8 @@ class Certificate: self.addExtKeyUsage(value) elif extensionType == 'subjectAlternativeName': self.addSubjectAlternativeName(value) + elif extensionType == 'authorityInformationAccess': + self.addAuthorityInformationAccess(value) else: raise UnknownExtensionTypeError(extensionType) @@ -321,6 +336,12 @@ class Certificate: count += 1 self.addExtension(rfc2459.id_ce_subjectAltName, subjectAlternativeName) + def addAuthorityInformationAccess(self, ocspURI): + sequence = univ.Sequence() + accessDescription = stringToAccessDescription(ocspURI) + sequence.setComponentByPosition(0, accessDescription) + self.addExtension(rfc2459.id_pe_authorityInfoAccess, sequence) + def getVersion(self): return rfc2459.Version(self.versionValue).subtype( explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)) diff --git a/security/manager/ssl/tests/unit/pykey.py b/security/manager/ssl/tests/unit/pykey.py index 862c67c5a8b1..3d701791a358 100755 --- a/security/manager/ssl/tests/unit/pykey.py +++ b/security/manager/ssl/tests/unit/pykey.py @@ -5,8 +5,10 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. """ -Provides methods for signing data and representing a key as a -subject public key info for use with pyasn1. +Reads a key specification from stdin or a file and outputs a +PKCS #8 file representing the (private) key. Also provides +methods for signing data and representing the key as a subject +public key info for use with pyasn1. The key specification format is currently very simple. If it is empty, one RSA key is used. If it consists of the string @@ -18,8 +20,10 @@ strength, signature algorithm, etc.). from pyasn1.codec.der import encoder from pyasn1.type import univ, namedtype from pyasn1_modules import rfc2459 +import base64 import binascii import rsa +import sys def byteStringToHexifiedBitString(string): """Takes a string of bytes and returns a hex string representing @@ -53,6 +57,30 @@ class RSAPublicKey(univ.Sequence): namedtype.NamedType('E', univ.Integer())) +class RSAPrivateKey(univ.Sequence): + """Helper type for encoding an RSA private key""" + componentType = namedtype.NamedTypes( + namedtype.NamedType('version', univ.Integer()), + namedtype.NamedType('modulus', univ.Integer()), + namedtype.NamedType('publicExponent', univ.Integer()), + namedtype.NamedType('privateExponent', univ.Integer()), + namedtype.NamedType('prime1', univ.Integer()), + namedtype.NamedType('prime2', univ.Integer()), + namedtype.NamedType('exponent1', univ.Integer()), + namedtype.NamedType('exponent2', univ.Integer()), + namedtype.NamedType('coefficient', univ.Integer()), + ) + + +class PrivateKeyInfo(univ.Sequence): + """Helper type for encoding a PKCS #8 private key info""" + componentType = namedtype.NamedTypes( + namedtype.NamedType('version', univ.Integer()), + namedtype.NamedType('privateKeyAlgorithm', rfc2459.AlgorithmIdentifier()), + namedtype.NamedType('privateKey', univ.OctetString()) + ) + + class RSAKey: # For reference, when encoded as a subject public key info, the # base64-encoded sha-256 hash of this key is @@ -186,6 +214,37 @@ class RSAKey: else: raise UnknownKeySpecificationError(specification) + def toDER(self): + privateKeyInfo = PrivateKeyInfo() + privateKeyInfo.setComponentByName('version', 0) + algorithmIdentifier = rfc2459.AlgorithmIdentifier() + algorithmIdentifier.setComponentByName('algorithm', rfc2459.rsaEncryption) + algorithmIdentifier.setComponentByName('parameters', univ.Null()) + privateKeyInfo.setComponentByName('privateKeyAlgorithm', algorithmIdentifier) + rsaPrivateKey = RSAPrivateKey() + rsaPrivateKey.setComponentByName('version', 0) + rsaPrivateKey.setComponentByName('modulus', self.RSA_N) + rsaPrivateKey.setComponentByName('publicExponent', self.RSA_E) + rsaPrivateKey.setComponentByName('privateExponent', self.RSA_D) + rsaPrivateKey.setComponentByName('prime1', self.RSA_P) + rsaPrivateKey.setComponentByName('prime2', self.RSA_Q) + rsaPrivateKey.setComponentByName('exponent1', self.RSA_exp1) + rsaPrivateKey.setComponentByName('exponent2', self.RSA_exp2) + rsaPrivateKey.setComponentByName('coefficient', self.RSA_coef) + rsaPrivateKeyEncoded = encoder.encode(rsaPrivateKey) + privateKeyInfo.setComponentByName('privateKey', univ.OctetString(rsaPrivateKeyEncoded)) + return encoder.encode(privateKeyInfo) + + def toPEM(self): + output = '-----BEGIN PRIVATE KEY-----' + der = self.toDER() + b64 = base64.b64encode(der) + while b64: + output += '\n' + b64[:64] + b64 = b64[64:] + output += '\n-----END PRIVATE KEY-----' + return output + def asSubjectPublicKeyInfo(self): """Returns a subject public key info representing this key for use by pyasn1.""" @@ -208,3 +267,16 @@ class RSAKey: rsaPrivateKey = rsa.PrivateKey(self.RSA_N, self.RSA_E, self.RSA_D, self.RSA_P, self.RSA_Q) signature = rsa.sign(data, rsaPrivateKey, 'SHA-256') return byteStringToHexifiedBitString(signature) + + +# The build harness will call this function with an output file-like +# object and a path to a file containing a specification. This will +# read the specification and output the key as ASCII-encoded PKCS #8. +def main(output, inputPath): + with open(inputPath) as configStream: + output.write(RSAKey(configStream.read()).toPEM()) + +# When run as a standalone program, this will read a specification from +# stdin and output the certificate as PEM to stdout. +if __name__ == '__main__': + print RSAKey(sys.stdin.read()).toPEM() diff --git a/security/manager/ssl/tests/unit/test_ocsp_url.js b/security/manager/ssl/tests/unit/test_ocsp_url.js index 385f568f853e..b731a1bcf6be 100644 --- a/security/manager/ssl/tests/unit/test_ocsp_url.js +++ b/security/manager/ssl/tests/unit/test_ocsp_url.js @@ -25,14 +25,14 @@ function start_ocsp_responder(expectedCertNames, expectedPaths) { } function check_cert_err(cert_name, expected_error) { - let cert = constructCertFromFile("test_ocsp_url/" + cert_name + ".der"); + let cert = constructCertFromFile("test_ocsp_url/" + cert_name + ".pem"); return checkCertErrorGeneric(certdb, cert, expected_error, certificateUsageSSLServer); } function run_test() { - addCertFromFile(certdb, "test_ocsp_url/ca.der", 'CTu,CTu,CTu'); - addCertFromFile(certdb, "test_ocsp_url/int.der", ',,'); + addCertFromFile(certdb, "test_ocsp_url/ca.pem", 'CTu,CTu,CTu'); + addCertFromFile(certdb, "test_ocsp_url/int.pem", ',,'); // Enabled so that we can force ocsp failure responses. Services.prefs.setBoolPref("security.OCSP.require", true); @@ -44,7 +44,7 @@ function run_test() { add_test(function() { clearOCSPCache(); let ocspResponder = failingOCSPResponder(); - check_cert_err("bad-scheme",SEC_ERROR_CERT_BAD_ACCESS_LOCATION); + check_cert_err("bad-scheme", SEC_ERROR_CERT_BAD_ACCESS_LOCATION); ocspResponder.stop(run_next_test); }); diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/bad-scheme.der b/security/manager/ssl/tests/unit/test_ocsp_url/bad-scheme.der deleted file mode 100644 index 0b26ef20e5e0a87faff02dc708b53b85ac45fc9d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 895 zcmXqLVy-r5VoF}X%*4pV#B32OV!+GBsnzDu_MMlJk(HIfAkL86fRl|ml!Z;0DKywn z*gz1(;SlC>PRz+n%P-2yOf(cT5CI9Y3-kKsm*$luX67k`Wu}%JiWmri#JPmI1A=`O zLQ;!MGV{_6c?`HfqRhg~nRz7!a^k#(CI+TPhKA(s( z%(nlt=PP1=|txjUzD<3 z8?LmSUZwM!^BzA(m4g1+4uh52*V{xHxa{v05EQ>siq?bfi~wsdnnEzZ7vU?v3cjUa^Wvh**6^Xe8IjMTd`MKbvBP-0pWWazNyugG7 z3|>Zto=dYM#P_aSz4+Z1>+ADkxLyhUozfk%XStA4jMdxe(P69pu-z3k(C|O<-e=B~ z483=1Ultu$n_+*(ccZR@q-!hNpJVqfHdnpf6|qU9onQIW=Oz1&DX&+G%Rj;As?F+? ze#l&f=i%EqTPJHQc1+OL@^|b0@j5@D_QJXIS#2Fjx1U|y|3`A~Ve1EX*NWchl3jIL zcCq32ov-6}&i+?&{E6!M#kXq~b5HRRdpk3qIsLVlrI7%*4pV#L6(=wnyH8myJ`a&7D}zC-A-4f18*?ZNn=n&o zu%WPlAc(^u%;lVzlbM!Zl$V)kC}to65@Z+V_02EMD@n}EQwYmUEjJV~5CVyF33CSo z`znN_7MEn^rNhi)7G_FLG>{YLH8e3WH8M0bH#Radj1uQHLgv!i`X)vtWDhg4GB7tW z@-rATF>*0AF)}i&HC!mv()#Vg%KZ!L`4zr5XReb{T_tpA#3qUYbU-nPS7VE)hKOjW@c=Qq+~{u@?>aLjio_q0*{X(Cr=@oCo5=|5*|-fO~d zE^Dl5>foPQ8d}8_H08d9@*Wsyy?`eA<_@4ln? z)#$#1xBdEHzxx;F-zhZW#Bmwq9zKuwU}Wue2(!2Dwmp6skmvVU9rLR!pm=BE_d zcaHDabIYU66fzUGb@Nv*{XJOw5c7jEe;f_zZY}F)1s|!fL?G$oL;Q%z%jm7-ozN zen($2ay)r`e$@`!!RPVFqL`g+Eh%?CqoZNIrx(m_sXp@;pkJjs+jE@9U3Gu@n0=Npz) z^4$~sUwPqJDBGWt(Mk25t%84_v7F7mQ>Of}|I0C5rKdCRH*R`(`jWe&+UN8d&In(1 zKigl8VPBs+{L+`{x^hG^Gkq54r#o9)l?zSf#Rr9bKueVp^# Q@c;hxvw8(nmg)Wk0Q$W{i2wiq diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/ca.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/ca.pem.certspec new file mode 100644 index 000000000000..d809dbd635d4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:ca +extension:basicConstraints:cA, +extension:keyUsage:keyCertSign,cRLSign diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/cert9.db b/security/manager/ssl/tests/unit/test_ocsp_url/cert9.db deleted file mode 100644 index ddfac8e73aa0f843fdd5466edc19b1dd1d138b65..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43008 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 diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/empty-port.der b/security/manager/ssl/tests/unit/test_ocsp_url/empty-port.der deleted file mode 100644 index 8293d79b2ab6b1309ea348fb0458dde0d3c659cf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 904 zcmXqLVs0^LV#-;-%*4pV#KI{2MAd+ojZ>@5qwPB{BO@y-gF&1jw*e;`b0`a&FjHu- zp|F7NzBYs2+K?@Hxw}t0*P}8a|Zfqr`cQkhun_RJR}M1!iHc z)ZBuSO5K9|q7s89MkQpQGqN%;H!<=v0L8hOniv@w9<{v-)~+iwDmj1UeM!)?+lQ{N z<#(E@Dp9xW#{c>I1ve@OuAH)R>YC}Rie4}JV|P2pAc1???v=;uGnnNrYMj5n>gr8{ zx|MO4A8$D&JN=qv{;oSu|1f^moH}s|Q>1fyaM{N)87ZQ>uz}mnTIq7GPeoYDK{ur_KO6{|zg}YxX+31vC2sII64L;~+x~sDP_wuNf^P>OT zS?H9{^$Bh6zSlKpmxcD!;C6=zT`J5rUuqBRx{{fEQ0SfKMp4tMZ|>Pl%!~|-i=7P| z4NTZLwAp}3gPoC)MZ-YNKn2D(U~H4fC@Cqh($_C9FV{=0NX#wBN!3fv&$ZGACm~s3 z7A6A* z=kY2lWxAmub!&=D-+XzctMxLbx>G|OuerZ@^UWb^&GJM4*moVcaK^fN=fj;JJhJCq znY=kui|@k1trCar)?}vt+EQELCv$o4D$Kc`TFh#IvE{c)3mTpTA+Ay}!)_7r)Cm>=bLG z9#q!w&aEZEVPo;j7x(uaZ8Q7v@V;f@>lD*RuX|d4#0G6FrjsO4v diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/empty-port.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/empty-port.pem.certspec new file mode 100644 index 000000000000..4f3e296f9c91 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/empty-port.pem.certspec @@ -0,0 +1,3 @@ +issuer:int +subject:empty-port +extension:authorityInformationAccess:http://www.example.com:/ diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/empty-scheme-url.der b/security/manager/ssl/tests/unit/test_ocsp_url/empty-scheme-url.der deleted file mode 100644 index 599c6ca54ee9a7712dc85aa6eb5818cc0cc9643b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 910 zcmXqLV(v0%Vk%m|%*4pV#KO2lO~`@5qwPB{BO@y-gF&1jw*e;`b0`a&FjHu- zp|F7NzBYs2+K?@Hxw}t0*P}8a|Z$hd3@xyS+*6TeJ|9p=pNw49S%%x!Qie>tqvn!lo%Er6wXKc}7%sSx`az zl17uAAN|igv6ht5{2g{zFS)F+XW!n8%^QL)7MHl6UdcC0wQ+G__I<7VkWCMl^6fk- zqV}@jx8^aapg#wN?eY(|p1ad%>T|n;U$uE-7}w*EmMy~5w~X-a7Q0gl~#zH4u*U%5Pwk%^g+ zfpM|3fun&58;3R9<>lpisTGO21v#mD$@#ff7C@j6 zPDrxCEKCLr$iWOuX24)(WU%{iI&9jG`pNef^;_P&zSBzf596hG-?n>nRL$-dzp#DJ zBT~Mo-^4VRQXkBi3_Ig`^cYH`Q)Z-C;6M{QWZ~D~6EY>5_h@%$pCb z`SEGrCW&2l*w>t!c(8#@l#5L^ZpFd?*2!KvhbKnU8 zb+KKu%Wrn@{nQg)9ygP-U`~?_7t5`*{*PPrek{Aer+)sI3%9-VoSy8h8rwVymMLv! z6cym@@7;1Ran|#6x2rF=gty%buI7mnX6T8v;L8kIc*p;~8e2w*VP5M?qqCXKu};^2 f{n|8ljX}rV8YPwg5i1&QWbWlH{L^Th`m7lM7R^o` diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/empty-scheme-url.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/empty-scheme-url.pem.certspec new file mode 100644 index 000000000000..e8959653f3c1 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/empty-scheme-url.pem.certspec @@ -0,0 +1,3 @@ +issuer:int +subject:empty-scheme-url +extension:authorityInformationAccess:://www.example.com:8888/ diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/ftp-url.der b/security/manager/ssl/tests/unit/test_ocsp_url/ftp-url.der deleted file mode 100644 index efa716a4b2a620b65ecd0d316f44456fd21d89c8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 903 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

=h`h!ceN7%}uSptrb zcq(-p&RpLHDC*$*0FPXuP9(LG;xBDjIc6I}Z^oIGPYsdK@Z+buRin{SdRGgVQoejC zyP7zHcr|+Y5&_k=5sb6nA9XjWp8#YnjVsrHB_bfbQA|g6bg^}-pNjrjEF)LZv0=HF zd)p{g4|Z&?uC32k49*CcuM1*L!<-yw6j}*62)3pvV)7jVQj_rPWH)ZbMlxy9B_$|o zZbEhN`|um^>|Niw-}m}<*Zc?bfB64${yz!N|9k$QrGL0Z7_qJVSoGt;Ml7G=jHWix zzvut|>u<+D=l>QQrTB@l{a6U?1RIz}$X<6<6=UCrHz5DFS6vuBse(SLq(9(-*v9T0 zs>R1H@R+X+#Z6-;Az0XH9{yeUn-veE7H;@-i8{_JGC_rWIY#VBxk^hqTZ8*SuFUEX^#$wQ`sIVS6+s4&N(cQ z=q)SEjMbG}ALDNu805$VtK`I_e?3cLKO znyhuX0rl0AeuDLQ*3WtIpiv_=H+x)%n8s8$0+;1f5%k@p>5{jEt_ce^8e%s|g}BTZ zTOrHW#Q9wqOVmUr=rVro&ppo^RF6Pqb9&!j}I|2zmN?1$mB8Wu| zPNR{j0PnJHVn`}~GFPCG5302!zoYBzj;|5Bo&1=`xVtO-p6czM3rWKI7$n9!VdA~G z`ygR;jl4_in;K_W$-qom-YQB6p- z)Vwr{kKAw4XlT+6UKpk8R~M!wlp_$_2bq;Anq}pBRy$50-?Kg)uSCnWqR$4>g_vK8 zLlwCw4A`XL3>5M~B867M4O8cma16KTil)`;_*aFX3Z@9p*uy5gV*3*&`D^ck9OUS2 z=Hv^dpp>nt^GbU!=RcRkUOi^YV}xs9%j0Xi>`&$d6!JkLMeJ;GD1_BQgCvJM0wY1# zbuI*)JLNTk*p=|)Ol)$;%ljb1&8idgI@>?!}0~VebxnB@Lef_Whw;7 zq#XYU`FBglLsHT!_7)jt13Dl zB#&>#2M^W^RTxD^&KwKcile8fyy$Cwo6r1hf64#<@%|5=-yh`HCX9zXh+(1^Ca6#4 zEm^H!r~erZ9=UX-sP~j33jvX|;gD)p<9!bzy%?k;Ku{M(w=t=T5ASHTlo&=;{OU`@ z{F2GH_DB7={$$?3As>=lTluzr7^q+sZ;-jteuj9PKq)=-8Jy8LTkc@qc#v!J;66wc zIexQ{Zx&jyS8J(8fm2s2WPy0dpAuz*`|%{exCDfrIytZm$JTQ?LNllq}O@wSD#}RIS;_ylC?fS4~__W*%X){ z>a{1-%T<5#C-nr%_z*wBf#8RjPB%Iaw5}CBW@;08ZVBPr^|7rL6K8?x`N!eY`xr|v zh=XJc?=Tvj`*L-4UV)rhb@48#d zoV{F7m zA((%TUtA~{DG88p#oj@*96;Q4gS;2S4FLR{fV?i4C_PWcaQ~5IFIUL~m{>+k^%&c!4Gbq1IuppKbtpr#q{zvTA0DkC7VyZg z!aq`fh2^OCny+S;|EuJS7Y+pt5=;m;%P(78&yDKt_QHGx@%)c!ay2JZ$g7R9ykq5q z6Vl>(Ea&Ysb@*|UdI4tPLOPvYz+cg+R$US)pkyJ|0R^-Xup zSAI9QY|34niPLtD&t3C-np_X=ViL$mDhb8S!qlUlp)QUNhV#-_QguI*x%t}D-Ak&B z5?Q(_JrRpd|0Mm8oPWAYVn~UJOx8{2>Ka;B0xtj1Ecsv@1%)n1QD&hx#Wy+2pFMWZ zRyTD-6-DiYgA;L*mkX@DgznGW%8&1`_U*0Nq*mCdf}pHwy@RB_4{?CMn^x80m|jRx zs(xkb(DTnJeUxprcEpukG_@nF6|Vd>nby+-r8)^8*3Yrw;zfMWe#i})7F-dY6jAio z$T2kq)D!fh0!TZD$Cs^^gWv^$Yu((hF8WUkR;}a48b_qwC2CG-JYF%)d#M?U)M9{j z{23h4B#pgcC=1~4D|ss3+B)A6l7=n$JahnYfSV1=DLbA|jT zw=Cyt9A$=BRI6r$BxjNJ^O7j9f;^s~mmW8{U%ODG#CyOzq&cB@zKY~LmN3zj5Roz^ zrFCqH?1hT`y!&aQ{9_jy;(5E(sky6hI&AK67rR1@DJN}|QyWKj*%dgO71xuvOFNTH z9Aj_KcH-o=Am%dg`lNh8J|9&hwcEIYB?*isv8)oRyPxNOtbGD4lc!X1D&il?b+>d{ zKZq3$CZ09{xAQz0(3>-$%SdO8#g&@v?o%ejf5A!n(QED4kh)&~8&h#XjSzo1d{Zt* zM;kcBdr=IWe)8>UB8M41+{6r|l4y(!qnbGEAVCW{XGe>MwRlr**5xrWceuq{P#X&a znAHBBwxvK%EgGeqd`GJ`7db?E%(glguVNFt&3?+qzp3h$K$4Gb)9=!; zsj#zMkDjK=A1{dBSEIOpVEkAl$&AZt>#m!Fglfv}?b3fR|3~;Q=l`2%^uOo-hhhQg zwPw1j9%8I-pe~zuh7Tf^|2_ZzUw=FPIsXqWBi%5MM<9l6cjydjINHWtYbN|YyaD-t z&rk@v2ZhARDVjpFD*u@XFXn4VooIZSyO~enA2=$eWL*VNVv(G0whW12M$w_gv!}JP zidC%7UV+0*_b4R@ADeHtQS3iw4yfr~^!2f@l~v7iK6wigBlN+TR`o`yDOJYuYgAKv zU4(*rEDg9#VS2ae>#pXmv(y8V{WsTah_PnUIURnS6g{-lwbsU?PrPv;sKw=m>&~JP zDTk32H7tY0Xq z`5W)5g^Tn--R&_lm0G_;iaRDtyB*TEP&OmYRhI3Md4w=v5YRMsBnFPM{*rgO#|D{> z2%6S{!Q;>KVh+D#uX!6?(R&|gmmTZaBYQWu@0A9?eEz6i`v!-|FRe;w-ppk-a&mJo zMH<5ZA8?&mt4pac(<=6au^F5gTJBBidjjb`|7{U5H=T&)XxQnLtsL61nq9c-Pw!Re zSLZa^x4qH_@weGorJ6vO*AJ2UiM$}O0T-0jdO_Jkn02`JxMs~hk3e|@7!CjD{QqVU zP;O97P&d$*pv|E3pch~`AoC#2VBDZMV47fVAQxaS!5YD)!H&UEz?s0GfLnowffs`J zfv}2WsaANdsmFoQ9VQ%+6s1^72yN%`&VPM> zEKs{4NF-3Z5l9p;J0}ZB1TZ_GZ~O&NI|oSgulAq*WBIG0n*}5RsGSWY@lW=@{ci}8 z49pJTPXcBK@TU-h3xR%b+qX7#*JoofGvnao=K32C449P-{1+=Li!qBa=fAE`Km=xG zL;BUq%E`&jX88B_;sCR<;r?o6GiEpB`qv>DWq0Hue?IDwh?)gc)!D0br9WeU=l`vF9*Nvg8BQ5hcLGle6&}p1^DzQdsN!lbt z>!1^fp_~Ae;6N!Kq)>kA(H(~nYnMd|5r$^x`}QR`xi;~!A@%ZWiwfgBB9eQL{-^kI zu@5o2gnL(}c!^J5ocDUy)w;p1R&GDXu}FxXAr?Rh29)wa5+!*>Q|Z&BtPK1)ssOl` zs!auwXh<8PH@p$KR1UilY8ZH{PogV46LAPzda-RQ~Q0CAd%io!TG6& zVGAt-+qIW8sfYO{>~>ScyFFfL4Yg@C07?*`ln)Xq4du%XmO?49sbusM26HIRKTDS# zpA4U^Axy20Amxf8-bY!~s^7sncGT-!Co>8Y2V?xAXzx|sJ5LMPlwUzh&C)O39^-+4*$&bI9C#hN&Nn8o{8Pdz1);#_sM~=QEmb zQHf&`-=gyA5EmkF_Us4l#<^-YGaOhRT4qF z(xq%%T0gn(br|uu1oNvv*Z+i;AY@cU@A!USE~dZmZgiiDTg70&3mHHO1Dx_9%3AfT zKvj23s_tYv9KoPoITBtW6j%Sp>Jtr)(u#6nt>pVC-|>AjjC1otYSE-dH4KbVuFJ=d z!V%v{>wmQz0(xhp=uheo{hR#v;|Kr0y0rRHvteCVg-}n*C)4ML`O&aoTms(|3S{GN zLh~3*MN0ULJ!{`O0&_-TE=8wG3bCbGp$y(bM}g_eJ%tz$^iz-h|IyK);^bRT zknf-!c|W1Z5WFKfvP#Hm7|+p}jcHlEfs~u_znul8fjYMn3aT7ffNofiVE}i0q~4mx zQb|xKL`Ft=;fPx3!SGC9yujg#aUFR%)2kNelccOo`wrm^geTZ@-4Rq(Q&+|_4DUxK z>SsN)EZ=5A@ONEx;!|7fDX57t3^l0GQ>kB6{F%EAB#UyxtJt+;$=sx-&ChuF#%ubg zzvbULhO}6u%esba;b=*L=4(0BUc%5tGd07)*!nhmEJ)wDDnu3T`fYl0oSnU%gewfreh(PP@s|#Y2?#Gu@cO5i|{i`=MD4(_!LspawoizJLoA)E3 zvk15`Mm=%h>c!wJG>+TfhJYZPemMJLVdVOP2&u$5ROTOa;_6(q)k}*JQQ|KNYcPvc zw+F}@J3qOR(@L6MhX^W4CDS`YLG3)vWSzEklexrg+5?#tggtXtS_DAJ!7DwdLDh^d zm+IU#hs|sth{HcxuRGxm$!3~}*j@@5ABpI!3rVIDY{=vSE=Sg}WudOVl3GYE-2ddv z@iM028oZ&~ZI|zq(!6ZH`Gh!Qy=)0HlD`_`>P3{+l3!7UgH`zBAN@a_ch4AcVJd}D zt}IwdHEKEf$_HEyY{l1$19(L|rI2)^CxXTdgkuq72lmHDaM@)U-BB&Lo@`=7zw%WC zN49+0B0pI)Zc+0Ud~Z%LF=kjxt}l7zd4%PoWM`CXuwu;B$!ss!{*0E@wrQgCIEN6P zPA-RFM4bzT0)j0Yh1dLfLOgjd>If(^VLxMs9($r#q!Nl)HJwzwXs}GwV8NH+lrge% z854&d*cr`wbh3#s5S#_kaT64@pTJCP^Ew-hF&X(>YYkEZjE~8ReLQj~4QdUvZD{zD zmA$n5q(;0$WL_J4c&Hx3NcV-dm7?zm-Mip(RJ_es+m3@=uFu3bVE=>qAL4&m|GSw= z08Dnj?ElGIlWyAPBM%s^GbuQ_wlFf`5wZJs{qKMM?f7T?@0&&ZU=+A>^h>~rajJyc zb5idr(7z9Ffc|I4bhtY?5FjAI6LQzJ$VpW;!{?}sJ)a5Rk3QZKj}X-7Zpw|fNSe8U z$I8J-6Z$r*+LH?r-62(y3O3S>u`j*)O>vwKs6xvLCZ7Oz z3D!GiqWzuLz3qNS=sLZqmlMP)sTJEVqk;u~#RdSV+;joJTnIj}>c8l8Q0>1-U2u&{{Z z9Yms=04jpmO`c3}r0{Wj$Z?-l-KyV)nzS-XN<-(x#k+`Wm1#>(O-G>{CAi|1AP+QV zl*)|L{@U{3;O=qjf1b}X=>1@un6hAxr`x5AA#QuopR9k+fC1~LFcy?=@9kA9 zj?<%eoFExPagPjM3nkL4PUy>S77WvQ(AEXjD52+LCh@0_tMI0!KbQXovY-$LGZrv3=CDcikf;DbGah>4apgWDycOIo1N>?n0?KL+nh z2XMe>5dIne6MT>V>%ovfEkJre2)@Sz-#>r|2Icn%=9lRIL1k9a-URu}nBmB#UQzN@ zvNlC_-PzJ%-?(Qm%)W4okt%Nh4-Yi`*G{;m?_F`3&$V{>WH#E(V$lBtr2;X9{p@vX)BlOB6)A(3lq93(df=-~ta zB_dGD2Zi+v(sOf>u^V8zm!ihSe<3%e~*Vbt4Me6W-m0-x5K4~Vm%UF zvI0u(@h55{?Jh&1qF)^lzn<9@IYj~}5r9%YNTgsr)j-?RPIX3Z=Nh-&f1S-I$>+(G zb1TvDx)7&tZ2I0a3fhdxg%ZTPQ5r#XK18frdkH7pHSCG-k9y{w z41OzwgSitra*5(3xQgO)Gx|Qx$B1l*h_>w0>?{uZ=HPA2nO0^qk=4TgJb#@i%x;QV z(iENE(T;3YYRjIDfm#2Yzd8c~iLG@cJ+~{KeSAjxZdzHVGJDAHZRwZDNCT*gPy}hg_4aOR(i9%^gwX!ig^z3p%V|9B0!RqC@ zKY_&BD()w?3#&QY?U1^xkBo)9oU)+m6ha<*!6?gP4nKv$mN(xk}7<+}PPrgX0{pd?# zHe}|Om(!E{N~g(JTbDKY)1z9}ouGqcpU);0XUl`0c-P~{$Hvv4b0y~Q45N0G6U z%X^Ui&)fybJfQX`;osaSCNgVT9uFVnC^Y=!uJoeat+0)LiliW$!Fo3dk>hh$D`$YnD^H9}%q^$F5p?zO+Uk?FTqie}22j7QSvN(~=U zrMlNMy>g-DoOBfh$(mmv^TTuon?0VVUSQ&^vYJD*ykqia#CZpjOE3t*%KA8Ql`JjcFN zxzv1agF+sUk8;@MxF7WXNBrMtZ!e72G)94HBwUV|=p^*qid+OUz|y-l47X1pj_Ei^ zG1h&TZble<=D1M|DbzZg^tgJ1R6Plkl&Z~-7c&l=y3O|{0Xupj*n8=KbbzuoeSLA) zkSEw~aZ3+Ui;;^~e?CQ`Soq`VDNHlIb~9!f2cgU>v@9A;rB+NIf7jij83ec_fi@D7Pj-%9@lbf^oJyX~NIw!pecV1;gQRVT)bTk$P7a8H2dn83_A2 ze9bp=P8iXjRxjUqozaA8M^`fRR}qECMN!#`TPA@sLwmGxPa~zc>^d;Hhig0L0;_XSo~7F&@2Scd2PDTQ*U!U8Pq)x_j!^F zKAyGYrLxyCCuo8C+#iZD8f{NNTy0Af2t<-b^qI~iER4evjrmcC;IyI}TubZ}L~7sJ zkgwU`)Ne{0`YA<=@3%IMj+R z1Ke5<#i(|D?c#%0OVzU%ZNV3Eyb>~?v2;o-e1Op)_P753{rs;#>Hk>2#W25>+8=WD z$9_GF<`HtE>d_geY(_wW&t%6(Bhf5n=}gt#;g{Kh!+^&JngOuI&183+H%g@wwu#p$ zAu)$A%Xxjg(Fk_I)WqkFu zw*>wPl%}B|rMne0d%*mdIDirzIORjM_2H}%L9Q?|Mg;UnHFBSyanSiSc>5zwzTa8R zbM1J$IdLB)>W3FaFegNG%#`MoSZGg~yl`G$>nR+0gmAoSVZ=8z0u%tyek}m}cr7{1 z{wkS2#FdeU+N+nA&jomPx6YOu9IW62I&w_QUo@g=d$QbMpx?XQV?KRAtSLBe`i1>A z|H4S@Tfgyd^s}~teZfihrZ8~^q22^1Z?WDA@dvU_JoK1YR^VOl#p?&AU}=Kh<|N9|9<`_G8iui z7%!mH#|11AtQKq>Y#$r}oDN(X+zdPjJRiIVd>rE};(UVQ(}SKV?a!*Ykit2_%gJ-!YH-fXlzGJDE{^6|k=BWyjduEy>#^+}8~kIp zy`j&?2D1Q4T%eQ>QYmfRp!nb}z~B%Kp~FAEhbRm?apS*vg~m_nC+CpfrRsGb<>MyP|63Xlz9!4#1kN=tHBacAFN0} zmCA#;M)u2vl^5g0O{iymw7ZYenKWvmBLAbNU*!RYXGh{&m#2PI-PKI-FXK8KnZ|o-WDM+tP+-t_7Z>92O%=b}3z_pj%kIB`vUJU5!3}!ZpB96t!ypO&{{ayUhbI64 diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/moz.build b/security/manager/ssl/tests/unit/test_ocsp_url/moz.build new file mode 100644 index 000000000000..5cf49a7f9946 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/moz.build @@ -0,0 +1,42 @@ +# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +test_certificates = ( + 'bad-scheme.pem', + 'ca.pem', + 'empty-port.pem', + 'empty-scheme-url.pem', + 'ftp-url.pem', + 'hTTp-url.pem', + 'https-url.pem', + 'int.pem', + 'negative-port.pem', + 'no-host-url.pem', + 'no-path-url.pem', + 'no-scheme-host-port.pem', + 'no-scheme-url.pem', + 'unknown-scheme.pem', +) + +for test_certificate in test_certificates: + input_file = test_certificate + '.certspec' + GENERATED_FILES += [test_certificate] + props = GENERATED_FILES[test_certificate] + props.script = '../pycert.py' + props.inputs = [input_file, '!/config/buildid'] + TEST_HARNESS_FILES.xpcshell.security.manager.ssl.tests.unit.test_ocsp_url += ['!%s' % test_certificate] + +test_keys = ( + 'int.key', +) + +for test_key in test_keys: + input_file = test_key + '.keyspec' + GENERATED_FILES += [test_key] + props = GENERATED_FILES[test_key] + props.script = '../pykey.py' + props.inputs = [input_file] + TEST_HARNESS_FILES.xpcshell.security.manager.ssl.tests.unit.test_ocsp_url += ['!%s' % test_key] diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/negative-port.der b/security/manager/ssl/tests/unit/test_ocsp_url/negative-port.der deleted file mode 100644 index 2e334b682eac577b0203cc5153c32ba269dc99f9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 908 zcmXqLV(u_#Vk%g`%*4pV#KQ3J#{mOgHcqWJkGAi;jEt#>@(l2>B(G)ZYY{<^3wnYp~axu40>Kt@k6Wa+!B+a^nK{4d=3cFK*0{HdP`tM&8$ z4|n*he#_{4WFm3$_iD#KGmNtICB7_i zc(%_zD2T10VuvPU-D&|Zz59#rN@VR@XZb*vHH1^gUnM8}$(kHPx#i7gbML3h@(aIV zRN5i>U;4Y{7;V5vxx{|6Ml!&bgR8IV_j|yL9dEUI@AO&pbNu-~r}et9{=sL9ib_Ab``BJzn`x#r zyDC|lXO@Igw`Z-nxO(yTTLC_WH~M?DKkn01KbgT&?04|eZ_zK8(`|!&B7O$!$laCl ze_zEx&amqH9^d!f<-S;@bhANxrHCR^)im)(f2J?by&C@EhMe$g!|A;@RbPaKm)Tbu dUEg%0T3NhS;CT(l6MmsAUs)&H&Ed1GbOBNzO6~vv diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/negative-port.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/negative-port.pem.certspec new file mode 100644 index 000000000000..4abc0720519f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/negative-port.pem.certspec @@ -0,0 +1,3 @@ +issuer:int +subject:negative-port +extension:authorityInformationAccess:http://www.example.com:-1 diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/no-host-url.der b/security/manager/ssl/tests/unit/test_ocsp_url/no-host-url.der deleted file mode 100644 index 236dd8186cb5db9bc51f0758d76d3b5e10c410ad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 894 zcmXqLVy-f1VoF-T%*4pV#KN#OCC7l5jZ>@5qwPB{BO@y-gF&1jw*e;`b0`a&FjHu- zp|F7NzBYs2+K?@Hxw}t0*P}8a|Z=qr`cQkhunFRJR}MDrRBs zynNk^{NfVb(xM!LCPpP>uQReTFgG#sGXTZ8n3@YMc#+$3tD})# z1r}>ggn8U5+fmi=@J`xf3452B>U$)vA9=yxAkRAnn{z4V>#4_N7#`0uUzlLf z)iisXbBy=7JG);TQ`63wpliPTQ{tMM%01`Q4v9}V9Gh47UBs-5%f&T|@9AE)iC_4aY`%Q(^ZMbX;8bZO5)ZZCtm`iCl>hUbNnc zgQdxH^3&(5WKW&Xn>;D>_yfh44J!}s3n;zAzO+>J%>BH#pD$lf-6j2+B|Gu8j?jr0 SWmV_*pVU4T!7??O-x&bGu1^;L diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/no-host-url.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/no-host-url.pem.certspec new file mode 100644 index 000000000000..4ac76e7eb33a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/no-host-url.pem.certspec @@ -0,0 +1,3 @@ +issuer:int +subject:no-host-url +extension:authorityInformationAccess:http://:8888/ diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/no-path-url.der b/security/manager/ssl/tests/unit/test_ocsp_url/no-path-url.der deleted file mode 100644 index 2333b33a1f837eeccd2f654daa90b7033e48e02b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 908 zcmXqLV(u_#Vk%g`%*4pV#KL&~^cMqOHcqWJkGAi;jEth&j1wXVrpV!WO#g!akZanaLIC;Qwu9IOP;=; z;Ls|6C51V^`u&Nx>j_$OX6sInbia1+NRX^_kD2D(n#Z3K)wjg|*ITi4qrJ@#=CMP2?l)IQX#_49~ zWQAFn3>c6@8kop{A%v}Afq$oc?^l1f zH^s-(Ui5U!b*H8ln;ZL19P6K-7uYT!@~8d|e+KtER_TnH+iZdw?$+0x*9&Axbo}%n zmgnvBX@~25%>q7q8RxR?;&ShgPi=eoZMsYX=f=h9RiDiq`9(PwINo3X;eMa3$BMPK z@5JrW{>VSuk#_ga^6hQA`A+XSaiU)1b2=NpwC9Omi&p%Jc6|_P-ML-!-1!8i^!-zG zzV81jrgG-#6_L;HnO^M;@mz6j&)uvmCtU*XUy7Z+_vz~XB}UGNFSZqDEK7X%t4@Dw e@S(KkIZ|A+Wg8pWC0OFUbgt(6ADLRv8x8>IJyX;G diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/no-path-url.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/no-path-url.pem.certspec new file mode 100644 index 000000000000..497bb287967c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/no-path-url.pem.certspec @@ -0,0 +1,3 @@ +issuer:int +subject:no-path-url +extension:authorityInformationAccess:http://www.example.com:8888 diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-host-port.der b/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-host-port.der deleted file mode 100644 index f6e0179a6e48f016bcb4c2c82e50b5dfe482cb61..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 889 zcmXqLVlFjkVv1eB%*4pV#2lCU*?^agQ>)FR?K>|cBP%O|L7XAC0Vf-CC<~h~Q)sZE zuz?_m!y(M&oS2iDmS2>YnP@0xAOaF(7v}ZNFU>1S%*;~=%SdZ*}iC|G%;0yW+(i+9kg#q(ur>M|cy^k3-zuw{Qc)7?ATA=9UPdA?_&OX889$vRW+IEGEInCz;^a^b<&i#sHq z+B9Z4T$po$^EFqk!NuTX9T!vkRHY{DVtkq&#eCYMVn@^i|FbKdOFwwrbnH(1dwcQ= z+szG|nH-d)&R6oxOlxFe+|hX_uX+EQKZoZ05>R>X)3#?V+gG-a>}QjA#HpOrDO=O$ z9{ohvoX_Hq+p%3%PA~OOKHDynZ6bd1D*w)vg0X=gToyQemJ?e1FOK{9&)GIl@6T?{ zWnyMzU|g(Ypk*M-#-YsyOe5@!j4Xl%{J>Cy@(mc<81=!4Mpl@G$$$YlJb_6H7@mv_ zYSG1|*D~F5EMt!EULUE$$U6PdYmB z_Pe*UPB3Mg#_gT>s=F}zV9f(=+rUJT0^zIMcY2>;S-^29XlL}-=)`kD-*2=h`xUN} zzJ7b@Z!>`@vrPUP+D9&Cj(p;>!+)vfG>0!g1v1hevL$Vr@chiKRhxI5PO6dXaQwkt zX}*7I(FDaileRf0d?xW{g#5NZ^Z(T34J7e;F zE+<2t!h?tGy|?etkvIEuar*wv&wHJ2E)bJWU2#d_cEl7W`~6x*MeWkNX5^}>{doDl O)Zv|-`^w|j97_SJmQM-* diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-host-port.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-host-port.pem.certspec new file mode 100644 index 000000000000..42a555e411b5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-host-port.pem.certspec @@ -0,0 +1,3 @@ +issuer:int +subject:no-scheme-host-port +extension:authorityInformationAccess:/ diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-url.der b/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-url.der deleted file mode 100644 index 0bab0213518ee7fff702f6164df06837cb81f73c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 904 zcmXqLVs0^LV#-;-%*4pV#KLIUKf!>PjZ>@5qwPB{BO@y-gF&1jw*e;`b0`a&FjHu- zp|F7NzBYs2+K?@Hxw}t0*P}8a|ZgqQrTPkhumKRJR}MT4rJ1 zynNl_PFeE>6mX5>!4 zOUo~0Z2Zpr_PX7a{?k#uN2Wb2>dG{pRx0qDX@%&cOY>_ukImWnXwMb7ZxajKEccri zw(`dO@LwwPBG-SH%_4itMLnBkROfO&5pVxgEs!x&)-h}Q=k+~XGpB?bNPC%iCFPf$ zcVR#A>fAiz&(C>Iw9aGM_ot=h-DG|F++FjTbf@uui+ao&&Sb5ZWpbhW)GW5gjC)R< zzL!+#-YsyOdafuj4Y}K$_9!sz5!#KXnA?LUTQ^RZb43}UUGh}l?4#!gOiY~Fbk6b z19BJx6Bsaz85vqj_Aq2ToVoV&y|fG#Z@;GZE9+*9I8{DQdUWHKroLf-xW^WQ)m+ED zh4i1#@U`5%khy3@vDO)u&a-roJjxG-^;Oc zkK}t%xeafwG3Fh=^z3>3tOX7HXSPl;WuJY+$l(z~vH6p7-N!A@ z)tL`HbXI#C$gH`4qrRdX&!&e}zy5CQjh}HVAUH12<<9S{8QsPyr`F$)b6#d^b%*4pV#KQ3V{5b<&HcqWJkGAi;jEtMI-j zTQ@f?Iu$fUOqca|=BcmmjZ@y8{qRt^|FqrxLxNG7N3JSwk$APeZtHEqA5sEk>3a-% zmNb_M_DxJZc+Rq9&db*i%|A)p^*f&T;;1&y#`hbQ=i9z^oO?p<+_rU_x}Lma{p@}w zsHgY8+3d+Fi{`#>ZVB>#x=s6SXlLA{h!^v`KX6SJm6=>Op~^@3mG0%uKeZB$E}lK@ z!;WJG$0NTQ8hV-XZ7R{&AADbLR+vNS8q3SS%+FX|xOINt|C*?NvsBN&`Q9;cCHrn& zk-Xu(ApP|DGk22L-AL@7Zu)cQwdzGH4;e_GtlhJG*QHd^{o1`-n_AgKf3AMqy^x8S zk%4isgMpoaAsdG_8!&mWGcvNM8Ymkm!uSS^ZK5S51y=g{<>lpisTGO21v#mD$@#h9 zG$bp`!eqdJ9LB&D1`K0H2Fv$1+}dWayUcyu{hgJ!L@ctYeaEHws!eGn7OeALy*bMK z_QPLA3BMNZZ||pvPPn(-)A){oyo!8;zH-<)yNz3yMU*#N zzv%RNtL4Au?Qd7UWVvo;zx0}F>Ap}8hX-5b>aUrd&Aznlqt&Wa-oNZm{=8oLv;79g zHaJ gG1cX8nyApE+DFG4^BHa$U%Kt&%eug%t}CJv0BJj6PXGV_ diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/unknown-scheme.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/unknown-scheme.pem.certspec new file mode 100644 index 000000000000..a5e62b3e6e65 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/unknown-scheme.pem.certspec @@ -0,0 +1,3 @@ +issuer:int +subject:unknown-scheme-url +extension:authorityInformationAccess:ttp://www.example.com diff --git a/security/manager/ssl/tests/unit/tlsserver/cmd/GenerateOCSPResponse.cpp b/security/manager/ssl/tests/unit/tlsserver/cmd/GenerateOCSPResponse.cpp index 8bb54bcbce6a..a19170611c19 100644 --- a/security/manager/ssl/tests/unit/tlsserver/cmd/GenerateOCSPResponse.cpp +++ b/security/manager/ssl/tests/unit/tlsserver/cmd/GenerateOCSPResponse.cpp @@ -13,6 +13,8 @@ #include "mozilla/ArrayUtils.h" +#include "base64.h" +#include "cert.h" #include "nspr.h" #include "nss.h" #include "plarenas.h" @@ -66,9 +68,8 @@ const static OCSPResponseName kOCSPResponseNameList[] = { // two years old }; - bool -stringToOCSPResponseType(const char* respText, +StringToOCSPResponseType(const char* respText, /*out*/ OCSPResponseType* OCSPType) { if (!OCSPType) { @@ -107,7 +108,201 @@ WriteResponse(const char* filename, const SECItem* item) return true; } +template +SECStatus +ReadFileToBuffer(const char* basePath, const char* filename, char (&buf)[N]) +{ + static_assert(N > 0, "input buffer too small for ReadFileToBuffer"); + if (PR_snprintf(buf, N - 1, "%s/%s", basePath, filename) == 0) { + PrintPRError("PR_snprintf failed"); + return SECFailure; + } + ScopedPRFileDesc fd(PR_OpenFile(buf, PR_RDONLY, 0)); + if (!fd) { + PrintPRError("PR_Open failed"); + return SECFailure; + } + int32_t fileSize = PR_Available(fd); + if (fileSize < 0) { + PrintPRError("PR_Available failed"); + return SECFailure; + } + if (static_cast(fileSize) > N - 1) { + PR_fprintf(PR_STDERR, "file too large - not reading\n"); + return SECFailure; + } + int32_t bytesRead = PR_Read(fd, buf, fileSize); + if (bytesRead != fileSize) { + PrintPRError("PR_Read failed"); + return SECFailure; + } + buf[bytesRead] = 0; + return SECSuccess; +} +namespace mozilla { + +MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPRDir, PRDir, PR_CloseDir); +MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPORTString, unsigned char, PORT_Free); + +}; + +void +AddKeyFromFile(const char* basePath, const char* filename) +{ + const char* PRIVATE_KEY_HEADER = "-----BEGIN PRIVATE KEY-----"; + const char* PRIVATE_KEY_FOOTER = "-----END PRIVATE KEY-----"; + + char buf[16384] = { 0 }; + SECStatus rv = ReadFileToBuffer(basePath, filename, buf); + if (rv != SECSuccess) { + return; + } + if (strncmp(buf, PRIVATE_KEY_HEADER, strlen(PRIVATE_KEY_HEADER)) != 0) { + PR_fprintf(PR_STDERR, "invalid key - not importing\n"); + return; + } + const char* bufPtr = buf + strlen(PRIVATE_KEY_HEADER); + size_t bufLen = strlen(buf); + char base64[16384] = { 0 }; + char* base64Ptr = base64; + while (bufPtr < buf + bufLen) { + if (strncmp(bufPtr, PRIVATE_KEY_FOOTER, strlen(PRIVATE_KEY_FOOTER)) == 0) { + break; + } + if (*bufPtr != '\r' && *bufPtr != '\n') { + *base64Ptr = *bufPtr; + base64Ptr++; + } + bufPtr++; + } + + unsigned int binLength; + ScopedPORTString bin(ATOB_AsciiToData(base64, &binLength)); + if (!bin || binLength == 0) { + PrintPRError("ATOB_AsciiToData failed"); + return; + } + ScopedSECItem secitem(SECITEM_AllocItem(nullptr, nullptr, binLength)); + if (!secitem) { + PrintPRError("SECITEM_AllocItem failed"); + return; + } + memcpy(secitem->data, bin, binLength); + ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot()); + if (!slot) { + PrintPRError("PK11_GetInternalKeySlot failed"); + return; + } + if (PK11_NeedUserInit(slot)) { + if (PK11_InitPin(slot, nullptr, nullptr) != SECSuccess) { + PrintPRError("PK11_InitPin failed"); + return; + } + } + SECKEYPrivateKey* privateKey; + if (PK11_ImportDERPrivateKeyInfoAndReturnKey(slot, secitem, nullptr, nullptr, + true, false, KU_ALL, + &privateKey, nullptr) + != SECSuccess) { + PrintPRError("PK11_ImportDERPrivateKeyInfoAndReturnKey failed"); + return; + } + SECKEY_DestroyPrivateKey(privateKey); +} + +SECStatus +DecodeCertCallback(void* arg, SECItem** certs, int numcerts) +{ + if (numcerts != 1) { + PR_SetError(SEC_ERROR_LIBRARY_FAILURE, 0); + return SECFailure; + } + SECItem* certDEROut = static_cast(arg); + return SECITEM_CopyItem(nullptr, certDEROut, *certs); +} + +void +AddCertificateFromFile(const char* basePath, const char* filename) +{ + char buf[16384] = { 0 }; + SECStatus rv = ReadFileToBuffer(basePath, filename, buf); + if (rv != SECSuccess) { + return; + } + SECItem certDER; + rv = CERT_DecodeCertPackage(buf, strlen(buf), DecodeCertCallback, &certDER); + if (rv != SECSuccess) { + PrintPRError("CERT_DecodeCertPackage failed"); + return; + } + ScopedCERTCertificate cert(CERT_NewTempCertificate(CERT_GetDefaultCertDB(), + &certDER, nullptr, false, + true)); + PORT_Free(certDER.data); + if (!cert) { + PrintPRError("CERT_NewTempCertificate failed"); + return; + } + const char* extension = strstr(filename, ".pem"); + if (!extension) { + PR_SetError(SEC_ERROR_INVALID_ARGS, 0); + return; + } + size_t nicknameLength = extension - filename; + memset(buf, 0, sizeof(buf)); + memcpy(buf, filename, nicknameLength); + buf[nicknameLength] = 0; + ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot()); + if (!slot) { + PrintPRError("PK11_GetInternalKeySlot failed"); + return; + } + rv = PK11_ImportCert(slot, cert, CK_INVALID_HANDLE, buf, false); + if (rv != SECSuccess) { + PrintPRError("PK11_ImportCert failed"); + } +} + +SECStatus +InitializeNSS(const char* nssCertDBDir) +{ + // First attempt to initialize NSS in read-only mode, in case the specified + // directory contains NSS DBs that are tracked by revision control. + // If this succeeds, we're done. + if (NSS_Initialize(nssCertDBDir, "", "", SECMOD_DB, NSS_INIT_READONLY) + == SECSuccess) { + return SECSuccess; + } + // Otherwise, create a new read-write DB and load all .pem and .key files. + if (NSS_Initialize(nssCertDBDir, "", "", SECMOD_DB, 0) != SECSuccess) { + PrintPRError("NSS_Initialize failed"); + return SECFailure; + } + const char* basePath = nssCertDBDir; + // The NSS cert DB path could have been specified as "sql:path". Trim off + // the leading "sql:" if so. + if (strncmp(basePath, "sql:", 4) == 0) { + basePath = basePath + 4; + } + ScopedPRDir fdDir(PR_OpenDir(basePath)); + if (!fdDir) { + PrintPRError("PR_OpenDir failed"); + return SECFailure; + } + for (PRDirEntry* dirEntry = PR_ReadDir(fdDir, PR_SKIP_BOTH); dirEntry; + dirEntry = PR_ReadDir(fdDir, PR_SKIP_BOTH)) { + size_t nameLength = strlen(dirEntry->name); + if (nameLength > 4) { + if (strncmp(dirEntry->name + nameLength - 4, ".pem", 4) == 0) { + AddCertificateFromFile(basePath, dirEntry->name); + } else if (strncmp(dirEntry->name + nameLength - 4, ".key", 4) == 0) { + AddKeyFromFile(basePath, dirEntry->name); + } + } + } + return SECSuccess; +} int main(int argc, char* argv[]) @@ -120,12 +315,9 @@ main(int argc, char* argv[]) argv[0]); exit(EXIT_FAILURE); } - const char* dbdir = argv[1]; - - SECStatus rv; - rv = NSS_Init(dbdir); + SECStatus rv = InitializeNSS(argv[1]); if (rv != SECSuccess) { - PrintPRError("Failed to initialize NSS"); + PR_fprintf(PR_STDERR, "Failed to initialize NSS\n"); exit(EXIT_FAILURE); } PLArenaPool* arena = PORT_NewArena(256 * argc); @@ -141,15 +333,15 @@ main(int argc, char* argv[]) const char* filename = argv[i + 3]; OCSPResponseType ORT; - if (!stringToOCSPResponseType(ocspTypeText, &ORT)) { + if (!StringToOCSPResponseType(ocspTypeText, &ORT)) { PR_fprintf(PR_STDERR, "Cannot generate OCSP response of type %s\n", ocspTypeText); exit(EXIT_FAILURE); } - ScopedCERTCertificate cert; - cert = PK11_FindCertFromNickname(certNick, nullptr); + ScopedCERTCertificate cert(PK11_FindCertFromNickname(certNick, nullptr)); if (!cert) { + PrintPRError("PK11_FindCertFromNickname failed"); PR_fprintf(PR_STDERR, "Failed to find certificate with nick '%s'\n", certNick); exit(EXIT_FAILURE); From da7508611c0eb902e890e69ed84905f2e89e4e6d Mon Sep 17 00:00:00 2001 From: David Keeler Date: Wed, 15 Jul 2015 14:12:02 -0700 Subject: [PATCH 04/69] bug 1178988 - work around PR_ReadDir bug on B2G ICS emulator by loading certs/keys in two phases r=Cykesiopka --- .../tlsserver/cmd/GenerateOCSPResponse.cpp | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/security/manager/ssl/tests/unit/tlsserver/cmd/GenerateOCSPResponse.cpp b/security/manager/ssl/tests/unit/tlsserver/cmd/GenerateOCSPResponse.cpp index a19170611c19..219f97377121 100644 --- a/security/manager/ssl/tests/unit/tlsserver/cmd/GenerateOCSPResponse.cpp +++ b/security/manager/ssl/tests/unit/tlsserver/cmd/GenerateOCSPResponse.cpp @@ -10,6 +10,8 @@ */ #include +#include +#include #include "mozilla/ArrayUtils.h" @@ -290,17 +292,32 @@ InitializeNSS(const char* nssCertDBDir) PrintPRError("PR_OpenDir failed"); return SECFailure; } + // On the B2G ICS emulator, operations taken in AddCertificateFromFile or + // AddKeyFromFile appear to interact poorly with PR_ReadDir (more + // specifically, something is causing PR_ReadDir to never return null - it + // indefinitely loops through every file in the directory, which causes + // timeouts). Rather than waste more time chasing this down, loading + // certificates and keys happens in two phases: filename collection and then + // loading. + std::vector certificates; + std::vector keys; for (PRDirEntry* dirEntry = PR_ReadDir(fdDir, PR_SKIP_BOTH); dirEntry; dirEntry = PR_ReadDir(fdDir, PR_SKIP_BOTH)) { size_t nameLength = strlen(dirEntry->name); if (nameLength > 4) { if (strncmp(dirEntry->name + nameLength - 4, ".pem", 4) == 0) { - AddCertificateFromFile(basePath, dirEntry->name); + certificates.push_back(dirEntry->name); } else if (strncmp(dirEntry->name + nameLength - 4, ".key", 4) == 0) { - AddKeyFromFile(basePath, dirEntry->name); + keys.push_back(dirEntry->name); } } } + for (std::string& certificate : certificates) { + AddCertificateFromFile(basePath, certificate.c_str()); + } + for (std::string& key : keys) { + AddKeyFromFile(basePath, key.c_str()); + } return SECSuccess; } From 24e44df271a008928eeb842994d6ef04ce42da69 Mon Sep 17 00:00:00 2001 From: Terrence Cole Date: Wed, 15 Jul 2015 16:42:32 -0700 Subject: [PATCH 05/69] Bug 1182658 - Add TraceNullableRoot and use it to simplify RootedMarking; r=jonco --HG-- extra : rebase_source : 6ea3255328c1e2856a99990fe98d7ffe4b74df94 --- js/src/gc/Barrier.h | 4 ++ js/src/gc/Marking.cpp | 10 +++++ js/src/gc/RootMarking.cpp | 79 ++++++++++++--------------------------- js/src/gc/Tracer.h | 6 +++ 4 files changed, 44 insertions(+), 55 deletions(-) diff --git a/js/src/gc/Barrier.h b/js/src/gc/Barrier.h index 4b87262a7908..0ec78eb358ea 100644 --- a/js/src/gc/Barrier.h +++ b/js/src/gc/Barrier.h @@ -237,6 +237,8 @@ struct InternalGCMethods { static bool isMarkable(T* v) { return v != nullptr; } + static bool isMarkableTaggedPointer(T* v) { return !IsNullTaggedPointer(v); } + static void preBarrier(T* v) { T::writeBarrierPre(v); } static void postBarrier(T** vp, T* prev, T* next) { T::writeBarrierPost(vp, prev, next); } @@ -256,6 +258,7 @@ template <> struct InternalGCMethods { static bool isMarkable(Value v) { return v.isMarkable(); } + static bool isMarkableTaggedPointer(Value v) { return isMarkable(v); } static void preBarrier(Value v) { DispatchValueTyped(PreBarrierFunctor(), v); @@ -291,6 +294,7 @@ template <> struct InternalGCMethods { static bool isMarkable(jsid id) { return JSID_IS_STRING(id) || JSID_IS_SYMBOL(id); } + static bool isMarkableTaggedPointer(jsid id) { return isMarkable(id); } static void preBarrier(jsid id) { DispatchIdTyped(PreBarrierFunctor(), id); } static void postBarrier(jsid* idp, jsid prev, jsid next) {} diff --git a/js/src/gc/Marking.cpp b/js/src/gc/Marking.cpp index 98514d480a5f..71ad5d2b4adc 100644 --- a/js/src/gc/Marking.cpp +++ b/js/src/gc/Marking.cpp @@ -449,6 +449,15 @@ js::TraceRoot(JSTracer* trc, T* thingp, const char* name) DispatchToTracer(trc, ConvertToBase(thingp), name); } +template +void +js::TraceNullableRoot(JSTracer* trc, T* thingp, const char* name) +{ + AssertRootMarkingPhase(trc); + if (InternalGCMethods::isMarkableTaggedPointer(*thingp)) + DispatchToTracer(trc, ConvertToBase(thingp), name); +} + template void js::TraceRange(JSTracer* trc, size_t len, BarrieredBase* vec, const char* name) @@ -479,6 +488,7 @@ js::TraceRootRange(JSTracer* trc, size_t len, T* vec, const char* name) template void js::TraceEdge(JSTracer*, BarrieredBase*, const char*); \ template void js::TraceManuallyBarrieredEdge(JSTracer*, type*, const char*); \ template void js::TraceRoot(JSTracer*, type*, const char*); \ + template void js::TraceNullableRoot(JSTracer*, type*, const char*); \ template void js::TraceRange(JSTracer*, size_t, BarrieredBase*, const char*); \ template void js::TraceRootRange(JSTracer*, size_t, type*, const char*); FOR_EACH_GC_POINTER_TYPE(INSTANTIATE_ALL_VALID_TRACE_FUNCTIONS) diff --git a/js/src/gc/RootMarking.cpp b/js/src/gc/RootMarking.cpp index bdd928ff58bb..9274df9c7156 100644 --- a/js/src/gc/RootMarking.cpp +++ b/js/src/gc/RootMarking.cpp @@ -50,36 +50,17 @@ MarkPropertyDescriptorRoot(JSTracer* trc, JSPropertyDescriptor* pd, const char* pd->trace(trc); } -template -static inline bool -IgnoreExactRoot(T* thingp) -{ - return false; -} +template +using TraceFunction = void (*)(JSTracer* trc, T* ref, const char* name); -template -inline bool -IgnoreExactRoot(T** thingp) -{ - return IsNullTaggedPointer(*thingp); -} - -template <> -inline bool -IgnoreExactRoot(JSObject** thingp) -{ - return IsNullTaggedPointer(*thingp) || *thingp == TaggedProto::LazyProto; -} - -template +template TraceFn = TraceNullableRoot, class Source> static inline void MarkExactStackRootList(JSTracer* trc, Source* s, const char* name) { Rooted* rooter = s->roots.template gcRooters(); while (rooter) { T* addr = rooter->address(); - if (!IgnoreExactRoot(addr)) - MarkFunc(trc, addr, name); + TraceFn(trc, addr, name); rooter = rooter->previous(); } } @@ -88,18 +69,18 @@ template static void MarkExactStackRootsAcrossTypes(T context, JSTracer* trc) { - MarkExactStackRootList(trc, context, "exact-object"); - MarkExactStackRootList(trc, context, "exact-shape"); - MarkExactStackRootList(trc, context, "exact-baseshape"); - MarkExactStackRootList( + MarkExactStackRootList(trc, context, "exact-object"); + MarkExactStackRootList(trc, context, "exact-shape"); + MarkExactStackRootList(trc, context, "exact-baseshape"); + MarkExactStackRootList( trc, context, "exact-objectgroup"); - MarkExactStackRootList(trc, context, "exact-string"); - MarkExactStackRootList(trc, context, "exact-symbol"); - MarkExactStackRootList(trc, context, "exact-jitcode"); - MarkExactStackRootList(trc, context, "exact-script"); - MarkExactStackRootList(trc, context, "exact-lazy-script"); - MarkExactStackRootList(trc, context, "exact-id"); - MarkExactStackRootList(trc, context, "exact-value"); + MarkExactStackRootList(trc, context, "exact-string"); + MarkExactStackRootList(trc, context, "exact-symbol"); + MarkExactStackRootList(trc, context, "exact-jitcode"); + MarkExactStackRootList(trc, context, "exact-script"); + MarkExactStackRootList(trc, context, "exact-lazy-script"); + MarkExactStackRootList(trc, context, "exact-id"); + MarkExactStackRootList(trc, context, "exact-value"); MarkExactStackRootList( trc, context, "JSPropertyDescriptor"); MarkExactStackRootList List; typedef void (*MarkFunc)(JSTracer* trc, T* ref, const char* name); - static void - markChainIfNotNull(JSTracer* trc, List& list, const char* name) - { - for (Element* r = list.getFirst(); r; r = r->getNext()) { - if (r->get()) - TraceRoot(trc, r->address(), name); - } - } - static void markChain(JSTracer* trc, List& list, const char* name) { for (Element* r = list.getFirst(); r; r = r->getNext()) - TraceRoot(trc, r->address(), name); + TraceNullableRoot(trc, r->address(), name); } }; @@ -358,17 +330,14 @@ js::gc::MarkPersistentRootedChains(JSTracer* trc) { JSRuntime* rt = trc->runtime(); - // Mark the PersistentRooted chains of types that may be null. - PersistentRootedMarker::markChainIfNotNull(trc, rt->functionPersistentRooteds, - "PersistentRooted"); - PersistentRootedMarker::markChainIfNotNull(trc, rt->objectPersistentRooteds, - "PersistentRooted"); - PersistentRootedMarker::markChainIfNotNull(trc, rt->scriptPersistentRooteds, - "PersistentRooted"); - PersistentRootedMarker::markChainIfNotNull(trc, rt->stringPersistentRooteds, - "PersistentRooted"); - - // Mark the PersistentRooted chains of types that are never null. + PersistentRootedMarker::markChain(trc, rt->functionPersistentRooteds, + "PersistentRooted"); + PersistentRootedMarker::markChain(trc, rt->objectPersistentRooteds, + "PersistentRooted"); + PersistentRootedMarker::markChain(trc, rt->scriptPersistentRooteds, + "PersistentRooted"); + PersistentRootedMarker::markChain(trc, rt->stringPersistentRooteds, + "PersistentRooted"); PersistentRootedMarker::markChain(trc, rt->idPersistentRooteds, "PersistentRooted"); PersistentRootedMarker::markChain(trc, rt->valuePersistentRooteds, diff --git a/js/src/gc/Tracer.h b/js/src/gc/Tracer.h index b81b790072d8..7d1fd0ca0155 100644 --- a/js/src/gc/Tracer.h +++ b/js/src/gc/Tracer.h @@ -62,6 +62,12 @@ template void TraceRoot(JSTracer* trc, T* thingp, const char* name); +// Idential to TraceRoot, except that this variant will not crash if |*thingp| +// is null. +template +void +TraceNullableRoot(JSTracer* trc, T* thingp, const char* name); + // Like TraceEdge, but for edges that do not use one of the automatic barrier // classes and, thus, must be treated specially for moving GC. This method is // separate from TraceEdge to make accidental use of such edges more obvious. From ea1fb17fdca87ecdedc44ebbc166e8bd82de9135 Mon Sep 17 00:00:00 2001 From: George Wright Date: Mon, 13 Jul 2015 22:14:31 -0400 Subject: [PATCH 06/69] Bug 1179478 - Support tooltips for option elements in e10s r=mconley --- toolkit/modules/SelectContentHelper.jsm | 1 + toolkit/modules/SelectParentHelper.jsm | 1 + 2 files changed, 2 insertions(+) diff --git a/toolkit/modules/SelectContentHelper.jsm b/toolkit/modules/SelectContentHelper.jsm index c065cf814d11..a2a54839ba4b 100644 --- a/toolkit/modules/SelectContentHelper.jsm +++ b/toolkit/modules/SelectContentHelper.jsm @@ -112,6 +112,7 @@ function buildOptionListForChildren(node) { // We need to do this for every option element as each one can have // an individual style set for direction textDirection: win.getComputedStyle(child).getPropertyValue("direction"), + tooltip: child.title, // XXX this uses a highlight color when this is the selected element. // We need to suppress such highlighting in the content process to get // the option's correct unhighlighted color here. diff --git a/toolkit/modules/SelectParentHelper.jsm b/toolkit/modules/SelectParentHelper.jsm index 2191f1c2b595..c0d5bd5f4651 100644 --- a/toolkit/modules/SelectParentHelper.jsm +++ b/toolkit/modules/SelectParentHelper.jsm @@ -86,6 +86,7 @@ function populateChildren(menulist, options, selectedIndex, zoom, startIndex = 0 item.setAttribute("label", option.textContent); item.style.direction = option.textDirection; item.style.fontSize = adjustedTextSize; + item.setAttribute("tooltiptext", option.tooltip); element.appendChild(item); From d9c58c62bbd769e61821249e7bff379e6d15596b Mon Sep 17 00:00:00 2001 From: George Wright Date: Mon, 13 Jul 2015 22:03:51 -0400 Subject: [PATCH 07/69] Bug 1168691 - Preserve the text direction for the select element itself r=mconley --- toolkit/content/widgets/remote-browser.xml | 1 + toolkit/modules/SelectContentHelper.jsm | 10 +++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/toolkit/content/widgets/remote-browser.xml b/toolkit/content/widgets/remote-browser.xml index 65e2174bc77b..2d26842e390e 100644 --- a/toolkit/content/widgets/remote-browser.xml +++ b/toolkit/content/widgets/remote-browser.xml @@ -315,6 +315,7 @@ } let menulist = document.getElementById(this.getAttribute("selectmenulist")); + menulist.menupopup.style.direction = data.direction; this._selectParentHelper.populate(menulist, data.options, data.selectedIndex, this._fullZoom); this._selectParentHelper.open(this, menulist, data.rect); break; diff --git a/toolkit/modules/SelectContentHelper.jsm b/toolkit/modules/SelectContentHelper.jsm index a2a54839ba4b..533798df5025 100644 --- a/toolkit/modules/SelectContentHelper.jsm +++ b/toolkit/modules/SelectContentHelper.jsm @@ -46,7 +46,8 @@ this.SelectContentHelper.prototype = { this.global.sendAsyncMessage("Forms:ShowDropDown", { rect: rect, options: this._buildOptionList(), - selectedIndex: this.element.selectedIndex + selectedIndex: this.element.selectedIndex, + direction: getComputedDirection(this.element) }); }, @@ -87,9 +88,12 @@ this.SelectContentHelper.prototype = { } +function getComputedDirection(element) { + return element.ownerDocument.defaultView.getComputedStyle(element).getPropertyValue("direction"); +} + function buildOptionListForChildren(node) { let result = []; - let win = node.ownerDocument.defaultView; for (let child of node.children) { let tagName = child.tagName.toUpperCase(); @@ -111,7 +115,7 @@ function buildOptionListForChildren(node) { disabled: child.disabled, // We need to do this for every option element as each one can have // an individual style set for direction - textDirection: win.getComputedStyle(child).getPropertyValue("direction"), + textDirection: getComputedDirection(child), tooltip: child.title, // XXX this uses a highlight color when this is the selected element. // We need to suppress such highlighting in the content process to get From 1d126fb5623a1387ebcb9fa32ffdc4d1a4e14f0a Mon Sep 17 00:00:00 2001 From: Tom Schuster Date: Fri, 17 Jul 2015 23:52:29 +0200 Subject: [PATCH 08/69] Bug 1180184 - Support JSOP_TOSTRING used by template strings in baseline JIT. r=jandem --- js/src/jit/BaselineCompiler.cpp | 28 ++++++++++++++++++++++++++++ js/src/jit/BaselineCompiler.h | 1 + 2 files changed, 29 insertions(+) diff --git a/js/src/jit/BaselineCompiler.cpp b/js/src/jit/BaselineCompiler.cpp index ca09cf01ce2d..810552a741b2 100644 --- a/js/src/jit/BaselineCompiler.cpp +++ b/js/src/jit/BaselineCompiler.cpp @@ -3314,6 +3314,34 @@ BaselineCompiler::emit_JSOP_TOID() return true; } +typedef JSString* (*ToStringFn)(JSContext*, HandleValue); +static const VMFunction ToStringInfo = FunctionInfo(ToStringSlow); + +bool +BaselineCompiler::emit_JSOP_TOSTRING() +{ + // Keep top stack value in R0. + frame.popRegsAndSync(1); + + // Inline path for string. + Label done; + masm.branchTestString(Assembler::Equal, R0, &done); + + prepareVMCall(); + + pushArg(R0); + + // Call ToStringSlow which doesn't handle string inputs. + if (!callVM(ToStringInfo)) + return false; + + masm.tagValue(JSVAL_TYPE_STRING, ReturnReg, R0); + + masm.bind(&done); + frame.push(R0); + return true; +} + bool BaselineCompiler::emit_JSOP_TABLESWITCH() { diff --git a/js/src/jit/BaselineCompiler.h b/js/src/jit/BaselineCompiler.h index b13a74e4ce5b..c9da772f032d 100644 --- a/js/src/jit/BaselineCompiler.h +++ b/js/src/jit/BaselineCompiler.h @@ -183,6 +183,7 @@ namespace jit { _(JSOP_RUNONCE) \ _(JSOP_REST) \ _(JSOP_TOID) \ + _(JSOP_TOSTRING) \ _(JSOP_TABLESWITCH) \ _(JSOP_ITER) \ _(JSOP_MOREITER) \ From ca434de20db7cf31cf05b4135e0fcdb1d2f1bb9d Mon Sep 17 00:00:00 2001 From: Ralph Giles Date: Mon, 6 Jul 2015 16:01:00 -0700 Subject: [PATCH 09/69] Bug 1177363 - Don't check parsers for canPlayType. r=edwin In bug 1080995 we added parsers here so we could reject candidates which depended on blocked elements. Unfortunately this also passes parsers which we weren't previously considering enabling, allowing the free mpegaudioparser to influence the canPlayType results for non-free mp3 decoders. On my system fluh264dec still works when connected straight to qtdemux without h264parse, so false negatives from systems with the decoder but not the parser may be better than false positives for mp3. --- dom/media/gstreamer/GStreamerFormatHelper.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dom/media/gstreamer/GStreamerFormatHelper.cpp b/dom/media/gstreamer/GStreamerFormatHelper.cpp index c4b4fa335d45..9b94817fe39d 100644 --- a/dom/media/gstreamer/GStreamerFormatHelper.cpp +++ b/dom/media/gstreamer/GStreamerFormatHelper.cpp @@ -258,8 +258,9 @@ static gboolean FactoryFilter(GstPluginFeature *aFeature, gpointer) const gchar *className = gst_element_factory_get_klass(GST_ELEMENT_FACTORY_CAST(aFeature)); - if (!strstr(className, "Decoder") && !strstr(className, "Demux") && - !strstr(className, "Parser")) { + // NB: We skip filtering parsers here, because adding them to + // the list can give false decoder positives to canPlayType(). + if (!strstr(className, "Decoder") && !strstr(className, "Demux") { return FALSE; } From b792a1d804c010f98c53300e6aee6405cfcdb643 Mon Sep 17 00:00:00 2001 From: Ralph Giles Date: Fri, 17 Jul 2015 15:13:04 -0700 Subject: [PATCH 10/69] Bug 1177363 - Fix typo. r=bustage CLOSED TREE --HG-- extra : amend_source : dd47bbcdc831eff7aaec3bc3c245ee1398c37c9d --- dom/media/gstreamer/GStreamerFormatHelper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dom/media/gstreamer/GStreamerFormatHelper.cpp b/dom/media/gstreamer/GStreamerFormatHelper.cpp index 9b94817fe39d..3e989254db40 100644 --- a/dom/media/gstreamer/GStreamerFormatHelper.cpp +++ b/dom/media/gstreamer/GStreamerFormatHelper.cpp @@ -260,7 +260,7 @@ static gboolean FactoryFilter(GstPluginFeature *aFeature, gpointer) // NB: We skip filtering parsers here, because adding them to // the list can give false decoder positives to canPlayType(). - if (!strstr(className, "Decoder") && !strstr(className, "Demux") { + if (!strstr(className, "Decoder") && !strstr(className, "Demux")) { return FALSE; } From 94743edaf7f7a75125aba0c026806ae550f07756 Mon Sep 17 00:00:00 2001 From: Valentin Gosu Date: Sat, 18 Jul 2015 00:22:45 +0200 Subject: [PATCH 11/69] Bug 1183781 - Fix leak in nsHostResolver r=sworkman --- netwerk/dns/nsHostResolver.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/netwerk/dns/nsHostResolver.cpp b/netwerk/dns/nsHostResolver.cpp index a343100bbbc9..44ffbdf4d0ac 100644 --- a/netwerk/dns/nsHostResolver.cpp +++ b/netwerk/dns/nsHostResolver.cpp @@ -471,6 +471,15 @@ HostDB_ClearEntry(PLDHashTable *table, } } #endif + + { + MutexAutoLock lock(he->rec->addr_info_lock); + if (he->rec->addr_info) { + delete hr->addr_info; + he->rec->addr_info = nullptr; + } + } + NS_RELEASE(he->rec); } @@ -853,8 +862,12 @@ nsHostResolver::ResolveHost(const char *host, LOG((" Trying AF_UNSPEC entry for host [%s%s%s] af: %s.\n", LOG_HOST(host, netInterface), (af == PR_AF_INET) ? "AF_INET" : "AF_INET6")); - - he->rec->addr_info = nullptr; + // Ensure existing `addr_info` in `he` is cleared before + // copying from `unSpecHe`. + if (he->rec->addr_info) { + delete he->rec->addr_info; + he->rec->addr_info = nullptr; + } if (unspecHe->rec->negative) { he->rec->negative = unspecHe->rec->negative; he->rec->CopyExpirationTimesAndFlagsFrom(unspecHe->rec); From b56b103240cf4977a536ddbc9772655fb1126ce9 Mon Sep 17 00:00:00 2001 From: Olli Pettay Date: Sat, 18 Jul 2015 01:15:44 +0300 Subject: [PATCH 12/69] Bug 1183901, properly support WrapperCache on DistributedContentList, r=wchen --HG-- extra : rebase_source : 1807da23dd4346e2b45c0ff84ee7618ad1bcca11 --- dom/html/HTMLContentElement.cpp | 6 ++++-- dom/html/HTMLContentElement.h | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/dom/html/HTMLContentElement.cpp b/dom/html/HTMLContentElement.cpp index a3ce716d0409..964b6c72088f 100644 --- a/dom/html/HTMLContentElement.cpp +++ b/dom/html/HTMLContentElement.cpp @@ -297,10 +297,12 @@ HTMLContentElement::GetDistributedNodes() return list.forget(); } -NS_IMPL_CYCLE_COLLECTION(DistributedContentList, mParent, mDistributedNodes) +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DistributedContentList, mParent, + mDistributedNodes) NS_INTERFACE_TABLE_HEAD(DistributedContentList) - NS_INTERFACE_TABLE(DistributedContentList, nsINodeList) + NS_WRAPPERCACHE_INTERFACE_TABLE_ENTRY + NS_INTERFACE_TABLE(DistributedContentList, nsINodeList, nsIDOMNodeList) NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(DistributedContentList) NS_INTERFACE_MAP_END diff --git a/dom/html/HTMLContentElement.h b/dom/html/HTMLContentElement.h index 7dbf4d4f7209..ce95a686fd40 100644 --- a/dom/html/HTMLContentElement.h +++ b/dom/html/HTMLContentElement.h @@ -102,7 +102,7 @@ public: explicit DistributedContentList(HTMLContentElement* aHostElement); NS_DECL_CYCLE_COLLECTING_ISUPPORTS - NS_DECL_CYCLE_COLLECTION_CLASS(DistributedContentList) + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DistributedContentList) // nsIDOMNodeList NS_DECL_NSIDOMNODELIST From 1b80a2239c00aa46e4ea9c40708d8b89b88aea19 Mon Sep 17 00:00:00 2001 From: Olli Pettay Date: Sat, 18 Jul 2015 01:16:43 +0300 Subject: [PATCH 13/69] Bug 1184065, properly support WrapperCache on DestinationInsertionPointList, r=wchen --HG-- extra : rebase_source : aa0bd44900473bbf03e56477a2041958944aa8c0 --- dom/base/Element.cpp | 6 ++++-- dom/base/Element.h | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp index 62f29573fc3c..e68e12545e1d 100644 --- a/dom/base/Element.cpp +++ b/dom/base/Element.cpp @@ -1059,10 +1059,12 @@ Element::CreateShadowRoot(ErrorResult& aError) return shadowRoot.forget(); } -NS_IMPL_CYCLE_COLLECTION(DestinationInsertionPointList, mParent, mDestinationPoints) +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DestinationInsertionPointList, mParent, + mDestinationPoints) NS_INTERFACE_TABLE_HEAD(DestinationInsertionPointList) - NS_INTERFACE_TABLE(DestinationInsertionPointList, nsINodeList) + NS_WRAPPERCACHE_INTERFACE_TABLE_ENTRY + NS_INTERFACE_TABLE(DestinationInsertionPointList, nsINodeList, nsIDOMNodeList) NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(DestinationInsertionPointList) NS_INTERFACE_MAP_END diff --git a/dom/base/Element.h b/dom/base/Element.h index fc9cf1773239..0f501d922f07 100644 --- a/dom/base/Element.h +++ b/dom/base/Element.h @@ -1301,7 +1301,7 @@ public: explicit DestinationInsertionPointList(Element* aElement); NS_DECL_CYCLE_COLLECTING_ISUPPORTS - NS_DECL_CYCLE_COLLECTION_CLASS(DestinationInsertionPointList) + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DestinationInsertionPointList) // nsIDOMNodeList NS_DECL_NSIDOMNODELIST From 8a40d313a1be091406eead50db4f905b180df80c Mon Sep 17 00:00:00 2001 From: Olli Pettay Date: Sat, 18 Jul 2015 01:17:14 +0300 Subject: [PATCH 14/69] Bug 1183882, properly implement wrapper caching on PushMessageData, r=nsm --HG-- extra : rebase_source : 779ada29196c741b6e34bb5e9adc6f0f7ce02623 --- dom/workers/ServiceWorkerEvents.cpp | 9 ++++++++- dom/workers/ServiceWorkerEvents.h | 3 ++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/dom/workers/ServiceWorkerEvents.cpp b/dom/workers/ServiceWorkerEvents.cpp index 021a27fcc1d9..772cf0bd48b2 100644 --- a/dom/workers/ServiceWorkerEvents.cpp +++ b/dom/workers/ServiceWorkerEvents.cpp @@ -435,8 +435,15 @@ PushMessageData::~PushMessageData() { } -NS_IMPL_ISUPPORTS0(PushMessageData); +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(PushMessageData); +NS_IMPL_CYCLE_COLLECTING_ADDREF(PushMessageData) +NS_IMPL_CYCLE_COLLECTING_RELEASE(PushMessageData) + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PushMessageData) + NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY + NS_INTERFACE_MAP_ENTRY(nsISupports) +NS_INTERFACE_MAP_END void PushMessageData::Json(JSContext* cx, JS::MutableHandle aRetval) diff --git a/dom/workers/ServiceWorkerEvents.h b/dom/workers/ServiceWorkerEvents.h index 87a856ae1dd3..e5f5dc9db1d2 100644 --- a/dom/workers/ServiceWorkerEvents.h +++ b/dom/workers/ServiceWorkerEvents.h @@ -163,7 +163,8 @@ class PushMessageData final : public nsISupports, nsString mData; public: - NS_DECL_ISUPPORTS + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(PushMessageData) virtual JSObject* WrapObject(JSContext* aCx, JS::Handle aGivenProto) override { From 2da78a9a273d2576ebd31afea773687bf8123339 Mon Sep 17 00:00:00 2001 From: Terrence Cole Date: Fri, 17 Jul 2015 14:02:46 -0700 Subject: [PATCH 15/69] Backout 73d2c854d770 (Bug 1182124) for being on top of a suspected regression. --HG-- extra : rebase_source : 6e8312d66411b9da95c5c031df822be79b6fd250 --- js/public/RootingAPI.h | 63 +++++++++++++++++++++++++++++++++++++++++ js/src/builtin/SIMD.cpp | 3 +- 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/js/public/RootingAPI.h b/js/public/RootingAPI.h index 4a17911c39e9..474e86a63e1a 100644 --- a/js/public/RootingAPI.h +++ b/js/public/RootingAPI.h @@ -508,6 +508,69 @@ class MOZ_STACK_CLASS MutableHandle : public js::MutableHandleBase namespace js { +/* + * InternalHandle is a handle to an internal pointer into a gcthing. Use + * InternalHandle when you have a pointer to a direct field of a gcthing, or + * when you need a parameter type for something that *may* be a pointer to a + * direct field of a gcthing. + */ +template +class InternalHandle {}; + +template +class InternalHandle +{ + void * const* holder; + size_t offset; + + public: + /* + * Create an InternalHandle using a Handle to the gcthing containing the + * field in question, and a pointer to the field. + */ + template + InternalHandle(const JS::Handle& handle, T* field) + : holder((void**)handle.address()), offset(uintptr_t(field) - uintptr_t(handle.get())) + {} + + /* + * Create an InternalHandle to a field within a Rooted<>. + */ + template + InternalHandle(const JS::Rooted& root, T* field) + : holder((void**)root.address()), offset(uintptr_t(field) - uintptr_t(root.get())) + {} + + InternalHandle(const InternalHandle& other) + : holder(other.holder), offset(other.offset) {} + + T* get() const { return reinterpret_cast(uintptr_t(*holder) + offset); } + + const T& operator*() const { return *get(); } + T* operator->() const { return get(); } + + static InternalHandle fromMarkedLocation(T* fieldPtr) { + return InternalHandle(fieldPtr); + } + + private: + /* + * Create an InternalHandle to something that is not a pointer to a + * gcthing, and so does not need to be rooted in the first place. Use these + * InternalHandles to pass pointers into functions that also need to accept + * regular InternalHandles to gcthing fields. + * + * Make this private to prevent accidental misuse; this is only for + * fromMarkedLocation(). + */ + explicit InternalHandle(T* field) + : holder(&js::ConstNullValue), + offset(uintptr_t(field)) + {} + + void operator=(InternalHandle other) = delete; +}; + /* * By default, things should use the inheritance hierarchy to find their * ThingRootKind. Some pointer types are explicitly set in jspubtd.h so that diff --git a/js/src/builtin/SIMD.cpp b/js/src/builtin/SIMD.cpp index db702b28d2a0..dfc46906b806 100644 --- a/js/src/builtin/SIMD.cpp +++ b/js/src/builtin/SIMD.cpp @@ -416,11 +416,12 @@ static bool FillLanes(JSContext* cx, Handle result, const CallArgs& args) { typedef typename T::Elem Elem; + InternalHandle mem(result, reinterpret_cast(result->typedMem())); Elem tmp; for (unsigned i = 0; i < T::lanes; i++) { if (!T::toType(cx, args.get(i), &tmp)) return false; - reinterpret_cast(result->typedMem())[i] = tmp; + mem.get()[i] = tmp; } args.rval().setObject(*result); return true; From 937de4247a6e5c907cce302d27573ca4cee8aaca Mon Sep 17 00:00:00 2001 From: Terrence Cole Date: Fri, 17 Jul 2015 15:08:04 -0700 Subject: [PATCH 16/69] Backout d588ff0a68d9 (Bug 1181869) for probably regressing Splay and others. --HG-- extra : rebase_source : 6767d1977b528755db9433bc792189ffe4915c3f --- js/src/frontend/BytecodeCompiler.cpp | 5 +- js/src/frontend/BytecodeEmitter.cpp | 3 +- js/src/frontend/Parser.cpp | 23 ++-- js/src/frontend/Parser.h | 2 +- js/src/gc/RootMarking.cpp | 7 ++ js/src/jspubtd.h | 1 + js/src/jsscript.cpp | 57 +++++---- js/src/jsscript.h | 174 +++++---------------------- js/src/jsscriptinlines.h | 8 ++ 9 files changed, 90 insertions(+), 190 deletions(-) diff --git a/js/src/frontend/BytecodeCompiler.cpp b/js/src/frontend/BytecodeCompiler.cpp index 38d63c097762..2da448fcee2b 100644 --- a/js/src/frontend/BytecodeCompiler.cpp +++ b/js/src/frontend/BytecodeCompiler.cpp @@ -448,13 +448,12 @@ frontend::CompileScript(ExclusiveContext* cx, LifoAlloc* alloc, HandleObject sco // scope dynamically via JSOP_DEFFUN/VAR). They may have block-scoped // locals, however, which are allocated to the fixed part of the stack // frame. - Rooted bindings(cx, script->bindings); - if (!Bindings::initWithTemporaryStorage(cx, &bindings, 0, 0, 0, + InternalHandle bindings(script, &script->bindings); + if (!Bindings::initWithTemporaryStorage(cx, bindings, 0, 0, 0, pc->blockScopeDepth, 0, 0, nullptr)) { return nullptr; } - script->bindings = bindings; if (!JSScript::fullyInitFromEmitter(cx, script, &bce)) return nullptr; diff --git a/js/src/frontend/BytecodeEmitter.cpp b/js/src/frontend/BytecodeEmitter.cpp index 35fc03faf7ee..0333248945de 100644 --- a/js/src/frontend/BytecodeEmitter.cpp +++ b/js/src/frontend/BytecodeEmitter.cpp @@ -3414,7 +3414,8 @@ BytecodeEmitter::emitFunctionScript(ParseNode* body) switchToPrologue(); if (!emit1(JSOP_ARGUMENTS)) return false; - BindingIter bi = Bindings::argumentsBinding(cx, script); + InternalBindingsHandle bindings(script, &script->bindings); + BindingIter bi = Bindings::argumentsBinding(cx, bindings); if (script->bindingIsAliased(bi)) { ScopeCoordinate sc; sc.setHops(0); diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp index 7d38c4f21e59..d56fdf2adf98 100644 --- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -371,7 +371,7 @@ template bool ParseContext::generateFunctionBindings(ExclusiveContext* cx, TokenStream& ts, LifoAlloc& alloc, - MutableHandle bindings) const + InternalHandle bindings) const { MOZ_ASSERT(sc->isFunctionBox()); MOZ_ASSERT(args_.length() < ARGNO_LIMIT); @@ -847,10 +847,10 @@ Parser::standaloneFunctionBody(HandleFunction fun, const AutoN } } - Rooted bindings(context, funbox->bindings); - if (!funpc.generateFunctionBindings(context, tokenStream, alloc, &bindings)) + InternalHandle funboxBindings = + InternalHandle::fromMarkedLocation(&funbox->bindings); + if (!funpc.generateFunctionBindings(context, tokenStream, alloc, funboxBindings)) return null(); - funbox->bindings = bindings; return fn; } @@ -1470,12 +1470,9 @@ Parser::leaveFunction(ParseNode* fn, ParseContext bindings(context, funbox->bindings); - if (!pc->generateFunctionBindings(context, tokenStream, alloc, &bindings)) - return false; - funbox->bindings = bindings; - - return true; + InternalHandle bindings = + InternalHandle::fromMarkedLocation(&funbox->bindings); + return pc->generateFunctionBindings(context, tokenStream, alloc, bindings); } template <> @@ -2495,10 +2492,10 @@ Parser::standaloneLazyFunction(HandleFunction fun, unsigned st } } - Rooted bindings(context, funbox->bindings); - if (!pc->generateFunctionBindings(context, tokenStream, alloc, &bindings)) + InternalHandle bindings = + InternalHandle::fromMarkedLocation(&funbox->bindings); + if (!pc->generateFunctionBindings(context, tokenStream, alloc, bindings)) return null(); - funbox->bindings = bindings; if (!FoldConstants(context, &pn, this)) return null(); diff --git a/js/src/frontend/Parser.h b/js/src/frontend/Parser.h index 9e5dff90a633..12236772bb4e 100644 --- a/js/src/frontend/Parser.h +++ b/js/src/frontend/Parser.h @@ -213,7 +213,7 @@ struct ParseContext : public GenericParseContext */ bool generateFunctionBindings(ExclusiveContext* cx, TokenStream& ts, LifoAlloc& alloc, - MutableHandle bindings) const; + InternalHandle bindings) const; private: ParseContext** parserPC; /* this points to the Parser's active pc diff --git a/js/src/gc/RootMarking.cpp b/js/src/gc/RootMarking.cpp index 9274df9c7156..0016eacf61f6 100644 --- a/js/src/gc/RootMarking.cpp +++ b/js/src/gc/RootMarking.cpp @@ -44,6 +44,12 @@ typedef RootedValueMap::Enum RootEnum; // GCC 4.4, since it requires template function parameters to have external // linkage. +void +MarkBindingsRoot(JSTracer* trc, Bindings* bindings, const char* name) +{ + bindings->trace(trc); +} + void MarkPropertyDescriptorRoot(JSTracer* trc, JSPropertyDescriptor* pd, const char* name) { @@ -81,6 +87,7 @@ MarkExactStackRootsAcrossTypes(T context, JSTracer* trc) MarkExactStackRootList(trc, context, "exact-lazy-script"); MarkExactStackRootList(trc, context, "exact-id"); MarkExactStackRootList(trc, context, "exact-value"); + MarkExactStackRootList(trc, context, "Bindings"); MarkExactStackRootList( trc, context, "JSPropertyDescriptor"); MarkExactStackRootListnames().arguments; - BindingIter bi(script); + BindingIter bi(bindings); while (bi->name() != arguments) bi++; return bi; } bool -Bindings::initWithTemporaryStorage(ExclusiveContext* cx, MutableHandle self, +Bindings::initWithTemporaryStorage(ExclusiveContext* cx, InternalBindingsHandle self, uint32_t numArgs, uint32_t numVars, uint32_t numBodyLevelLexicals, uint32_t numBlockScoped, uint32_t numUnaliasedVars, uint32_t numUnaliasedBodyLevelLexicals, - const Binding* bindingArray) + Binding* bindingArray) { - MOZ_ASSERT(!self.callObjShape()); - MOZ_ASSERT(self.bindingArrayUsingTemporaryStorage()); - MOZ_ASSERT(!self.bindingArray()); + MOZ_ASSERT(!self->callObjShape_); + MOZ_ASSERT(self->bindingArrayAndFlag_ == TEMPORARY_STORAGE_BIT); MOZ_ASSERT(!(uintptr_t(bindingArray) & TEMPORARY_STORAGE_BIT)); MOZ_ASSERT(numArgs <= ARGC_LIMIT); MOZ_ASSERT(numVars <= LOCALNO_LIMIT); @@ -94,13 +93,13 @@ Bindings::initWithTemporaryStorage(ExclusiveContext* cx, MutableHandle MOZ_ASSERT(numUnaliasedVars <= numVars); MOZ_ASSERT(numUnaliasedBodyLevelLexicals <= numBodyLevelLexicals); - self.setBindingArray(bindingArray, TEMPORARY_STORAGE_BIT); - self.setNumArgs(numArgs); - self.setNumVars(numVars); - self.setNumBodyLevelLexicals(numBodyLevelLexicals); - self.setNumBlockScoped(numBlockScoped); - self.setNumUnaliasedVars(numUnaliasedVars); - self.setNumUnaliasedBodyLevelLexicals(numUnaliasedBodyLevelLexicals); + self->bindingArrayAndFlag_ = uintptr_t(bindingArray) | TEMPORARY_STORAGE_BIT; + self->numArgs_ = numArgs; + self->numVars_ = numVars; + self->numBodyLevelLexicals_ = numBodyLevelLexicals; + self->numBlockScoped_ = numBlockScoped; + self->numUnaliasedVars_ = numUnaliasedVars; + self->numUnaliasedBodyLevelLexicals_ = numUnaliasedBodyLevelLexicals; // Get the initial shape to use when creating CallObjects for this script. // After creation, a CallObject's shape may change completely (via direct eval() or @@ -135,7 +134,7 @@ Bindings::initWithTemporaryStorage(ExclusiveContext* cx, MutableHandle nslots++; } } - self.setAliasedBodyLevelLexicalBegin(aliasedBodyLevelLexicalBegin); + self->aliasedBodyLevelLexicalBegin_ = aliasedBodyLevelLexicalBegin; // Put as many of nslots inline into the object header as possible. uint32_t nfixed = gc::GetGCKindSlots(gc::GetGCObjectKind(nslots)); @@ -191,7 +190,7 @@ Bindings::initWithTemporaryStorage(ExclusiveContext* cx, MutableHandle MOZ_ASSERT(slot == nslots); MOZ_ASSERT(!shape->inDictionary()); - self.setCallObjShape(shape); + self->callObjShape_.init(shape); return true; } @@ -219,12 +218,12 @@ Bindings::switchToScriptStorage(Binding* newBindingArray) return reinterpret_cast(newBindingArray + count()); } -/* static */ bool -Bindings::clone(JSContext* cx, MutableHandle self, +bool +Bindings::clone(JSContext* cx, InternalBindingsHandle self, uint8_t* dstScriptData, HandleScript srcScript) { /* The clone has the same bindingArray_ offset as 'src'. */ - Handle src = Handle::fromMarkedLocation(&srcScript->bindings); + Bindings& src = srcScript->bindings; ptrdiff_t off = (uint8_t*)src.bindingArray() - srcScript->data; MOZ_ASSERT(off >= 0); MOZ_ASSERT(size_t(off) <= srcScript->dataSize()); @@ -244,10 +243,16 @@ Bindings::clone(JSContext* cx, MutableHandle self, return false; } - self.switchToScriptStorage(dstPackedBindings); + self->switchToScriptStorage(dstPackedBindings); return true; } +/* static */ Bindings +GCMethods::initial() +{ + return Bindings(); +} + template static bool XDRScriptBindings(XDRState* xdr, LifoAllocScope& las, uint16_t numArgs, uint32_t numVars, @@ -297,15 +302,14 @@ XDRScriptBindings(XDRState* xdr, LifoAllocScope& las, uint16_t numArgs, ui bindingArray[i] = Binding(name, kind, aliased); } - Rooted bindings(cx, script->bindings); - if (!Bindings::initWithTemporaryStorage(cx, &bindings, numArgs, numVars, + InternalBindingsHandle bindings(script, &script->bindings); + if (!Bindings::initWithTemporaryStorage(cx, bindings, numArgs, numVars, numBodyLevelLexicals, numBlockScoped, numUnaliasedVars, numUnaliasedBodyLevelLexicals, bindingArray)) { return false; } - script->bindings = bindings; } return true; @@ -3121,7 +3125,9 @@ js::detail::CopyScript(JSContext* cx, HandleObject scriptStaticScope, HandleScri /* Bindings */ Rooted bindings(cx); - if (!Bindings::clone(cx, &bindings, data, src)) + InternalHandle bindingsHandle = + InternalHandle::fromMarkedLocation(bindings.address()); + if (!Bindings::clone(cx, bindingsHandle, data, src)) return false; /* Objects */ @@ -3706,7 +3712,8 @@ js::SetFrameArgumentsObject(JSContext* cx, AbstractFramePtr frame, * object. Note that 'arguments' may have already been overwritten. */ - BindingIter bi = Bindings::argumentsBinding(cx, script); + InternalBindingsHandle bindings(script, &script->bindings); + BindingIter bi = Bindings::argumentsBinding(cx, bindings); if (script->bindingIsAliased(bi)) { /* diff --git a/js/src/jsscript.h b/js/src/jsscript.h index 37c5060feb23..f3757e1d5503 100644 --- a/js/src/jsscript.h +++ b/js/src/jsscript.h @@ -200,18 +200,19 @@ class Binding JS_STATIC_ASSERT(sizeof(Binding) == sizeof(uintptr_t)); +class Bindings; +typedef InternalHandle InternalBindingsHandle; + /* * Formal parameters and local variables are stored in a shape tree * path encapsulated within this class. This class represents bindings for * both function and top-level scripts (the latter is needed to track names in * strict mode eval code, to give such code its own lexical environment). */ -class Bindings : public JS::StaticTraceable +class Bindings { friend class BindingIter; friend class AliasedFormalIter; - template friend class BindingsOperations; - template friend class MutableBindingsOperations; RelocatablePtrShape callObjShape_; uintptr_t bindingArrayAndFlag_; @@ -249,12 +250,7 @@ class Bindings : public JS::StaticTraceable return reinterpret_cast(bindingArrayAndFlag_ & ~TEMPORARY_STORAGE_BIT); } - Bindings() - : callObjShape_(nullptr), bindingArrayAndFlag_(TEMPORARY_STORAGE_BIT), - numArgs_(0), numBlockScoped_(0), - numBodyLevelLexicals_(0), numUnaliasedBodyLevelLexicals_(0), - numVars_(0), numUnaliasedVars_(0) - {} + inline Bindings(); /* * Initialize a Bindings with a pointer into temporary storage. @@ -263,14 +259,11 @@ class Bindings : public JS::StaticTraceable * switchToScriptStorage must be called, providing a pointer into the * Binding array stored in script->data. */ - static bool initWithTemporaryStorage(ExclusiveContext* cx, MutableHandle self, - uint32_t numArgs, - uint32_t numVars, - uint32_t numBodyLevelLexicals, - uint32_t numBlockScoped, - uint32_t numUnaliasedVars, - uint32_t numUnaliasedBodyLevelLexicals, - const Binding* bindingArray); + static bool initWithTemporaryStorage(ExclusiveContext* cx, InternalBindingsHandle self, + uint32_t numArgs, uint32_t numVars, + uint32_t numBodyLevelLexicals, uint32_t numBlockScoped, + uint32_t numUnaliasedVars, uint32_t numUnaliasedBodyLevelLexicals, + Binding* bindingArray); // Initialize a trivial Bindings with no slots and an empty callObjShape. bool initTrivial(ExclusiveContext* cx); @@ -299,7 +292,7 @@ class Bindings : public JS::StaticTraceable * Clone srcScript's bindings (as part of js::CloneScript). dstScriptData * is the pointer to what will eventually be dstScript->data. */ - static bool clone(JSContext* cx, MutableHandle self, uint8_t* dstScriptData, + static bool clone(JSContext* cx, InternalBindingsHandle self, uint8_t* dstScriptData, HandleScript srcScript); uint32_t numArgs() const { return numArgs_; } @@ -324,7 +317,7 @@ class Bindings : public JS::StaticTraceable Shape* callObjShape() const { return callObjShape_; } /* Convenience method to get the var index of 'arguments'. */ - static BindingIter argumentsBinding(ExclusiveContext* cx, HandleScript script); + static BindingIter argumentsBinding(ExclusiveContext* cx, InternalBindingsHandle); /* Return whether the binding at bindingIndex is aliased. */ bool bindingIsAliased(uint32_t bindingIndex); @@ -340,122 +333,13 @@ class Bindings : public JS::StaticTraceable Binding* begin() const { return bindingArray(); } Binding* end() const { return bindingArray() + count(); } - static void trace(Bindings* self, JSTracer* trc) { self->trace(trc); } + static js::ThingRootKind rootKind() { return js::THING_ROOT_BINDINGS; } void trace(JSTracer* trc); }; -template -class BindingsOperations -{ - const Bindings& bindings() const { return static_cast(this)->extract(); } - - public: - // Direct data access to the underlying bindings. - const RelocatablePtrShape& callObjShape() const { - return bindings().callObjShape_; - } - uint16_t numArgs() const { - return bindings().numArgs_; - } - uint16_t numBlockScoped() const { - return bindings().numBlockScoped_; - } - uint16_t numBodyLevelLexicals() const { - return bindings().numBodyLevelLexicals_; - } - uint16_t aliasedBodyLevelLexicalBegin() const { - return bindings().aliasedBodyLevelLexicalBegin_; - } - uint16_t numUnaliasedBodyLevelLexicals() const { - return bindings().numUnaliasedBodyLevelLexicals_; - } - uint32_t numVars() const { - return bindings().numVars_; - } - uint32_t numUnaliasedVars() const { - return bindings().numUnaliasedVars_; - } - - // Binding array access. - bool bindingArrayUsingTemporaryStorage() const { - return bindings().bindingArrayUsingTemporaryStorage(); - } - const Binding* bindingArray() const { - return bindings().bindingArray(); - } - uint32_t count() const { - return bindings().count(); - } - - // Helpers. - uint32_t numBodyLevelLocals() const { - return numVars() + numBodyLevelLexicals(); - } - uint32_t numUnaliasedBodyLevelLocals() const { - return numUnaliasedVars() + numUnaliasedBodyLevelLexicals(); - } - uint32_t numAliasedBodyLevelLocals() const { - return numBodyLevelLocals() - numUnaliasedBodyLevelLocals(); - } - uint32_t numLocals() const { - return numVars() + numBodyLevelLexicals() + numBlockScoped(); - } - uint32_t numFixedLocals() const { - return numUnaliasedVars() + numUnaliasedBodyLevelLexicals() + numBlockScoped(); - } - uint32_t lexicalBegin() const { - return numArgs() + numVars(); - } -}; - -template -class MutableBindingsOperations : public BindingsOperations -{ - Bindings& bindings() { return static_cast(this)->extractMutable(); } - - public: - void setCallObjShape(HandleShape shape) { bindings().callObjShape_ = shape; } - void setBindingArray(const Binding* bindingArray, uintptr_t temporaryBit) { - bindings().bindingArrayAndFlag_ = uintptr_t(bindingArray) | temporaryBit; - } - void setNumArgs(uint16_t num) { bindings().numArgs_ = num; } - void setNumVars(uint32_t num) { bindings().numVars_ = num; } - void setNumBodyLevelLexicals(uint16_t num) { bindings().numBodyLevelLexicals_ = num; } - void setNumBlockScoped(uint16_t num) { bindings().numBlockScoped_ = num; } - void setNumUnaliasedVars(uint32_t num) { bindings().numUnaliasedVars_ = num; } - void setNumUnaliasedBodyLevelLexicals(uint16_t num) { - bindings().numUnaliasedBodyLevelLexicals_ = num; - } - void setAliasedBodyLevelLexicalBegin(uint16_t offset) { - bindings().aliasedBodyLevelLexicalBegin_ = offset; - } - uint8_t* switchToScriptStorage(Binding* permanentStorage) { - return bindings().switchToScriptStorage(permanentStorage); - } -}; - template <> -class HandleBase : public BindingsOperations> -{ - friend class BindingsOperations>; - const Bindings& extract() const { - return static_cast*>(this)->get(); - } -}; - -template <> -class MutableHandleBase - : public MutableBindingsOperations> -{ - friend class BindingsOperations>; - const Bindings& extract() const { - return static_cast*>(this)->get(); - } - - friend class MutableBindingsOperations>; - Bindings& extractMutable() { - return static_cast*>(this)->get(); - } +struct GCMethods { + static Bindings initial(); }; class ScriptCounts @@ -1898,7 +1782,7 @@ namespace js { */ class BindingIter { - Handle bindings_; + const InternalBindingsHandle bindings_; uint32_t i_; uint32_t unaliasedLocal_; @@ -1906,16 +1790,12 @@ class BindingIter friend class Bindings; public: - explicit BindingIter(Handle bindings) - : bindings_(bindings), i_(0), unaliasedLocal_(0) - {} - + explicit BindingIter(const InternalBindingsHandle& bindings) + : bindings_(bindings), i_(0), unaliasedLocal_(0) {} explicit BindingIter(const HandleScript& script) - : bindings_(Handle::fromMarkedLocation(&script->bindings)), - i_(0), unaliasedLocal_(0) - {} + : bindings_(script, &script->bindings), i_(0), unaliasedLocal_(0) {} - bool done() const { return i_ == bindings_.count(); } + bool done() const { return i_ == bindings_->count(); } explicit operator bool() const { return !done(); } BindingIter& operator++() { (*this)++; return *this; } @@ -1933,7 +1813,7 @@ class BindingIter // has no stack slot. uint32_t frameIndex() const { MOZ_ASSERT(!done()); - if (i_ < bindings_.numArgs()) + if (i_ < bindings_->numArgs()) return i_; MOZ_ASSERT(!(*this)->aliased()); return unaliasedLocal_; @@ -1944,17 +1824,17 @@ class BindingIter // both unaliased and aliased arguments. uint32_t argIndex() const { MOZ_ASSERT(!done()); - MOZ_ASSERT(i_ < bindings_.numArgs()); + MOZ_ASSERT(i_ < bindings_->numArgs()); return i_; } uint32_t argOrLocalIndex() const { MOZ_ASSERT(!done()); - return i_ < bindings_.numArgs() ? i_ : i_ - bindings_.numArgs(); + return i_ < bindings_->numArgs() ? i_ : i_ - bindings_->numArgs(); } uint32_t localIndex() const { MOZ_ASSERT(!done()); - MOZ_ASSERT(i_ >= bindings_.numArgs()); - return i_ - bindings_.numArgs(); + MOZ_ASSERT(i_ >= bindings_->numArgs()); + return i_ - bindings_->numArgs(); } bool isBodyLevelLexical() const { MOZ_ASSERT(!done()); @@ -1962,8 +1842,8 @@ class BindingIter return binding.kind() != Binding::ARGUMENT; } - const Binding& operator*() const { MOZ_ASSERT(!done()); return bindings_.bindingArray()[i_]; } - const Binding* operator->() const { MOZ_ASSERT(!done()); return &bindings_.bindingArray()[i_]; } + const Binding& operator*() const { MOZ_ASSERT(!done()); return bindings_->bindingArray()[i_]; } + const Binding* operator->() const { MOZ_ASSERT(!done()); return &bindings_->bindingArray()[i_]; } }; /* diff --git a/js/src/jsscriptinlines.h b/js/src/jsscriptinlines.h index b3b7867da206..7117878b7f3c 100644 --- a/js/src/jsscriptinlines.h +++ b/js/src/jsscriptinlines.h @@ -20,6 +20,14 @@ namespace js { +inline +Bindings::Bindings() + : callObjShape_(nullptr), bindingArrayAndFlag_(TEMPORARY_STORAGE_BIT), + numArgs_(0), numBlockScoped_(0), + numBodyLevelLexicals_(0), numUnaliasedBodyLevelLexicals_(0), + numVars_(0), numUnaliasedVars_(0) +{} + inline AliasedFormalIter::AliasedFormalIter(JSScript* script) : begin_(script->bindingArray()), From 0a1b43054d005bb7a7eded9de00fb21fcc521a9a Mon Sep 17 00:00:00 2001 From: Steven Michaud Date: Fri, 17 Jul 2015 18:10:07 -0500 Subject: [PATCH 17/69] Bug 1184221 - Fix null dereferences at mozilla::TrackBuffer::UpdateBufferedRanges(). r=jyavenard --- dom/media/mediasource/TrackBuffer.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dom/media/mediasource/TrackBuffer.cpp b/dom/media/mediasource/TrackBuffer.cpp index 52b16235ac74..c9dae754ab8f 100644 --- a/dom/media/mediasource/TrackBuffer.cpp +++ b/dom/media/mediasource/TrackBuffer.cpp @@ -298,7 +298,11 @@ TrackBuffer::AppendDataToCurrentResource(MediaByteBuffer* aData, uint32_t aDurat nsRefPtr TrackBuffer::UpdateBufferedRanges(Interval aByteRange, bool aNotifyParent) { - if (aByteRange.Length()) { + if (!mParentDecoder) { + return BufferedRangesUpdatedPromise::CreateAndResolve(true, __func__); + } + + if (mCurrentDecoder && aByteRange.Length()) { mCurrentDecoder->GetReader()->NotifyDataArrived(aByteRange); } From 5c8d42ea2d0e8c613dc1926c93034de8d0befc09 Mon Sep 17 00:00:00 2001 From: Daniel Holbert Date: Fri, 17 Jul 2015 16:11:10 -0700 Subject: [PATCH 18/69] Bug 1185104: Move MOZ_WARN_UNUSED_RESULT to the beginning of function-decls (where it's supposed to be) in jsfriendapi.h. r=tromey --- js/src/jsfriendapi.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/js/src/jsfriendapi.h b/js/src/jsfriendapi.h index fd06a81b6283..eb7a8554ec9a 100644 --- a/js/src/jsfriendapi.h +++ b/js/src/jsfriendapi.h @@ -1306,10 +1306,12 @@ class MOZ_STACK_CLASS AutoStableStringChars {} ~AutoStableStringChars(); - bool init(JSContext* cx, JSString* s) MOZ_WARN_UNUSED_RESULT; + MOZ_WARN_UNUSED_RESULT + bool init(JSContext* cx, JSString* s); /* Like init(), but Latin1 chars are inflated to TwoByte. */ - bool initTwoByte(JSContext* cx, JSString* s) MOZ_WARN_UNUSED_RESULT; + MOZ_WARN_UNUSED_RESULT + bool initTwoByte(JSContext* cx, JSString* s); bool isLatin1() const { return state_ == Latin1; } bool isTwoByte() const { return state_ == TwoByte; } From b9baa34b08dfb6c2136f6c9269b0138f6f1ae771 Mon Sep 17 00:00:00 2001 From: Wes Kocher Date: Fri, 17 Jul 2015 17:49:46 -0700 Subject: [PATCH 19/69] Backed out 3 changesets (bug 1178988) for ocsp orange CLOSED TREE Backed out changeset 7fb6a9114916 (bug 1178988) Backed out changeset 2700ec4adc3e (bug 1178988) Backed out changeset 07b9c2331ac1 (bug 1178988) --- security/manager/ssl/tests/unit/moz.build | 1 - security/manager/ssl/tests/unit/pycert.py | 174 ++++++++--- security/manager/ssl/tests/unit/pykey.py | 282 ------------------ .../manager/ssl/tests/unit/test_ocsp_url.js | 8 +- .../tests/unit/test_ocsp_url/bad-scheme.der | Bin 0 -> 895 bytes .../test_ocsp_url/bad-scheme.pem.certspec | 3 - .../ssl/tests/unit/test_ocsp_url/ca.der | Bin 0 -> 845 bytes .../tests/unit/test_ocsp_url/ca.pem.certspec | 4 - .../ssl/tests/unit/test_ocsp_url/cert9.db | Bin 0 -> 43008 bytes .../tests/unit/test_ocsp_url/empty-port.der | Bin 0 -> 904 bytes .../test_ocsp_url/empty-port.pem.certspec | 3 - .../unit/test_ocsp_url/empty-scheme-url.der | Bin 0 -> 910 bytes .../empty-scheme-url.pem.certspec | 3 - .../ssl/tests/unit/test_ocsp_url/ftp-url.der | Bin 0 -> 903 bytes .../unit/test_ocsp_url/ftp-url.pem.certspec | 3 - .../ssl/tests/unit/test_ocsp_url/generate.py | 40 +++ .../ssl/tests/unit/test_ocsp_url/hTTp-url.der | Bin 0 -> 914 bytes .../unit/test_ocsp_url/hTTp-url.pem.certspec | 3 - .../tests/unit/test_ocsp_url/https-url.der | Bin 0 -> 917 bytes .../unit/test_ocsp_url/https-url.pem.certspec | 3 - .../ssl/tests/unit/test_ocsp_url/int.der | Bin 0 -> 845 bytes .../tests/unit/test_ocsp_url/int.key.keyspec | 0 .../tests/unit/test_ocsp_url/int.pem.certspec | 4 - .../ssl/tests/unit/test_ocsp_url/key4.db | Bin 0 -> 72704 bytes .../ssl/tests/unit/test_ocsp_url/moz.build | 42 --- .../unit/test_ocsp_url/negative-port.der | Bin 0 -> 908 bytes .../test_ocsp_url/negative-port.pem.certspec | 3 - .../tests/unit/test_ocsp_url/no-host-url.der | Bin 0 -> 894 bytes .../test_ocsp_url/no-host-url.pem.certspec | 3 - .../tests/unit/test_ocsp_url/no-path-url.der | Bin 0 -> 908 bytes .../test_ocsp_url/no-path-url.pem.certspec | 3 - .../test_ocsp_url/no-scheme-host-port.der | Bin 0 -> 889 bytes .../no-scheme-host-port.pem.certspec | 3 - .../unit/test_ocsp_url/no-scheme-url.der | Bin 0 -> 904 bytes .../test_ocsp_url/no-scheme-url.pem.certspec | 3 - .../ssl/tests/unit/test_ocsp_url/pkcs11.txt | 5 + .../unit/test_ocsp_url/unknown-scheme.der | Bin 0 -> 905 bytes .../test_ocsp_url/unknown-scheme.pem.certspec | 3 - .../tlsserver/cmd/GenerateOCSPResponse.cpp | 229 +------------- 39 files changed, 198 insertions(+), 627 deletions(-) delete mode 100755 security/manager/ssl/tests/unit/pykey.py create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/bad-scheme.der delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/bad-scheme.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/ca.der delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/cert9.db create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/empty-port.der delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/empty-port.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/empty-scheme-url.der delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/empty-scheme-url.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/ftp-url.der delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/ftp-url.pem.certspec create mode 100755 security/manager/ssl/tests/unit/test_ocsp_url/generate.py create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/hTTp-url.der delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/hTTp-url.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/https-url.der delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/https-url.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/int.der delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/int.key.keyspec delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/int.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/key4.db delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/moz.build create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/negative-port.der delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/negative-port.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/no-host-url.der delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/no-host-url.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/no-path-url.der delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/no-path-url.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-host-port.der delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-host-port.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-url.der delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-url.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/pkcs11.txt create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/unknown-scheme.der delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/unknown-scheme.pem.certspec diff --git a/security/manager/ssl/tests/unit/moz.build b/security/manager/ssl/tests/unit/moz.build index 2433f5b843f2..85bea2f51150 100644 --- a/security/manager/ssl/tests/unit/moz.build +++ b/security/manager/ssl/tests/unit/moz.build @@ -12,7 +12,6 @@ TEST_DIRS += [ 'test_cert_version', 'test_intermediate_basic_usage_constraints', 'test_pinning_dynamic', - 'test_ocsp_url', ] if not CONFIG['MOZ_NO_SMART_CARDS']: diff --git a/security/manager/ssl/tests/unit/pycert.py b/security/manager/ssl/tests/unit/pycert.py index 0da1e71b5516..bf8b7c8734d1 100755 --- a/security/manager/ssl/tests/unit/pycert.py +++ b/security/manager/ssl/tests/unit/pycert.py @@ -26,7 +26,6 @@ extKeyUsage:[serverAuth,clientAuth,codeSigning,emailProtection nsSGC, # Netscape Server Gated Crypto OCSPSigning,timeStamping] subjectAlternativeName:[,...] -authorityInformationAccess: Where: [] indicates an optional field or component of a field @@ -49,14 +48,14 @@ or as the subject public key information field, respectively. from pyasn1.codec.der import decoder from pyasn1.codec.der import encoder -from pyasn1.type import constraint, tag, univ, useful +from pyasn1.type import constraint, namedtype, tag, univ, useful from pyasn1_modules import rfc2459 import base64 +import binascii import datetime import hashlib import sys - -import pykey +import rsa class UnknownBaseError(Exception): """Base class for handling unexpected input in this module.""" @@ -100,6 +99,14 @@ class UnknownKeyPurposeTypeError(UnknownBaseError): self.category = 'keyPurpose' +class UnknownKeySpecificationError(UnknownBaseError): + """Helper exception type to handle unknown key specifications.""" + + def __init__(self, value): + UnknownBaseError.__init__(self, value) + self.category = 'key specification' + + class UnknownKeyTargetError(UnknownBaseError): """Helper exception type to handle unknown key targets.""" @@ -121,18 +128,6 @@ def getASN1Tag(asn1Type): type from the pyasn1 package""" return asn1Type.baseTagSet.getBaseTag().asTuple()[2] -def stringToAccessDescription(string): - """Helper function that takes a string representing a URI - presumably identifying an OCSP authority information access - location. Returns an AccessDescription usable by pyasn1.""" - accessMethod = rfc2459.id_ad_ocsp - accessLocation = rfc2459.GeneralName() - accessLocation.setComponentByName('uniformResourceIdentifier', string) - sequence = univ.Sequence() - sequence.setComponentByPosition(0, accessMethod) - sequence.setComponentByPosition(1, accessLocation) - return sequence - def stringToAlgorithmIdentifier(string): """Helper function that converts a description of an algorithm to a representation usable by the pyasn1 package""" @@ -171,10 +166,97 @@ def datetimeToTime(dt): time.setComponentByName('generalTime', useful.GeneralizedTime(dt.strftime('%Y%m%d%H%M%SZ'))) return time +def byteStringToHexifiedBitString(string): + """Takes a string of bytes and returns a hex string representing + those bytes for use with pyasn1.type.univ.BitString. It must be of + the form "''H", where the trailing 'H' indicates to + pyasn1 that the input is a hex string.""" + return "'%s'H" % binascii.hexlify(string) + +class RSAPublicKey(univ.Sequence): + """Helper type for encoding an RSA public key""" + componentType = namedtype.NamedTypes( + namedtype.NamedType('N', univ.Integer()), + namedtype.NamedType('E', univ.Integer())) + + class Certificate: """Utility class for reading a certificate specification and generating a signed x509 certificate""" + # For reference, when encoded as a subject public key info, the + # base64-encoded sha-256 hash of this key is + # VCIlmPM9NkgFQtrs4Oa5TeFcDu6MWRTKSNdePEhOgD8= + sharedRSA_N = long( + '00ba8851a8448e16d641fd6eb6880636103d3c13d9eae4354ab4ecf56857' + '6c247bc1c725a8e0d81fbdb19c069b6e1a86f26be2af5a756b6a6471087a' + 'a55aa74587f71cd5249c027ecd43fc1e69d038202993ab20c349e4dbb94c' + 'c26b6c0eed15820ff17ead691ab1d3023a8b2a41eea770e00f0d8dfd660b' + '2bb02492a47db988617990b157903dd23bc5e0b8481fa837d38843ef2716' + 'd855b7665aaa7e02902f3a7b10800624cc1c6c97ad96615bb7e29612c075' + '31a30c91ddb4caf7fcad1d25d309efb9170ea768e1b37b2f226f69e3b48a' + '95611dee26d6259dab91084e36cb1c24042cbf168b2fe5f18f991731b8b3' + 'fe4923fa7251c431d503acda180a35ed8d', 16) + sharedRSA_E = 65537L + sharedRSA_D = long( + '009ecbce3861a454ecb1e0fe8f85dd43c92f5825ce2e997884d0e1a949da' + 'a2c5ac559b240450e5ac9fe0c3e31c0eefa6525a65f0c22194004ee1ab46' + '3dde9ee82287cc93e746a91929c5e6ac3d88753f6c25ba5979e73e5d8fb2' + '39111a3cdab8a4b0cdf5f9cab05f1233a38335c64b5560525e7e3b92ad7c' + '7504cf1dc7cb005788afcbe1e8f95df7402a151530d5808346864eb370aa' + '79956a587862cb533791307f70d91c96d22d001a69009b923c683388c9f3' + '6cb9b5ebe64302041c78d908206b87009cb8cabacad3dbdb2792fb911b2c' + 'f4db6603585be9ae0ca3b8e6417aa04b06e470ea1a3b581ca03a6781c931' + '5b62b30e6011f224725946eec57c6d9441', 16) + sharedRSA_P = long( + '00dd6e1d4fffebf68d889c4d114cdaaa9caa63a59374286c8a5c29a717bb' + 'a60375644d5caa674c4b8bc7326358646220e4550d7608ac27d55b6db74f' + '8d8127ef8fa09098b69147de065573447e183d22fe7d885aceb513d9581d' + 'd5e07c1a90f5ce0879de131371ecefc9ce72e9c43dc127d238190de81177' + '3ca5d19301f48c742b', 16) + sharedRSA_Q = long( + '00d7a773d9ebc380a767d2fec0934ad4e8b5667240771acdebb5ad796f47' + '8fec4d45985efbc9532968289c8d89102fadf21f34e2dd4940eba8c09d6d' + '1f16dcc29729774c43275e9251ddbe4909e1fd3bf1e4bedf46a39b8b3833' + '28ef4ae3b95b92f2070af26c9e7c5c9b587fedde05e8e7d86ca57886fb16' + '5810a77b9845bc3127', 16) + # For reference, when encoded as a subject public key info, the + # base64-encoded sha-256 hash of this key is + # K+uamI+1JmrxMsBxEfGOoydEDJVMa5MY/eaTj+43Lzc= + alternateRSA_N = long( + '00cd6e66a71b9a104c7c5f270b5869da966a52e547f8a026eef128c4d51f' + 'a7d949b1df8a1e342c59cbad0fb6ef867427bd9e76f2e9bf0b582745c646' + '4446db7bdd4d0f2f361da724ff206d070b3d75ad87d690fa307dcccc2ad1' + '4283921f9621f2a564e7e9f708a98556194df12fb4b0a2f0b89f76ac7e59' + '668285aa50f14f310b6ebd8f001d0c115393bd27f3334f67780abfe0b19e' + '5ac3414c5b4a3819fbed39198050e1c660e44cacaf108cbe1671d5a14602' + '6090f371b2873d419eeb6de982fb493c3d4d33fb8a12bd65f1c59a3494dd' + 'd7e1131aa45e896d817bbb28e6fd4c2323ed17a26dc8e4e49281decc641e' + 'f7b7acfe65e7c0e5212fb2a9d472902c35', 16) + alternateRSA_E = 65537L + alternateRSA_D = long( + '6ae6e0946550aeda9e7e059b69ceebe90a3b490542e4545e53309bfd2c13' + 'f486dd012ea6b90fbb4aba2c4b4e29f1981c9cb1d986b9dbf56bba6b8b75' + '4c4a3b12d65ee87a88c3ca04d9a2e2df7e84166171cecfe31c13cecb194a' + '3b9d76c271b80b498f45b93fd0b78a2e70d8e9b26598e51bae1fdb7384a2' + '4b99b31f9bf351d9692c00d6f05c30424be4b4de55331ac77532c3fdaf74' + '95dbf7aef601b517ed227d0efa3de443d56d8b29e556f6be938eabf4c0e4' + '2e2fe38bec60cba5b5ff9192b68620ee4b629b9d0b64b9a8810809813b0b' + '04e485d97fdad2961c0982a589863643974e3900dd8a75112a0fffc59f4b' + '24c31307901dd04a848b02db32f61a01', 16) + alternateRSA_P = long( + '00feeacc987c0494cb5e9550eefb9dc56f9d957022a11539dae04c6361ab' + 'd5081dce2a6aec0905450886f5bb7e56e8bd2bef37cfa16fbda5ffc268ca' + 'e0499017552c37fa4a041341d67d4d69d093d8950f50672fb085b636560e' + '2446689474b29be7abeba358ab7bc4cde3fd065d46f762adeb5c4b54ccca' + '651a14b498311615b1', 16) + alternateRSA_Q = long( + '00ce4dca3fdda86b8c800c268082446633c8aaf0f20c729878092198585b' + 'd2ed134a7bdb2c93f829f99e6e9070db6598b3113627fd87bf6bc46cb2e5' + '121777cbea9c41e74c9c2c248931dbccb5ae8a1dccfad284784cc35b8329' + 'abc420ce95640085dbf325fa7f6a2a567d487c1ef67d07a56c6beade9404' + 'd039ba01adf328ebc5', 16) + def __init__(self, paramStream, now=datetime.datetime.utcnow()): self.versionValue = 2 # a value of 2 is X509v3 self.signature = 'sha256WithRSAEncryption' @@ -185,8 +267,13 @@ class Certificate: self.subject = 'Default Subject' self.signatureAlgorithm = 'sha256WithRSAEncryption' self.extensions = None - self.subjectKey = pykey.RSAKey() - self.issuerKey = pykey.RSAKey() + self.subjectRSA_N = self.sharedRSA_N + self.subjectRSA_E = self.sharedRSA_E + self.issuerRSA_N = self.sharedRSA_N + self.issuerRSA_E = self.sharedRSA_E + self.issuerRSA_D = self.sharedRSA_D + self.issuerRSA_P = self.sharedRSA_P + self.issuerRSA_Q = self.sharedRSA_Q self.decodeParams(paramStream) self.serialNumber = self.generateSerialNumber() @@ -260,18 +347,24 @@ class Certificate: self.addExtKeyUsage(value) elif extensionType == 'subjectAlternativeName': self.addSubjectAlternativeName(value) - elif extensionType == 'authorityInformationAccess': - self.addAuthorityInformationAccess(value) else: raise UnknownExtensionTypeError(extensionType) def setupKey(self, subjectOrIssuer, value): - if subjectOrIssuer == 'subject': - self.subjectKey = pykey.RSAKey(value) - elif subjectOrIssuer == 'issuer': - self.issuerKey = pykey.RSAKey(value) + if value == 'alternate': + if subjectOrIssuer == 'subject': + self.subjectRSA_N = self.alternateRSA_N + self.subjectRSA_E = self.alternateRSA_E + elif subjectOrIssuer == 'issuer': + self.issuerRSA_N = self.alternateRSA_N + self.issuerRSA_E = self.alternateRSA_E + self.issuerRSA_D = self.alternateRSA_D + self.issuerRSA_P = self.alternateRSA_P + self.issuerRSA_Q = self.alternateRSA_Q + else: + raise UnknownKeyTargetError(subjectOrIssuer) else: - raise UnknownKeyTargetError(subjectOrIssuer) + raise UnknownKeySpecificationError(value) def addExtension(self, extensionType, extensionValue): if not self.extensions: @@ -336,12 +429,6 @@ class Certificate: count += 1 self.addExtension(rfc2459.id_ce_subjectAltName, subjectAlternativeName) - def addAuthorityInformationAccess(self, ocspURI): - sequence = univ.Sequence() - accessDescription = stringToAccessDescription(ocspURI) - sequence.setComponentByPosition(0, accessDescription) - self.addExtension(rfc2459.id_pe_authorityInfoAccess, sequence) - def getVersion(self): return rfc2459.Version(self.versionValue).subtype( explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)) @@ -373,6 +460,21 @@ class Certificate: def getSignatureAlgorithm(self): return stringToAlgorithmIdentifier(self.signature) + def getSubjectPublicKey(self): + rsaKey = RSAPublicKey() + rsaKey.setComponentByName('N', univ.Integer(self.subjectRSA_N)) + rsaKey.setComponentByName('E', univ.Integer(self.subjectRSA_E)) + return univ.BitString(byteStringToHexifiedBitString(encoder.encode(rsaKey))) + + def getSubjectPublicKeyInfo(self): + algorithmIdentifier = rfc2459.AlgorithmIdentifier() + algorithmIdentifier.setComponentByName('algorithm', rfc2459.rsaEncryption) + algorithmIdentifier.setComponentByName('parameters', univ.Null()) + spki = rfc2459.SubjectPublicKeyInfo() + spki.setComponentByName('algorithm', algorithmIdentifier) + spki.setComponentByName('subjectPublicKey', self.getSubjectPublicKey()) + return spki + def toDER(self): tbsCertificate = rfc2459.TBSCertificate() tbsCertificate.setComponentByName('version', self.getVersion()) @@ -381,8 +483,7 @@ class Certificate: tbsCertificate.setComponentByName('issuer', self.getIssuer()) tbsCertificate.setComponentByName('validity', self.getValidity()) tbsCertificate.setComponentByName('subject', self.getSubject()) - tbsCertificate.setComponentByName('subjectPublicKeyInfo', - self.subjectKey.asSubjectPublicKeyInfo()) + tbsCertificate.setComponentByName('subjectPublicKeyInfo', self.getSubjectPublicKeyInfo()) if self.extensions: extensions = rfc2459.Extensions().subtype( explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3)) @@ -391,11 +492,14 @@ class Certificate: extensions.setComponentByPosition(count, extension) count += 1 tbsCertificate.setComponentByName('extensions', extensions) + tbsDER = encoder.encode(tbsCertificate) + rsaPrivateKey = rsa.PrivateKey(self.issuerRSA_N, self.issuerRSA_E, self.issuerRSA_D, + self.issuerRSA_P, self.issuerRSA_Q) + signature = rsa.sign(tbsDER, rsaPrivateKey, 'SHA-256') certificate = rfc2459.Certificate() certificate.setComponentByName('tbsCertificate', tbsCertificate) certificate.setComponentByName('signatureAlgorithm', self.getSignatureAlgorithm()) - tbsDER = encoder.encode(tbsCertificate) - certificate.setComponentByName('signatureValue', self.issuerKey.sign(tbsDER)) + certificate.setComponentByName('signatureValue', byteStringToHexifiedBitString(signature)) return encoder.encode(certificate) def toPEM(self): diff --git a/security/manager/ssl/tests/unit/pykey.py b/security/manager/ssl/tests/unit/pykey.py deleted file mode 100755 index 3d701791a358..000000000000 --- a/security/manager/ssl/tests/unit/pykey.py +++ /dev/null @@ -1,282 +0,0 @@ -#!/usr/bin/env python -# -# 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/. - -""" -Reads a key specification from stdin or a file and outputs a -PKCS #8 file representing the (private) key. Also provides -methods for signing data and representing the key as a subject -public key info for use with pyasn1. - -The key specification format is currently very simple. If it is -empty, one RSA key is used. If it consists of the string -'alternate', a different RSA key is used. In the future it will -be possible to specify other properties of the key (type, -strength, signature algorithm, etc.). -""" - -from pyasn1.codec.der import encoder -from pyasn1.type import univ, namedtype -from pyasn1_modules import rfc2459 -import base64 -import binascii -import rsa -import sys - -def byteStringToHexifiedBitString(string): - """Takes a string of bytes and returns a hex string representing - those bytes for use with pyasn1.type.univ.BitString. It must be of - the form "''H", where the trailing 'H' indicates to - pyasn1 that the input is a hex string.""" - return "'%s'H" % binascii.hexlify(string) - -class UnknownBaseError(Exception): - """Base class for handling unexpected input in this module.""" - def __init__(self, value): - self.value = value - self.category = 'input' - - def __str__(self): - return 'Unknown %s type "%s"' % (self.category, repr(self.value)) - - -class UnknownKeySpecificationError(UnknownBaseError): - """Helper exception type to handle unknown key specifications.""" - - def __init__(self, value): - UnknownBaseError.__init__(self, value) - self.category = 'key specification' - - -class RSAPublicKey(univ.Sequence): - """Helper type for encoding an RSA public key""" - componentType = namedtype.NamedTypes( - namedtype.NamedType('N', univ.Integer()), - namedtype.NamedType('E', univ.Integer())) - - -class RSAPrivateKey(univ.Sequence): - """Helper type for encoding an RSA private key""" - componentType = namedtype.NamedTypes( - namedtype.NamedType('version', univ.Integer()), - namedtype.NamedType('modulus', univ.Integer()), - namedtype.NamedType('publicExponent', univ.Integer()), - namedtype.NamedType('privateExponent', univ.Integer()), - namedtype.NamedType('prime1', univ.Integer()), - namedtype.NamedType('prime2', univ.Integer()), - namedtype.NamedType('exponent1', univ.Integer()), - namedtype.NamedType('exponent2', univ.Integer()), - namedtype.NamedType('coefficient', univ.Integer()), - ) - - -class PrivateKeyInfo(univ.Sequence): - """Helper type for encoding a PKCS #8 private key info""" - componentType = namedtype.NamedTypes( - namedtype.NamedType('version', univ.Integer()), - namedtype.NamedType('privateKeyAlgorithm', rfc2459.AlgorithmIdentifier()), - namedtype.NamedType('privateKey', univ.OctetString()) - ) - - -class RSAKey: - # For reference, when encoded as a subject public key info, the - # base64-encoded sha-256 hash of this key is - # VCIlmPM9NkgFQtrs4Oa5TeFcDu6MWRTKSNdePEhOgD8= - sharedRSA_N = long( - '00ba8851a8448e16d641fd6eb6880636103d3c13d9eae4354ab4ecf56857' - '6c247bc1c725a8e0d81fbdb19c069b6e1a86f26be2af5a756b6a6471087a' - 'a55aa74587f71cd5249c027ecd43fc1e69d038202993ab20c349e4dbb94c' - 'c26b6c0eed15820ff17ead691ab1d3023a8b2a41eea770e00f0d8dfd660b' - '2bb02492a47db988617990b157903dd23bc5e0b8481fa837d38843ef2716' - 'd855b7665aaa7e02902f3a7b10800624cc1c6c97ad96615bb7e29612c075' - '31a30c91ddb4caf7fcad1d25d309efb9170ea768e1b37b2f226f69e3b48a' - '95611dee26d6259dab91084e36cb1c24042cbf168b2fe5f18f991731b8b3' - 'fe4923fa7251c431d503acda180a35ed8d', 16) - sharedRSA_E = 65537L - sharedRSA_D = long( - '009ecbce3861a454ecb1e0fe8f85dd43c92f5825ce2e997884d0e1a949da' - 'a2c5ac559b240450e5ac9fe0c3e31c0eefa6525a65f0c22194004ee1ab46' - '3dde9ee82287cc93e746a91929c5e6ac3d88753f6c25ba5979e73e5d8fb2' - '39111a3cdab8a4b0cdf5f9cab05f1233a38335c64b5560525e7e3b92ad7c' - '7504cf1dc7cb005788afcbe1e8f95df7402a151530d5808346864eb370aa' - '79956a587862cb533791307f70d91c96d22d001a69009b923c683388c9f3' - '6cb9b5ebe64302041c78d908206b87009cb8cabacad3dbdb2792fb911b2c' - 'f4db6603585be9ae0ca3b8e6417aa04b06e470ea1a3b581ca03a6781c931' - '5b62b30e6011f224725946eec57c6d9441', 16) - sharedRSA_P = long( - '00dd6e1d4fffebf68d889c4d114cdaaa9caa63a59374286c8a5c29a717bb' - 'a60375644d5caa674c4b8bc7326358646220e4550d7608ac27d55b6db74f' - '8d8127ef8fa09098b69147de065573447e183d22fe7d885aceb513d9581d' - 'd5e07c1a90f5ce0879de131371ecefc9ce72e9c43dc127d238190de81177' - '3ca5d19301f48c742b', 16) - sharedRSA_Q = long( - '00d7a773d9ebc380a767d2fec0934ad4e8b5667240771acdebb5ad796f47' - '8fec4d45985efbc9532968289c8d89102fadf21f34e2dd4940eba8c09d6d' - '1f16dcc29729774c43275e9251ddbe4909e1fd3bf1e4bedf46a39b8b3833' - '28ef4ae3b95b92f2070af26c9e7c5c9b587fedde05e8e7d86ca57886fb16' - '5810a77b9845bc3127', 16) - sharedRSA_exp1 = long( - '0096472b41a610c0ade1af2266c1600e3671355ba42d4b5a0eb4e9d7eb35' - '81400ba5dd132cdb1a5e9328c7bbc0bbb0155ea192972edf97d12751d8fc' - 'f6ae572a30b1ea309a8712dd4e33241db1ee455fc093f5bc9b592d756e66' - '21474f32c07af22fb275d340792b32ba2590bbb261aefb95a258eea53765' - '5315be9c24d191992d', 16) - sharedRSA_exp2 = long( - '28b450a7a75a856413b2bda6f7a63e3d964fb9ecf50e3823ef6cc8e8fa26' - 'ee413f8b9d1205540f12bbe7a0c76828b7ba65ad83cca4d0fe2a220114e1' - 'b35d03d5a85bfe2706bd50fce6cfcdd571b46ca621b8ed47d605bbe765b0' - 'aa4a0665ac25364da20154032e1204b8559d3e34fb5b177c9a56ff93510a' - '5a4a6287c151de2d', 16) - sharedRSA_coef = long( - '28067b9355801d2ef52dfa96d8adb589673cf8ee8a9c6ff72aeeabe9ef6b' - 'e58a4f4abf05f788947dc851fdaa34542147a71a246bfb054ee76aa346ab' - 'cd2692cfc9e44c51e6f069c735e073ba019f6a7214961c91b26871caeabf' - '8f064418a02690e39a8d5ff3067b7cdb7f50b1f53418a703966c4fc774bf' - '7402af6c43247f43', 16) - - # For reference, when encoded as a subject public key info, the - # base64-encoded sha-256 hash of this key is - # MQj2tt1yGAfwFpWETYUCVrZxk2CD2705NKBQUlAaKJI= - alternateRSA_N = long( - '00c175c65266099f77082a6791f1b876c37f5ce538b06c4acd22b1cbd46f' - 'a65ada2add41c8c2498ac4a3b3c1f61487f41b698941bd80a51c3c120244' - 'c584a4c4483305e5138c0106cf08be9a862760bae6a2e8f36f23c5d98313' - 'b9dfaf378345dace51d4d6dcd2a6cb3cc706ebcd3070ec98cce40aa591d7' - '295a7f71c5be66691d2b2dfec84944590bc5a3ea49fd93b1d753405f1773' - '7699958666254797ed426908880811422069988a43fee48ce68781dd22b6' - 'a69cd28375131f932b128ce286fa7d251c062ad27ef016f187cdd54e832b' - '35b8930f74ba90aa8bc76167242ab1fd6d62140d18c4c0b8c68fc3748457' - '324ad7de86e6552f1d1e191d712168d3bb', 16) - alternateRSA_E = 65537L - alternateRSA_D = long( - '7e3f6d7cb839ef66ae5d7dd92ff5410bb341dc14728d39034570e1a37079' - '0f30f0681355fff41e2ad4e9a9d9fcebfbd127bdfab8c00affb1f3cea732' - '7ead47aa1621f2ac1ee14ca02f04b3b2786017980b181a449d03b03e69d1' - '12b83571e55434f012056575d2832ed6731dce799e37c83f6d51c55ab71e' - 'b58015af05e1af15c747603ef7f27d03a6ff049d96bbf854c1e4e50ef5b0' - '58d0fb08180e0ac7f7be8f2ff1673d97fc9e55dba838077bbf8a7cff2962' - '857785269cd9d5bad2b57469e4afcd33c4ca2d2f699f11e7c8fbdcd484f0' - '8d8efb8a3cb8a972eb24bed972efaae4bb712093e48fe94a46eb629a8750' - '78c4021a9a2c93c9a70390e9d0a54401', 16) - alternateRSA_P = long( - '00e63fc725a6ba76925a7ff8cb59c4f56dd7ec83fe85bf1f53e11cac9a81' - '258bcfc0ae819077b0f2d1477aaf868de6a8ecbeaf7bb22b196f2a9ad82d' - '3286f0d0cc29de719e5f2be8e509b7284d5963edd362f927887a4c4a8979' - '9d340d51b301ac7601ab27179024fcaadd38bf6522af63eb16461ec02a7f' - '27b06fe09ddda7c0a1', 16) - alternateRSA_Q = long( - '00d718b1fe9f8f99f00e832ae1fbdc6fe2ab27f34e049c498010fa0eb708' - '4852182346083b5c96c3eee5592c014a410c6b930b165c13b5c26aa32eac' - '6e7c925a8551c25134f2f4a72c6421f19a73148a0edfaba5d3a6888b35cb' - 'a18c00fd38ee5aaf0b545731d720761bbccdee744a52ca415e98e4de01cd' - 'fe764c1967b3e8cadb', 16) - alternateRSA_exp1 = long( - '01e5aca266c94a88d22e13c2b92ea247116c657a076817bdfd30db4b3a9d' - '3095b9a4b6749647e2f84e7a784fc7838b08c85971cf7a036fa30e3b91c3' - 'c4d0df278f80c1b6e859d8456adb137defaa9f1f0ac5bac9a9184fd4ea27' - '9d722ea626f160d78aad7bc83845ccb29df115c83f61b7622b99bd439c60' - '9b5790a63c595181', 16) - alternateRSA_exp2 = long( - '0080cc45d10d2484ee0d1297fc07bf80b3beff461ea27e1f38f371789c3a' - 'f66b4a0edd2192c227791db4f1c77ae246bf342f31856b0f56581b58a95b' - '1131c0c5396db2a8c3c6f39ea2e336bc205ae6a2a0b36869fca98cbba733' - 'cf01319a6f9bb26b7ca23d3017fc551cd8da8afdd17f6fa2e30d34868798' - '1cd6234d571e90b7df', 16) - alternateRSA_coef = long( - '6f77c0c1f2ae7ac169561cca499c52bdfbe04cddccdbdc12aec5a85691e8' - '594b7ee29908f30e7b96aa6254b80ed4aeec9b993782bdfc79b69d8d58c6' - '8870fa4be1bc0c3527288c5c82bb4aebaf15edff110403fc78e6ace6a828' - '27bf42f0cfa751e507651c5638db9393dd23dd1f6b295151de44b77fe55a' - '7b0df271e19a65c0', 16) - - def __init__(self, specification = None): - if not specification: - self.RSA_N = self.sharedRSA_N - self.RSA_E = self.sharedRSA_E - self.RSA_D = self.sharedRSA_D - self.RSA_P = self.sharedRSA_P - self.RSA_Q = self.sharedRSA_Q - self.RSA_exp1 = self.sharedRSA_exp1 - self.RSA_exp2 = self.sharedRSA_exp2 - self.RSA_coef = self.sharedRSA_coef - elif specification == 'alternate': - self.RSA_N = self.alternateRSA_N - self.RSA_E = self.alternateRSA_E - self.RSA_D = self.alternateRSA_D - self.RSA_P = self.alternateRSA_P - self.RSA_Q = self.alternateRSA_Q - self.RSA_exp1 = self.alternateRSA_exp1 - self.RSA_exp2 = self.alternateRSA_exp2 - self.RSA_coef = self.alternateRSA_coef - else: - raise UnknownKeySpecificationError(specification) - - def toDER(self): - privateKeyInfo = PrivateKeyInfo() - privateKeyInfo.setComponentByName('version', 0) - algorithmIdentifier = rfc2459.AlgorithmIdentifier() - algorithmIdentifier.setComponentByName('algorithm', rfc2459.rsaEncryption) - algorithmIdentifier.setComponentByName('parameters', univ.Null()) - privateKeyInfo.setComponentByName('privateKeyAlgorithm', algorithmIdentifier) - rsaPrivateKey = RSAPrivateKey() - rsaPrivateKey.setComponentByName('version', 0) - rsaPrivateKey.setComponentByName('modulus', self.RSA_N) - rsaPrivateKey.setComponentByName('publicExponent', self.RSA_E) - rsaPrivateKey.setComponentByName('privateExponent', self.RSA_D) - rsaPrivateKey.setComponentByName('prime1', self.RSA_P) - rsaPrivateKey.setComponentByName('prime2', self.RSA_Q) - rsaPrivateKey.setComponentByName('exponent1', self.RSA_exp1) - rsaPrivateKey.setComponentByName('exponent2', self.RSA_exp2) - rsaPrivateKey.setComponentByName('coefficient', self.RSA_coef) - rsaPrivateKeyEncoded = encoder.encode(rsaPrivateKey) - privateKeyInfo.setComponentByName('privateKey', univ.OctetString(rsaPrivateKeyEncoded)) - return encoder.encode(privateKeyInfo) - - def toPEM(self): - output = '-----BEGIN PRIVATE KEY-----' - der = self.toDER() - b64 = base64.b64encode(der) - while b64: - output += '\n' + b64[:64] - b64 = b64[64:] - output += '\n-----END PRIVATE KEY-----' - return output - - def asSubjectPublicKeyInfo(self): - """Returns a subject public key info representing - this key for use by pyasn1.""" - algorithmIdentifier = rfc2459.AlgorithmIdentifier() - algorithmIdentifier.setComponentByName('algorithm', rfc2459.rsaEncryption) - algorithmIdentifier.setComponentByName('parameters', univ.Null()) - spki = rfc2459.SubjectPublicKeyInfo() - spki.setComponentByName('algorithm', algorithmIdentifier) - rsaKey = RSAPublicKey() - rsaKey.setComponentByName('N', univ.Integer(self.RSA_N)) - rsaKey.setComponentByName('E', univ.Integer(self.RSA_E)) - subjectPublicKey = univ.BitString(byteStringToHexifiedBitString(encoder.encode(rsaKey))) - spki.setComponentByName('subjectPublicKey', subjectPublicKey) - return spki - - def sign(self, data): - """Returns a hexified bit string representing a - signature by this key over the specified data. - Intended for use with pyasn1.type.univ.BitString""" - rsaPrivateKey = rsa.PrivateKey(self.RSA_N, self.RSA_E, self.RSA_D, self.RSA_P, self.RSA_Q) - signature = rsa.sign(data, rsaPrivateKey, 'SHA-256') - return byteStringToHexifiedBitString(signature) - - -# The build harness will call this function with an output file-like -# object and a path to a file containing a specification. This will -# read the specification and output the key as ASCII-encoded PKCS #8. -def main(output, inputPath): - with open(inputPath) as configStream: - output.write(RSAKey(configStream.read()).toPEM()) - -# When run as a standalone program, this will read a specification from -# stdin and output the certificate as PEM to stdout. -if __name__ == '__main__': - print RSAKey(sys.stdin.read()).toPEM() diff --git a/security/manager/ssl/tests/unit/test_ocsp_url.js b/security/manager/ssl/tests/unit/test_ocsp_url.js index b731a1bcf6be..385f568f853e 100644 --- a/security/manager/ssl/tests/unit/test_ocsp_url.js +++ b/security/manager/ssl/tests/unit/test_ocsp_url.js @@ -25,14 +25,14 @@ function start_ocsp_responder(expectedCertNames, expectedPaths) { } function check_cert_err(cert_name, expected_error) { - let cert = constructCertFromFile("test_ocsp_url/" + cert_name + ".pem"); + let cert = constructCertFromFile("test_ocsp_url/" + cert_name + ".der"); return checkCertErrorGeneric(certdb, cert, expected_error, certificateUsageSSLServer); } function run_test() { - addCertFromFile(certdb, "test_ocsp_url/ca.pem", 'CTu,CTu,CTu'); - addCertFromFile(certdb, "test_ocsp_url/int.pem", ',,'); + addCertFromFile(certdb, "test_ocsp_url/ca.der", 'CTu,CTu,CTu'); + addCertFromFile(certdb, "test_ocsp_url/int.der", ',,'); // Enabled so that we can force ocsp failure responses. Services.prefs.setBoolPref("security.OCSP.require", true); @@ -44,7 +44,7 @@ function run_test() { add_test(function() { clearOCSPCache(); let ocspResponder = failingOCSPResponder(); - check_cert_err("bad-scheme", SEC_ERROR_CERT_BAD_ACCESS_LOCATION); + check_cert_err("bad-scheme",SEC_ERROR_CERT_BAD_ACCESS_LOCATION); ocspResponder.stop(run_next_test); }); diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/bad-scheme.der b/security/manager/ssl/tests/unit/test_ocsp_url/bad-scheme.der new file mode 100644 index 0000000000000000000000000000000000000000..0b26ef20e5e0a87faff02dc708b53b85ac45fc9d GIT binary patch literal 895 zcmXqLVy-r5VoF}X%*4pV#B32OV!+GBsnzDu_MMlJk(HIfAkL86fRl|ml!Z;0DKywn z*gz1(;SlC>PRz+n%P-2yOf(cT5CI9Y3-kKsm*$luX67k`Wu}%JiWmri#JPmI1A=`O zLQ;!MGV{_6c?`HfqRhg~nRz7!a^k#(CI+TPhKA(s( z%(nlt=PP1=|txjUzD<3 z8?LmSUZwM!^BzA(m4g1+4uh52*V{xHxa{v05EQ>siq?bfi~wsdnnEzZ7vU?v3cjUa^Wvh**6^Xe8IjMTd`MKbvBP-0pWWazNyugG7 z3|>Zto=dYM#P_aSz4+Z1>+ADkxLyhUozfk%XStA4jMdxe(P69pu-z3k(C|O<-e=B~ z483=1Ultu$n_+*(ccZR@q-!hNpJVqfHdnpf6|qU9onQIW=Oz1&DX&+G%Rj;As?F+? ze#l&f=i%EqTPJHQc1+OL@^|b0@j5@D_QJXIS#2Fjx1U|y|3`A~Ve1EX*NWchl3jIL zcCq32ov-6}&i+?&{E6!M#kXq~b5HRRdpk3qIsLVlrI7%*4pV#L6(=wnyH8myJ`a&7D}zC-A-4f18*?ZNn=n&o zu%WPlAc(^u%;lVzlbM!Zl$V)kC}to65@Z+V_02EMD@n}EQwYmUEjJV~5CVyF33CSo z`znN_7MEn^rNhi)7G_FLG>{YLH8e3WH8M0bH#Radj1uQHLgv!i`X)vtWDhg4GB7tW z@-rATF>*0AF)}i&HC!mv()#Vg%KZ!L`4zr5XReb{T_tpA#3qUYbU-nPS7VE)hKOjW@c=Qq+~{u@?>aLjio_q0*{X(Cr=@oCo5=|5*|-fO~d zE^Dl5>foPQ8d}8_H08d9@*Wsyy?`eA<_@4ln? z)#$#1xBdEHzxx;F-zhZW#Bmwq9zKuwU}Wue2(!2Dwmp6skmvVU9rLR!pm=BE_d zcaHDabIYU66fzUGb@Nv*{XJOw5c7jEe;f_zZY}F)1s|!fL?G$oL;Q%z%jm7-ozN zen($2ay)r`e$@`!!RPVFqL`g+Eh%?CqoZNIrx(m_sXp@;pkJjs+jE@9U3Gu@n0=Npz) z^4$~sUwPqJDBGWt(Mk25t%84_v7F7mQ>Of}|I0C5rKdCRH*R`(`jWe&+UN8d&In(1 zKigl8VPBs+{L+`{x^hG^Gkq54r#o9)l?zSf#Rr9bKueVp^# Q@c;hxvw8(nmg)Wk0Q$W{i2wiq literal 0 HcmV?d00001 diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/ca.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/ca.pem.certspec deleted file mode 100644 index d809dbd635d4..000000000000 --- a/security/manager/ssl/tests/unit/test_ocsp_url/ca.pem.certspec +++ /dev/null @@ -1,4 +0,0 @@ -issuer:ca -subject:ca -extension:basicConstraints:cA, -extension:keyUsage:keyCertSign,cRLSign diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/cert9.db b/security/manager/ssl/tests/unit/test_ocsp_url/cert9.db new file mode 100644 index 0000000000000000000000000000000000000000..ddfac8e73aa0f843fdd5466edc19b1dd1d138b65 GIT binary patch literal 43008 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 literal 0 HcmV?d00001 diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/empty-port.der b/security/manager/ssl/tests/unit/test_ocsp_url/empty-port.der new file mode 100644 index 0000000000000000000000000000000000000000..8293d79b2ab6b1309ea348fb0458dde0d3c659cf GIT binary patch literal 904 zcmXqLVs0^LV#-;-%*4pV#KI{2MAd+ojZ>@5qwPB{BO@y-gF&1jw*e;`b0`a&FjHu- zp|F7NzBYs2+K?@Hxw}t0*P}8a|Zfqr`cQkhun_RJR}M1!iHc z)ZBuSO5K9|q7s89MkQpQGqN%;H!<=v0L8hOniv@w9<{v-)~+iwDmj1UeM!)?+lQ{N z<#(E@Dp9xW#{c>I1ve@OuAH)R>YC}Rie4}JV|P2pAc1???v=;uGnnNrYMj5n>gr8{ zx|MO4A8$D&JN=qv{;oSu|1f^moH}s|Q>1fyaM{N)87ZQ>uz}mnTIq7GPeoYDK{ur_KO6{|zg}YxX+31vC2sII64L;~+x~sDP_wuNf^P>OT zS?H9{^$Bh6zSlKpmxcD!;C6=zT`J5rUuqBRx{{fEQ0SfKMp4tMZ|>Pl%!~|-i=7P| z4NTZLwAp}3gPoC)MZ-YNKn2D(U~H4fC@Cqh($_C9FV{=0NX#wBN!3fv&$ZGACm~s3 z7A6A* z=kY2lWxAmub!&=D-+XzctMxLbx>G|OuerZ@^UWb^&GJM4*moVcaK^fN=fj;JJhJCq znY=kui|@k1trCar)?}vt+EQELCv$o4D$Kc`TFh#IvE{c)3mTpTA+Ay}!)_7r)Cm>=bLG z9#q!w&aEZEVPo;j7x(uaZ8Q7v@V;f@>lD*RuX|d4#0G6FrjsO4v literal 0 HcmV?d00001 diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/empty-port.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/empty-port.pem.certspec deleted file mode 100644 index 4f3e296f9c91..000000000000 --- a/security/manager/ssl/tests/unit/test_ocsp_url/empty-port.pem.certspec +++ /dev/null @@ -1,3 +0,0 @@ -issuer:int -subject:empty-port -extension:authorityInformationAccess:http://www.example.com:/ diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/empty-scheme-url.der b/security/manager/ssl/tests/unit/test_ocsp_url/empty-scheme-url.der new file mode 100644 index 0000000000000000000000000000000000000000..599c6ca54ee9a7712dc85aa6eb5818cc0cc9643b GIT binary patch literal 910 zcmXqLV(v0%Vk%m|%*4pV#KO2lO~`@5qwPB{BO@y-gF&1jw*e;`b0`a&FjHu- zp|F7NzBYs2+K?@Hxw}t0*P}8a|Z$hd3@xyS+*6TeJ|9p=pNw49S%%x!Qie>tqvn!lo%Er6wXKc}7%sSx`az zl17uAAN|igv6ht5{2g{zFS)F+XW!n8%^QL)7MHl6UdcC0wQ+G__I<7VkWCMl^6fk- zqV}@jx8^aapg#wN?eY(|p1ad%>T|n;U$uE-7}w*EmMy~5w~X-a7Q0gl~#zH4u*U%5Pwk%^g+ zfpM|3fun&58;3R9<>lpisTGO21v#mD$@#ff7C@j6 zPDrxCEKCLr$iWOuX24)(WU%{iI&9jG`pNef^;_P&zSBzf596hG-?n>nRL$-dzp#DJ zBT~Mo-^4VRQXkBi3_Ig`^cYH`Q)Z-C;6M{QWZ~D~6EY>5_h@%$pCb z`SEGrCW&2l*w>t!c(8#@l#5L^ZpFd?*2!KvhbKnU8 zb+KKu%Wrn@{nQg)9ygP-U`~?_7t5`*{*PPrek{Aer+)sI3%9-VoSy8h8rwVymMLv! z6cym@@7;1Ran|#6x2rF=gty%buI7mnX6T8v;L8kIc*p;~8e2w*VP5M?qqCXKu};^2 f{n|8ljX}rV8YPwg5i1&QWbWlH{L^Th`m7lM7R^o` literal 0 HcmV?d00001 diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/empty-scheme-url.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/empty-scheme-url.pem.certspec deleted file mode 100644 index e8959653f3c1..000000000000 --- a/security/manager/ssl/tests/unit/test_ocsp_url/empty-scheme-url.pem.certspec +++ /dev/null @@ -1,3 +0,0 @@ -issuer:int -subject:empty-scheme-url -extension:authorityInformationAccess:://www.example.com:8888/ diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/ftp-url.der b/security/manager/ssl/tests/unit/test_ocsp_url/ftp-url.der new file mode 100644 index 0000000000000000000000000000000000000000..efa716a4b2a620b65ecd0d316f44456fd21d89c8 GIT binary patch literal 903 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

=h`h!ceN7%}uSptrb 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 literal 0 HcmV?d00001 diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/moz.build b/security/manager/ssl/tests/unit/test_ocsp_url/moz.build deleted file mode 100644 index 5cf49a7f9946..000000000000 --- a/security/manager/ssl/tests/unit/test_ocsp_url/moz.build +++ /dev/null @@ -1,42 +0,0 @@ -# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# 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/. - -test_certificates = ( - 'bad-scheme.pem', - 'ca.pem', - 'empty-port.pem', - 'empty-scheme-url.pem', - 'ftp-url.pem', - 'hTTp-url.pem', - 'https-url.pem', - 'int.pem', - 'negative-port.pem', - 'no-host-url.pem', - 'no-path-url.pem', - 'no-scheme-host-port.pem', - 'no-scheme-url.pem', - 'unknown-scheme.pem', -) - -for test_certificate in test_certificates: - input_file = test_certificate + '.certspec' - GENERATED_FILES += [test_certificate] - props = GENERATED_FILES[test_certificate] - props.script = '../pycert.py' - props.inputs = [input_file, '!/config/buildid'] - TEST_HARNESS_FILES.xpcshell.security.manager.ssl.tests.unit.test_ocsp_url += ['!%s' % test_certificate] - -test_keys = ( - 'int.key', -) - -for test_key in test_keys: - input_file = test_key + '.keyspec' - GENERATED_FILES += [test_key] - props = GENERATED_FILES[test_key] - props.script = '../pykey.py' - props.inputs = [input_file] - TEST_HARNESS_FILES.xpcshell.security.manager.ssl.tests.unit.test_ocsp_url += ['!%s' % test_key] diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/negative-port.der b/security/manager/ssl/tests/unit/test_ocsp_url/negative-port.der new file mode 100644 index 0000000000000000000000000000000000000000..2e334b682eac577b0203cc5153c32ba269dc99f9 GIT binary patch literal 908 zcmXqLV(u_#Vk%g`%*4pV#KQ3J#{mOgHcqWJkGAi;jEt#>@(l2>B(G)ZYY{<^3wnYp~axu40>Kt@k6Wa+!B+a^nK{4d=3cFK*0{HdP`tM&8$ z4|n*he#_{4WFm3$_iD#KGmNtICB7_i zc(%_zD2T10VuvPU-D&|Zz59#rN@VR@XZb*vHH1^gUnM8}$(kHPx#i7gbML3h@(aIV zRN5i>U;4Y{7;V5vxx{|6Ml!&bgR8IV_j|yL9dEUI@AO&pbNu-~r}et9{=sL9ib_Ab``BJzn`x#r zyDC|lXO@Igw`Z-nxO(yTTLC_WH~M?DKkn01KbgT&?04|eZ_zK8(`|!&B7O$!$laCl ze_zEx&amqH9^d!f<-S;@bhANxrHCR^)im)(f2J?by&C@EhMe$g!|A;@RbPaKm)Tbu dUEg%0T3NhS;CT(l6MmsAUs)&H&Ed1GbOBNzO6~vv literal 0 HcmV?d00001 diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/negative-port.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/negative-port.pem.certspec deleted file mode 100644 index 4abc0720519f..000000000000 --- a/security/manager/ssl/tests/unit/test_ocsp_url/negative-port.pem.certspec +++ /dev/null @@ -1,3 +0,0 @@ -issuer:int -subject:negative-port -extension:authorityInformationAccess:http://www.example.com:-1 diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/no-host-url.der b/security/manager/ssl/tests/unit/test_ocsp_url/no-host-url.der new file mode 100644 index 0000000000000000000000000000000000000000..236dd8186cb5db9bc51f0758d76d3b5e10c410ad GIT binary patch literal 894 zcmXqLVy-f1VoF-T%*4pV#KN#OCC7l5jZ>@5qwPB{BO@y-gF&1jw*e;`b0`a&FjHu- zp|F7NzBYs2+K?@Hxw}t0*P}8a|Z=qr`cQkhunFRJR}MDrRBs zynNk^{NfVb(xM!LCPpP>uQReTFgG#sGXTZ8n3@YMc#+$3tD})# z1r}>ggn8U5+fmi=@J`xf3452B>U$)vA9=yxAkRAnn{z4V>#4_N7#`0uUzlLf z)iisXbBy=7JG);TQ`63wpliPTQ{tMM%01`Q4v9}V9Gh47UBs-5%f&T|@9AE)iC_4aY`%Q(^ZMbX;8bZO5)ZZCtm`iCl>hUbNnc zgQdxH^3&(5WKW&Xn>;D>_yfh44J!}s3n;zAzO+>J%>BH#pD$lf-6j2+B|Gu8j?jr0 SWmV_*pVU4T!7??O-x&bGu1^;L literal 0 HcmV?d00001 diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/no-host-url.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/no-host-url.pem.certspec deleted file mode 100644 index 4ac76e7eb33a..000000000000 --- a/security/manager/ssl/tests/unit/test_ocsp_url/no-host-url.pem.certspec +++ /dev/null @@ -1,3 +0,0 @@ -issuer:int -subject:no-host-url -extension:authorityInformationAccess:http://:8888/ diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/no-path-url.der b/security/manager/ssl/tests/unit/test_ocsp_url/no-path-url.der new file mode 100644 index 0000000000000000000000000000000000000000..2333b33a1f837eeccd2f654daa90b7033e48e02b GIT binary patch literal 908 zcmXqLV(u_#Vk%g`%*4pV#KL&~^cMqOHcqWJkGAi;jEth&j1wXVrpV!WO#g!akZanaLIC;Qwu9IOP;=; z;Ls|6C51V^`u&Nx>j_$OX6sInbia1+NRX^_kD2D(n#Z3K)wjg|*ITi4qrJ@#=CMP2?l)IQX#_49~ zWQAFn3>c6@8kop{A%v}Afq$oc?^l1f zH^s-(Ui5U!b*H8ln;ZL19P6K-7uYT!@~8d|e+KtER_TnH+iZdw?$+0x*9&Axbo}%n zmgnvBX@~25%>q7q8RxR?;&ShgPi=eoZMsYX=f=h9RiDiq`9(PwINo3X;eMa3$BMPK z@5JrW{>VSuk#_ga^6hQA`A+XSaiU)1b2=NpwC9Omi&p%Jc6|_P-ML-!-1!8i^!-zG zzV81jrgG-#6_L;HnO^M;@mz6j&)uvmCtU*XUy7Z+_vz~XB}UGNFSZqDEK7X%t4@Dw e@S(KkIZ|A+Wg8pWC0OFUbgt(6ADLRv8x8>IJyX;G literal 0 HcmV?d00001 diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/no-path-url.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/no-path-url.pem.certspec deleted file mode 100644 index 497bb287967c..000000000000 --- a/security/manager/ssl/tests/unit/test_ocsp_url/no-path-url.pem.certspec +++ /dev/null @@ -1,3 +0,0 @@ -issuer:int -subject:no-path-url -extension:authorityInformationAccess:http://www.example.com:8888 diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-host-port.der b/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-host-port.der new file mode 100644 index 0000000000000000000000000000000000000000..f6e0179a6e48f016bcb4c2c82e50b5dfe482cb61 GIT binary patch literal 889 zcmXqLVlFjkVv1eB%*4pV#2lCU*?^agQ>)FR?K>|cBP%O|L7XAC0Vf-CC<~h~Q)sZE zuz?_m!y(M&oS2iDmS2>YnP@0xAOaF(7v}ZNFU>1S%*;~=%SdZ*}iC|G%;0yW+(i+9kg#q(ur>M|cy^k3-zuw{Qc)7?ATA=9UPdA?_&OX889$vRW+IEGEInCz;^a^b<&i#sHq z+B9Z4T$po$^EFqk!NuTX9T!vkRHY{DVtkq&#eCYMVn@^i|FbKdOFwwrbnH(1dwcQ= z+szG|nH-d)&R6oxOlxFe+|hX_uX+EQKZoZ05>R>X)3#?V+gG-a>}QjA#HpOrDO=O$ z9{ohvoX_Hq+p%3%PA~OOKHDynZ6bd1D*w)vg0X=gToyQemJ?e1FOK{9&)GIl@6T?{ zWnyMzU|g(Ypk*M-#-YsyOe5@!j4Xl%{J>Cy@(mc<81=!4Mpl@G$$$YlJb_6H7@mv_ zYSG1|*D~F5EMt!EULUE$$U6PdYmB z_Pe*UPB3Mg#_gT>s=F}zV9f(=+rUJT0^zIMcY2>;S-^29XlL}-=)`kD-*2=h`xUN} zzJ7b@Z!>`@vrPUP+D9&Cj(p;>!+)vfG>0!g1v1hevL$Vr@chiKRhxI5PO6dXaQwkt zX}*7I(FDaileRf0d?xW{g#5NZ^Z(T34J7e;F zE+<2t!h?tGy|?etkvIEuar*wv&wHJ2E)bJWU2#d_cEl7W`~6x*MeWkNX5^}>{doDl O)Zv|-`^w|j97_SJmQM-* literal 0 HcmV?d00001 diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-host-port.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-host-port.pem.certspec deleted file mode 100644 index 42a555e411b5..000000000000 --- a/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-host-port.pem.certspec +++ /dev/null @@ -1,3 +0,0 @@ -issuer:int -subject:no-scheme-host-port -extension:authorityInformationAccess:/ diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-url.der b/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-url.der new file mode 100644 index 0000000000000000000000000000000000000000..0bab0213518ee7fff702f6164df06837cb81f73c GIT binary patch literal 904 zcmXqLVs0^LV#-;-%*4pV#KLIUKf!>PjZ>@5qwPB{BO@y-gF&1jw*e;`b0`a&FjHu- zp|F7NzBYs2+K?@Hxw}t0*P}8a|ZgqQrTPkhumKRJR}MT4rJ1 zynNl_PFeE>6mX5>!4 zOUo~0Z2Zpr_PX7a{?k#uN2Wb2>dG{pRx0qDX@%&cOY>_ukImWnXwMb7ZxajKEccri zw(`dO@LwwPBG-SH%_4itMLnBkROfO&5pVxgEs!x&)-h}Q=k+~XGpB?bNPC%iCFPf$ zcVR#A>fAiz&(C>Iw9aGM_ot=h-DG|F++FjTbf@uui+ao&&Sb5ZWpbhW)GW5gjC)R< zzL!+#-YsyOdafuj4Y}K$_9!sz5!#KXnA?LUTQ^RZb43}UUGh}l?4#!gOiY~Fbk6b z19BJx6Bsaz85vqj_Aq2ToVoV&y|fG#Z@;GZE9+*9I8{DQdUWHKroLf-xW^WQ)m+ED zh4i1#@U`5%khy3@vDO)u&a-roJjxG-^;Oc zkK}t%xeafwG3Fh=^z3>3tOX7HXSPl;WuJY+$l(z~vH6p7-N!A@ z)tL`HbXI#C$gH`4qrRdX&!&e}zy5CQjh}HVAUH12<<9S{8QsPyr`F$)b6#d^b%*4pV#KQ3V{5b<&HcqWJkGAi;jEtMI-j zTQ@f?Iu$fUOqca|=BcmmjZ@y8{qRt^|FqrxLxNG7N3JSwk$APeZtHEqA5sEk>3a-% zmNb_M_DxJZc+Rq9&db*i%|A)p^*f&T;;1&y#`hbQ=i9z^oO?p<+_rU_x}Lma{p@}w zsHgY8+3d+Fi{`#>ZVB>#x=s6SXlLA{h!^v`KX6SJm6=>Op~^@3mG0%uKeZB$E}lK@ z!;WJG$0NTQ8hV-XZ7R{&AADbLR+vNS8q3SS%+FX|xOINt|C*?NvsBN&`Q9;cCHrn& zk-Xu(ApP|DGk22L-AL@7Zu)cQwdzGH4;e_GtlhJG*QHd^{o1`-n_AgKf3AMqy^x8S zk%4isgMpoaAsdG_8!&mWGcvNM8Ymkm!uSS^ZK5S51y=g{<>lpisTGO21v#mD$@#h9 zG$bp`!eqdJ9LB&D1`K0H2Fv$1+}dWayUcyu{hgJ!L@ctYeaEHws!eGn7OeALy*bMK z_QPLA3BMNZZ||pvPPn(-)A){oyo!8;zH-<)yNz3yMU*#N zzv%RNtL4Au?Qd7UWVvo;zx0}F>Ap}8hX-5b>aUrd&Aznlqt&Wa-oNZm{=8oLv;79g zHaJ gG1cX8nyApE+DFG4^BHa$U%Kt&%eug%t}CJv0BJj6PXGV_ literal 0 HcmV?d00001 diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/unknown-scheme.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/unknown-scheme.pem.certspec deleted file mode 100644 index a5e62b3e6e65..000000000000 --- a/security/manager/ssl/tests/unit/test_ocsp_url/unknown-scheme.pem.certspec +++ /dev/null @@ -1,3 +0,0 @@ -issuer:int -subject:unknown-scheme-url -extension:authorityInformationAccess:ttp://www.example.com diff --git a/security/manager/ssl/tests/unit/tlsserver/cmd/GenerateOCSPResponse.cpp b/security/manager/ssl/tests/unit/tlsserver/cmd/GenerateOCSPResponse.cpp index 219f97377121..8bb54bcbce6a 100644 --- a/security/manager/ssl/tests/unit/tlsserver/cmd/GenerateOCSPResponse.cpp +++ b/security/manager/ssl/tests/unit/tlsserver/cmd/GenerateOCSPResponse.cpp @@ -10,13 +10,9 @@ */ #include -#include -#include #include "mozilla/ArrayUtils.h" -#include "base64.h" -#include "cert.h" #include "nspr.h" #include "nss.h" #include "plarenas.h" @@ -70,8 +66,9 @@ const static OCSPResponseName kOCSPResponseNameList[] = { // two years old }; + bool -StringToOCSPResponseType(const char* respText, +stringToOCSPResponseType(const char* respText, /*out*/ OCSPResponseType* OCSPType) { if (!OCSPType) { @@ -110,216 +107,7 @@ WriteResponse(const char* filename, const SECItem* item) return true; } -template -SECStatus -ReadFileToBuffer(const char* basePath, const char* filename, char (&buf)[N]) -{ - static_assert(N > 0, "input buffer too small for ReadFileToBuffer"); - if (PR_snprintf(buf, N - 1, "%s/%s", basePath, filename) == 0) { - PrintPRError("PR_snprintf failed"); - return SECFailure; - } - ScopedPRFileDesc fd(PR_OpenFile(buf, PR_RDONLY, 0)); - if (!fd) { - PrintPRError("PR_Open failed"); - return SECFailure; - } - int32_t fileSize = PR_Available(fd); - if (fileSize < 0) { - PrintPRError("PR_Available failed"); - return SECFailure; - } - if (static_cast(fileSize) > N - 1) { - PR_fprintf(PR_STDERR, "file too large - not reading\n"); - return SECFailure; - } - int32_t bytesRead = PR_Read(fd, buf, fileSize); - if (bytesRead != fileSize) { - PrintPRError("PR_Read failed"); - return SECFailure; - } - buf[bytesRead] = 0; - return SECSuccess; -} -namespace mozilla { - -MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPRDir, PRDir, PR_CloseDir); -MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPORTString, unsigned char, PORT_Free); - -}; - -void -AddKeyFromFile(const char* basePath, const char* filename) -{ - const char* PRIVATE_KEY_HEADER = "-----BEGIN PRIVATE KEY-----"; - const char* PRIVATE_KEY_FOOTER = "-----END PRIVATE KEY-----"; - - char buf[16384] = { 0 }; - SECStatus rv = ReadFileToBuffer(basePath, filename, buf); - if (rv != SECSuccess) { - return; - } - if (strncmp(buf, PRIVATE_KEY_HEADER, strlen(PRIVATE_KEY_HEADER)) != 0) { - PR_fprintf(PR_STDERR, "invalid key - not importing\n"); - return; - } - const char* bufPtr = buf + strlen(PRIVATE_KEY_HEADER); - size_t bufLen = strlen(buf); - char base64[16384] = { 0 }; - char* base64Ptr = base64; - while (bufPtr < buf + bufLen) { - if (strncmp(bufPtr, PRIVATE_KEY_FOOTER, strlen(PRIVATE_KEY_FOOTER)) == 0) { - break; - } - if (*bufPtr != '\r' && *bufPtr != '\n') { - *base64Ptr = *bufPtr; - base64Ptr++; - } - bufPtr++; - } - - unsigned int binLength; - ScopedPORTString bin(ATOB_AsciiToData(base64, &binLength)); - if (!bin || binLength == 0) { - PrintPRError("ATOB_AsciiToData failed"); - return; - } - ScopedSECItem secitem(SECITEM_AllocItem(nullptr, nullptr, binLength)); - if (!secitem) { - PrintPRError("SECITEM_AllocItem failed"); - return; - } - memcpy(secitem->data, bin, binLength); - ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot()); - if (!slot) { - PrintPRError("PK11_GetInternalKeySlot failed"); - return; - } - if (PK11_NeedUserInit(slot)) { - if (PK11_InitPin(slot, nullptr, nullptr) != SECSuccess) { - PrintPRError("PK11_InitPin failed"); - return; - } - } - SECKEYPrivateKey* privateKey; - if (PK11_ImportDERPrivateKeyInfoAndReturnKey(slot, secitem, nullptr, nullptr, - true, false, KU_ALL, - &privateKey, nullptr) - != SECSuccess) { - PrintPRError("PK11_ImportDERPrivateKeyInfoAndReturnKey failed"); - return; - } - SECKEY_DestroyPrivateKey(privateKey); -} - -SECStatus -DecodeCertCallback(void* arg, SECItem** certs, int numcerts) -{ - if (numcerts != 1) { - PR_SetError(SEC_ERROR_LIBRARY_FAILURE, 0); - return SECFailure; - } - SECItem* certDEROut = static_cast(arg); - return SECITEM_CopyItem(nullptr, certDEROut, *certs); -} - -void -AddCertificateFromFile(const char* basePath, const char* filename) -{ - char buf[16384] = { 0 }; - SECStatus rv = ReadFileToBuffer(basePath, filename, buf); - if (rv != SECSuccess) { - return; - } - SECItem certDER; - rv = CERT_DecodeCertPackage(buf, strlen(buf), DecodeCertCallback, &certDER); - if (rv != SECSuccess) { - PrintPRError("CERT_DecodeCertPackage failed"); - return; - } - ScopedCERTCertificate cert(CERT_NewTempCertificate(CERT_GetDefaultCertDB(), - &certDER, nullptr, false, - true)); - PORT_Free(certDER.data); - if (!cert) { - PrintPRError("CERT_NewTempCertificate failed"); - return; - } - const char* extension = strstr(filename, ".pem"); - if (!extension) { - PR_SetError(SEC_ERROR_INVALID_ARGS, 0); - return; - } - size_t nicknameLength = extension - filename; - memset(buf, 0, sizeof(buf)); - memcpy(buf, filename, nicknameLength); - buf[nicknameLength] = 0; - ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot()); - if (!slot) { - PrintPRError("PK11_GetInternalKeySlot failed"); - return; - } - rv = PK11_ImportCert(slot, cert, CK_INVALID_HANDLE, buf, false); - if (rv != SECSuccess) { - PrintPRError("PK11_ImportCert failed"); - } -} - -SECStatus -InitializeNSS(const char* nssCertDBDir) -{ - // First attempt to initialize NSS in read-only mode, in case the specified - // directory contains NSS DBs that are tracked by revision control. - // If this succeeds, we're done. - if (NSS_Initialize(nssCertDBDir, "", "", SECMOD_DB, NSS_INIT_READONLY) - == SECSuccess) { - return SECSuccess; - } - // Otherwise, create a new read-write DB and load all .pem and .key files. - if (NSS_Initialize(nssCertDBDir, "", "", SECMOD_DB, 0) != SECSuccess) { - PrintPRError("NSS_Initialize failed"); - return SECFailure; - } - const char* basePath = nssCertDBDir; - // The NSS cert DB path could have been specified as "sql:path". Trim off - // the leading "sql:" if so. - if (strncmp(basePath, "sql:", 4) == 0) { - basePath = basePath + 4; - } - ScopedPRDir fdDir(PR_OpenDir(basePath)); - if (!fdDir) { - PrintPRError("PR_OpenDir failed"); - return SECFailure; - } - // On the B2G ICS emulator, operations taken in AddCertificateFromFile or - // AddKeyFromFile appear to interact poorly with PR_ReadDir (more - // specifically, something is causing PR_ReadDir to never return null - it - // indefinitely loops through every file in the directory, which causes - // timeouts). Rather than waste more time chasing this down, loading - // certificates and keys happens in two phases: filename collection and then - // loading. - std::vector certificates; - std::vector keys; - for (PRDirEntry* dirEntry = PR_ReadDir(fdDir, PR_SKIP_BOTH); dirEntry; - dirEntry = PR_ReadDir(fdDir, PR_SKIP_BOTH)) { - size_t nameLength = strlen(dirEntry->name); - if (nameLength > 4) { - if (strncmp(dirEntry->name + nameLength - 4, ".pem", 4) == 0) { - certificates.push_back(dirEntry->name); - } else if (strncmp(dirEntry->name + nameLength - 4, ".key", 4) == 0) { - keys.push_back(dirEntry->name); - } - } - } - for (std::string& certificate : certificates) { - AddCertificateFromFile(basePath, certificate.c_str()); - } - for (std::string& key : keys) { - AddKeyFromFile(basePath, key.c_str()); - } - return SECSuccess; -} int main(int argc, char* argv[]) @@ -332,9 +120,12 @@ main(int argc, char* argv[]) argv[0]); exit(EXIT_FAILURE); } - SECStatus rv = InitializeNSS(argv[1]); + const char* dbdir = argv[1]; + + SECStatus rv; + rv = NSS_Init(dbdir); if (rv != SECSuccess) { - PR_fprintf(PR_STDERR, "Failed to initialize NSS\n"); + PrintPRError("Failed to initialize NSS"); exit(EXIT_FAILURE); } PLArenaPool* arena = PORT_NewArena(256 * argc); @@ -350,15 +141,15 @@ main(int argc, char* argv[]) const char* filename = argv[i + 3]; OCSPResponseType ORT; - if (!StringToOCSPResponseType(ocspTypeText, &ORT)) { + if (!stringToOCSPResponseType(ocspTypeText, &ORT)) { PR_fprintf(PR_STDERR, "Cannot generate OCSP response of type %s\n", ocspTypeText); exit(EXIT_FAILURE); } - ScopedCERTCertificate cert(PK11_FindCertFromNickname(certNick, nullptr)); + ScopedCERTCertificate cert; + cert = PK11_FindCertFromNickname(certNick, nullptr); if (!cert) { - PrintPRError("PK11_FindCertFromNickname failed"); PR_fprintf(PR_STDERR, "Failed to find certificate with nick '%s'\n", certNick); exit(EXIT_FAILURE); From 605f42ffc0d51c42564b648a25a83feedf8f75c5 Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Wed, 15 Jul 2015 20:31:12 -0400 Subject: [PATCH 20/69] Bug 1184395 - Remove nsCookieService::mObserverService; r=jdm This is done to ensure that the cookie service cannot hold the observer service alive. --- netwerk/cookie/nsCookieService.cpp | 61 +++++++++++++++++++----------- netwerk/cookie/nsCookieService.h | 1 - 2 files changed, 39 insertions(+), 23 deletions(-) diff --git a/netwerk/cookie/nsCookieService.cpp b/netwerk/cookie/nsCookieService.cpp index 124beb16d7e7..057e2863d876 100644 --- a/netwerk/cookie/nsCookieService.cpp +++ b/netwerk/cookie/nsCookieService.cpp @@ -751,11 +751,11 @@ nsCookieService::Init() RegisterWeakMemoryReporter(this); - mObserverService = mozilla::services::GetObserverService(); - NS_ENSURE_STATE(mObserverService); - mObserverService->AddObserver(this, "profile-before-change", true); - mObserverService->AddObserver(this, "profile-do-change", true); - mObserverService->AddObserver(this, "last-pb-context-exited", true); + nsCOMPtr os = mozilla::services::GetObserverService(); + NS_ENSURE_STATE(os); + os->AddObserver(this, "profile-before-change", true); + os->AddObserver(this, "profile-do-change", true); + os->AddObserver(this, "last-pb-context-exited", true); mPermissionService = do_GetService(NS_COOKIEPERMISSION_CONTRACTID); if (!mPermissionService) { @@ -1358,10 +1358,14 @@ nsCookieService::HandleDBClosed(DBState* aDBState) COOKIE_LOGSTRING(LogLevel::Debug, ("HandleDBClosed(): DBState %x closed", aDBState)); + nsCOMPtr os = mozilla::services::GetObserverService(); + switch (aDBState->corruptFlag) { case DBState::OK: { // Database is healthy. Notify of closure. - mObserverService->NotifyObservers(nullptr, "cookie-db-closed", nullptr); + if (os) { + os->NotifyObservers(nullptr, "cookie-db-closed", nullptr); + } break; } case DBState::CLOSING_FOR_REBUILD: { @@ -1382,7 +1386,9 @@ nsCookieService::HandleDBClosed(DBState* aDBState) COOKIE_LOGSTRING(LogLevel::Warning, ("HandleDBClosed(): DBState %x encountered error rebuilding db; move to " "'cookies.sqlite.bak-rebuild' gave rv 0x%x", aDBState, rv)); - mObserverService->NotifyObservers(nullptr, "cookie-db-closed", nullptr); + if (os) { + os->NotifyObservers(nullptr, "cookie-db-closed", nullptr); + } break; } } @@ -1469,6 +1475,8 @@ nsCookieService::RebuildCorruptDB(DBState* aDBState) NS_ASSERTION(aDBState->corruptFlag == DBState::CLOSING_FOR_REBUILD, "should be in CLOSING_FOR_REBUILD state"); + nsCOMPtr os = mozilla::services::GetObserverService(); + aDBState->corruptFlag = DBState::REBUILDING; if (mDefaultDBState != aDBState) { @@ -1478,7 +1486,9 @@ nsCookieService::RebuildCorruptDB(DBState* aDBState) // do so now. COOKIE_LOGSTRING(LogLevel::Warning, ("RebuildCorruptDB(): DBState %x is stale, aborting", aDBState)); - mObserverService->NotifyObservers(nullptr, "cookie-db-closed", nullptr); + if (os) { + os->NotifyObservers(nullptr, "cookie-db-closed", nullptr); + } return; } @@ -1496,12 +1506,16 @@ nsCookieService::RebuildCorruptDB(DBState* aDBState) CleanupCachedStatements(); CleanupDefaultDBConnection(); mDefaultDBState->corruptFlag = DBState::OK; - mObserverService->NotifyObservers(nullptr, "cookie-db-closed", nullptr); + if (os) { + os->NotifyObservers(nullptr, "cookie-db-closed", nullptr); + } return; } // Notify observers that we're beginning the rebuild. - mObserverService->NotifyObservers(nullptr, "cookie-db-rebuilding", nullptr); + if (os) { + os->NotifyObservers(nullptr, "cookie-db-rebuilding", nullptr); + } // Enumerate the hash, and add cookies to the params array. mozIStorageAsyncStatement* stmt = aDBState->stmtInsert; @@ -1784,8 +1798,9 @@ nsCookieService::SetCookieStringInternal(nsIURI *aHostURI, void nsCookieService::NotifyRejected(nsIURI *aHostURI) { - if (mObserverService) { - mObserverService->NotifyObservers(aHostURI, "cookie-rejected", nullptr); + nsCOMPtr os = mozilla::services::GetObserverService(); + if (os) { + os->NotifyObservers(aHostURI, "cookie-rejected", nullptr); } } @@ -1794,7 +1809,8 @@ nsCookieService::NotifyRejected(nsIURI *aHostURI) void nsCookieService::NotifyThirdParty(nsIURI *aHostURI, bool aIsAccepted, nsIChannel *aChannel) { - if (!mObserverService) { + nsCOMPtr os = mozilla::services::GetObserverService(); + if (!os) { return; } @@ -1834,16 +1850,12 @@ nsCookieService::NotifyThirdParty(nsIURI *aHostURI, bool aIsAccepted, nsIChannel } nsAutoString referringHostUTF16 = NS_ConvertUTF8toUTF16(referringHost); - mObserverService->NotifyObservers(aHostURI, - topic, - referringHostUTF16.get()); + os->NotifyObservers(aHostURI, topic, referringHostUTF16.get()); return; } while (0); // This can fail for a number of reasons, in which kind we fallback to "?" - mObserverService->NotifyObservers(aHostURI, - topic, - MOZ_UTF16("?")); + os->NotifyObservers(aHostURI, topic, MOZ_UTF16("?")); } // notify observers that the cookie list changed. there are five possible @@ -1860,8 +1872,10 @@ nsCookieService::NotifyChanged(nsISupports *aSubject, { const char* topic = mDBState == mPrivateDBState ? "private-cookie-changed" : "cookie-changed"; - if (mObserverService) - mObserverService->NotifyObservers(aSubject, topic, aData); + nsCOMPtr os = mozilla::services::GetObserverService(); + if (os) { + os->NotifyObservers(aSubject, topic, aData); + } } already_AddRefed @@ -2215,7 +2229,10 @@ nsCookieService::AsyncReadComplete() COOKIE_LOGSTRING(LogLevel::Debug, ("Read(): %ld cookies read", mDefaultDBState->cookieCount)); - mObserverService->NotifyObservers(nullptr, "cookie-db-read", nullptr); + nsCOMPtr os = mozilla::services::GetObserverService(); + if (os) { + os->NotifyObservers(nullptr, "cookie-db-read", nullptr); + } } void diff --git a/netwerk/cookie/nsCookieService.h b/netwerk/cookie/nsCookieService.h index 1d375ad94a99..e404ee112181 100644 --- a/netwerk/cookie/nsCookieService.h +++ b/netwerk/cookie/nsCookieService.h @@ -333,7 +333,6 @@ class nsCookieService final : public nsICookieService protected: // cached members. - nsCOMPtr mObserverService; nsCOMPtr mPermissionService; nsCOMPtr mThirdPartyUtil; nsCOMPtr mTLDService; From 29d8c3e5046f7062ab428fbc2ee56d685802c7da Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Fri, 17 Jul 2015 19:34:47 -0400 Subject: [PATCH 21/69] Bug 1123386 - Part 3: Mark DoNothingCallback::Callback as override in order to fix a build issue in warnings as errors mode --- xpcom/base/nsMemoryReporterManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xpcom/base/nsMemoryReporterManager.cpp b/xpcom/base/nsMemoryReporterManager.cpp index eb19151be4ca..0d63557103fa 100644 --- a/xpcom/base/nsMemoryReporterManager.cpp +++ b/xpcom/base/nsMemoryReporterManager.cpp @@ -2380,7 +2380,7 @@ public: NS_IMETHOD Callback(const nsACString& aProcess, const nsACString& aPath, int32_t aKind, int32_t aUnits, int64_t aAmount, const nsACString& aDescription, - nsISupports* aData) + nsISupports* aData) override { // Do nothing; the reporter has already reported to DMD. return NS_OK; From 4979ef2b154c4e00452b370fa2451dbb4d5b8f44 Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Sun, 5 Jul 2015 22:50:39 -0400 Subject: [PATCH 22/69] Bug 1123386 - Part 4: Update the tooltool manifests for the OSX and Linux static analysis builds in order to upgrade clang; r=rail --- browser/config/tooltool-manifests/linux32/clang.manifest | 6 +++--- browser/config/tooltool-manifests/linux64/clang.manifest | 6 +++--- browser/config/tooltool-manifests/macosx64/clang.manifest | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/browser/config/tooltool-manifests/linux32/clang.manifest b/browser/config/tooltool-manifests/linux32/clang.manifest index 6d75f637c117..2da4b025644e 100644 --- a/browser/config/tooltool-manifests/linux32/clang.manifest +++ b/browser/config/tooltool-manifests/linux32/clang.manifest @@ -1,10 +1,10 @@ [ { -"clang_version": "r183744" +"clang_version": "r241406" }, { -"size": 70206124, -"digest": "a6b8046bd9485f9387dcb1c14b8d442822f02b1caa61b653e8b6cfd96906deadfb4b29809f2cd2b71f919b321d97dd2ebec6020c15f6d485f1641c0f710a762f", +"size": 100307285, +"digest": "4d147d0072a928945fc1e938f39a5d0a9d3c676399c09e092c8750b2f973cdbbebda8d94d4d05805fae74a5c49c54263dc22b8b443c23c9a0ae830a261d3cf30", "algorithm": "sha512", "filename": "clang.tar.bz2", "unpack": true, diff --git a/browser/config/tooltool-manifests/linux64/clang.manifest b/browser/config/tooltool-manifests/linux64/clang.manifest index 2bad4b994b96..216b4eae7037 100644 --- a/browser/config/tooltool-manifests/linux64/clang.manifest +++ b/browser/config/tooltool-manifests/linux64/clang.manifest @@ -1,10 +1,10 @@ [ { -"clang_version": "r183744" +"clang_version": "r241406" }, { -"size": 70350828, -"digest": "6cd04e8ec44c6fef159349c22bd0476891e4a2d46479f9586283eaf3305e42f79c720d40dfec0e78d8899c1651189b12e285de60862ffd0612b0dac7a0c336c6", +"size": 100307285, +"digest": "4d147d0072a928945fc1e938f39a5d0a9d3c676399c09e092c8750b2f973cdbbebda8d94d4d05805fae74a5c49c54263dc22b8b443c23c9a0ae830a261d3cf30", "algorithm": "sha512", "filename": "clang.tar.bz2", "unpack": true diff --git a/browser/config/tooltool-manifests/macosx64/clang.manifest b/browser/config/tooltool-manifests/macosx64/clang.manifest index aa1ef98af6c3..c84370fc6b19 100644 --- a/browser/config/tooltool-manifests/macosx64/clang.manifest +++ b/browser/config/tooltool-manifests/macosx64/clang.manifest @@ -1,10 +1,10 @@ [ { -"clang_version": "r183744" +"clang_version": "r241406" }, { -"size": 59602619, -"digest": "86662ebc0ef650490559005948c4f0cb015dad72c7cac43732c2bf2995247081e30c139cf8008d19670a0009fc302c4eee2676981ee3f9ff4a15c01af22b783b", +"size": 86465808, +"digest": "947eaaf11ac8cbe12e11b48c8b052721e018d31fb8ce20f8bf14b117b6623c56513b1422d8d9c8011bc0b0b985ef74d8f181e7200c6d7a05d79a1bce0d75ddee", "algorithm": "sha512", "filename": "clang.tar.bz2", "unpack": true From 0b606b54d0dfe3b0cf3caefe5ab710688d3c5cf1 Mon Sep 17 00:00:00 2001 From: Lorien Hu Date: Fri, 17 Jul 2015 11:07:37 -0400 Subject: [PATCH 23/69] Bug 1180798 - Pass event names in nsIEventListenerChangeListener r=smaug --- dom/events/EventListenerManager.cpp | 10 ++-- dom/events/EventListenerService.cpp | 50 ++++++++++++++++-- dom/events/EventListenerService.h | 28 ++++++++-- dom/events/nsIEventListenerService.idl | 15 +++++- dom/events/test/test_bug524674.xul | 72 +++++++++++++++++++------- 5 files changed, 143 insertions(+), 32 deletions(-) diff --git a/dom/events/EventListenerManager.cpp b/dom/events/EventListenerManager.cpp index 27e7197c6a64..3c4ce1a28b54 100644 --- a/dom/events/EventListenerManager.cpp +++ b/dom/events/EventListenerManager.cpp @@ -398,7 +398,8 @@ EventListenerManager::AddEventListenerInternal( } if (mIsMainThreadELM && mTarget) { - EventListenerService::NotifyAboutMainThreadListenerChange(mTarget); + EventListenerService::NotifyAboutMainThreadListenerChange(mTarget, + aTypeAtom); } } @@ -518,7 +519,8 @@ EventListenerManager::RemoveEventListenerInternal( mTarget->EventListenerRemoved(aUserType); } if (mIsMainThreadELM && mTarget) { - EventListenerService::NotifyAboutMainThreadListenerChange(mTarget); + EventListenerService::NotifyAboutMainThreadListenerChange(mTarget, + aUserType); } if (!deviceType @@ -654,7 +656,7 @@ EventListenerManager::SetEventHandlerInternal( mTarget->EventListenerAdded(aName); } if (mIsMainThreadELM && mTarget) { - EventListenerService::NotifyAboutMainThreadListenerChange(mTarget); + EventListenerService::NotifyAboutMainThreadListenerChange(mTarget, aName); } } @@ -784,7 +786,7 @@ EventListenerManager::RemoveEventHandler(nsIAtom* aName, mTarget->EventListenerRemoved(aName); } if (mIsMainThreadELM && mTarget) { - EventListenerService::NotifyAboutMainThreadListenerChange(mTarget); + EventListenerService::NotifyAboutMainThreadListenerChange(mTarget, aName); } } } diff --git a/dom/events/EventListenerService.cpp b/dom/events/EventListenerService.cpp index 7d2f43713134..94189b6ab9c2 100644 --- a/dom/events/EventListenerService.cpp +++ b/dom/events/EventListenerService.cpp @@ -23,6 +23,44 @@ namespace mozilla { using namespace dom; +/****************************************************************************** + * mozilla::EventListenerChange + ******************************************************************************/ + +NS_IMPL_ISUPPORTS(EventListenerChange, nsIEventListenerChange) + +EventListenerChange::~EventListenerChange() +{ +} + +EventListenerChange::EventListenerChange(dom::EventTarget* aTarget) : + mTarget(aTarget) +{ + mChangedListenerNames = nsArrayBase::Create(); +} + +void +EventListenerChange::AddChangedListenerName(nsIAtom* aEventName) +{ + mChangedListenerNames->AppendElement(aEventName, false); +} + +NS_IMETHODIMP +EventListenerChange::GetTarget(nsIDOMEventTarget** aTarget) +{ + NS_ENSURE_ARG_POINTER(aTarget); + NS_ADDREF(*aTarget = mTarget); + return NS_OK; +} + +NS_IMETHODIMP +EventListenerChange::GetChangedListenerNames(nsIArray** aEventNames) +{ + NS_ENSURE_ARG_POINTER(aEventNames); + NS_ADDREF(*aEventNames = mChangedListenerNames); + return NS_OK; +} + /****************************************************************************** * mozilla::EventListenerInfo ******************************************************************************/ @@ -323,7 +361,8 @@ EventListenerService::RemoveListenerChangeListener(nsIListenerChangeListener* aL }; void -EventListenerService::NotifyAboutMainThreadListenerChangeInternal(dom::EventTarget* aTarget) +EventListenerService::NotifyAboutMainThreadListenerChangeInternal(dom::EventTarget* aTarget, + nsIAtom* aName) { MOZ_ASSERT(NS_IsMainThread()); if (mChangeListeners.IsEmpty()) { @@ -337,10 +376,13 @@ EventListenerService::NotifyAboutMainThreadListenerChangeInternal(dom::EventTarg NS_DispatchToCurrentThread(runnable); } - if (!mPendingListenerChangesSet.Get(aTarget)) { - mPendingListenerChanges->AppendElement(aTarget, false); - mPendingListenerChangesSet.Put(aTarget, true); + nsRefPtr changes = mPendingListenerChangesSet.Get(aTarget); + if (!changes) { + changes = new EventListenerChange(aTarget); + mPendingListenerChanges->AppendElement(changes, false); + mPendingListenerChangesSet.Put(aTarget, changes); } + changes->AddChangedListenerName(aName); } void diff --git a/dom/events/EventListenerService.h b/dom/events/EventListenerService.h index 51be12b065ba..3b67af0c8d5b 100644 --- a/dom/events/EventListenerService.h +++ b/dom/events/EventListenerService.h @@ -16,6 +16,7 @@ #include "nsString.h" #include "nsTObserverArray.h" #include "nsDataHashtable.h" +#include "nsGkAtoms.h" class nsIMutableArray; @@ -27,6 +28,23 @@ class EventTarget; template class Maybe; +class EventListenerChange final : public nsIEventListenerChange +{ +public: + explicit EventListenerChange(dom::EventTarget* aTarget); + + void AddChangedListenerName(nsIAtom* aEventName); + + NS_DECL_ISUPPORTS + NS_DECL_NSIEVENTLISTENERCHANGE + +protected: + virtual ~EventListenerChange(); + nsCOMPtr mTarget; + nsCOMPtr mChangedListenerNames; + +}; + class EventListenerInfo final : public nsIEventListenerInfo { public: @@ -70,19 +88,21 @@ public: NS_DECL_ISUPPORTS NS_DECL_NSIEVENTLISTENERSERVICE - static void NotifyAboutMainThreadListenerChange(dom::EventTarget* aTarget) + static void NotifyAboutMainThreadListenerChange(dom::EventTarget* aTarget, + nsIAtom* aName) { if (sInstance) { - sInstance->NotifyAboutMainThreadListenerChangeInternal(aTarget); + sInstance->NotifyAboutMainThreadListenerChangeInternal(aTarget, aName); } } void NotifyPendingChanges(); private: - void NotifyAboutMainThreadListenerChangeInternal(dom::EventTarget* aTarget); + void NotifyAboutMainThreadListenerChangeInternal(dom::EventTarget* aTarget, + nsIAtom* aName); nsTObserverArray> mChangeListeners; nsCOMPtr mPendingListenerChanges; - nsDataHashtable mPendingListenerChangesSet; + nsDataHashtable> mPendingListenerChangesSet; static EventListenerService* sInstance; }; diff --git a/dom/events/nsIEventListenerService.idl b/dom/events/nsIEventListenerService.idl index 250f208bfe63..46c65e21dd5d 100644 --- a/dom/events/nsIEventListenerService.idl +++ b/dom/events/nsIEventListenerService.idl @@ -9,10 +9,21 @@ interface nsIDOMEventListener; interface nsIDOMEventTarget; interface nsIArray; -[scriptable, function, uuid(8d5b5a6b-dec0-473d-86c4-591801dfaac1)] +/** + * Contains an event target along with an array of nsIAtom in form "oneventname" + * representing changed event listener names. + */ +[scriptable, uuid(07222b02-da12-4cf4-b2f7-761da007a8d8)] +interface nsIEventListenerChange : nsISupports +{ + readonly attribute nsIDOMEventTarget target; + readonly attribute nsIArray changedListenerNames; +}; + +[scriptable, function, uuid(aa7c95f6-d3b5-44b3-9597-1d9f19b9c5f2)] interface nsIListenerChangeListener : nsISupports { - void listenersChanged(in nsIArray aEventTargets); + void listenersChanged(in nsIArray aEventListenerChanges); }; /** diff --git a/dom/events/test/test_bug524674.xul b/dom/events/test/test_bug524674.xul index 4efc80859dbb..463d9269b31d 100644 --- a/dom/events/test/test_bug524674.xul +++ b/dom/events/test/test_bug524674.xul @@ -22,6 +22,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=524674 var els = Components.classes["@mozilla.org/eventlistenerservice;1"] .getService(Components.interfaces.nsIEventListenerService); + const Ci = Components.interfaces; + function dummyListener() {} var runningTest = null; @@ -35,29 +37,49 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=524674 d.addEventListener("foo", dummyListener); d.addEventListener("foo", dummyListener); xhr.addEventListener("foo", dummyListener); - tests[0] = [d, xhr]; + tests[0] = [{target: d, listeners: ["onfoo"]}, + {target: xhr, listeners: ["onfoo"]}]; + }, + function() { + d.addEventListener("bar", dummyListener); + d.addEventListener("baz", dummyListener); + xhr.addEventListener("bar", dummyListener); + xhr.addEventListener("baz", dummyListener); + tests[0] = [{target: d, listeners: ["onbaz", "onbar"]}, + {target: xhr, listeners: ["onbaz", "onbar"]}]; }, function() { d.onclick = dummyListener; d.onclick = dummyListener; xhr.onload = dummyListener; - tests[0] = [d, xhr]; + tests[0] = [{target: d, listeners: ["onclick"]}, + {target: xhr, listeners: ["onload"]}]; }, function() { d.onclick = function() {}; - tests[0] = [d]; + tests[0] = [{target: d, listeners: ["onclick"]}]; }, function() { d.removeEventListener("foo", dummyListener); d.removeEventListener("foo", dummyListener); xhr.removeEventListener("foo", dummyListener); - tests[0] = [d, xhr]; + tests[0] = [{target: d, listeners: ["onfoo"]}, + {target: xhr, listeners: ["onfoo"]}]; + }, + function() { + d.removeEventListener("bar", dummyListener); + d.removeEventListener("baz", dummyListener); + xhr.removeEventListener("bar", dummyListener); + xhr.removeEventListener("baz", dummyListener); + tests[0] = [{target: d, listeners: ["onbar", "onbaz"]}, + {target: xhr, listeners: ["onbar", "onbaz"]}]; }, function() { d.onclick = null; d.onclick = null; xhr.onload = null; - tests[0] = [d, xhr]; + tests[0] = [{target: d, listeners: ["onclick"]}, + {target: xhr, listeners: ["onload"]}]; }, function() { els.removeListenerChangeListener(changeListener); @@ -76,29 +98,43 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=524674 if (typeof tests[0] == "function") { return; } - var expectedEventTargets = tests[0]; - var e = array.enumerate(); + var expectedEventChanges = tests[0]; + var eventChanges = array.enumerate(); var i = 0; - while (e.hasMoreElements()) { + while (eventChanges.hasMoreElements() && i < expectedEventChanges.length) { var current; try { - current = e.getNext(); + current = eventChanges.getNext().QueryInterface(Ci.nsIEventListenerChange); + var expected = expectedEventChanges[i]; + + if (current.target == expected.target) { + // expected.target.listeners should be a subset of + // current.changedListenerNames if all expected listener changes were + // sent. We may get random other event listener changes here too, not + // just the one from the test. + is(current.target, expected.target, current.target + " = " + expected.target); + + var eNames = current.changedListenerNames.enumerate(); + var listeners = []; + while (eNames.hasMoreElements()) { + var listenerName = eNames.getNext().QueryInterface(Ci.nsIAtom).toString(); + listeners.push(listenerName); + } + var matchAll = expected.listeners.every(function(val) + { return listeners.indexOf(val) >= 0; }); + if (!matchAll) + return; + ++i; + } } catch(ex) { continue; } - var expected = expectedEventTargets[i]; - if (current == expected) { - is(current, expected, current + " = " + expected); - // We may get random other event listener changes here too, not just the one from the - // test. - ++i - } } - if (expectedEventTargets.length != i) { + if (expectedEventChanges.length != i) { return; } - is(expectedEventTargets.length, i, "Should have got notification for all the changes."); + is(expectedEventChanges.length, i, "Should have got notification for all the changes."); tests.shift(); ok(tests.length); From 86090d9f09e3ffaa299398305a6a4bbebc054643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Pag=C3=A8s?= Date: Fri, 17 Jul 2015 20:58:42 +0200 Subject: [PATCH 24/69] Bug 970886 - MarionetteTestRunner runs tests twice if the filename is the same. r=dburns --HG-- extra : commitid : H4PWlVdG6KZ extra : rebase_source : d18eac8637b5650d591c69a943e58dc9feeb70cd --- .../client/marionette/marionette_test.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/testing/marionette/client/marionette/marionette_test.py b/testing/marionette/client/marionette/marionette_test.py index a06bc9b36e17..97454b25a4f0 100644 --- a/testing/marionette/client/marionette/marionette_test.py +++ b/testing/marionette/client/marionette/marionette_test.py @@ -655,6 +655,20 @@ class MarionetteTestCase(CommonTestCase): @classmethod def add_tests_to_suite(cls, mod_name, filepath, suite, testloader, marionette, testvars, **kwargs): + # since we use imp.load_source to load test modules, if a module + # is loaded with the same name as another one the module would just be + # reloaded. + # + # We may end up by finding too many test in a module then since + # reload() only update the module dict (so old keys are still there!) + # see https://docs.python.org/2/library/functions.html#reload + # + # we get rid of that by removing the module from sys.modules, + # so we ensure that it will be fully loaded by the + # imp.load_source call. + if mod_name in sys.modules: + del sys.modules[mod_name] + test_mod = imp.load_source(mod_name, filepath) for name in dir(test_mod): From 1b995b9a16dadf7003f0391ce573e0c44f464cf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Pag=C3=A8s?= Date: Fri, 17 Jul 2015 21:06:12 +0200 Subject: [PATCH 25/69] Bug 1183157 - make marionette --version flag also show the transport and driver package versions. r=dburns --HG-- extra : commitid : 9r6zCILoeE4 extra : rebase_source : 6d0475dec01fe9b97ac318ad0948bfe8e9e15e56 --- .../marionette/client/marionette/runtests.py | 12 +++++++-- .../driver/marionette_driver/__init__.py | 8 ++++++ testing/marionette/driver/setup.py | 25 ++++++++++++----- .../marionette_transport/__init__.py | 7 +++++ testing/marionette/transport/setup.py | 27 ++++++++++++++----- 5 files changed, 65 insertions(+), 14 deletions(-) diff --git a/testing/marionette/client/marionette/runtests.py b/testing/marionette/client/marionette/runtests.py index 132610eb8522..f719e6b244a2 100644 --- a/testing/marionette/client/marionette/runtests.py +++ b/testing/marionette/client/marionette/runtests.py @@ -5,6 +5,8 @@ import sys from marionette import __version__ +from marionette_driver import __version__ as driver_version +from marionette_transport import __version__ as transport_version from marionette.marionette_test import MarionetteTestCase, MarionetteJSTestCase from marionette.runner import ( BaseMarionetteTestRunner, @@ -36,8 +38,14 @@ def startTestRunner(runner_class, options, tests): return runner def cli(runner_class=MarionetteTestRunner, parser_class=MarionetteOptions): - parser = parser_class(usage='%prog [options] test_file_or_dir ...', - version='%prog ' + __version__) + parser = parser_class( + usage='%prog [options] test_file_or_dir ...', + version="%prog {version} (using marionette-driver: {driver_version}" + ", marionette-transport: {transport_version})".format( + version=__version__, + driver_version=driver_version, + transport_version=transport_version) + ) mozlog.commandline.add_logging_group(parser) options, tests = parser.parse_args() parser.verify_usage(options, tests) diff --git a/testing/marionette/driver/marionette_driver/__init__.py b/testing/marionette/driver/marionette_driver/__init__.py index 35e6736a9531..1b6d67717f8b 100644 --- a/testing/marionette/driver/marionette_driver/__init__.py +++ b/testing/marionette/driver/marionette_driver/__init__.py @@ -1,3 +1,11 @@ +# 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/. + + +__version__ = '0.10' + + from marionette_driver import ( errors, by, decorators, expected, geckoinstance, gestures, keys, marionette, selection, wait, application_cache, date_time_value ) diff --git a/testing/marionette/driver/setup.py b/testing/marionette/driver/setup.py index da231733974c..dfcbc15dec75 100644 --- a/testing/marionette/driver/setup.py +++ b/testing/marionette/driver/setup.py @@ -1,13 +1,26 @@ +# 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/. + +import os +import re from setuptools import setup, find_packages -version = '0.10' +THIS_DIR = os.path.dirname(os.path.realpath(__name__)) + + +def read(*parts): + with open(os.path.join(THIS_DIR, *parts)) as f: + return f.read() + + +def get_version(): + return re.findall("__version__ = '([\d\.]+)'", + read('marionette_driver', '__init__.py'), re.M)[0] -# dependencies -with open('requirements.txt') as f: - deps = f.read().splitlines() setup(name='marionette_driver', - version=version, + version=get_version(), description="Marionette Driver", long_description='See http://marionette-driver.readthedocs.org/', classifiers=[], # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers @@ -19,5 +32,5 @@ setup(name='marionette_driver', packages=find_packages(), include_package_data=True, zip_safe=False, - install_requires=deps, + install_requires=read('requirements.txt').splitlines(), ) diff --git a/testing/marionette/transport/marionette_transport/__init__.py b/testing/marionette/transport/marionette_transport/__init__.py index b379d10d64bd..d8fc39cba4d2 100644 --- a/testing/marionette/transport/marionette_transport/__init__.py +++ b/testing/marionette/transport/marionette_transport/__init__.py @@ -1 +1,8 @@ +# 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/ + +__version__ = '0.5' + + from transport import MarionetteTransport diff --git a/testing/marionette/transport/setup.py b/testing/marionette/transport/setup.py index e398d4ebeae7..1be3ff9d1e96 100644 --- a/testing/marionette/transport/setup.py +++ b/testing/marionette/transport/setup.py @@ -1,6 +1,24 @@ +# 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/. + +import os +import re from setuptools import setup, find_packages -version = '0.5' + +THIS_DIR = os.path.dirname(os.path.realpath(__name__)) + + +def read(*parts): + with open(os.path.join(THIS_DIR, *parts)) as f: + return f.read() + + +def get_version(): + return re.findall("__version__ = '([\d\.]+)'", + read('marionette_transport', '__init__.py'), re.M)[0] + long_description = \ """Marionette_ is a Mozilla project to enable remote automation in Gecko-based @@ -14,11 +32,9 @@ points; rather it's designed to be used by a Marionette client implementation. .. _Marionette: https://developer.mozilla.org/en/Marionette .. _`Selenium Webdriver`: http://www.seleniumhq.org/projects/webdriver/""" -# dependencies -deps = [] setup(name='marionette-transport', - version=version, + version=get_version(), description="Transport layer for Marionette client", long_description=long_description, classifiers=[], # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers @@ -33,6 +49,5 @@ setup(name='marionette-transport', zip_safe=False, entry_points=""" """, - install_requires=deps, + install_requires=[], ) - From 7a736df66f058c63a345a1cef5ab39431f4257cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Pag=C3=A8s?= Date: Fri, 17 Jul 2015 23:00:26 +0200 Subject: [PATCH 26/69] Bug 1081970 - Gracefully handle interrupts when running test suite. r=dburns --HG-- extra : commitid : 9JQBIHQNMoV extra : rebase_source : 9db8ccab407a78095fb67ee61e574d301364d416 --- .../client/marionette/runner/base.py | 32 +++++++++++++++---- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/testing/marionette/client/marionette/runner/base.py b/testing/marionette/client/marionette/runner/base.py index b76a13a492dc..e60d6260e435 100644 --- a/testing/marionette/client/marionette/runner/base.py +++ b/testing/marionette/client/marionette/runner/base.py @@ -808,14 +808,32 @@ setReq.onerror = function() { message=test['disabled']) self.todo += 1 - counter = self.repeat - while counter >=0: - round = self.repeat - counter - if round > 0: - self.logger.info('\nREPEAT %d\n-------' % round) - self.run_test_sets() - counter -= 1 + interrupted = None + try: + counter = self.repeat + while counter >=0: + round = self.repeat - counter + if round > 0: + self.logger.info('\nREPEAT %d\n-------' % round) + self.run_test_sets() + counter -= 1 + except KeyboardInterrupt: + # in case of KeyboardInterrupt during the test execution + # we want to display current test results. + # so we keep the exception to raise it later. + interrupted = sys.exc_info() + try: + self._print_summary(tests) + except: + # raise only the exception if we were not interrupted + if not interrupted: + raise + finally: + # reraise previous interruption now + if interrupted: + raise interrupted[0], interrupted[1], interrupted[2] + def _print_summary(self, tests): self.logger.info('\nSUMMARY\n-------') self.logger.info('passed: %d' % self.passed) if self.unexpected_successes == 0: From 088713752a0308972f1aee5258b6fdb676dc8935 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Pag=C3=A8s?= Date: Fri, 17 Jul 2015 22:53:27 +0200 Subject: [PATCH 27/69] Bug 1129122 - Marionette should show an error if a test file doesn't start with the test_ prefix. r=dburns --HG-- extra : commitid : 4INcHog6PGS extra : rebase_source : 7240887c3fc7373619cfbe2f500b66038149747b --- testing/marionette/client/marionette/runner/base.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/testing/marionette/client/marionette/runner/base.py b/testing/marionette/client/marionette/runner/base.py index e60d6260e435..61231b2f1182 100644 --- a/testing/marionette/client/marionette/runner/base.py +++ b/testing/marionette/client/marionette/runner/base.py @@ -784,6 +784,15 @@ setReq.onerror = function() { for test in tests: self.add_test(test) + # ensure we have only tests files with names starting with 'test_' + invalid_tests = \ + [t['filepath'] for t in self.tests + if not os.path.basename(t['filepath']).startswith('test_')] + if invalid_tests: + raise Exception("Tests file names must starts with 'test_'." + " Invalid test names:\n %s" + % '\n '.join(invalid_tests)) + version_info = mozversion.get_version(binary=self.bin, sources=self.sources, dm_type=os.environ.get('DM_TRANS', 'adb'), From f84f7d4021c14815f3e6742d3f2716d3fcb1bd5b Mon Sep 17 00:00:00 2001 From: Jonathan Kew Date: Sat, 18 Jul 2015 11:03:28 +0100 Subject: [PATCH 28/69] Bug 1180528 - Reftest for table row progression in vertical-rl writing mode with ltr and rtl directionality. r=dholbert --- .../reftests/writing-mode/tables/reftest.list | 3 + .../vertical-rl-row-progression-1-ref.html | 50 ++++++++++++++++ .../vertical-rl-row-progression-1a.html | 57 +++++++++++++++++++ .../vertical-rl-row-progression-1b.html | 57 +++++++++++++++++++ 4 files changed, 167 insertions(+) create mode 100644 layout/reftests/writing-mode/tables/vertical-rl-row-progression-1-ref.html create mode 100644 layout/reftests/writing-mode/tables/vertical-rl-row-progression-1a.html create mode 100644 layout/reftests/writing-mode/tables/vertical-rl-row-progression-1b.html diff --git a/layout/reftests/writing-mode/tables/reftest.list b/layout/reftests/writing-mode/tables/reftest.list index 35555b1b48f3..5fc2cdddcc90 100644 --- a/layout/reftests/writing-mode/tables/reftest.list +++ b/layout/reftests/writing-mode/tables/reftest.list @@ -88,3 +88,6 @@ fuzzy-if(cocoaWidget,23,162) == border-collapse-bevels-1b.html border-collapse-b fuzzy-if(cocoaWidget,23,162) == border-collapse-bevels-1c.html border-collapse-bevels-1-ref.html fuzzy-if(cocoaWidget,23,162) == border-collapse-bevels-1d.html border-collapse-bevels-1-ref.html fuzzy-if(cocoaWidget,23,162) == border-collapse-bevels-1e.html border-collapse-bevels-1-ref.html + +== vertical-rl-row-progression-1a.html vertical-rl-row-progression-1-ref.html +== vertical-rl-row-progression-1b.html vertical-rl-row-progression-1-ref.html diff --git a/layout/reftests/writing-mode/tables/vertical-rl-row-progression-1-ref.html b/layout/reftests/writing-mode/tables/vertical-rl-row-progression-1-ref.html new file mode 100644 index 000000000000..60afb00d9bc9 --- /dev/null +++ b/layout/reftests/writing-mode/tables/vertical-rl-row-progression-1-ref.html @@ -0,0 +1,50 @@ + +CSS Reference: vertical-rl Table Row/Rowgroup/Cell Ordering + + + + + + + + + + +
+ + + +
+ + + + +
+ + +
+ +
diff --git a/layout/reftests/writing-mode/tables/vertical-rl-row-progression-1a.html b/layout/reftests/writing-mode/tables/vertical-rl-row-progression-1a.html new file mode 100644 index 000000000000..6b0929495f3e --- /dev/null +++ b/layout/reftests/writing-mode/tables/vertical-rl-row-progression-1a.html @@ -0,0 +1,57 @@ + +CSS Test: vertical-rl Table Row/Rowgroup/Cell Ordering + + + + + + + + + + + + + + + + + +
+ + +
+ + +
+ + +
+ +
+
+ +
diff --git a/layout/reftests/writing-mode/tables/vertical-rl-row-progression-1b.html b/layout/reftests/writing-mode/tables/vertical-rl-row-progression-1b.html new file mode 100644 index 000000000000..69f4f52e6ce3 --- /dev/null +++ b/layout/reftests/writing-mode/tables/vertical-rl-row-progression-1b.html @@ -0,0 +1,57 @@ + +CSS Test: vertical-rl Table Row/Rowgroup/Cell Ordering + + + + + + + + + + + + + + + + + +
+ + +
+ + +
+ + +
+ +
+
+ +
From 7a7ba032a99e70fbb20062860f2962a609206a49 Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Sat, 18 Jul 2015 13:17:30 -0400 Subject: [PATCH 29/69] Bug 1123386 - Part 5: Touch CLOBBER for having upgraded to use a new compiler --- CLOBBER | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CLOBBER b/CLOBBER index 864c1c575427..eec9e5c31b8a 100644 --- a/CLOBBER +++ b/CLOBBER @@ -22,4 +22,4 @@ # changes to stick? As of bug 928195, this shouldn't be necessary! Please # don't change CLOBBER for WebIDL changes any more. -Bug 1178850 requires clobber for Android JNI header changes +Bug 1123386 requires clobber for switching to use a new compiler From 020deeb50793eae5ed7bbd13f1121778837ffcae Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Mon, 13 Jul 2015 17:06:53 -0400 Subject: [PATCH 30/69] Bug 1148044 - Correctly reflect frame and iframe RequestContext values; r=smaug --- docshell/base/nsDocShell.cpp | 3 ++- dom/fetch/InternalRequest.cpp | 5 ++++- dom/fetch/InternalRequest.h | 5 ++--- .../test/serviceworkers/fetch/context/context_test.js | 3 +-- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 6ded2df52eb7..70d5d639177b 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -9715,7 +9715,8 @@ nsDocShell::InternalLoad(nsIURI* aURI, } if (IsFrame() && !isNewDocShell && !isTargetTopLevelDocShell) { NS_ASSERTION(requestingElement, "A frame but no DOM element!?"); - contentType = nsIContentPolicy::TYPE_SUBDOCUMENT; + contentType = requestingElement->IsHTMLElement(nsGkAtoms::iframe) ? + nsIContentPolicy::TYPE_INTERNAL_IFRAME : nsIContentPolicy::TYPE_INTERNAL_FRAME; } else { contentType = nsIContentPolicy::TYPE_DOCUMENT; } diff --git a/dom/fetch/InternalRequest.cpp b/dom/fetch/InternalRequest.cpp index 86b5c42e563a..74b471fe02fa 100644 --- a/dom/fetch/InternalRequest.cpp +++ b/dom/fetch/InternalRequest.cpp @@ -134,9 +134,12 @@ InternalRequest::MapContentPolicyTypeToRequestContext(nsContentPolicyType aConte case nsIContentPolicy::TYPE_DOCUMENT: context = RequestContext::Internal; break; - case nsIContentPolicy::TYPE_SUBDOCUMENT: + case nsIContentPolicy::TYPE_INTERNAL_IFRAME: context = RequestContext::Iframe; break; + case nsIContentPolicy::TYPE_INTERNAL_FRAME: + context = RequestContext::Frame; + break; case nsIContentPolicy::TYPE_REFRESH: context = RequestContext::Internal; break; diff --git a/dom/fetch/InternalRequest.h b/dom/fetch/InternalRequest.h index d20ac226f007..7a041abd79e4 100644 --- a/dom/fetch/InternalRequest.h +++ b/dom/fetch/InternalRequest.h @@ -40,9 +40,9 @@ namespace dom { * fetch | TYPE_FETCH * font | TYPE_FONT * form | - * frame | TYPE_SUBDOCUMENT + * frame | TYPE_INTERNAL_FRAME * hyperlink | - * iframe | TYPE_SUBDOCUMENT + * iframe | TYPE_INTERNAL_IFRAME * image | TYPE_IMAGE * imageset | TYPE_IMAGESET * import | Not supported by Gecko @@ -67,7 +67,6 @@ namespace dom { * TODO: Figure out if TYPE_DTD maps to anything useful * TODO: Split TYPE_XMLHTTPREQUEST and TYPE_DATAREQUEST for EventSource * TODO: Figure out if TYPE_WEBSOCKET maps to anything useful - * TODO: Differentiate between frame and iframe * TODO: Add a content type for prefetch * TODO: Use the content type for manifest when it becomes available * TODO: Add a content type for location diff --git a/dom/workers/test/serviceworkers/fetch/context/context_test.js b/dom/workers/test/serviceworkers/fetch/context/context_test.js index 66d22b7da5b3..b98d2ab3ca73 100644 --- a/dom/workers/test/serviceworkers/fetch/context/context_test.js +++ b/dom/workers/test/serviceworkers/fetch/context/context_test.js @@ -46,8 +46,7 @@ self.addEventListener("fetch", function(event) { event.respondWith(fetch("context_test.js")); } } else if (event.request.url.indexOf("frame") >= 0) { - // FIXME: Bug 1148044: This should be "frame". - if (event.request.context == "iframe") { + if (event.request.context == "frame") { event.respondWith(fetch("context_test.js")); } } else if (event.request.url.indexOf("newwindow") >= 0) { From e2513278b259e37b1ba3d7bc5015913599358145 Mon Sep 17 00:00:00 2001 From: Rail Aliiev Date: Sat, 18 Jul 2015 14:48:22 -0400 Subject: [PATCH 31/69] Bug 1184087 - L10N nightly repacks should not upload mar tools. Fix en-US typo. r=mshal --- toolkit/mozapps/installer/upload-files.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolkit/mozapps/installer/upload-files.mk b/toolkit/mozapps/installer/upload-files.mk index 224ffba1a9a2..9358054ed24f 100644 --- a/toolkit/mozapps/installer/upload-files.mk +++ b/toolkit/mozapps/installer/upload-files.mk @@ -717,7 +717,7 @@ CHECKSUM_FILE = '$(DIST)/$(PKG_PATH)/$(CHECKSUMS_FILE_BASENAME).checksums' CHECKSUM_FILES = $(CHECKSUM_FILE) # Upload MAR tools only if AB_CD is unset or en_US -ifeq (,$(AB_CD:en_US=)) +ifeq (,$(AB_CD:en-US=)) ifeq (WINNT,$(OS_TARGET)) UPLOAD_EXTRA_FILES += host/bin/mar.exe UPLOAD_EXTRA_FILES += host/bin/mbsdiff.exe From 250652b04a239aad0bb8e616d55f137ca9787f4c Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Sat, 18 Jul 2015 21:45:35 +0200 Subject: [PATCH 32/69] Bug 1184564 part 1 - Use Value instead of jsval in XPConnect. r=bholley --- js/xpconnect/loader/mozJSComponentLoader.cpp | 2 +- js/xpconnect/src/Sandbox.cpp | 14 ++--- js/xpconnect/src/XPCCallContext.cpp | 10 ++-- js/xpconnect/src/XPCConvert.cpp | 6 +- js/xpconnect/src/XPCInlines.h | 6 +- js/xpconnect/src/XPCShellImpl.cpp | 26 ++++----- js/xpconnect/src/XPCVariant.cpp | 6 +- js/xpconnect/src/XPCWrappedJSClass.cpp | 6 +- js/xpconnect/src/XPCWrappedNative.cpp | 6 +- js/xpconnect/src/XPCWrappedNativeInfo.cpp | 6 +- js/xpconnect/src/XPCWrappedNativeJSOps.cpp | 14 ++--- js/xpconnect/src/XPCWrapper.cpp | 5 +- js/xpconnect/src/xpcprivate.h | 60 ++++++++++---------- 13 files changed, 84 insertions(+), 83 deletions(-) diff --git a/js/xpconnect/loader/mozJSComponentLoader.cpp b/js/xpconnect/loader/mozJSComponentLoader.cpp index f8d3aa1a13b9..c35a597a3cca 100644 --- a/js/xpconnect/loader/mozJSComponentLoader.cpp +++ b/js/xpconnect/loader/mozJSComponentLoader.cpp @@ -116,7 +116,7 @@ Dump(JSContext* cx, unsigned argc, Value* vp) } static bool -Debug(JSContext* cx, unsigned argc, jsval* vp) +Debug(JSContext* cx, unsigned argc, Value* vp) { #ifdef DEBUG return Dump(cx, argc, vp); diff --git a/js/xpconnect/src/Sandbox.cpp b/js/xpconnect/src/Sandbox.cpp index bcbdaf1b8df7..269ba3a12851 100644 --- a/js/xpconnect/src/Sandbox.cpp +++ b/js/xpconnect/src/Sandbox.cpp @@ -110,7 +110,7 @@ xpc::NewSandboxConstructor() } static bool -SandboxDump(JSContext* cx, unsigned argc, jsval* vp) +SandboxDump(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -147,7 +147,7 @@ SandboxDump(JSContext* cx, unsigned argc, jsval* vp) } static bool -SandboxDebug(JSContext* cx, unsigned argc, jsval* vp) +SandboxDebug(JSContext* cx, unsigned argc, Value* vp) { #ifdef DEBUG return SandboxDump(cx, argc, vp); @@ -299,7 +299,7 @@ SandboxFetch(JSContext* cx, JS::HandleObject scope, const CallArgs& args) return true; } -static bool SandboxFetchPromise(JSContext* cx, unsigned argc, jsval* vp) +static bool SandboxFetchPromise(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); RootedObject callee(cx, &args.callee()); @@ -323,7 +323,7 @@ SandboxCreateFetch(JSContext* cx, HandleObject obj) } static bool -SandboxIsProxy(JSContext* cx, unsigned argc, jsval* vp) +SandboxIsProxy(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() < 1) { @@ -350,7 +350,7 @@ SandboxIsProxy(JSContext* cx, unsigned argc, jsval* vp) * [optional] object options) */ static bool -SandboxExportFunction(JSContext* cx, unsigned argc, jsval* vp) +SandboxExportFunction(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() < 2) { @@ -363,7 +363,7 @@ SandboxExportFunction(JSContext* cx, unsigned argc, jsval* vp) } static bool -SandboxCreateObjectIn(JSContext* cx, unsigned argc, jsval* vp) +SandboxCreateObjectIn(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() < 1) { @@ -389,7 +389,7 @@ SandboxCreateObjectIn(JSContext* cx, unsigned argc, jsval* vp) } static bool -SandboxCloneInto(JSContext* cx, unsigned argc, jsval* vp) +SandboxCloneInto(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() < 2) { diff --git a/js/xpconnect/src/XPCCallContext.cpp b/js/xpconnect/src/XPCCallContext.cpp index 57b891108af1..7dd594900394 100644 --- a/js/xpconnect/src/XPCCallContext.cpp +++ b/js/xpconnect/src/XPCCallContext.cpp @@ -22,8 +22,8 @@ XPCCallContext::XPCCallContext(XPCContext::LangType callerLanguage, HandleObject funobj /* = nullptr */, HandleId name /* = JSID_VOID */, unsigned argc /* = NO_ARGS */, - jsval* argv /* = nullptr */, - jsval* rval /* = nullptr */) + Value* argv /* = nullptr */, + Value* rval /* = nullptr */) : mAr(cx), mState(INIT_FAILED), mXPC(nsXPConnect::XPConnect()), @@ -166,8 +166,8 @@ XPCCallContext::SetCallInfo(XPCNativeInterface* iface, XPCNativeMember* member, void XPCCallContext::SetArgsAndResultPtr(unsigned argc, - jsval* argv, - jsval* rval) + Value* argv, + Value* rval) { CHECK_STATE(HAVE_OBJECT); @@ -287,7 +287,7 @@ XPCCallContext::GetArgc(uint32_t* aArgc) /* readonly attribute JSValPtr ArgvPtr; */ NS_IMETHODIMP -XPCCallContext::GetArgvPtr(jsval * *aArgvPtr) +XPCCallContext::GetArgvPtr(Value** aArgvPtr) { *aArgvPtr = mArgv; return NS_OK; diff --git a/js/xpconnect/src/XPCConvert.cpp b/js/xpconnect/src/XPCConvert.cpp index 367602b717f6..8beffbe3b6b1 100644 --- a/js/xpconnect/src/XPCConvert.cpp +++ b/js/xpconnect/src/XPCConvert.cpp @@ -460,7 +460,7 @@ XPCConvert::JSData2Native(void* d, HandleValue s, break; } case nsXPTType::T_JSVAL : - *((jsval*)d) = s; + *((Value*)d) = s; break; case nsXPTType::T_VOID: XPC_LOG_ERROR(("XPCConvert::JSData2Native : void* params not supported")); @@ -969,7 +969,7 @@ XPCConvert::ConstructException(nsresult rv, const char* message, nsISupports* data, nsIException** exceptn, JSContext* cx, - jsval* jsExceptionPtr) + Value* jsExceptionPtr) { MOZ_ASSERT(!cx == !jsExceptionPtr, "Expected cx and jsExceptionPtr to cooccur."); @@ -1159,7 +1159,7 @@ XPCConvert::JSValToXPCException(MutableHandleValue s, nullptr, exceptn, cx, s.address()); else { // XXX all this nsISupportsDouble code seems a little redundant - // now that we're storing the jsval in the exception... + // now that we're storing the Value in the exception... nsISupportsDouble* data; nsCOMPtr cm; if (NS_FAILED(NS_GetComponentManager(getter_AddRefs(cm))) || !cm || diff --git a/js/xpconnect/src/XPCInlines.h b/js/xpconnect/src/XPCInlines.h index f73db94fa46b..b33eba5146a6 100644 --- a/js/xpconnect/src/XPCInlines.h +++ b/js/xpconnect/src/XPCInlines.h @@ -187,14 +187,14 @@ XPCCallContext::GetArgc() const return mArgc; } -inline jsval* +inline JS::Value* XPCCallContext::GetArgv() const { CHECK_STATE(READY_TO_CALL); return mArgv; } -inline jsval* +inline JS::Value* XPCCallContext::GetRetVal() const { CHECK_STATE(READY_TO_CALL); @@ -202,7 +202,7 @@ XPCCallContext::GetRetVal() const } inline void -XPCCallContext::SetRetVal(jsval val) +XPCCallContext::SetRetVal(JS::Value val) { CHECK_STATE(HAVE_ARGS); if (mRetVal) diff --git a/js/xpconnect/src/XPCShellImpl.cpp b/js/xpconnect/src/XPCShellImpl.cpp index fd02323c23fe..61290e0f41b4 100644 --- a/js/xpconnect/src/XPCShellImpl.cpp +++ b/js/xpconnect/src/XPCShellImpl.cpp @@ -211,7 +211,7 @@ GetLine(JSContext* cx, char* bufp, FILE* file, const char* prompt) } static bool -ReadLine(JSContext* cx, unsigned argc, jsval* vp) +ReadLine(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -255,7 +255,7 @@ ReadLine(JSContext* cx, unsigned argc, jsval* vp) } static bool -Print(JSContext* cx, unsigned argc, jsval* vp) +Print(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); args.rval().setUndefined(); @@ -283,7 +283,7 @@ Print(JSContext* cx, unsigned argc, jsval* vp) } static bool -Dump(JSContext* cx, unsigned argc, jsval* vp) +Dump(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); args.rval().setUndefined(); @@ -316,7 +316,7 @@ Dump(JSContext* cx, unsigned argc, jsval* vp) } static bool -Load(JSContext* cx, unsigned argc, jsval* vp) +Load(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -365,7 +365,7 @@ Load(JSContext* cx, unsigned argc, jsval* vp) } static bool -Version(JSContext* cx, unsigned argc, jsval* vp) +Version(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); args.rval().setInt32(JS_GetVersion(cx)); @@ -376,7 +376,7 @@ Version(JSContext* cx, unsigned argc, jsval* vp) } static bool -Quit(JSContext* cx, unsigned argc, jsval* vp) +Quit(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -390,7 +390,7 @@ Quit(JSContext* cx, unsigned argc, jsval* vp) } static bool -DumpXPC(JSContext* cx, unsigned argc, jsval* vp) +DumpXPC(JSContext* cx, unsigned argc, Value* vp) { JS::CallArgs args = CallArgsFromVp(argc, vp); @@ -408,7 +408,7 @@ DumpXPC(JSContext* cx, unsigned argc, jsval* vp) } static bool -GC(JSContext* cx, unsigned argc, jsval* vp) +GC(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); JSRuntime* rt = JS_GetRuntime(cx); @@ -422,7 +422,7 @@ GC(JSContext* cx, unsigned argc, jsval* vp) #ifdef JS_GC_ZEAL static bool -GCZeal(JSContext* cx, unsigned argc, jsval* vp) +GCZeal(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); uint32_t zeal; @@ -466,7 +466,7 @@ SendCommand(JSContext* cx, unsigned argc, Value* vp) } static bool -Options(JSContext* cx, unsigned argc, jsval* vp) +Options(JSContext* cx, unsigned argc, Value* vp) { JS::CallArgs args = CallArgsFromVp(argc, vp); RuntimeOptions oldRuntimeOptions = RuntimeOptionsRef(cx); @@ -571,7 +571,7 @@ XPCShellInterruptCallback(JSContext* cx) } static bool -SetInterruptCallback(JSContext* cx, unsigned argc, jsval* vp) +SetInterruptCallback(JSContext* cx, unsigned argc, Value* vp) { MOZ_ASSERT(sScriptedInterruptCallback.initialized()); @@ -600,7 +600,7 @@ SetInterruptCallback(JSContext* cx, unsigned argc, jsval* vp) } static bool -SimulateActivityCallback(JSContext* cx, unsigned argc, jsval* vp) +SimulateActivityCallback(JSContext* cx, unsigned argc, Value* vp) { // Sanity-check args. JS::CallArgs args = JS::CallArgsFromVp(argc, vp); @@ -613,7 +613,7 @@ SimulateActivityCallback(JSContext* cx, unsigned argc, jsval* vp) } static bool -RegisterAppManifest(JSContext* cx, unsigned argc, jsval* vp) +RegisterAppManifest(JSContext* cx, unsigned argc, Value* vp) { JS::CallArgs args = JS::CallArgsFromVp(argc, vp); if (args.length() != 1) { diff --git a/js/xpconnect/src/XPCVariant.cpp b/js/xpconnect/src/XPCVariant.cpp index 9e04621035c0..c18400f896d0 100644 --- a/js/xpconnect/src/XPCVariant.cpp +++ b/js/xpconnect/src/XPCVariant.cpp @@ -29,7 +29,7 @@ NS_IMPL_CI_INTERFACE_GETTER(XPCVariant, XPCVariant, nsIVariant) NS_IMPL_CYCLE_COLLECTING_ADDREF(XPCVariant) NS_IMPL_CYCLE_COLLECTING_RELEASE(XPCVariant) -XPCVariant::XPCVariant(JSContext* cx, jsval aJSVal) +XPCVariant::XPCVariant(JSContext* cx, Value aJSVal) : mJSVal(aJSVal), mCCGeneration(0) { nsVariant::Initialize(&mData); @@ -55,7 +55,7 @@ XPCVariant::XPCVariant(JSContext* cx, jsval aJSVal) XPCTraceableVariant::~XPCTraceableVariant() { - jsval val = GetJSValPreserveColor(); + Value val = GetJSValPreserveColor(); MOZ_ASSERT(val.isGCThing(), "Must be traceable or unlinked"); @@ -97,7 +97,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END // static already_AddRefed -XPCVariant::newVariant(JSContext* cx, jsval aJSVal) +XPCVariant::newVariant(JSContext* cx, Value aJSVal) { nsRefPtr variant; diff --git a/js/xpconnect/src/XPCWrappedJSClass.cpp b/js/xpconnect/src/XPCWrappedJSClass.cpp index 1619108c4cbe..572a0e7e33f7 100644 --- a/js/xpconnect/src/XPCWrappedJSClass.cpp +++ b/js/xpconnect/src/XPCWrappedJSClass.cpp @@ -322,7 +322,7 @@ nsXPCWrappedJSClass::GetNamedPropertyAsVariant(XPCCallContext& ccx, if (!scriptEval.StartEvaluating(aJSObj)) return NS_ERROR_FAILURE; - // Wrap the string in a jsval after the AutoScriptEvaluate, so that the + // Wrap the string in a Value after the AutoScriptEvaluate, so that the // resulting value ends up in the correct compartment. nsStringBuffer* buf; RootedValue value(cx); @@ -943,8 +943,8 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS* wrapper, uint16_t methodIndex, const XPTMethodDescriptor* info_, nsXPTCMiniVariant* nativeParams) { - jsval* sp = nullptr; - jsval* argv = nullptr; + Value* sp = nullptr; + Value* argv = nullptr; uint8_t i; nsresult retval = NS_ERROR_FAILURE; bool success; diff --git a/js/xpconnect/src/XPCWrappedNative.cpp b/js/xpconnect/src/XPCWrappedNative.cpp index e96eb385abd6..a7420b55f177 100644 --- a/js/xpconnect/src/XPCWrappedNative.cpp +++ b/js/xpconnect/src/XPCWrappedNative.cpp @@ -1299,7 +1299,7 @@ class MOZ_STACK_CLASS CallMethodHelper uint8_t mJSContextIndex; // TODO make const uint8_t mOptArgcIndex; // TODO make const - jsval* const mArgv; + Value* const mArgv; const uint32_t mArgc; MOZ_ALWAYS_INLINE bool @@ -1559,7 +1559,7 @@ CallMethodHelper::GetOutParamSource(uint8_t paramIndex, MutableHandleValue srcp) if (paramInfo.IsOut() && !paramInfo.IsRetval()) { MOZ_ASSERT(paramIndex < mArgc || paramInfo.IsOptional(), "Expected either enough arguments or an optional argument"); - jsval arg = paramIndex < mArgc ? mArgv[paramIndex] : JS::NullValue(); + Value arg = paramIndex < mArgc ? mArgv[paramIndex] : JS::NullValue(); if (paramIndex < mArgc) { RootedObject obj(mCallContext); if (!arg.isPrimitive()) @@ -2040,7 +2040,7 @@ CallMethodHelper::CleanupParam(nsXPTCMiniVariant& param, nsXPTType& type) switch (type.TagPart()) { case nsXPTType::T_JSVAL: - js::RemoveRawValueRoot(mCallContext, (jsval*)¶m.val); + js::RemoveRawValueRoot(mCallContext, (Value*)¶m.val); break; case nsXPTType::T_INTERFACE: case nsXPTType::T_INTERFACE_IS: diff --git a/js/xpconnect/src/XPCWrappedNativeInfo.cpp b/js/xpconnect/src/XPCWrappedNativeInfo.cpp index 79170f90cb59..48816435fae8 100644 --- a/js/xpconnect/src/XPCWrappedNativeInfo.cpp +++ b/js/xpconnect/src/XPCWrappedNativeInfo.cpp @@ -27,7 +27,7 @@ XPCNativeMember::GetCallInfo(JSObject* funobj, XPCNativeMember** pMember) { funobj = js::UncheckedUnwrap(funobj); - jsval memberVal = + Value memberVal = js::GetFunctionNativeReserved(funobj, XPC_FUNCTION_NATIVE_MEMBER_SLOT); @@ -40,7 +40,7 @@ XPCNativeMember::GetCallInfo(JSObject* funobj, bool XPCNativeMember::NewFunctionObject(XPCCallContext& ccx, XPCNativeInterface* iface, HandleObject parent, - jsval* pval) + Value* pval) { MOZ_ASSERT(!IsConstant(), "Only call this if you're sure this is not a constant!"); @@ -49,7 +49,7 @@ XPCNativeMember::NewFunctionObject(XPCCallContext& ccx, bool XPCNativeMember::Resolve(XPCCallContext& ccx, XPCNativeInterface* iface, - HandleObject parent, jsval* vp) + HandleObject parent, Value* vp) { MOZ_ASSERT(iface == GetInterface()); if (IsConstant()) { diff --git a/js/xpconnect/src/XPCWrappedNativeJSOps.cpp b/js/xpconnect/src/XPCWrappedNativeJSOps.cpp index a3f62b34098c..80ce3202347d 100644 --- a/js/xpconnect/src/XPCWrappedNativeJSOps.cpp +++ b/js/xpconnect/src/XPCWrappedNativeJSOps.cpp @@ -68,7 +68,7 @@ ToStringGuts(XPCCallContext& ccx) /***************************************************************************/ static bool -XPC_WN_Shared_ToString(JSContext* cx, unsigned argc, jsval* vp) +XPC_WN_Shared_ToString(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); RootedObject obj(cx, JS_THIS_OBJECT(cx, vp)); @@ -84,7 +84,7 @@ XPC_WN_Shared_ToString(JSContext* cx, unsigned argc, jsval* vp) } static bool -XPC_WN_Shared_ToSource(JSContext* cx, unsigned argc, jsval* vp) +XPC_WN_Shared_ToSource(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); static const char empty[] = "({})"; @@ -136,7 +136,7 @@ GetDoubleWrappedJSObject(XPCCallContext& ccx, XPCWrappedNative* wrapper) // double wrapped JSObjects. static bool -XPC_WN_DoubleWrappedGetter(JSContext* cx, unsigned argc, jsval* vp) +XPC_WN_DoubleWrappedGetter(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -778,7 +778,7 @@ XPC_WN_Helper_SetProperty(JSContext* cx, HandleObject obj, HandleId id, } static bool -XPC_WN_Helper_Call(JSContext* cx, unsigned argc, jsval* vp) +XPC_WN_Helper_Call(JSContext* cx, unsigned argc, Value* vp) { JS::CallArgs args = JS::CallArgsFromVp(argc, vp); // N.B. we want obj to be the callee, not JS_THIS(cx, vp) @@ -795,7 +795,7 @@ XPC_WN_Helper_Call(JSContext* cx, unsigned argc, jsval* vp) } static bool -XPC_WN_Helper_Construct(JSContext* cx, unsigned argc, jsval* vp) +XPC_WN_Helper_Construct(JSContext* cx, unsigned argc, Value* vp) { JS::CallArgs args = JS::CallArgsFromVp(argc, vp); RootedObject obj(cx, &args.callee()); @@ -1119,7 +1119,7 @@ FixUpThisIfBroken(JSObject* obj, JSObject* funobj) } bool -XPC_WN_CallMethod(JSContext* cx, unsigned argc, jsval* vp) +XPC_WN_CallMethod(JSContext* cx, unsigned argc, Value* vp) { JS::CallArgs args = JS::CallArgsFromVp(argc, vp); MOZ_ASSERT(JS_TypeOfValue(cx, args.calleev()) == JSTYPE_FUNCTION, "bad function"); @@ -1145,7 +1145,7 @@ XPC_WN_CallMethod(JSContext* cx, unsigned argc, jsval* vp) } bool -XPC_WN_GetterSetter(JSContext* cx, unsigned argc, jsval* vp) +XPC_WN_GetterSetter(JSContext* cx, unsigned argc, Value* vp) { JS::CallArgs args = JS::CallArgsFromVp(argc, vp); MOZ_ASSERT(JS_TypeOfValue(cx, args.calleev()) == JSTYPE_FUNCTION, "bad function"); diff --git a/js/xpconnect/src/XPCWrapper.cpp b/js/xpconnect/src/XPCWrapper.cpp index 1c8b41944427..a6b331017fb0 100644 --- a/js/xpconnect/src/XPCWrapper.cpp +++ b/js/xpconnect/src/XPCWrapper.cpp @@ -11,6 +11,7 @@ using namespace xpc; using namespace mozilla; +using namespace JS; namespace XPCNativeWrapper { @@ -24,7 +25,7 @@ ThrowException(nsresult ex, JSContext* cx) } static bool -UnwrapNW(JSContext* cx, unsigned argc, jsval* vp) +UnwrapNW(JSContext* cx, unsigned argc, Value* vp) { JS::CallArgs args = JS::CallArgsFromVp(argc, vp); if (args.length() != 1) { @@ -45,7 +46,7 @@ UnwrapNW(JSContext* cx, unsigned argc, jsval* vp) } static bool -XrayWrapperConstructor(JSContext* cx, unsigned argc, jsval* vp) +XrayWrapperConstructor(JSContext* cx, unsigned argc, Value* vp) { JS::CallArgs args = CallArgsFromVp(argc, vp); if (args.length() == 0) { diff --git a/js/xpconnect/src/xpcprivate.h b/js/xpconnect/src/xpcprivate.h index 904d3d02cd9d..70205ee0dead 100644 --- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -635,7 +635,7 @@ private: static const char* const mStrings[IDX_TOTAL_COUNT]; jsid mStrIDs[IDX_TOTAL_COUNT]; - jsval mStrJSVals[IDX_TOTAL_COUNT]; + JS::Value mStrJSVals[IDX_TOTAL_COUNT]; XPCJSContextStack* mJSContextStack; XPCCallContext* mCallContext; @@ -798,7 +798,7 @@ public: NS_IMETHOD GetCalleeMethodIndex(uint16_t* aResult); NS_IMETHOD GetJSContext(JSContext** aResult); NS_IMETHOD GetArgc(uint32_t* aResult); - NS_IMETHOD GetArgvPtr(jsval** aResult); + NS_IMETHOD GetArgvPtr(JS::Value** aResult); NS_IMETHOD GetCalleeInterface(nsIInterfaceInfo** aResult); NS_IMETHOD GetCalleeClassInfo(nsIClassInfo** aResult); NS_IMETHOD GetPreviousCallContext(nsAXPCNativeCallContext** aResult); @@ -814,8 +814,8 @@ public: JS::HandleObject funobj = nullptr, JS::HandleId id = JSID_VOIDHANDLE, unsigned argc = NO_ARGS, - jsval* argv = nullptr, - jsval* rval = nullptr); + JS::Value* argv = nullptr, + JS::Value* rval = nullptr); virtual ~XPCCallContext(); @@ -847,8 +847,8 @@ public: inline jsid GetName() const ; inline bool GetStaticMemberIsLocal() const ; inline unsigned GetArgc() const ; - inline jsval* GetArgv() const ; - inline jsval* GetRetVal() const ; + inline JS::Value* GetArgv() const ; + inline JS::Value* GetRetVal() const ; inline uint16_t GetMethodIndex() const ; inline void SetMethodIndex(uint16_t index) ; @@ -859,10 +859,10 @@ public: inline XPCWrappedNative* GetResolvingWrapper() const; inline XPCWrappedNative* SetResolvingWrapper(XPCWrappedNative* w); - inline void SetRetVal(jsval val); + inline void SetRetVal(JS::Value val); void SetName(jsid name); - void SetArgsAndResultPtr(unsigned argc, jsval* argv, jsval* rval); + void SetArgsAndResultPtr(unsigned argc, JS::Value* argv, JS::Value* rval); void SetCallInfo(XPCNativeInterface* iface, XPCNativeMember* member, bool isSetter); @@ -927,8 +927,8 @@ private: bool mStaticMemberIsLocal; unsigned mArgc; - jsval* mArgv; - jsval* mRetVal; + JS::Value* mArgv; + JS::Value* mRetVal; uint16_t mMethodIndex; }; @@ -956,10 +956,10 @@ extern const js::Class XPC_WN_Tearoff_JSClass; extern const js::Class XPC_WN_NoHelper_Proto_JSClass; extern bool -XPC_WN_CallMethod(JSContext* cx, unsigned argc, jsval* vp); +XPC_WN_CallMethod(JSContext* cx, unsigned argc, JS::Value* vp); extern bool -XPC_WN_GetterSetter(JSContext* cx, unsigned argc, jsval* vp); +XPC_WN_GetterSetter(JSContext* cx, unsigned argc, JS::Value* vp); extern JSObject* XPC_WN_JSOp_ThisObject(JSContext* cx, JS::HandleObject obj); @@ -1290,13 +1290,13 @@ public: uint16_t GetIndex() const {return mIndex;} bool GetConstantValue(XPCCallContext& ccx, XPCNativeInterface* iface, - jsval* pval) + JS::Value* pval) {MOZ_ASSERT(IsConstant(), "Only call this if you're sure this is a constant!"); return Resolve(ccx, iface, nullptr, pval);} bool NewFunctionObject(XPCCallContext& ccx, XPCNativeInterface* iface, - JS::HandleObject parent, jsval* pval); + JS::HandleObject parent, JS::Value* pval); bool IsMethod() const {return 0 != (mFlags & METHOD);} @@ -1342,7 +1342,7 @@ public: private: bool Resolve(XPCCallContext& ccx, XPCNativeInterface* iface, - JS::HandleObject parent, jsval* vp); + JS::HandleObject parent, JS::Value* vp); enum { METHOD = 0x01, @@ -2583,9 +2583,9 @@ public: static bool IsMethodReflectable(const XPTMethodDescriptor& info); /** - * Convert a native object into a jsval. + * Convert a native object into a JS::Value. * - * @param d [out] the resulting jsval + * @param d [out] the resulting JS::Value * @param s the native object we're working with * @param type the type of object that s is * @param iid the interface of s that we want @@ -2639,9 +2639,9 @@ public: static bool GetISupportsFromJSObject(JSObject* obj, nsISupports** iface); /** - * Convert a native array into a jsval. + * Convert a native array into a JS::Value. * - * @param d [out] the resulting jsval + * @param d [out] the resulting JS::Value * @param s the native array we're working with * @param type the type of objects in the array * @param iid the interface of each object in the array that we want @@ -2689,7 +2689,7 @@ public: nsISupports* data, nsIException** exception, JSContext* cx, - jsval* jsExceptionPtr); + JS::Value* jsExceptionPtr); private: XPCConvert(); // not implemented @@ -3285,21 +3285,21 @@ public: // if a given nsIVariant is in fact an XPCVariant. NS_DECLARE_STATIC_IID_ACCESSOR(XPCVARIANT_IID) - static already_AddRefed newVariant(JSContext* cx, jsval aJSVal); + static already_AddRefed newVariant(JSContext* cx, JS::Value aJSVal); /** - * This getter clears the gray bit before handing out the jsval if the jsval + * This getter clears the gray bit before handing out the Value if the Value * represents a JSObject. That means that the object is guaranteed to be * kept alive past the next CC. */ - jsval GetJSVal() const { + JS::Value GetJSVal() const { if (!mJSVal.isPrimitive()) JS::ExposeObjectToActiveJS(&mJSVal.toObject()); return mJSVal; } /** - * This getter does not change the color of the jsval (if it represents a + * This getter does not change the color of the Value (if it represents a * JSObject) meaning that the value returned is not guaranteed to be kept * alive past the next CC. * @@ -3307,12 +3307,12 @@ public: * be passed into a JS API function and that it won't be stored without * being rooted (or otherwise signaling the stored value to the CC). */ - jsval GetJSValPreserveColor() const {return mJSVal;} + JS::Value GetJSValPreserveColor() const {return mJSVal;} - XPCVariant(JSContext* cx, jsval aJSVal); + XPCVariant(JSContext* cx, JS::Value aJSVal); /** - * Convert a variant into a jsval. + * Convert a variant into a JS::Value. * * @param ccx the context for the whole procedure * @param variant the variant to convert @@ -3357,7 +3357,7 @@ class XPCTraceableVariant: public XPCVariant, public XPCRootSetElem { public: - XPCTraceableVariant(JSContext* cx, jsval aJSVal) + XPCTraceableVariant(JSContext* cx, JS::Value aJSVal) : XPCVariant(cx, aJSVal) { nsXPConnect::GetRuntimeInstance()->AddVariantRoot(this); @@ -3390,10 +3390,10 @@ NewAddonId(JSContext* cx, const nsACString& id); // JSNatives to expose atob and btoa in various non-DOM XPConnect scopes. bool -Atob(JSContext* cx, unsigned argc, jsval* vp); +Atob(JSContext* cx, unsigned argc, JS::Value* vp); bool -Btoa(JSContext* cx, unsigned argc, jsval* vp); +Btoa(JSContext* cx, unsigned argc, JS::Value* vp); // Helper function that creates a JSFunction that wraps a native function that // forwards the call to the original 'callable'. From 9d74419a905d7232d72ddd9b767e0c9d0043363a Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Sat, 18 Jul 2015 21:45:35 +0200 Subject: [PATCH 33/69] Bug 1184564 part 2 - Use Value instead of jsval in dom/ and storage/. r=bz --- dom/base/nsDOMClassInfo.cpp | 8 ++++---- dom/workers/Workers.h | 2 +- storage/mozStorageAsyncStatementJSHelper.cpp | 4 ++-- storage/mozStorageStatementJSHelper.cpp | 8 ++++---- storage/mozStorageStatementRow.cpp | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/dom/base/nsDOMClassInfo.cpp b/dom/base/nsDOMClassInfo.cpp index 210c00970ac2..c2c05e6466d9 100644 --- a/dom/base/nsDOMClassInfo.cpp +++ b/dom/base/nsDOMClassInfo.cpp @@ -902,7 +902,7 @@ nsDOMClassInfo::AddProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHODIMP nsDOMClassInfo::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, - JSObject *obj, jsid id, jsval *vp, + JSObject *obj, jsid id, JS::Value *vp, bool *_retval) { NS_WARNING("nsDOMClassInfo::GetProperty Don't call me!"); @@ -912,7 +912,7 @@ nsDOMClassInfo::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHODIMP nsDOMClassInfo::SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, - JSObject *obj, jsid id, jsval *vp, + JSObject *obj, jsid id, JS::Value *vp, bool *_retval) { NS_WARNING("nsDOMClassInfo::SetProperty Don't call me!"); @@ -1339,7 +1339,7 @@ public: bool *_retval); nsresult HasInstance(nsIXPConnectWrappedNative *wrapper, JSContext *cx, - JS::Handle obj, const jsval &val, bool *bp, + JS::Handle obj, const JS::Value &val, bool *bp, bool *_retval); nsresult ResolveInterfaceConstants(JSContext *cx, JS::Handle obj); @@ -1499,7 +1499,7 @@ nsDOMConstructor::Construct(nsIXPConnectWrappedNative *wrapper, JSContext * cx, nsresult nsDOMConstructor::HasInstance(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JS::Handle obj, - const jsval &v, bool *bp, bool *_retval) + const JS::Value &v, bool *bp, bool *_retval) { // No need to look these up in the hash. diff --git a/dom/workers/Workers.h b/dom/workers/Workers.h index 7fa9967c5571..4a8fc7c791f6 100644 --- a/dom/workers/Workers.h +++ b/dom/workers/Workers.h @@ -340,7 +340,7 @@ public: }; WorkerCrossThreadDispatcher* -GetWorkerCrossThreadDispatcher(JSContext* aCx, jsval aWorker); +GetWorkerCrossThreadDispatcher(JSContext* aCx, JS::Value aWorker); // Random unique constant to facilitate JSPrincipal debugging const uint32_t kJSPrincipalsDebugToken = 0x7e2df9d2; diff --git a/storage/mozStorageAsyncStatementJSHelper.cpp b/storage/mozStorageAsyncStatementJSHelper.cpp index 9b365d0396d3..69397db1ff60 100644 --- a/storage/mozStorageAsyncStatementJSHelper.cpp +++ b/storage/mozStorageAsyncStatementJSHelper.cpp @@ -28,7 +28,7 @@ nsresult AsyncStatementJSHelper::getParams(AsyncStatement *aStatement, JSContext *aCtx, JSObject *aScopeObj, - jsval *_params) + JS::Value *_params) { MOZ_ASSERT(NS_IsMainThread()); nsresult rv; @@ -91,7 +91,7 @@ AsyncStatementJSHelper::GetProperty(nsIXPConnectWrappedNative *aWrapper, JSContext *aCtx, JSObject *aScopeObj, jsid aId, - jsval *_result, + JS::Value *_result, bool *_retval) { if (!JSID_IS_STRING(aId)) diff --git a/storage/mozStorageStatementJSHelper.cpp b/storage/mozStorageStatementJSHelper.cpp index 1c92f586049a..c05a0a53afc0 100644 --- a/storage/mozStorageStatementJSHelper.cpp +++ b/storage/mozStorageStatementJSHelper.cpp @@ -29,7 +29,7 @@ static bool stepFunc(JSContext *aCtx, uint32_t, - jsval *_vp) + JS::Value *_vp) { nsCOMPtr xpc(Service::getXPConnect()); nsCOMPtr wrapper; @@ -82,7 +82,7 @@ nsresult StatementJSHelper::getRow(Statement *aStatement, JSContext *aCtx, JSObject *aScopeObj, - jsval *_row) + JS::Value *_row) { MOZ_ASSERT(NS_IsMainThread()); nsresult rv; @@ -126,7 +126,7 @@ nsresult StatementJSHelper::getParams(Statement *aStatement, JSContext *aCtx, JSObject *aScopeObj, - jsval *_params) + JS::Value *_params) { MOZ_ASSERT(NS_IsMainThread()); nsresult rv; @@ -190,7 +190,7 @@ StatementJSHelper::GetProperty(nsIXPConnectWrappedNative *aWrapper, JSContext *aCtx, JSObject *aScopeObj, jsid aId, - jsval *_result, + JS::Value *_result, bool *_retval) { if (!JSID_IS_STRING(aId)) diff --git a/storage/mozStorageStatementRow.cpp b/storage/mozStorageStatementRow.cpp index af61804b3357..57954615c6a0 100644 --- a/storage/mozStorageStatementRow.cpp +++ b/storage/mozStorageStatementRow.cpp @@ -44,7 +44,7 @@ StatementRow::GetProperty(nsIXPConnectWrappedNative *aWrapper, JSContext *aCtx, JSObject *aScopeObj, jsid aId, - jsval *_vp, + JS::Value *_vp, bool *_retval) { NS_ENSURE_TRUE(mStatement, NS_ERROR_NOT_INITIALIZED); From cbcb91d961872d4e7278af9e1c03e56f07992622 Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Sat, 18 Jul 2015 21:45:35 +0200 Subject: [PATCH 34/69] Bug 1184564 part 3 - Use Value instead of jsval in CTypes. r=arai --- js/src/ctypes/CTypes.cpp | 304 +++++++++++++++++++------------------- js/src/ctypes/CTypes.h | 18 +-- js/src/ctypes/Library.cpp | 16 +- 3 files changed, 169 insertions(+), 169 deletions(-) diff --git a/js/src/ctypes/CTypes.cpp b/js/src/ctypes/CTypes.cpp index 01e1ad4b0575..f92dc5612e03 100644 --- a/js/src/ctypes/CTypes.cpp +++ b/js/src/ctypes/CTypes.cpp @@ -221,10 +221,10 @@ struct Property } }; -static bool ConstructAbstract(JSContext* cx, unsigned argc, jsval* vp); +static bool ConstructAbstract(JSContext* cx, unsigned argc, Value* vp); namespace CType { - static bool ConstructData(JSContext* cx, unsigned argc, jsval* vp); + static bool ConstructData(JSContext* cx, unsigned argc, Value* vp); static bool ConstructBasic(JSContext* cx, HandleObject obj, const CallArgs& args); static void Trace(JSTracer* trc, JSObject* obj); @@ -238,9 +238,9 @@ namespace CType { bool SizeGetter(JSContext* cx, JS::CallArgs args); bool PtrGetter(JSContext* cx, JS::CallArgs args); - static bool CreateArray(JSContext* cx, unsigned argc, jsval* vp); - static bool ToString(JSContext* cx, unsigned argc, jsval* vp); - static bool ToSource(JSContext* cx, unsigned argc, jsval* vp); + static bool CreateArray(JSContext* cx, unsigned argc, Value* vp); + static bool ToString(JSContext* cx, unsigned argc, Value* vp); + static bool ToSource(JSContext* cx, unsigned argc, Value* vp); static bool HasInstance(JSContext* cx, HandleObject obj, MutableHandleValue v, bool* bp); @@ -257,11 +257,11 @@ namespace CType { namespace ABI { bool IsABI(JSObject* obj); - static bool ToSource(JSContext* cx, unsigned argc, jsval* vp); + static bool ToSource(JSContext* cx, unsigned argc, Value* vp); } // namespace ABI namespace PointerType { - static bool Create(JSContext* cx, unsigned argc, jsval* vp); + static bool Create(JSContext* cx, unsigned argc, Value* vp); static bool ConstructData(JSContext* cx, HandleObject obj, const CallArgs& args); bool IsPointerType(HandleValue v); @@ -271,9 +271,9 @@ namespace PointerType { bool ContentsGetter(JSContext* cx, JS::CallArgs args); bool ContentsSetter(JSContext* cx, JS::CallArgs args); - static bool IsNull(JSContext* cx, unsigned argc, jsval* vp); - static bool Increment(JSContext* cx, unsigned argc, jsval* vp); - static bool Decrement(JSContext* cx, unsigned argc, jsval* vp); + static bool IsNull(JSContext* cx, unsigned argc, Value* vp); + static bool Increment(JSContext* cx, unsigned argc, Value* vp); + static bool Decrement(JSContext* cx, unsigned argc, Value* vp); // The following is not an instance function, since we don't want to expose arbitrary // pointer arithmetic at this moment. static bool OffsetBy(JSContext* cx, const CallArgs& args, int offset); @@ -283,7 +283,7 @@ namespace ArrayType { bool IsArrayType(HandleValue v); bool IsArrayOrArrayType(HandleValue v); - static bool Create(JSContext* cx, unsigned argc, jsval* vp); + static bool Create(JSContext* cx, unsigned argc, Value* vp); static bool ConstructData(JSContext* cx, HandleObject obj, const CallArgs& args); bool ElementTypeGetter(JSContext* cx, JS::CallArgs args); @@ -292,13 +292,13 @@ namespace ArrayType { static bool Getter(JSContext* cx, HandleObject obj, HandleId idval, MutableHandleValue vp); static bool Setter(JSContext* cx, HandleObject obj, HandleId idval, MutableHandleValue vp, ObjectOpResult& result); - static bool AddressOfElement(JSContext* cx, unsigned argc, jsval* vp); + static bool AddressOfElement(JSContext* cx, unsigned argc, Value* vp); } // namespace ArrayType namespace StructType { bool IsStruct(HandleValue v); - static bool Create(JSContext* cx, unsigned argc, jsval* vp); + static bool Create(JSContext* cx, unsigned argc, Value* vp); static bool ConstructData(JSContext* cx, HandleObject obj, const CallArgs& args); bool FieldsArrayGetter(JSContext* cx, JS::CallArgs args); @@ -309,16 +309,16 @@ namespace StructType { static bool FieldGetter(JSContext* cx, unsigned argc, Value* vp); static bool FieldSetter(JSContext* cx, unsigned argc, Value* vp); - static bool AddressOfField(JSContext* cx, unsigned argc, jsval* vp); - static bool Define(JSContext* cx, unsigned argc, jsval* vp); + static bool AddressOfField(JSContext* cx, unsigned argc, Value* vp); + static bool Define(JSContext* cx, unsigned argc, Value* vp); } // namespace StructType namespace FunctionType { - static bool Create(JSContext* cx, unsigned argc, jsval* vp); + static bool Create(JSContext* cx, unsigned argc, Value* vp); static bool ConstructData(JSContext* cx, HandleObject typeObj, - HandleObject dataObj, HandleObject fnObj, HandleObject thisObj, jsval errVal); + HandleObject dataObj, HandleObject fnObj, HandleObject thisObj, Value errVal); - static bool Call(JSContext* cx, unsigned argc, jsval* vp); + static bool Call(JSContext* cx, unsigned argc, Value* vp); bool IsFunctionType(HandleValue v); @@ -355,10 +355,10 @@ namespace CData { bool ValueGetter(JSContext* cx, JS::CallArgs args); bool ValueSetter(JSContext* cx, JS::CallArgs args); - static bool Address(JSContext* cx, unsigned argc, jsval* vp); - static bool ReadString(JSContext* cx, unsigned argc, jsval* vp); - static bool ReadStringReplaceMalformed(JSContext* cx, unsigned argc, jsval* vp); - static bool ToSource(JSContext* cx, unsigned argc, jsval* vp); + static bool Address(JSContext* cx, unsigned argc, Value* vp); + static bool ReadString(JSContext* cx, unsigned argc, Value* vp); + static bool ReadStringReplaceMalformed(JSContext* cx, unsigned argc, Value* vp); + static bool ToSource(JSContext* cx, unsigned argc, Value* vp); static JSString* GetSourceString(JSContext* cx, HandleObject typeObj, void* data); @@ -382,7 +382,7 @@ namespace CDataFinalizer { * Where |finalizer| is a one-argument function taking a value * with the same type as |value|. */ - static bool Construct(JSContext* cx, unsigned argc, jsval* vp); + static bool Construct(JSContext* cx, unsigned argc, Value* vp); /* * Private data held by |CDataFinalizer|. @@ -428,10 +428,10 @@ namespace CDataFinalizer { * Methods of instances of |CDataFinalizer| */ namespace Methods { - static bool Dispose(JSContext* cx, unsigned argc, jsval* vp); - static bool Forget(JSContext* cx, unsigned argc, jsval* vp); - static bool ToSource(JSContext* cx, unsigned argc, jsval* vp); - static bool ToString(JSContext* cx, unsigned argc, jsval* vp); + static bool Dispose(JSContext* cx, unsigned argc, Value* vp); + static bool Forget(JSContext* cx, unsigned argc, Value* vp); + static bool ToSource(JSContext* cx, unsigned argc, Value* vp); + static bool ToString(JSContext* cx, unsigned argc, Value* vp); } // namespace Methods /* @@ -473,9 +473,9 @@ namespace CDataFinalizer { static void Finalize(JSFreeOp* fop, JSObject* obj); /* - * Return the jsval contained by this finalizer. + * Return the Value contained by this finalizer. * - * Note that the jsval is actually not recorded, but converted back from C. + * Note that the Value is actually not recorded, but converted back from C. */ static bool GetValue(JSContext* cx, JSObject* obj, MutableHandleValue result); @@ -500,27 +500,27 @@ namespace Int64Base { } // namespace Int64Base namespace Int64 { - static bool Construct(JSContext* cx, unsigned argc, jsval* vp); + static bool Construct(JSContext* cx, unsigned argc, Value* vp); - static bool ToString(JSContext* cx, unsigned argc, jsval* vp); - static bool ToSource(JSContext* cx, unsigned argc, jsval* vp); + static bool ToString(JSContext* cx, unsigned argc, Value* vp); + static bool ToSource(JSContext* cx, unsigned argc, Value* vp); - static bool Compare(JSContext* cx, unsigned argc, jsval* vp); - static bool Lo(JSContext* cx, unsigned argc, jsval* vp); - static bool Hi(JSContext* cx, unsigned argc, jsval* vp); - static bool Join(JSContext* cx, unsigned argc, jsval* vp); + static bool Compare(JSContext* cx, unsigned argc, Value* vp); + static bool Lo(JSContext* cx, unsigned argc, Value* vp); + static bool Hi(JSContext* cx, unsigned argc, Value* vp); + static bool Join(JSContext* cx, unsigned argc, Value* vp); } // namespace Int64 namespace UInt64 { - static bool Construct(JSContext* cx, unsigned argc, jsval* vp); + static bool Construct(JSContext* cx, unsigned argc, Value* vp); - static bool ToString(JSContext* cx, unsigned argc, jsval* vp); - static bool ToSource(JSContext* cx, unsigned argc, jsval* vp); + static bool ToString(JSContext* cx, unsigned argc, Value* vp); + static bool ToSource(JSContext* cx, unsigned argc, Value* vp); - static bool Compare(JSContext* cx, unsigned argc, jsval* vp); - static bool Lo(JSContext* cx, unsigned argc, jsval* vp); - static bool Hi(JSContext* cx, unsigned argc, jsval* vp); - static bool Join(JSContext* cx, unsigned argc, jsval* vp); + static bool Compare(JSContext* cx, unsigned argc, Value* vp); + static bool Lo(JSContext* cx, unsigned argc, Value* vp); + static bool Hi(JSContext* cx, unsigned argc, Value* vp); + static bool Join(JSContext* cx, unsigned argc, Value* vp); } // namespace UInt64 /******************************************************************************* @@ -872,7 +872,7 @@ GetABICode(JSObject* obj) if (JS_GetClass(obj) != &sCABIClass) return INVALID_ABI; - jsval result = JS_GetReservedSlot(obj, SLOT_ABICODE); + Value result = JS_GetReservedSlot(obj, SLOT_ABICODE); return ABICode(result.toInt32()); } @@ -1001,7 +1001,7 @@ BuildFunctionTypeSource(JSContext* cx, HandleObject funObj, AutoString& source) MOZ_ASSERT(CData::IsCData(funObj) || CType::IsCType(funObj)); if (CData::IsCData(funObj)) { - jsval slot = JS_GetReservedSlot(funObj, SLOT_REFERENT); + Value slot = JS_GetReservedSlot(funObj, SLOT_REFERENT); if (!slot.isUndefined() && Library::IsLibrary(&slot.toObject())) { slot = JS_GetReservedSlot(funObj, SLOT_FUNNAME); MOZ_ASSERT(!slot.isUndefined()); @@ -1922,7 +1922,7 @@ GetCallbacks(JSObject* obj) { MOZ_ASSERT(IsCTypesGlobal(obj)); - jsval result = JS_GetReservedSlot(obj, SLOT_CALLBACKS); + Value result = JS_GetReservedSlot(obj, SLOT_CALLBACKS); if (result.isUndefined()) return nullptr; @@ -2022,7 +2022,7 @@ SizeOfDataIfCDataObject(mozilla::MallocSizeOf mallocSizeOf, JSObject* obj) return 0; size_t n = 0; - jsval slot = JS_GetReservedSlot(obj, ctypes::SLOT_OWNS); + Value slot = JS_GetReservedSlot(obj, ctypes::SLOT_OWNS); if (!slot.isUndefined()) { bool owns = slot.toBoolean(); slot = JS_GetReservedSlot(obj, ctypes::SLOT_DATA); @@ -2212,7 +2212,7 @@ static MOZ_ALWAYS_INLINE bool IsNegative(Type i) // Implicitly convert val to bool, allowing bool, int, and double // arguments numerically equal to 0 or 1. static bool -jsvalToBool(JSContext* cx, jsval val, bool* result) +jsvalToBool(JSContext* cx, Value val, bool* result) { if (val.isBoolean()) { *result = val.toBoolean(); @@ -2238,7 +2238,7 @@ jsvalToBool(JSContext* cx, jsval val, bool* result) // representable by IntegerType. template static bool -jsvalToInteger(JSContext* cx, jsval val, IntegerType* result) +jsvalToInteger(JSContext* cx, Value val, IntegerType* result) { JS_STATIC_ASSERT(NumericLimits::is_exact); @@ -2328,7 +2328,7 @@ jsvalToInteger(JSContext* cx, jsval val, IntegerType* result) // representable by FloatType. template static bool -jsvalToFloat(JSContext* cx, jsval val, FloatType* result) +jsvalToFloat(JSContext* cx, Value val, FloatType* result) { JS_STATIC_ASSERT(!NumericLimits::is_exact); @@ -2454,7 +2454,7 @@ StringToInteger(JSContext* cx, JSString* string, IntegerType* result) template static bool jsvalToBigInteger(JSContext* cx, - jsval val, + Value val, bool allowString, IntegerType* result) { @@ -2510,7 +2510,7 @@ jsvalToBigInteger(JSContext* cx, // Implicitly convert val to a size value, where the size value is represented // by size_t but must also fit in a double. static bool -jsvalToSize(JSContext* cx, jsval val, bool allowString, size_t* result) +jsvalToSize(JSContext* cx, Value val, bool allowString, size_t* result) { if (!jsvalToBigInteger(cx, val, allowString, result)) return false; @@ -2559,7 +2559,7 @@ jsidToSize(JSContext* cx, jsid val, bool allowString, size_t* result) return Convert(double(*result)) == *result; } -// Implicitly convert a size value to a jsval, ensuring that the size_t value +// Implicitly convert a size value to a Value, ensuring that the size_t value // fits in a double. static bool SizeTojsval(JSContext* cx, size_t size, MutableHandleValue result) @@ -2576,7 +2576,7 @@ SizeTojsval(JSContext* cx, size_t size, MutableHandleValue result) // Forcefully convert val to IntegerType when explicitly requested. template static bool -jsvalToIntegerExplicit(jsval val, IntegerType* result) +jsvalToIntegerExplicit(Value val, IntegerType* result) { JS_STATIC_ASSERT(NumericLimits::is_exact); @@ -2605,7 +2605,7 @@ jsvalToIntegerExplicit(jsval val, IntegerType* result) // Forcefully convert val to a pointer value when explicitly requested. static bool -jsvalToPtrExplicit(JSContext* cx, jsval val, uintptr_t* result) +jsvalToPtrExplicit(JSContext* cx, Value val, uintptr_t* result) { if (val.isInt32()) { // int32_t always fits in intptr_t. If the integer is negative, cast through @@ -2858,7 +2858,7 @@ bool CanConvertTypedArrayItemTo(JSObject* baseType, JSObject* valObj, JSContext* return elementTypeCode == baseTypeCode; } -// Implicitly convert jsval 'val' to a C binary representation of CType +// Implicitly convert Value 'val' to a C binary representation of CType // 'targetType', storing the result in 'buffer'. Adequate space must be // provided in 'buffer' by the caller. This function generally does minimal // coercion between types. There are two cases in which this function is used: @@ -3320,7 +3320,7 @@ ImplicitConvert(JSContext* cx, return true; } -// Convert jsval 'val' to a C binary representation of CType 'targetType', +// Convert Value 'val' to a C binary representation of CType 'targetType', // storing the result in 'buffer'. This function is more forceful than // ImplicitConvert. static bool @@ -3822,7 +3822,7 @@ BuildDataSource(JSContext* cx, bool ConstructAbstract(JSContext* cx, unsigned argc, - jsval* vp) + Value* vp) { // Calling an abstract base class constructor is disallowed. JS_ReportError(cx, "cannot construct from abstract type"); @@ -3836,7 +3836,7 @@ ConstructAbstract(JSContext* cx, bool CType::ConstructData(JSContext* cx, unsigned argc, - jsval* vp) + Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); // get the callee object... @@ -3898,8 +3898,8 @@ CType::Create(JSContext* cx, HandleObject dataProto, TypeCode type, JSString* name_, - jsval size_, - jsval align_, + Value size_, + Value align_, ffi_type* ffiType) { RootedString name(cx, name_); @@ -3970,8 +3970,8 @@ CType::DefineBuiltin(JSContext* cx, JSObject* dataProto_, const char* name, TypeCode type, - jsval size_, - jsval align_, + Value size_, + Value align_, ffi_type* ffiType) { RootedObject typeProto(cx, typeProto_); @@ -4000,7 +4000,7 @@ void CType::Finalize(JSFreeOp* fop, JSObject* obj) { // Make sure our TypeCode slot is legit. If it's not, bail. - jsval slot = JS_GetReservedSlot(obj, SLOT_TYPECODE); + Value slot = JS_GetReservedSlot(obj, SLOT_TYPECODE); if (slot.isUndefined()) return; @@ -4057,7 +4057,7 @@ void CType::Trace(JSTracer* trc, JSObject* obj) { // Make sure our TypeCode slot is legit. If it's not, bail. - jsval slot = obj->as().getSlot(SLOT_TYPECODE); + Value slot = obj->as().getSlot(SLOT_TYPECODE); if (slot.isUndefined()) return; @@ -4112,7 +4112,7 @@ CType::GetTypeCode(JSObject* typeObj) { MOZ_ASSERT(IsCType(typeObj)); - jsval result = JS_GetReservedSlot(typeObj, SLOT_TYPECODE); + Value result = JS_GetReservedSlot(typeObj, SLOT_TYPECODE); return TypeCode(result.toInt32()); } @@ -4190,7 +4190,7 @@ CType::GetSafeSize(JSObject* obj, size_t* result) { MOZ_ASSERT(CType::IsCType(obj)); - jsval size = JS_GetReservedSlot(obj, SLOT_SIZE); + Value size = JS_GetReservedSlot(obj, SLOT_SIZE); // The "size" property can be an int, a double, or JS::UndefinedValue() // (for arrays of undefined length), and must always fit in a size_t. @@ -4212,7 +4212,7 @@ CType::GetSize(JSObject* obj) { MOZ_ASSERT(CType::IsCType(obj)); - jsval size = JS_GetReservedSlot(obj, SLOT_SIZE); + Value size = JS_GetReservedSlot(obj, SLOT_SIZE); MOZ_ASSERT(!size.isUndefined()); @@ -4230,7 +4230,7 @@ CType::IsSizeDefined(JSObject* obj) { MOZ_ASSERT(CType::IsCType(obj)); - jsval size = JS_GetReservedSlot(obj, SLOT_SIZE); + Value size = JS_GetReservedSlot(obj, SLOT_SIZE); // The "size" property can be an int, a double, or JS::UndefinedValue() // (for arrays of undefined length), and must always fit in a size_t. @@ -4243,7 +4243,7 @@ CType::GetAlignment(JSObject* obj) { MOZ_ASSERT(CType::IsCType(obj)); - jsval slot = JS_GetReservedSlot(obj, SLOT_ALIGN); + Value slot = JS_GetReservedSlot(obj, SLOT_ALIGN); return static_cast(slot.toInt32()); } @@ -4252,7 +4252,7 @@ CType::GetFFIType(JSContext* cx, JSObject* obj) { MOZ_ASSERT(CType::IsCType(obj)); - jsval slot = JS_GetReservedSlot(obj, SLOT_FFITYPE); + Value slot = JS_GetReservedSlot(obj, SLOT_FFITYPE); if (!slot.isUndefined()) { return static_cast(slot.toPrivate()); @@ -4283,7 +4283,7 @@ CType::GetName(JSContext* cx, HandleObject obj) { MOZ_ASSERT(CType::IsCType(obj)); - jsval string = JS_GetReservedSlot(obj, SLOT_NAME); + Value string = JS_GetReservedSlot(obj, SLOT_NAME); if (!string.isUndefined()) return string.toString(); @@ -4300,13 +4300,13 @@ CType::GetProtoFromCtor(JSObject* obj, CTypeProtoSlot slot) { // Get ctypes.{Pointer,Array,Struct}Type.prototype from a reserved slot // on the type constructor. - jsval protoslot = js::GetFunctionNativeReserved(obj, SLOT_FN_CTORPROTO); + Value protoslot = js::GetFunctionNativeReserved(obj, SLOT_FN_CTORPROTO); JSObject* proto = &protoslot.toObject(); MOZ_ASSERT(proto); MOZ_ASSERT(CType::IsCTypeProto(proto)); // Get the desired prototype. - jsval result = JS_GetReservedSlot(proto, slot); + Value result = JS_GetReservedSlot(proto, slot); return &result.toObject(); } @@ -4324,7 +4324,7 @@ CType::GetProtoFromType(JSContext* cx, JSObject* objArg, CTypeProtoSlot slot) MOZ_ASSERT(CType::IsCTypeProto(proto)); // Get the requested ctypes.{Pointer,Array,Struct,Function}Type.prototype. - jsval result = JS_GetReservedSlot(proto, slot); + Value result = JS_GetReservedSlot(proto, slot); MOZ_ASSERT(result.isObject()); return &result.toObject(); } @@ -4389,7 +4389,7 @@ CType::PtrGetter(JSContext* cx, JS::CallArgs args) } bool -CType::CreateArray(JSContext* cx, unsigned argc, jsval* vp) +CType::CreateArray(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); RootedObject baseType(cx, JS_THIS_OBJECT(cx, vp)); @@ -4421,7 +4421,7 @@ CType::CreateArray(JSContext* cx, unsigned argc, jsval* vp) } bool -CType::ToString(JSContext* cx, unsigned argc, jsval* vp) +CType::ToString(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); RootedObject obj(cx, JS_THIS_OBJECT(cx, vp)); @@ -4452,7 +4452,7 @@ CType::ToString(JSContext* cx, unsigned argc, jsval* vp) } bool -CType::ToSource(JSContext* cx, unsigned argc, jsval* vp) +CType::ToSource(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); JSObject* obj = JS_THIS_OBJECT(cx, vp); @@ -4486,7 +4486,7 @@ CType::HasInstance(JSContext* cx, HandleObject obj, MutableHandleValue v, bool* { MOZ_ASSERT(CType::IsCType(obj)); - jsval slot = JS_GetReservedSlot(obj, SLOT_PROTO); + Value slot = JS_GetReservedSlot(obj, SLOT_PROTO); JS::Rooted prototype(cx, &slot.toObject()); MOZ_ASSERT(prototype); MOZ_ASSERT(CData::IsCDataProto(prototype)); @@ -4521,7 +4521,7 @@ CType::GetGlobalCTypes(JSContext* cx, JSObject* objArg) MOZ_ASSERT(objTypeProto); MOZ_ASSERT(CType::IsCTypeProto(objTypeProto)); - jsval valCTypes = JS_GetReservedSlot(objTypeProto, SLOT_CTYPES); + Value valCTypes = JS_GetReservedSlot(objTypeProto, SLOT_CTYPES); MOZ_ASSERT(valCTypes.isObject()); return &valCTypes.toObject(); } @@ -4537,7 +4537,7 @@ ABI::IsABI(JSObject* obj) } bool -ABI::ToSource(JSContext* cx, unsigned argc, jsval* vp) +ABI::ToSource(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 0) { @@ -4580,7 +4580,7 @@ ABI::ToSource(JSContext* cx, unsigned argc, jsval* vp) *******************************************************************************/ bool -PointerType::Create(JSContext* cx, unsigned argc, jsval* vp) +PointerType::Create(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); // Construct and return a new PointerType object. @@ -4588,7 +4588,7 @@ PointerType::Create(JSContext* cx, unsigned argc, jsval* vp) return ArgumentLengthError(cx, "PointerType", "one", ""); } - jsval arg = args[0]; + Value arg = args[0]; RootedObject obj(cx); if (arg.isPrimitive() || !CType::IsCType(obj = &arg.toObject())) { return ArgumentTypeMismatch(cx, "", "PointerType", "a CType"); @@ -4606,7 +4606,7 @@ JSObject* PointerType::CreateInternal(JSContext* cx, HandleObject baseType) { // check if we have a cached PointerType on our base CType. - jsval slot = JS_GetReservedSlot(baseType, SLOT_PTR); + Value slot = JS_GetReservedSlot(baseType, SLOT_PTR); if (!slot.isUndefined()) return &slot.toObject(); @@ -4724,7 +4724,7 @@ PointerType::GetBaseType(JSObject* obj) { MOZ_ASSERT(CType::GetTypeCode(obj) == TYPE_pointer); - jsval type = JS_GetReservedSlot(obj, SLOT_TARGET_T); + Value type = JS_GetReservedSlot(obj, SLOT_TARGET_T); MOZ_ASSERT(!type.isNull()); return &type.toObject(); } @@ -4757,7 +4757,7 @@ PointerType::TargetTypeGetter(JSContext* cx, JS::CallArgs args) } bool -PointerType::IsNull(JSContext* cx, unsigned argc, jsval* vp) +PointerType::IsNull(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); JSObject* obj = JS_THIS_OBJECT(cx, vp); @@ -4817,14 +4817,14 @@ PointerType::OffsetBy(JSContext* cx, const CallArgs& args, int offset) } bool -PointerType::Increment(JSContext* cx, unsigned argc, jsval* vp) +PointerType::Increment(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); return OffsetBy(cx, args, 1); } bool -PointerType::Decrement(JSContext* cx, unsigned argc, jsval* vp) +PointerType::Decrement(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); return OffsetBy(cx, args, -1); @@ -4880,7 +4880,7 @@ PointerType::ContentsSetter(JSContext* cx, JS::CallArgs args) *******************************************************************************/ bool -ArrayType::Create(JSContext* cx, unsigned argc, jsval* vp) +ArrayType::Create(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); // Construct and return a new ArrayType object. @@ -5073,7 +5073,7 @@ ArrayType::GetBaseType(JSObject* obj) MOZ_ASSERT(CType::IsCType(obj)); MOZ_ASSERT(CType::GetTypeCode(obj) == TYPE_array); - jsval type = JS_GetReservedSlot(obj, SLOT_ELEMENT_T); + Value type = JS_GetReservedSlot(obj, SLOT_ELEMENT_T); MOZ_ASSERT(!type.isNull()); return &type.toObject(); } @@ -5084,7 +5084,7 @@ ArrayType::GetSafeLength(JSObject* obj, size_t* result) MOZ_ASSERT(CType::IsCType(obj)); MOZ_ASSERT(CType::GetTypeCode(obj) == TYPE_array); - jsval length = JS_GetReservedSlot(obj, SLOT_LENGTH); + Value length = JS_GetReservedSlot(obj, SLOT_LENGTH); // The "length" property can be an int, a double, or JS::UndefinedValue() // (for arrays of undefined length), and must always fit in a size_t. @@ -5107,7 +5107,7 @@ ArrayType::GetLength(JSObject* obj) MOZ_ASSERT(CType::IsCType(obj)); MOZ_ASSERT(CType::GetTypeCode(obj) == TYPE_array); - jsval length = JS_GetReservedSlot(obj, SLOT_LENGTH); + Value length = JS_GetReservedSlot(obj, SLOT_LENGTH); MOZ_ASSERT(!length.isUndefined()); @@ -5290,7 +5290,7 @@ ArrayType::Setter(JSContext* cx, HandleObject obj, HandleId idval, MutableHandle } bool -ArrayType::AddressOfElement(JSContext* cx, unsigned argc, jsval* vp) +ArrayType::AddressOfElement(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); RootedObject obj(cx, JS_THIS_OBJECT(cx, vp)); @@ -5347,7 +5347,7 @@ ArrayType::AddressOfElement(JSContext* cx, unsigned argc, jsval* vp) // For a struct field descriptor 'val' of the form { name : type }, extract // 'name' and 'type'. static JSFlatString* -ExtractStructField(JSContext* cx, jsval val, MutableHandleObject typeObj) +ExtractStructField(JSContext* cx, Value val, MutableHandleObject typeObj) { if (val.isPrimitive()) { JS_ReportError(cx, "struct field descriptors require a valid name and type"); @@ -5423,7 +5423,7 @@ AddFieldToArray(JSContext* cx, } bool -StructType::Create(JSContext* cx, unsigned argc, jsval* vp) +StructType::Create(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -5432,7 +5432,7 @@ StructType::Create(JSContext* cx, unsigned argc, jsval* vp) return ArgumentLengthError(cx, "StructType", "one or two", "s"); } - jsval name = args[0]; + Value name = args[0]; if (!name.isString()) { return ArgumentTypeMismatch(cx, "first ", "StructType", "a string"); } @@ -5717,7 +5717,7 @@ StructType::BuildFFIType(JSContext* cx, JSObject* obj) } bool -StructType::Define(JSContext* cx, unsigned argc, jsval* vp) +StructType::Define(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); RootedObject obj(cx, JS_THIS_OBJECT(cx, vp)); @@ -5738,7 +5738,7 @@ StructType::Define(JSContext* cx, unsigned argc, jsval* vp) return ArgumentLengthError(cx, "StructType.prototype.define", "one", ""); } - jsval arg = args[0]; + Value arg = args[0]; if (arg.isPrimitive()) { return ArgumentTypeMismatch(cx, "", "StructType.prototype.define", "an array"); @@ -5838,7 +5838,7 @@ StructType::GetFieldInfo(JSObject* obj) MOZ_ASSERT(CType::IsCType(obj)); MOZ_ASSERT(CType::GetTypeCode(obj) == TYPE_struct); - jsval slot = JS_GetReservedSlot(obj, SLOT_FIELDINFO); + Value slot = JS_GetReservedSlot(obj, SLOT_FIELDINFO); MOZ_ASSERT(!slot.isUndefined() && slot.toPrivate()); return static_cast(slot.toPrivate()); @@ -6007,7 +6007,7 @@ StructType::FieldSetter(JSContext* cx, unsigned argc, Value* vp) } bool -StructType::AddressOfField(JSContext* cx, unsigned argc, jsval* vp) +StructType::AddressOfField(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); RootedObject obj(cx, JS_THIS_OBJECT(cx, vp)); @@ -6088,7 +6088,7 @@ struct AutoValue }; static bool -GetABI(JSContext* cx, jsval abiType, ffi_abi* result) +GetABI(JSContext* cx, Value abiType, ffi_abi* result) { if (abiType.isPrimitive()) return false; @@ -6120,7 +6120,7 @@ GetABI(JSContext* cx, jsval abiType, ffi_abi* result) } static JSObject* -PrepareType(JSContext* cx, jsval type) +PrepareType(JSContext* cx, Value type) { if (type.isPrimitive() || !CType::IsCType(type.toObjectOrNull())) { JS_ReportError(cx, "not a ctypes type"); @@ -6156,7 +6156,7 @@ PrepareType(JSContext* cx, jsval type) } static JSObject* -PrepareReturnType(JSContext* cx, jsval type) +PrepareReturnType(JSContext* cx, Value type) { if (type.isPrimitive() || !CType::IsCType(type.toObjectOrNull())) { JS_ReportError(cx, "not a ctypes type"); @@ -6184,7 +6184,7 @@ PrepareReturnType(JSContext* cx, jsval type) } static MOZ_ALWAYS_INLINE bool -IsEllipsis(JSContext* cx, jsval v, bool* isEllipsis) +IsEllipsis(JSContext* cx, Value v, bool* isEllipsis) { *isEllipsis = false; if (!v.isString()) @@ -6365,7 +6365,7 @@ CreateFunctionInfo(JSContext* cx, } bool -FunctionType::Create(JSContext* cx, unsigned argc, jsval* vp) +FunctionType::Create(JSContext* cx, unsigned argc, Value* vp) { // Construct and return a new FunctionType object. CallArgs args = CallArgsFromVp(argc, vp); @@ -6377,7 +6377,7 @@ FunctionType::Create(JSContext* cx, unsigned argc, jsval* vp) RootedObject arrayObj(cx, nullptr); if (args.length() == 3) { - // Prepare an array of jsvals for the arguments. + // Prepare an array of Values for the arguments. if (args[2].isObject()) arrayObj = &args[2].toObject(); if (!arrayObj || !JS_IsArrayObject(cx, arrayObj)) { @@ -6451,7 +6451,7 @@ FunctionType::ConstructData(JSContext* cx, HandleObject dataObj, HandleObject fnObj, HandleObject thisObj, - jsval errVal) + Value errVal) { MOZ_ASSERT(CType::GetTypeCode(typeObj) == TYPE_function); @@ -6522,7 +6522,7 @@ ConvertArgument(JSContext* cx, bool FunctionType::Call(JSContext* cx, unsigned argc, - jsval* vp) + Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); // get the callee object... @@ -6554,7 +6554,7 @@ FunctionType::Call(JSContext* cx, } // Check if we have a Library object. If we do, make sure it's open. - jsval slot = JS_GetReservedSlot(obj, SLOT_REFERENT); + Value slot = JS_GetReservedSlot(obj, SLOT_REFERENT); if (!slot.isUndefined() && Library::IsLibrary(&slot.toObject())) { PRLibrary* library = Library::GetLibrary(&slot.toObject()); if (!library) { @@ -6691,7 +6691,7 @@ FunctionType::GetFunctionInfo(JSObject* obj) MOZ_ASSERT(CType::IsCType(obj)); MOZ_ASSERT(CType::GetTypeCode(obj) == TYPE_function); - jsval slot = JS_GetReservedSlot(obj, SLOT_FNINFO); + Value slot = JS_GetReservedSlot(obj, SLOT_FNINFO); MOZ_ASSERT(!slot.isUndefined() && slot.toPrivate()); return static_cast(slot.toPrivate()); @@ -6774,7 +6774,7 @@ CClosure::Create(JSContext* cx, HandleObject typeObj, HandleObject fnObj, HandleObject thisObj, - jsval errVal_, + Value errVal_, PRFuncPtr* fnptr) { RootedValue errVal(cx, errVal_); @@ -6868,7 +6868,7 @@ void CClosure::Trace(JSTracer* trc, JSObject* obj) { // Make sure our ClosureInfo slot is legit. If it's not, bail. - jsval slot = JS_GetReservedSlot(obj, SLOT_CLOSUREINFO); + Value slot = JS_GetReservedSlot(obj, SLOT_CLOSUREINFO); if (slot.isUndefined()) return; @@ -6886,7 +6886,7 @@ void CClosure::Finalize(JSFreeOp* fop, JSObject* obj) { // Make sure our ClosureInfo slot is legit. If it's not, bail. - jsval slot = JS_GetReservedSlot(obj, SLOT_CLOSUREINFO); + Value slot = JS_GetReservedSlot(obj, SLOT_CLOSUREINFO); if (slot.isUndefined()) return; @@ -7069,7 +7069,7 @@ CData::Create(JSContext* cx, MOZ_ASSERT_IF(refObj && CData::IsCData(refObj), !ownResult); // Get the 'prototype' property from the type. - jsval slot = JS_GetReservedSlot(typeObj, SLOT_PROTO); + Value slot = JS_GetReservedSlot(typeObj, SLOT_PROTO); MOZ_ASSERT(slot.isObject()); RootedObject proto(cx, &slot.toObject()); @@ -7126,7 +7126,7 @@ void CData::Finalize(JSFreeOp* fop, JSObject* obj) { // Delete our buffer, and the data it contains if we own it. - jsval slot = JS_GetReservedSlot(obj, SLOT_OWNS); + Value slot = JS_GetReservedSlot(obj, SLOT_OWNS); if (slot.isUndefined()) return; @@ -7147,7 +7147,7 @@ CData::GetCType(JSObject* dataObj) { MOZ_ASSERT(CData::IsCData(dataObj)); - jsval slot = JS_GetReservedSlot(dataObj, SLOT_CTYPE); + Value slot = JS_GetReservedSlot(dataObj, SLOT_CTYPE); JSObject* typeObj = slot.toObjectOrNull(); MOZ_ASSERT(CType::IsCType(typeObj)); return typeObj; @@ -7158,7 +7158,7 @@ CData::GetData(JSObject* dataObj) { MOZ_ASSERT(CData::IsCData(dataObj)); - jsval slot = JS_GetReservedSlot(dataObj, SLOT_DATA); + Value slot = JS_GetReservedSlot(dataObj, SLOT_DATA); void** buffer = static_cast(slot.toPrivate()); MOZ_ASSERT(buffer); @@ -7204,7 +7204,7 @@ CData::ValueSetter(JSContext* cx, JS::CallArgs args) } bool -CData::Address(JSContext* cx, unsigned argc, jsval* vp) +CData::Address(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 0) { @@ -7238,7 +7238,7 @@ CData::Address(JSContext* cx, unsigned argc, jsval* vp) } bool -CData::Cast(JSContext* cx, unsigned argc, jsval* vp) +CData::Cast(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 2) { @@ -7276,7 +7276,7 @@ CData::Cast(JSContext* cx, unsigned argc, jsval* vp) } bool -CData::GetRuntime(JSContext* cx, unsigned argc, jsval* vp) +CData::GetRuntime(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 1) { @@ -7307,7 +7307,7 @@ CData::GetRuntime(JSContext* cx, unsigned argc, jsval* vp) typedef JS::TwoByteCharsZ (*InflateUTF8Method)(JSContext*, const JS::UTF8Chars, size_t*); static bool -ReadStringCommon(JSContext* cx, InflateUTF8Method inflateUTF8, unsigned argc, jsval* vp) +ReadStringCommon(JSContext* cx, InflateUTF8Method inflateUTF8, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 0) { @@ -7394,13 +7394,13 @@ ReadStringCommon(JSContext* cx, InflateUTF8Method inflateUTF8, unsigned argc, js } bool -CData::ReadString(JSContext* cx, unsigned argc, jsval* vp) +CData::ReadString(JSContext* cx, unsigned argc, Value* vp) { return ReadStringCommon(cx, JS::UTF8CharsToNewTwoByteCharsZ, argc, vp); } bool -CData::ReadStringReplaceMalformed(JSContext* cx, unsigned argc, jsval* vp) +CData::ReadStringReplaceMalformed(JSContext* cx, unsigned argc, Value* vp) { return ReadStringCommon(cx, JS::LossyUTF8CharsToNewTwoByteCharsZ, argc, vp); } @@ -7426,7 +7426,7 @@ CData::GetSourceString(JSContext* cx, HandleObject typeObj, void* data) } bool -CData::ToSource(JSContext* cx, unsigned argc, jsval* vp) +CData::ToSource(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 0) { @@ -7475,7 +7475,7 @@ CData::LastErrorGetter(JSContext* cx, JS::CallArgs args) #endif // defined(XP_WIN) bool -CDataFinalizer::Methods::ToSource(JSContext* cx, unsigned argc, jsval* vp) +CDataFinalizer::Methods::ToSource(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); RootedObject objThis(cx, JS_THIS_OBJECT(cx, vp)); @@ -7507,7 +7507,7 @@ CDataFinalizer::Methods::ToSource(JSContext* cx, unsigned argc, jsval* vp) } AppendString(source, srcValue); AppendString(source, ", "); - jsval valCodePtrType = JS_GetReservedSlot(objThis, + Value valCodePtrType = JS_GetReservedSlot(objThis, SLOT_DATAFINALIZER_CODETYPE); if (valCodePtrType.isPrimitive()) { return false; @@ -7534,7 +7534,7 @@ CDataFinalizer::Methods::ToSource(JSContext* cx, unsigned argc, jsval* vp) } bool -CDataFinalizer::Methods::ToString(JSContext* cx, unsigned argc, jsval* vp) +CDataFinalizer::Methods::ToString(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); JSObject* objThis = JS_THIS_OBJECT(cx, vp); @@ -7578,7 +7578,7 @@ CDataFinalizer::GetCType(JSContext* cx, JSObject* obj) { MOZ_ASSERT(IsCDataFinalizer(obj)); - jsval valData = JS_GetReservedSlot(obj, + Value valData = JS_GetReservedSlot(obj, SLOT_DATAFINALIZER_VALTYPE); if (valData.isUndefined()) { return nullptr; @@ -7640,7 +7640,7 @@ CDataFinalizer::GetValue(JSContext* cx, JSObject* obj, MutableHandleValue aResul * CData functions are initialized during creation. */ bool -CDataFinalizer::Construct(JSContext* cx, unsigned argc, jsval* vp) +CDataFinalizer::Construct(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); RootedObject objSelf(cx, &args.callee()); @@ -7868,7 +7868,7 @@ CDataFinalizer::CallFinalizer(CDataFinalizer::Private* p, * strong references. */ bool -CDataFinalizer::Methods::Forget(JSContext* cx, unsigned argc, jsval* vp) +CDataFinalizer::Methods::Forget(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 0) { @@ -7916,7 +7916,7 @@ CDataFinalizer::Methods::Forget(JSContext* cx, unsigned argc, jsval* vp) * strong references. */ bool -CDataFinalizer::Methods::Dispose(JSContext* cx, unsigned argc, jsval* vp) +CDataFinalizer::Methods::Dispose(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 0) { @@ -7940,14 +7940,14 @@ CDataFinalizer::Methods::Dispose(JSContext* cx, unsigned argc, jsval* vp) return false; } - jsval valType = JS_GetReservedSlot(obj, SLOT_DATAFINALIZER_VALTYPE); + Value valType = JS_GetReservedSlot(obj, SLOT_DATAFINALIZER_VALTYPE); MOZ_ASSERT(valType.isObject()); JSObject* objCTypes = CType::GetGlobalCTypes(cx, &valType.toObject()); if (!objCTypes) return false; - jsval valCodePtrType = JS_GetReservedSlot(obj, SLOT_DATAFINALIZER_CODETYPE); + Value valCodePtrType = JS_GetReservedSlot(obj, SLOT_DATAFINALIZER_CODETYPE); MOZ_ASSERT(valCodePtrType.isObject()); JSObject* objCodePtrType = &valCodePtrType.toObject(); @@ -8072,7 +8072,7 @@ Int64Base::Construct(JSContext* cx, void Int64Base::Finalize(JSFreeOp* fop, JSObject* obj) { - jsval slot = JS_GetReservedSlot(obj, SLOT_INT64); + Value slot = JS_GetReservedSlot(obj, SLOT_INT64); if (slot.isUndefined()) return; @@ -8083,7 +8083,7 @@ uint64_t Int64Base::GetInt(JSObject* obj) { MOZ_ASSERT(Int64::IsInt64(obj) || UInt64::IsUInt64(obj)); - jsval slot = JS_GetReservedSlot(obj, SLOT_INT64); + Value slot = JS_GetReservedSlot(obj, SLOT_INT64); return *static_cast(slot.toPrivate()); } @@ -8104,7 +8104,7 @@ Int64Base::ToString(JSContext* cx, int radix = 10; if (args.length() == 1) { - jsval arg = args[0]; + Value arg = args[0]; if (arg.isInt32()) radix = arg.toInt32(); if (!arg.isInt32() || radix < 2 || radix > 36) { @@ -8165,7 +8165,7 @@ Int64Base::ToSource(JSContext* cx, bool Int64::Construct(JSContext* cx, unsigned argc, - jsval* vp) + Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -8201,7 +8201,7 @@ Int64::IsInt64(JSObject* obj) } bool -Int64::ToString(JSContext* cx, unsigned argc, jsval* vp) +Int64::ToString(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); JSObject* obj = JS_THIS_OBJECT(cx, vp); @@ -8216,7 +8216,7 @@ Int64::ToString(JSContext* cx, unsigned argc, jsval* vp) } bool -Int64::ToSource(JSContext* cx, unsigned argc, jsval* vp) +Int64::ToSource(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); JSObject* obj = JS_THIS_OBJECT(cx, vp); @@ -8231,7 +8231,7 @@ Int64::ToSource(JSContext* cx, unsigned argc, jsval* vp) } bool -Int64::Compare(JSContext* cx, unsigned argc, jsval* vp) +Int64::Compare(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 2) { @@ -8265,7 +8265,7 @@ Int64::Compare(JSContext* cx, unsigned argc, jsval* vp) #define INT64_HI(i) ((i) >> 32) bool -Int64::Lo(JSContext* cx, unsigned argc, jsval* vp) +Int64::Lo(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 1) { @@ -8284,7 +8284,7 @@ Int64::Lo(JSContext* cx, unsigned argc, jsval* vp) } bool -Int64::Hi(JSContext* cx, unsigned argc, jsval* vp) +Int64::Hi(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 1) { @@ -8303,7 +8303,7 @@ Int64::Hi(JSContext* cx, unsigned argc, jsval* vp) } bool -Int64::Join(JSContext* cx, unsigned argc, jsval* vp) +Int64::Join(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 2) { @@ -8322,7 +8322,7 @@ Int64::Join(JSContext* cx, unsigned argc, jsval* vp) // Get Int64.prototype from the function's reserved slot. JSObject* callee = &args.callee(); - jsval slot = js::GetFunctionNativeReserved(callee, SLOT_FN_INT64PROTO); + Value slot = js::GetFunctionNativeReserved(callee, SLOT_FN_INT64PROTO); RootedObject proto(cx, &slot.toObject()); MOZ_ASSERT(JS_GetClass(proto) == &sInt64ProtoClass); @@ -8337,7 +8337,7 @@ Int64::Join(JSContext* cx, unsigned argc, jsval* vp) bool UInt64::Construct(JSContext* cx, unsigned argc, - jsval* vp) + Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -8373,7 +8373,7 @@ UInt64::IsUInt64(JSObject* obj) } bool -UInt64::ToString(JSContext* cx, unsigned argc, jsval* vp) +UInt64::ToString(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); JSObject* obj = JS_THIS_OBJECT(cx, vp); @@ -8388,7 +8388,7 @@ UInt64::ToString(JSContext* cx, unsigned argc, jsval* vp) } bool -UInt64::ToSource(JSContext* cx, unsigned argc, jsval* vp) +UInt64::ToSource(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); JSObject* obj = JS_THIS_OBJECT(cx, vp); @@ -8403,7 +8403,7 @@ UInt64::ToSource(JSContext* cx, unsigned argc, jsval* vp) } bool -UInt64::Compare(JSContext* cx, unsigned argc, jsval* vp) +UInt64::Compare(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 2) { @@ -8433,7 +8433,7 @@ UInt64::Compare(JSContext* cx, unsigned argc, jsval* vp) } bool -UInt64::Lo(JSContext* cx, unsigned argc, jsval* vp) +UInt64::Lo(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 1) { @@ -8452,7 +8452,7 @@ UInt64::Lo(JSContext* cx, unsigned argc, jsval* vp) } bool -UInt64::Hi(JSContext* cx, unsigned argc, jsval* vp) +UInt64::Hi(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 1) { @@ -8471,7 +8471,7 @@ UInt64::Hi(JSContext* cx, unsigned argc, jsval* vp) } bool -UInt64::Join(JSContext* cx, unsigned argc, jsval* vp) +UInt64::Join(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 2) { @@ -8490,7 +8490,7 @@ UInt64::Join(JSContext* cx, unsigned argc, jsval* vp) // Get UInt64.prototype from the function's reserved slot. JSObject* callee = &args.callee(); - jsval slot = js::GetFunctionNativeReserved(callee, SLOT_FN_INT64PROTO); + Value slot = js::GetFunctionNativeReserved(callee, SLOT_FN_INT64PROTO); RootedObject proto(cx, &slot.toObject()); MOZ_ASSERT(JS_GetClass(proto) == &sUInt64ProtoClass); diff --git a/js/src/ctypes/CTypes.h b/js/src/ctypes/CTypes.h index 01b0e79e51f8..280cceb39c03 100644 --- a/js/src/ctypes/CTypes.h +++ b/js/src/ctypes/CTypes.h @@ -294,7 +294,7 @@ struct FunctionInfo ffi_cif mCIF; // Calling convention of the function. Convert to ffi_abi using GetABI - // and OBJECT_TO_JSVAL. Stored as a JSObject* for ease of tracing. + // and ObjectValue. Stored as a JSObject* for ease of tracing. JS::Heap mABI; // The CType of the value returned by the function. @@ -351,8 +351,8 @@ const JSCTypesCallbacks* GetCallbacks(JSObject* obj); enum CTypesGlobalSlot { SLOT_CALLBACKS = 0, // pointer to JSCTypesCallbacks struct - SLOT_ERRNO = 1, // jsval for latest |errno| - SLOT_LASTERROR = 2, // jsval for latest |GetLastError|, used only with Windows + SLOT_ERRNO = 1, // Value for latest |errno| + SLOT_LASTERROR = 2, // Value for latest |GetLastError|, used only with Windows CTYPESGLOBAL_SLOTS }; @@ -402,7 +402,7 @@ enum CDataSlot { SLOT_CTYPE = 0, // CType object representing the underlying type SLOT_REFERENT = 1, // JSObject this object must keep alive, if any SLOT_DATA = 2, // pointer to a buffer containing the binary data - SLOT_OWNS = 3, // JSVAL_TRUE if this CData owns its own buffer + SLOT_OWNS = 3, // TrueValue() if this CData owns its own buffer SLOT_FUNNAME = 4, // JSString representing the function name CDATA_SLOTS }; @@ -443,11 +443,11 @@ enum Int64FunctionSlot { namespace CType { JSObject* Create(JSContext* cx, HandleObject typeProto, HandleObject dataProto, - TypeCode type, JSString* name, jsval size, jsval align, ffi_type* ffiType); + TypeCode type, JSString* name, Value size, Value align, ffi_type* ffiType); JSObject* DefineBuiltin(JSContext* cx, HandleObject ctypesObj, const char* propName, JSObject* typeProto, JSObject* dataProto, const char* name, TypeCode type, - jsval size, jsval align, ffi_type* ffiType); + Value size, Value align, ffi_type* ffiType); bool IsCType(JSObject* obj); bool IsCTypeProto(JSObject* obj); @@ -505,7 +505,7 @@ namespace FunctionType { namespace CClosure { JSObject* Create(JSContext* cx, HandleObject typeObj, HandleObject fnObj, - HandleObject thisObj, jsval errVal, PRFuncPtr* fnptr); + HandleObject thisObj, Value errVal, PRFuncPtr* fnptr); } // namespace CClosure namespace CData { @@ -519,9 +519,9 @@ namespace CData { bool IsCDataProto(JSObject* obj); // Attached by JSAPI as the function 'ctypes.cast' - bool Cast(JSContext* cx, unsigned argc, jsval* vp); + bool Cast(JSContext* cx, unsigned argc, Value* vp); // Attached by JSAPI as the function 'ctypes.getRuntime' - bool GetRuntime(JSContext* cx, unsigned argc, jsval* vp); + bool GetRuntime(JSContext* cx, unsigned argc, Value* vp); } // namespace CData namespace Int64 { diff --git a/js/src/ctypes/Library.cpp b/js/src/ctypes/Library.cpp index 3578b2feffc5..19895d8b6ff3 100644 --- a/js/src/ctypes/Library.cpp +++ b/js/src/ctypes/Library.cpp @@ -22,8 +22,8 @@ namespace Library { static void Finalize(JSFreeOp* fop, JSObject* obj); - static bool Close(JSContext* cx, unsigned argc, jsval* vp); - static bool Declare(JSContext* cx, unsigned argc, jsval* vp); + static bool Close(JSContext* cx, unsigned argc, Value* vp); + static bool Declare(JSContext* cx, unsigned argc, Value* vp); } // namespace Library /******************************************************************************* @@ -49,7 +49,7 @@ static const JSFunctionSpec sLibraryFunctions[] = { }; bool -Library::Name(JSContext* cx, unsigned argc, jsval* vp) +Library::Name(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 1) { @@ -81,7 +81,7 @@ Library::Name(JSContext* cx, unsigned argc, jsval* vp) } JSObject* -Library::Create(JSContext* cx, jsval path_, const JSCTypesCallbacks* callbacks) +Library::Create(JSContext* cx, Value path_, const JSCTypesCallbacks* callbacks) { RootedValue path(cx, path_); RootedObject libraryObj(cx, JS_NewObject(cx, &sLibraryClass)); @@ -182,7 +182,7 @@ Library::GetLibrary(JSObject* obj) { MOZ_ASSERT(IsLibrary(obj)); - jsval slot = JS_GetReservedSlot(obj, SLOT_LIBRARY); + Value slot = JS_GetReservedSlot(obj, SLOT_LIBRARY); return static_cast(slot.toPrivate()); } @@ -201,7 +201,7 @@ Library::Finalize(JSFreeOp* fop, JSObject* obj) } bool -Library::Open(JSContext* cx, unsigned argc, jsval* vp) +Library::Open(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); JSObject* ctypesObj = JS_THIS_OBJECT(cx, vp); @@ -226,7 +226,7 @@ Library::Open(JSContext* cx, unsigned argc, jsval* vp) } bool -Library::Close(JSContext* cx, unsigned argc, jsval* vp) +Library::Close(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); JSObject* obj = JS_THIS_OBJECT(cx, vp); @@ -251,7 +251,7 @@ Library::Close(JSContext* cx, unsigned argc, jsval* vp) } bool -Library::Declare(JSContext* cx, unsigned argc, jsval* vp) +Library::Declare(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); RootedObject obj(cx, JS_THIS_OBJECT(cx, vp)); From fd94e85bdb781c0c80965bfef552b5b840fa8788 Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Sat, 18 Jul 2015 21:45:35 +0200 Subject: [PATCH 35/69] Bug 1184564 part 4 - Use Value instead of jsval in SpiderMonkey. r=evilpie --- js/src/builtin/AtomicsObject.h | 2 +- js/src/builtin/ReflectParse.cpp | 2 +- js/src/builtin/SIMD.h | 2 +- js/src/builtin/TestingFunctions.cpp | 122 +++++++++--------- js/src/gdb/tests/test-Root.cpp | 2 +- js/src/jsapi-tests/testChromeBuffer.cpp | 2 +- js/src/jsapi-tests/testClassGetter.cpp | 6 +- js/src/jsapi-tests/testContexts.cpp | 2 +- .../testDefineGetterSetterNonEnumerable.cpp | 2 +- js/src/jsapi-tests/testNewObject.cpp | 2 +- .../testObjectEmulatingUndefined.cpp | 2 +- js/src/jsapi-tests/testOps.cpp | 2 +- js/src/jsapi-tests/testParseJSON.cpp | 2 +- js/src/jsapi-tests/testProfileStrings.cpp | 10 +- js/src/jsapi-tests/tests.h | 4 +- js/src/jsapi.cpp | 22 ++-- js/src/jsapi.h | 18 +-- js/src/jsobj.h | 4 +- js/src/jsscript.cpp | 14 +- js/src/perf/jsperf.cpp | 14 +- js/src/proxy/ScriptedDirectProxyHandler.h | 4 +- js/src/shell/OSObject.cpp | 12 +- js/src/shell/js.cpp | 104 +++++++-------- js/src/vm/StructuredClone.cpp | 6 +- js/src/vm/Value.cpp | 8 +- 25 files changed, 185 insertions(+), 185 deletions(-) diff --git a/js/src/builtin/AtomicsObject.h b/js/src/builtin/AtomicsObject.h index 9cf0a0f6daaf..b07b4ae60f38 100644 --- a/js/src/builtin/AtomicsObject.h +++ b/js/src/builtin/AtomicsObject.h @@ -17,7 +17,7 @@ class AtomicsObject : public JSObject public: static const Class class_; static JSObject* initClass(JSContext* cx, Handle global); - static bool toString(JSContext* cx, unsigned int argc, jsval* vp); + static bool toString(JSContext* cx, unsigned int argc, Value* vp); // Defined return values for futexWait. // The error values must be negative because APIs such as futexWaitOrRequeue diff --git a/js/src/builtin/ReflectParse.cpp b/js/src/builtin/ReflectParse.cpp index ae1c03cf11ac..e0b54ad92b42 100644 --- a/js/src/builtin/ReflectParse.cpp +++ b/js/src/builtin/ReflectParse.cpp @@ -3621,7 +3621,7 @@ ASTSerializer::functionBody(ParseNode* pn, TokenPos* pos, MutableHandleValue dst } static bool -reflect_parse(JSContext* cx, uint32_t argc, jsval* vp) +reflect_parse(JSContext* cx, uint32_t argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); diff --git a/js/src/builtin/SIMD.h b/js/src/builtin/SIMD.h index 0682aacf623e..4b8b80d3d123 100644 --- a/js/src/builtin/SIMD.h +++ b/js/src/builtin/SIMD.h @@ -361,7 +361,7 @@ class SIMDObject : public JSObject public: static const Class class_; static JSObject* initClass(JSContext* cx, Handle global); - static bool toString(JSContext* cx, unsigned int argc, jsval* vp); + static bool toString(JSContext* cx, unsigned int argc, Value* vp); }; // These classes exist for use with templates below. diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp index 3aa278b770bf..b7c38fa568ab 100644 --- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -49,7 +49,7 @@ using mozilla::UniquePtr; static bool fuzzingSafe = false; static bool -GetBuildConfiguration(JSContext* cx, unsigned argc, jsval* vp) +GetBuildConfiguration(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); RootedObject info(cx, JS_NewPlainObject(cx)); @@ -229,7 +229,7 @@ GetBuildConfiguration(JSContext* cx, unsigned argc, jsval* vp) } static bool -GC(JSContext* cx, unsigned argc, jsval* vp) +GC(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -285,7 +285,7 @@ GC(JSContext* cx, unsigned argc, jsval* vp) } static bool -MinorGC(JSContext* cx, unsigned argc, jsval* vp) +MinorGC(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.get(0) == BooleanValue(true)) @@ -459,7 +459,7 @@ IsRelazifiableFunction(JSContext* cx, unsigned argc, Value* vp) } static bool -InternalConst(JSContext* cx, unsigned argc, jsval* vp) +InternalConst(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() == 0) { @@ -484,7 +484,7 @@ InternalConst(JSContext* cx, unsigned argc, jsval* vp) } static bool -GCPreserveCode(JSContext* cx, unsigned argc, jsval* vp) +GCPreserveCode(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -585,7 +585,7 @@ SelectForGC(JSContext* cx, unsigned argc, Value* vp) } static bool -VerifyPreBarriers(JSContext* cx, unsigned argc, jsval* vp) +VerifyPreBarriers(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -601,7 +601,7 @@ VerifyPreBarriers(JSContext* cx, unsigned argc, jsval* vp) } static bool -VerifyPostBarriers(JSContext* cx, unsigned argc, jsval* vp) +VerifyPostBarriers(JSContext* cx, unsigned argc, Value* vp) { // This is a no-op since the post barrier verifier was removed. CallArgs args = CallArgsFromVp(argc, vp); @@ -615,7 +615,7 @@ VerifyPostBarriers(JSContext* cx, unsigned argc, jsval* vp) } static bool -GCState(JSContext* cx, unsigned argc, jsval* vp) +GCState(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -646,7 +646,7 @@ GCState(JSContext* cx, unsigned argc, jsval* vp) } static bool -DeterministicGC(JSContext* cx, unsigned argc, jsval* vp) +DeterministicGC(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -750,7 +750,7 @@ AbortGC(JSContext* cx, unsigned argc, Value* vp) } static bool -ValidateGC(JSContext* cx, unsigned argc, jsval* vp) +ValidateGC(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -766,7 +766,7 @@ ValidateGC(JSContext* cx, unsigned argc, jsval* vp) } static bool -FullCompartmentChecks(JSContext* cx, unsigned argc, jsval* vp) +FullCompartmentChecks(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -782,7 +782,7 @@ FullCompartmentChecks(JSContext* cx, unsigned argc, jsval* vp) } static bool -NondeterministicGetWeakMapKeys(JSContext* cx, unsigned argc, jsval* vp) +NondeterministicGetWeakMapKeys(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -830,7 +830,7 @@ class HasChildTracer : public JS::CallbackTracer }; static bool -HasChild(JSContext* cx, unsigned argc, jsval* vp) +HasChild(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); RootedValue parent(cx, args.get(0)); @@ -848,7 +848,7 @@ HasChild(JSContext* cx, unsigned argc, jsval* vp) } static bool -SetSavedStacksRNGState(JSContext* cx, unsigned argc, jsval* vp) +SetSavedStacksRNGState(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (!args.requireAtLeast(cx, "setSavedStacksRNGState", 1)) @@ -863,7 +863,7 @@ SetSavedStacksRNGState(JSContext* cx, unsigned argc, jsval* vp) } static bool -GetSavedFrameCount(JSContext* cx, unsigned argc, jsval* vp) +GetSavedFrameCount(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); args.rval().setNumber(cx->compartment()->savedStacks().count()); @@ -871,7 +871,7 @@ GetSavedFrameCount(JSContext* cx, unsigned argc, jsval* vp) } static bool -SaveStack(JSContext* cx, unsigned argc, jsval* vp) +SaveStack(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -918,7 +918,7 @@ SaveStack(JSContext* cx, unsigned argc, jsval* vp) } static bool -CallFunctionWithAsyncStack(JSContext* cx, unsigned argc, jsval* vp) +CallFunctionWithAsyncStack(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -949,14 +949,14 @@ CallFunctionWithAsyncStack(JSContext* cx, unsigned argc, jsval* vp) } static bool -EnableTrackAllocations(JSContext* cx, unsigned argc, jsval* vp) +EnableTrackAllocations(JSContext* cx, unsigned argc, Value* vp) { SetObjectMetadataCallback(cx, SavedStacksMetadataCallback); return true; } static bool -DisableTrackAllocations(JSContext* cx, unsigned argc, jsval* vp) +DisableTrackAllocations(JSContext* cx, unsigned argc, Value* vp) { SetObjectMetadataCallback(cx, nullptr); return true; @@ -964,7 +964,7 @@ DisableTrackAllocations(JSContext* cx, unsigned argc, jsval* vp) #if defined(DEBUG) || defined(JS_OOM_BREAKPOINT) static bool -OOMAfterAllocations(JSContext* cx, unsigned argc, jsval* vp) +OOMAfterAllocations(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 1) { @@ -982,7 +982,7 @@ OOMAfterAllocations(JSContext* cx, unsigned argc, jsval* vp) } static bool -OOMAtAllocation(JSContext* cx, unsigned argc, jsval* vp) +OOMAtAllocation(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 1) { @@ -1000,7 +1000,7 @@ OOMAtAllocation(JSContext* cx, unsigned argc, jsval* vp) } static bool -ResetOOMFailure(JSContext* cx, unsigned argc, jsval* vp) +ResetOOMFailure(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); args.rval().setBoolean(OOM_counter >= OOM_maxAllocations); @@ -1014,7 +1014,7 @@ static const js::Class FakePromiseClass = { }; static bool -MakeFakePromise(JSContext* cx, unsigned argc, jsval* vp) +MakeFakePromise(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -1028,7 +1028,7 @@ MakeFakePromise(JSContext* cx, unsigned argc, jsval* vp) } static bool -SettleFakePromise(JSContext* cx, unsigned argc, jsval* vp) +SettleFakePromise(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (!args.requireAtLeast(cx, "settleFakePromise", 1)) @@ -1065,7 +1065,7 @@ static const JSClass FinalizeCounterClass = { }; static bool -MakeFinalizeObserver(JSContext* cx, unsigned argc, jsval* vp) +MakeFinalizeObserver(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -1078,7 +1078,7 @@ MakeFinalizeObserver(JSContext* cx, unsigned argc, jsval* vp) } static bool -FinalizeCount(JSContext* cx, unsigned argc, jsval* vp) +FinalizeCount(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); args.rval().setInt32(finalizeCount); @@ -1144,7 +1144,7 @@ DumpHeap(JSContext* cx, unsigned argc, Value* vp) } static bool -Terminate(JSContext* cx, unsigned arg, jsval* vp) +Terminate(JSContext* cx, unsigned arg, Value* vp) { #ifdef JS_MORE_DETERMINISTIC // Print a message to stderr in more-deterministic builds to help jsfunfuzz @@ -1161,7 +1161,7 @@ static ProfileEntry SPS_PROFILING_STACK[SPS_PROFILING_STACK_MAX_SIZE]; static uint32_t SPS_PROFILING_STACK_SIZE = 0; static bool -EnableSPSProfiling(JSContext* cx, unsigned argc, jsval* vp) +EnableSPSProfiling(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -1179,7 +1179,7 @@ EnableSPSProfiling(JSContext* cx, unsigned argc, jsval* vp) } static bool -EnableSPSProfilingWithSlowAssertions(JSContext* cx, unsigned argc, jsval* vp) +EnableSPSProfilingWithSlowAssertions(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); args.rval().setUndefined(); @@ -1208,7 +1208,7 @@ EnableSPSProfilingWithSlowAssertions(JSContext* cx, unsigned argc, jsval* vp) } static bool -DisableSPSProfiling(JSContext* cx, unsigned argc, jsval* vp) +DisableSPSProfiling(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (cx->runtime()->spsProfiler.installed()) @@ -1218,7 +1218,7 @@ DisableSPSProfiling(JSContext* cx, unsigned argc, jsval* vp) } static bool -ReadSPSProfilingStack(JSContext* cx, unsigned argc, jsval* vp) +ReadSPSProfilingStack(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); args.rval().setUndefined(); @@ -1304,7 +1304,7 @@ ReadSPSProfilingStack(JSContext* cx, unsigned argc, jsval* vp) } static bool -EnableOsiPointRegisterChecks(JSContext*, unsigned argc, jsval* vp) +EnableOsiPointRegisterChecks(JSContext*, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); #ifdef CHECK_OSIPOINT_REGISTERS @@ -1315,7 +1315,7 @@ EnableOsiPointRegisterChecks(JSContext*, unsigned argc, jsval* vp) } static bool -DisplayName(JSContext* cx, unsigned argc, jsval* vp) +DisplayName(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (!args.get(0).isObject() || !args[0].toObject().is()) { @@ -1376,7 +1376,7 @@ ShellObjectMetadataCallback(JSContext* cx, JSObject*) } static bool -SetObjectMetadataCallback(JSContext* cx, unsigned argc, jsval* vp) +SetObjectMetadataCallback(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -1388,7 +1388,7 @@ SetObjectMetadataCallback(JSContext* cx, unsigned argc, jsval* vp) } static bool -GetObjectMetadata(JSContext* cx, unsigned argc, jsval* vp) +GetObjectMetadata(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 1 || !args[0].isObject()) { @@ -1401,7 +1401,7 @@ GetObjectMetadata(JSContext* cx, unsigned argc, jsval* vp) } bool -js::testingFunc_bailout(JSContext* cx, unsigned argc, jsval* vp) +js::testingFunc_bailout(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -1411,7 +1411,7 @@ js::testingFunc_bailout(JSContext* cx, unsigned argc, jsval* vp) } bool -js::testingFunc_inJit(JSContext* cx, unsigned argc, jsval* vp) +js::testingFunc_inJit(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -1439,7 +1439,7 @@ js::testingFunc_inJit(JSContext* cx, unsigned argc, jsval* vp) } bool -js::testingFunc_inIon(JSContext* cx, unsigned argc, jsval* vp) +js::testingFunc_inIon(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -1476,7 +1476,7 @@ js::testingFunc_inIon(JSContext* cx, unsigned argc, jsval* vp) } bool -js::testingFunc_assertFloat32(JSContext* cx, unsigned argc, jsval* vp) +js::testingFunc_assertFloat32(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 2) { @@ -1490,7 +1490,7 @@ js::testingFunc_assertFloat32(JSContext* cx, unsigned argc, jsval* vp) } static bool -TestingFunc_assertJitStackInvariants(JSContext* cx, unsigned argc, jsval* vp) +TestingFunc_assertJitStackInvariants(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -1500,7 +1500,7 @@ TestingFunc_assertJitStackInvariants(JSContext* cx, unsigned argc, jsval* vp) } bool -js::testingFunc_assertRecoveredOnBailout(JSContext* cx, unsigned argc, jsval* vp) +js::testingFunc_assertRecoveredOnBailout(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 2) { @@ -1514,7 +1514,7 @@ js::testingFunc_assertRecoveredOnBailout(JSContext* cx, unsigned argc, jsval* vp } static bool -SetJitCompilerOption(JSContext* cx, unsigned argc, jsval* vp) +SetJitCompilerOption(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); RootedObject callee(cx, &args.callee()); @@ -1573,7 +1573,7 @@ SetJitCompilerOption(JSContext* cx, unsigned argc, jsval* vp) } static bool -GetJitCompilerOptions(JSContext* cx, unsigned argc, jsval* vp) +GetJitCompilerOptions(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); RootedObject info(cx, JS_NewPlainObject(cx)); @@ -1598,7 +1598,7 @@ GetJitCompilerOptions(JSContext* cx, unsigned argc, jsval* vp) } static bool -SetIonCheckGraphCoherency(JSContext* cx, unsigned argc, jsval* vp) +SetIonCheckGraphCoherency(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); jit::js_JitOptions.checkGraphConsistency = ToBoolean(args.get(0)); @@ -1762,7 +1762,7 @@ const JSPropertySpec CloneBufferObject::props_[] = { }; static bool -Serialize(JSContext* cx, unsigned argc, jsval* vp) +Serialize(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -1779,7 +1779,7 @@ Serialize(JSContext* cx, unsigned argc, jsval* vp) } static bool -Deserialize(JSContext* cx, unsigned argc, jsval* vp) +Deserialize(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -1820,7 +1820,7 @@ Deserialize(JSContext* cx, unsigned argc, jsval* vp) } static bool -Neuter(JSContext* cx, unsigned argc, jsval* vp) +Neuter(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -1862,7 +1862,7 @@ Neuter(JSContext* cx, unsigned argc, jsval* vp) } static bool -HelperThreadCount(JSContext* cx, unsigned argc, jsval* vp) +HelperThreadCount(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); #ifdef JS_MORE_DETERMINISTIC @@ -1878,7 +1878,7 @@ HelperThreadCount(JSContext* cx, unsigned argc, jsval* vp) } static bool -TimesAccessed(JSContext* cx, unsigned argc, jsval* vp) +TimesAccessed(JSContext* cx, unsigned argc, Value* vp) { static int32_t accessed = 0; CallArgs args = CallArgsFromVp(argc, vp); @@ -1888,7 +1888,7 @@ TimesAccessed(JSContext* cx, unsigned argc, jsval* vp) #ifdef JS_TRACE_LOGGING static bool -EnableTraceLogger(JSContext* cx, unsigned argc, jsval* vp) +EnableTraceLogger(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); TraceLoggerThread* logger = TraceLoggerForMainThread(cx->runtime()); @@ -1900,7 +1900,7 @@ EnableTraceLogger(JSContext* cx, unsigned argc, jsval* vp) } static bool -DisableTraceLogger(JSContext* cx, unsigned argc, jsval* vp) +DisableTraceLogger(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); TraceLoggerThread* logger = TraceLoggerForMainThread(cx->runtime()); @@ -1912,7 +1912,7 @@ DisableTraceLogger(JSContext* cx, unsigned argc, jsval* vp) #ifdef DEBUG static bool -DumpObject(JSContext* cx, unsigned argc, jsval* vp) +DumpObject(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); RootedObject obj(cx, ToObject(cx, args.get(0))); @@ -1928,7 +1928,7 @@ DumpObject(JSContext* cx, unsigned argc, jsval* vp) #ifdef NIGHTLY_BUILD static bool -ObjectAddress(JSContext* cx, unsigned argc, jsval* vp) +ObjectAddress(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 1) { @@ -1961,7 +1961,7 @@ ObjectAddress(JSContext* cx, unsigned argc, jsval* vp) #endif static bool -DumpBacktrace(JSContext* cx, unsigned argc, jsval* vp) +DumpBacktrace(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); DumpBacktrace(cx); @@ -1970,7 +1970,7 @@ DumpBacktrace(JSContext* cx, unsigned argc, jsval* vp) } static bool -GetBacktrace(JSContext* cx, unsigned argc, jsval* vp) +GetBacktrace(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -2014,7 +2014,7 @@ GetBacktrace(JSContext* cx, unsigned argc, jsval* vp) } static bool -ReportOutOfMemory(JSContext* cx, unsigned argc, jsval* vp) +ReportOutOfMemory(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); JS_ReportOutOfMemory(cx); @@ -2024,7 +2024,7 @@ ReportOutOfMemory(JSContext* cx, unsigned argc, jsval* vp) } static bool -ReportLargeAllocationFailure(JSContext* cx, unsigned argc, jsval* vp) +ReportLargeAllocationFailure(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); void* buf = cx->runtime()->onOutOfMemoryCanGC(AllocFunction::Malloc, JSRuntime::LARGE_ALLOCATION); @@ -2147,7 +2147,7 @@ struct FindPathHandler { } // namespace heaptools static bool -FindPath(JSContext* cx, unsigned argc, jsval* vp) +FindPath(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (argc < 2) { @@ -2247,7 +2247,7 @@ FindPath(JSContext* cx, unsigned argc, jsval* vp) } static bool -EvalReturningScope(JSContext* cx, unsigned argc, jsval* vp) +EvalReturningScope(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (!args.requireAtLeast(cx, "evalReturningScope", 1)) @@ -2495,7 +2495,7 @@ GetConstructorName(JSContext* cx, unsigned argc, Value* vp) } static bool -AllocationMarker(JSContext* cx, unsigned argc, jsval* vp) +AllocationMarker(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -2557,7 +2557,7 @@ MinorGC* prevMinorGC = nullptr; } /* namespace gcCallback */ static bool -SetGCCallback(JSContext* cx, unsigned argc, jsval* vp) +SetGCCallback(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); diff --git a/js/src/gdb/tests/test-Root.cpp b/js/src/gdb/tests/test-Root.cpp index e067a0bea0a8..82cfb2581dec 100644 --- a/js/src/gdb/tests/test-Root.cpp +++ b/js/src/gdb/tests/test-Root.cpp @@ -28,7 +28,7 @@ FRAGMENT(Root, handle) { } FRAGMENT(Root, HeapSlot) { - JS::Rooted plinth(cx, JS::StringValue(JS_NewStringCopyZ(cx, "plinth"))); + JS::Rooted plinth(cx, JS::StringValue(JS_NewStringCopyZ(cx, "plinth"))); JS::Rooted array(cx, JS_NewArrayObject(cx, JS::HandleValueArray(plinth))); breakpoint(); diff --git a/js/src/jsapi-tests/testChromeBuffer.cpp b/js/src/jsapi-tests/testChromeBuffer.cpp index 43f29c548296..c425e155f9b1 100644 --- a/js/src/jsapi-tests/testChromeBuffer.cpp +++ b/js/src/jsapi-tests/testChromeBuffer.cpp @@ -30,7 +30,7 @@ static JS::PersistentRootedObject trusted_glob; static JS::PersistentRootedObject trusted_fun; static bool -CallTrusted(JSContext* cx, unsigned argc, jsval* vp) +CallTrusted(JSContext* cx, unsigned argc, JS::Value* vp) { JS::CallArgs args = JS::CallArgsFromVp(argc, vp); diff --git a/js/src/jsapi-tests/testClassGetter.cpp b/js/src/jsapi-tests/testClassGetter.cpp index b94feebd9fc7..ef21848a8803 100644 --- a/js/src/jsapi-tests/testClassGetter.cpp +++ b/js/src/jsapi-tests/testClassGetter.cpp @@ -19,7 +19,7 @@ static bool test_prop_get( JSContext* cx, JS::HandleObject obj, JS::HandleId id, } static bool -PTest(JSContext* cx, unsigned argc, jsval* vp); +PTest(JSContext* cx, unsigned argc, JS::Value* vp); static const JSClass ptestClass = { "PTest", @@ -31,7 +31,7 @@ static const JSClass ptestClass = { }; static bool -PTest(JSContext* cx, unsigned argc, jsval* vp) +PTest(JSContext* cx, unsigned argc, JS::Value* vp) { JS::CallArgs args = JS::CallArgsFromVp(argc, vp); JSObject* obj = JS_NewObjectForConstructor(cx, &ptestClass, args); @@ -40,7 +40,7 @@ PTest(JSContext* cx, unsigned argc, jsval* vp) args.rval().setObject(*obj); return true; } -static bool test_fn(JSContext* cx, unsigned argc, jsval* vp) +static bool test_fn(JSContext* cx, unsigned argc, JS::Value* vp) { called_test_fn++; return true; diff --git a/js/src/jsapi-tests/testContexts.cpp b/js/src/jsapi-tests/testContexts.cpp index 86852b69714d..f9d5c4e14345 100644 --- a/js/src/jsapi-tests/testContexts.cpp +++ b/js/src/jsapi-tests/testContexts.cpp @@ -13,7 +13,7 @@ BEGIN_TEST(testContexts_IsRunning) return true; } - static bool chk(JSContext* cx, unsigned argc, jsval* vp) + static bool chk(JSContext* cx, unsigned argc, JS::Value* vp) { JSRuntime* rt = JS_GetRuntime(cx); JSContext* acx = JS_NewContext(rt, 8192); diff --git a/js/src/jsapi-tests/testDefineGetterSetterNonEnumerable.cpp b/js/src/jsapi-tests/testDefineGetterSetterNonEnumerable.cpp index adf2bffc41b2..2c82725fc984 100644 --- a/js/src/jsapi-tests/testDefineGetterSetterNonEnumerable.cpp +++ b/js/src/jsapi-tests/testDefineGetterSetterNonEnumerable.cpp @@ -8,7 +8,7 @@ #include "jsapi-tests/tests.h" static bool -NativeGetterSetter(JSContext* cx, unsigned argc, jsval* vp) +NativeGetterSetter(JSContext* cx, unsigned argc, JS::Value* vp) { return true; } diff --git a/js/src/jsapi-tests/testNewObject.cpp b/js/src/jsapi-tests/testNewObject.cpp index 3178140f4798..3a7e6e2f5b01 100644 --- a/js/src/jsapi-tests/testNewObject.cpp +++ b/js/src/jsapi-tests/testNewObject.cpp @@ -8,7 +8,7 @@ #include "jsapi-tests/tests.h" static bool -constructHook(JSContext* cx, unsigned argc, jsval* vp) +constructHook(JSContext* cx, unsigned argc, JS::Value* vp) { JS::CallArgs args = CallArgsFromVp(argc, vp); diff --git a/js/src/jsapi-tests/testObjectEmulatingUndefined.cpp b/js/src/jsapi-tests/testObjectEmulatingUndefined.cpp index 8ba4b4b634a5..6d0e7979c31f 100644 --- a/js/src/jsapi-tests/testObjectEmulatingUndefined.cpp +++ b/js/src/jsapi-tests/testObjectEmulatingUndefined.cpp @@ -10,7 +10,7 @@ static const JSClass ObjectEmulatingUndefinedClass = { }; static bool -ObjectEmulatingUndefinedConstructor(JSContext* cx, unsigned argc, jsval* vp) +ObjectEmulatingUndefinedConstructor(JSContext* cx, unsigned argc, JS::Value* vp) { JS::CallArgs args = JS::CallArgsFromVp(argc, vp); JSObject* obj = JS_NewObjectForConstructor(cx, &ObjectEmulatingUndefinedClass, args); diff --git a/js/src/jsapi-tests/testOps.cpp b/js/src/jsapi-tests/testOps.cpp index 1cd34cac6e5c..dd48076f7ce9 100644 --- a/js/src/jsapi-tests/testOps.cpp +++ b/js/src/jsapi-tests/testOps.cpp @@ -27,7 +27,7 @@ static const JSClass myClass = { }; static bool -createMyObject(JSContext* context, unsigned argc, jsval* vp) +createMyObject(JSContext* context, unsigned argc, JS::Value* vp) { JS_BeginRequest(context); diff --git a/js/src/jsapi-tests/testParseJSON.cpp b/js/src/jsapi-tests/testParseJSON.cpp index f381825088eb..75c8c799d564 100644 --- a/js/src/jsapi-tests/testParseJSON.cpp +++ b/js/src/jsapi-tests/testParseJSON.cpp @@ -327,7 +327,7 @@ ReportJSONError(JSContext* cx, const char* message, JSErrorReport* report) END_TEST(testParseJSON_error) static bool -Censor(JSContext* cx, unsigned argc, jsval* vp) +Censor(JSContext* cx, unsigned argc, JS::Value* vp) { JS::CallArgs args = JS::CallArgsFromVp(argc, vp); MOZ_RELEASE_ASSERT(args.length() == 2); diff --git a/js/src/jsapi-tests/testProfileStrings.cpp b/js/src/jsapi-tests/testProfileStrings.cpp index 9bfa29bb6cd4..903c87af582a 100644 --- a/js/src/jsapi-tests/testProfileStrings.cpp +++ b/js/src/jsapi-tests/testProfileStrings.cpp @@ -30,14 +30,14 @@ static const JSClass ptestClass = { }; static bool -test_fn(JSContext* cx, unsigned argc, jsval* vp) +test_fn(JSContext* cx, unsigned argc, JS::Value* vp) { max_stack = psize; return true; } static bool -test_fn2(JSContext* cx, unsigned argc, jsval* vp) +test_fn2(JSContext* cx, unsigned argc, JS::Value* vp) { JS::RootedValue r(cx); JS::RootedObject global(cx, JS::CurrentGlobalOrNull(cx)); @@ -45,21 +45,21 @@ test_fn2(JSContext* cx, unsigned argc, jsval* vp) } static bool -enable(JSContext* cx, unsigned argc, jsval* vp) +enable(JSContext* cx, unsigned argc, JS::Value* vp) { js::EnableRuntimeProfilingStack(cx->runtime(), true); return true; } static bool -disable(JSContext* cx, unsigned argc, jsval* vp) +disable(JSContext* cx, unsigned argc, JS::Value* vp) { js::EnableRuntimeProfilingStack(cx->runtime(), false); return true; } static bool -Prof(JSContext* cx, unsigned argc, jsval* vp) +Prof(JSContext* cx, unsigned argc, JS::Value* vp) { JS::CallArgs args = JS::CallArgsFromVp(argc, vp); JSObject* obj = JS_NewObjectForConstructor(cx, &ptestClass, args); diff --git a/js/src/jsapi-tests/tests.h b/js/src/jsapi-tests/tests.h index b70d45b23db5..a34a40dd47d1 100644 --- a/js/src/jsapi-tests/tests.h +++ b/js/src/jsapi-tests/tests.h @@ -182,7 +182,7 @@ class JSAPITest return false; \ } while (false) - bool checkSame(jsval actualArg, jsval expectedArg, + bool checkSame(JS::Value actualArg, JS::Value expectedArg, const char* actualExpr, const char* expectedExpr, const char* filename, int lineno) { bool same; @@ -238,7 +238,7 @@ class JSAPITest protected: static bool - print(JSContext* cx, unsigned argc, jsval* vp) + print(JSContext* cx, unsigned argc, JS::Value* vp) { JS::CallArgs args = JS::CallArgsFromVp(argc, vp); diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 84653b470c00..2305230a04b1 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -266,25 +266,25 @@ JS_Now() return PRMJ_Now(); } -JS_PUBLIC_API(jsval) +JS_PUBLIC_API(Value) JS_GetNaNValue(JSContext* cx) { return cx->runtime()->NaNValue; } -JS_PUBLIC_API(jsval) +JS_PUBLIC_API(Value) JS_GetNegativeInfinityValue(JSContext* cx) { return cx->runtime()->negativeInfinityValue; } -JS_PUBLIC_API(jsval) +JS_PUBLIC_API(Value) JS_GetPositiveInfinityValue(JSContext* cx) { return cx->runtime()->positiveInfinityValue; } -JS_PUBLIC_API(jsval) +JS_PUBLIC_API(Value) JS_GetEmptyStringValue(JSContext* cx) { return StringValue(cx->runtime()->emptyString); @@ -1435,8 +1435,8 @@ JS::CurrentGlobalOrNull(JSContext* cx) return cx->global(); } -JS_PUBLIC_API(jsval) -JS_ComputeThis(JSContext* cx, jsval* vp) +JS_PUBLIC_API(Value) +JS_ComputeThis(JSContext* cx, Value* vp) { AssertHeapIsIdle(cx); assertSameCompartment(cx, JSValueArray(vp, 2)); @@ -3144,7 +3144,7 @@ JS_Enumerate(JSContext* cx, HandleObject obj) return ida; } -JS_PUBLIC_API(jsval) +JS_PUBLIC_API(Value) JS_GetReservedSlot(JSObject* obj, uint32_t index) { return obj->as().getReservedSlot(index); @@ -3528,7 +3528,7 @@ GenericNativeMethodDispatcher(JSContext* cx, unsigned argc, Value* vp) * call the corresponding prototype native method with our first argument * passed as |this|. */ - memmove(vp + 1, vp + 2, argc * sizeof(jsval)); + memmove(vp + 1, vp + 2, argc * sizeof(Value)); /* Clear the last parameter in case too few arguments were passed. */ vp[2 + --argc].setUndefined(); @@ -4323,7 +4323,7 @@ JS_DecompileFunctionBody(JSContext* cx, HandleFunction fun, unsigned indent) } MOZ_NEVER_INLINE static bool -ExecuteScript(JSContext* cx, HandleObject scope, HandleScript script, jsval* rval) +ExecuteScript(JSContext* cx, HandleObject scope, HandleScript script, Value* rval) { MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment())); AssertHeapIsIdle(cx); @@ -4335,7 +4335,7 @@ ExecuteScript(JSContext* cx, HandleObject scope, HandleScript script, jsval* rva } static bool -ExecuteScript(JSContext* cx, AutoObjectVector& scopeChain, HandleScript scriptArg, jsval* rval) +ExecuteScript(JSContext* cx, AutoObjectVector& scopeChain, HandleScript scriptArg, Value* rval) { RootedObject dynamicScope(cx); Rooted staticScope(cx); @@ -5813,7 +5813,7 @@ JS_ThrowStopIteration(JSContext* cx) } JS_PUBLIC_API(bool) -JS_IsStopIteration(jsval v) +JS_IsStopIteration(Value v) { return v.isObject() && v.toObject().is(); } diff --git a/js/src/jsapi.h b/js/src/jsapi.h index f4a5cec94265..b2d67217f086 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -734,7 +734,7 @@ typedef void* /************************************************************************/ -static MOZ_ALWAYS_INLINE jsval +static MOZ_ALWAYS_INLINE JS::Value JS_NumberValue(double d) { int32_t i; @@ -936,17 +936,17 @@ JS_CallOnce(JSCallOnceType* once, JSInitCallback func); extern JS_PUBLIC_API(int64_t) JS_Now(void); -/* Don't want to export data, so provide accessors for non-inline jsvals. */ -extern JS_PUBLIC_API(jsval) +/* Don't want to export data, so provide accessors for non-inline Values. */ +extern JS_PUBLIC_API(JS::Value) JS_GetNaNValue(JSContext* cx); -extern JS_PUBLIC_API(jsval) +extern JS_PUBLIC_API(JS::Value) JS_GetNegativeInfinityValue(JSContext* cx); -extern JS_PUBLIC_API(jsval) +extern JS_PUBLIC_API(JS::Value) JS_GetPositiveInfinityValue(JSContext* cx); -extern JS_PUBLIC_API(jsval) +extern JS_PUBLIC_API(JS::Value) JS_GetEmptyStringValue(JSContext* cx); extern JS_PUBLIC_API(JSString*) @@ -3192,11 +3192,11 @@ JS_ReleaseMappedArrayBufferContents(void* contents, size_t length); extern JS_PUBLIC_API(JSIdArray*) JS_Enumerate(JSContext* cx, JS::HandleObject obj); -extern JS_PUBLIC_API(jsval) +extern JS_PUBLIC_API(JS::Value) JS_GetReservedSlot(JSObject* obj, uint32_t index); extern JS_PUBLIC_API(void) -JS_SetReservedSlot(JSObject* obj, uint32_t index, jsval v); +JS_SetReservedSlot(JSObject* obj, uint32_t index, JS::Value v); /************************************************************************/ @@ -4926,7 +4926,7 @@ extern JS_PUBLIC_API(bool) JS_ThrowStopIteration(JSContext* cx); extern JS_PUBLIC_API(bool) -JS_IsStopIteration(jsval v); +JS_IsStopIteration(JS::Value v); extern JS_PUBLIC_API(intptr_t) JS_GetCurrentThread(); diff --git a/js/src/jsobj.h b/js/src/jsobj.h index 1006eacd61d3..26a720bad4dd 100644 --- a/js/src/jsobj.h +++ b/js/src/jsobj.h @@ -669,10 +669,10 @@ IsConstructor(const Value& v) class JSValueArray { public: - const jsval* array; + const js::Value* array; size_t length; - JSValueArray(const jsval* v, size_t c) : array(v), length(c) {} + JSValueArray(const js::Value* v, size_t c) : array(v), length(c) {} }; class ValueArray { diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp index fc28dc672280..5f0428fc2180 100644 --- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -2364,7 +2364,7 @@ js::FreeScriptData(JSRuntime* rt) * * IMPORTANT: This layout has two key properties. * - It ensures that everything has sufficient alignment; in particular, the - * consts() elements need jsval alignment. + * consts() elements need Value alignment. * - It ensures there are no gaps between elements, which saves space and makes * manual layout easy. In particular, in the second part, arrays with larger * elements precede arrays with smaller elements. @@ -2387,12 +2387,12 @@ js::FreeScriptData(JSRuntime* rt) */ #define KEEPS_JSVAL_ALIGNMENT(T) \ - (JS_ALIGNMENT_OF(jsval) % JS_ALIGNMENT_OF(T) == 0 && \ - sizeof(T) % sizeof(jsval) == 0) + (JS_ALIGNMENT_OF(JS::Value) % JS_ALIGNMENT_OF(T) == 0 && \ + sizeof(T) % sizeof(JS::Value) == 0) #define HAS_JSVAL_ALIGNMENT(T) \ - (JS_ALIGNMENT_OF(jsval) == JS_ALIGNMENT_OF(T) && \ - sizeof(T) == sizeof(jsval)) + (JS_ALIGNMENT_OF(JS::Value) == JS_ALIGNMENT_OF(T) && \ + sizeof(T) == sizeof(JS::Value)) #define NO_PADDING_BETWEEN_ENTRIES(T1, T2) \ (JS_ALIGNMENT_OF(T1) % JS_ALIGNMENT_OF(T2) == 0) @@ -2400,7 +2400,7 @@ js::FreeScriptData(JSRuntime* rt) /* * These assertions ensure that there is no padding between the array headers, * and also that the consts() elements (which follow immediately afterward) are - * jsval-aligned. (There is an assumption that |data| itself is jsval-aligned; + * Value-aligned. (There is an assumption that |data| itself is Value-aligned; * we check this below). */ JS_STATIC_ASSERT(KEEPS_JSVAL_ALIGNMENT(ConstArray)); @@ -2565,7 +2565,7 @@ JSScript::partiallyInit(ExclusiveContext* cx, HandleScript script, uint32_t ncon } if (nconsts != 0) { - MOZ_ASSERT(reinterpret_cast(cursor) % sizeof(jsval) == 0); + MOZ_ASSERT(reinterpret_cast(cursor) % sizeof(JS::Value) == 0); script->consts()->length = nconsts; script->consts()->vector = (HeapValue*)cursor; cursor += nconsts * sizeof(script->consts()->vector[0]); diff --git a/js/src/perf/jsperf.cpp b/js/src/perf/jsperf.cpp index b28134dcfcbb..8ea79051e03b 100644 --- a/js/src/perf/jsperf.cpp +++ b/js/src/perf/jsperf.cpp @@ -49,7 +49,7 @@ GETTER(eventsMeasured) // Calls static bool -pm_start(JSContext* cx, unsigned argc, jsval* vp) +pm_start(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); PerfMeasurement* p = GetPM(cx, args.thisv(), "start"); @@ -62,7 +62,7 @@ pm_start(JSContext* cx, unsigned argc, jsval* vp) } static bool -pm_stop(JSContext* cx, unsigned argc, jsval* vp) +pm_stop(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); PerfMeasurement* p = GetPM(cx, args.thisv(), "stop"); @@ -75,7 +75,7 @@ pm_stop(JSContext* cx, unsigned argc, jsval* vp) } static bool -pm_reset(JSContext* cx, unsigned argc, jsval* vp) +pm_reset(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); PerfMeasurement* p = GetPM(cx, args.thisv(), "reset"); @@ -88,7 +88,7 @@ pm_reset(JSContext* cx, unsigned argc, jsval* vp) } static bool -pm_canMeasureSomething(JSContext* cx, unsigned argc, jsval* vp) +pm_canMeasureSomething(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); PerfMeasurement* p = GetPM(cx, args.thisv(), "canMeasureSomething"); @@ -158,7 +158,7 @@ static const struct pm_const { #undef CONSTANT -static bool pm_construct(JSContext* cx, unsigned argc, jsval* vp); +static bool pm_construct(JSContext* cx, unsigned argc, Value* vp); static void pm_finalize(JSFreeOp* fop, JSObject* obj); static const JSClass pm_class = { @@ -170,7 +170,7 @@ static const JSClass pm_class = { // Constructor and destructor static bool -pm_construct(JSContext* cx, unsigned argc, jsval* vp) +pm_construct(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -267,7 +267,7 @@ RegisterPerfMeasurement(JSContext* cx, HandleObject globalArg) } PerfMeasurement* -ExtractPerfMeasurement(jsval wrapper) +ExtractPerfMeasurement(Value wrapper) { if (wrapper.isPrimitive()) return 0; diff --git a/js/src/proxy/ScriptedDirectProxyHandler.h b/js/src/proxy/ScriptedDirectProxyHandler.h index 7c710b68ab44..133c31ab71ff 100644 --- a/js/src/proxy/ScriptedDirectProxyHandler.h +++ b/js/src/proxy/ScriptedDirectProxyHandler.h @@ -101,10 +101,10 @@ class ScriptedDirectProxyHandler : public BaseProxyHandler { }; bool -proxy(JSContext* cx, unsigned argc, jsval* vp); +proxy(JSContext* cx, unsigned argc, Value* vp); bool -proxy_revocable(JSContext* cx, unsigned argc, jsval* vp); +proxy_revocable(JSContext* cx, unsigned argc, Value* vp); } /* namespace js */ diff --git a/js/src/shell/OSObject.cpp b/js/src/shell/OSObject.cpp index 53300db36735..0674bf49f9af 100644 --- a/js/src/shell/OSObject.cpp +++ b/js/src/shell/OSObject.cpp @@ -151,7 +151,7 @@ FileAsTypedArray(JSContext* cx, const char* pathname) } static bool -ReadFile(JSContext* cx, unsigned argc, jsval* vp, bool scriptRelative) +ReadFile(JSContext* cx, unsigned argc, Value* vp, bool scriptRelative) { CallArgs args = CallArgsFromVp(argc, vp); @@ -199,13 +199,13 @@ ReadFile(JSContext* cx, unsigned argc, jsval* vp, bool scriptRelative) } static bool -osfile_readFile(JSContext* cx, unsigned argc, jsval* vp) +osfile_readFile(JSContext* cx, unsigned argc, Value* vp) { return ReadFile(cx, argc, vp, false); } static bool -osfile_readRelativeToScript(JSContext* cx, unsigned argc, jsval* vp) +osfile_readRelativeToScript(JSContext* cx, unsigned argc, Value* vp) { return ReadFile(cx, argc, vp, true); } @@ -227,7 +227,7 @@ Redirect(JSContext* cx, FILE* fp, HandleString relFilename) } static bool -osfile_redirect(JSContext* cx, unsigned argc, jsval* vp) +osfile_redirect(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -371,7 +371,7 @@ ReportSysError(JSContext* cx, const char* prefix) } static bool -os_system(JSContext* cx, unsigned argc, jsval* vp) +os_system(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -400,7 +400,7 @@ os_system(JSContext* cx, unsigned argc, jsval* vp) #ifndef XP_WIN static bool -os_spawn(JSContext* cx, unsigned argc, jsval* vp) +os_spawn(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index fc2a2f96ef77..5b62455358ab 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -581,7 +581,7 @@ Process(JSContext* cx, const char* filename, bool forceTTY) } static bool -Version(JSContext* cx, unsigned argc, jsval* vp) +Version(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); JSVersion origVersion = JS_GetVersion(cx); @@ -691,7 +691,7 @@ CreateMappedArrayBuffer(JSContext* cx, unsigned argc, Value* vp) } static bool -Options(JSContext* cx, unsigned argc, jsval* vp) +Options(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -750,7 +750,7 @@ Options(JSContext* cx, unsigned argc, jsval* vp) } static bool -LoadScript(JSContext* cx, unsigned argc, jsval* vp, bool scriptRelative) +LoadScript(JSContext* cx, unsigned argc, Value* vp, bool scriptRelative) { CallArgs args = CallArgsFromVp(argc, vp); @@ -789,13 +789,13 @@ LoadScript(JSContext* cx, unsigned argc, jsval* vp, bool scriptRelative) } static bool -Load(JSContext* cx, unsigned argc, jsval* vp) +Load(JSContext* cx, unsigned argc, Value* vp) { return LoadScript(cx, argc, vp, false); } static bool -LoadScriptRelativeToScript(JSContext* cx, unsigned argc, jsval* vp) +LoadScriptRelativeToScript(JSContext* cx, unsigned argc, Value* vp) { return LoadScript(cx, argc, vp, true); } @@ -1031,7 +1031,7 @@ class AutoSaveFrameChain }; static bool -Evaluate(JSContext* cx, unsigned argc, jsval* vp) +Evaluate(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -1329,7 +1329,7 @@ js::shell::FileAsString(JSContext* cx, const char* pathname) * to produce benchmark timings by SunSpider. */ static bool -Run(JSContext* cx, unsigned argc, jsval* vp) +Run(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 1) { @@ -1382,7 +1382,7 @@ Run(JSContext* cx, unsigned argc, jsval* vp) * Provides a hook for scripts to read a line from stdin. */ static bool -ReadLine(JSContext* cx, unsigned argc, jsval* vp) +ReadLine(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -1456,7 +1456,7 @@ ReadLine(JSContext* cx, unsigned argc, jsval* vp) } static bool -PutStr(JSContext* cx, unsigned argc, jsval* vp) +PutStr(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -1477,7 +1477,7 @@ PutStr(JSContext* cx, unsigned argc, jsval* vp) } static bool -Now(JSContext* cx, unsigned argc, jsval* vp) +Now(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); double now = PRMJ_Now() / double(PRMJ_USEC_PER_MSEC); @@ -1507,24 +1507,24 @@ PrintInternal(JSContext* cx, const CallArgs& args, FILE* file) } static bool -Print(JSContext* cx, unsigned argc, jsval* vp) +Print(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); return PrintInternal(cx, args, gOutFile); } static bool -PrintErr(JSContext* cx, unsigned argc, jsval* vp) +PrintErr(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); return PrintInternal(cx, args, gErrFile); } static bool -Help(JSContext* cx, unsigned argc, jsval* vp); +Help(JSContext* cx, unsigned argc, Value* vp); static bool -Quit(JSContext* cx, unsigned argc, jsval* vp) +Quit(JSContext* cx, unsigned argc, Value* vp) { #ifdef JS_MORE_DETERMINISTIC // Print a message to stderr in more-deterministic builds to help jsfunfuzz @@ -1553,7 +1553,7 @@ Quit(JSContext* cx, unsigned argc, jsval* vp) } static bool -StartTimingMutator(JSContext* cx, unsigned argc, jsval* vp) +StartTimingMutator(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() > 0) { @@ -1568,7 +1568,7 @@ StartTimingMutator(JSContext* cx, unsigned argc, jsval* vp) } static bool -StopTimingMutator(JSContext* cx, unsigned argc, jsval* vp) +StopTimingMutator(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() > 0) { @@ -1606,7 +1606,7 @@ ToSource(JSContext* cx, MutableHandleValue vp, JSAutoByteString* bytes) } static bool -AssertEq(JSContext* cx, unsigned argc, jsval* vp) +AssertEq(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (!(args.length() == 2 || (args.length() == 3 && args[2].isString()))) { @@ -1644,7 +1644,7 @@ AssertEq(JSContext* cx, unsigned argc, jsval* vp) } static JSScript* -ValueToScript(JSContext* cx, jsval vArg, JSFunction** funp = nullptr) +ValueToScript(JSContext* cx, Value vArg, JSFunction** funp = nullptr) { RootedValue v(cx, vArg); RootedFunction fun(cx, JS_ValueToFunction(cx, v)); @@ -1683,13 +1683,13 @@ GetTopScript(JSContext* cx) } static bool -GetScriptAndPCArgs(JSContext* cx, unsigned argc, jsval* argv, MutableHandleScript scriptp, +GetScriptAndPCArgs(JSContext* cx, unsigned argc, Value* argv, MutableHandleScript scriptp, int32_t* ip) { RootedScript script(cx, GetTopScript(cx)); *ip = 0; if (argc != 0) { - jsval v = argv[0]; + Value v = argv[0]; unsigned intarg = 0; if (v.isObject() && JS_GetClass(&v.toObject()) == Jsvalify(&JSFunction::class_)) { @@ -1714,7 +1714,7 @@ GetScriptAndPCArgs(JSContext* cx, unsigned argc, jsval* argv, MutableHandleScrip } static bool -LineToPC(JSContext* cx, unsigned argc, jsval* vp) +LineToPC(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -1744,7 +1744,7 @@ LineToPC(JSContext* cx, unsigned argc, jsval* vp) } static bool -PCToLine(JSContext* cx, unsigned argc, jsval* vp) +PCToLine(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); RootedScript script(cx); @@ -1893,7 +1893,7 @@ SrcNotes(JSContext* cx, HandleScript script, Sprinter* sp) } static bool -Notes(JSContext* cx, unsigned argc, jsval* vp) +Notes(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); Sprinter sprinter(cx); @@ -2016,11 +2016,11 @@ namespace { struct DisassembleOptionParser { unsigned argc; - jsval* argv; + Value* argv; bool lines; bool recursive; - DisassembleOptionParser(unsigned argc, jsval* argv) + DisassembleOptionParser(unsigned argc, Value* argv) : argc(argc), argv(argv), lines(false), recursive(false) {} bool parse(JSContext* cx) { @@ -2045,7 +2045,7 @@ struct DisassembleOptionParser { } /* anonymous namespace */ static bool -DisassembleToSprinter(JSContext* cx, unsigned argc, jsval* vp, Sprinter* sprinter) +DisassembleToSprinter(JSContext* cx, unsigned argc, Value* vp, Sprinter* sprinter) { CallArgs args = CallArgsFromVp(argc, vp); DisassembleOptionParser p(args.length(), args.array()); @@ -2077,7 +2077,7 @@ DisassembleToSprinter(JSContext* cx, unsigned argc, jsval* vp, Sprinter* sprinte } static bool -DisassembleToString(JSContext* cx, unsigned argc, jsval* vp) +DisassembleToString(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); Sprinter sprinter(cx); @@ -2094,7 +2094,7 @@ DisassembleToString(JSContext* cx, unsigned argc, jsval* vp) } static bool -Disassemble(JSContext* cx, unsigned argc, jsval* vp) +Disassemble(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); Sprinter sprinter(cx); @@ -2109,7 +2109,7 @@ Disassemble(JSContext* cx, unsigned argc, jsval* vp) } static bool -DisassFile(JSContext* cx, unsigned argc, jsval* vp) +DisassFile(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -2158,7 +2158,7 @@ DisassFile(JSContext* cx, unsigned argc, jsval* vp) } static bool -DisassWithSrc(JSContext* cx, unsigned argc, jsval* vp) +DisassWithSrc(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -2256,7 +2256,7 @@ DisassWithSrc(JSContext* cx, unsigned argc, jsval* vp) #endif /* DEBUG */ static bool -Intern(JSContext* cx, unsigned argc, jsval* vp) +Intern(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); JSString* str = JS::ToString(cx, args.get(0)); @@ -2277,7 +2277,7 @@ Intern(JSContext* cx, unsigned argc, jsval* vp) } static bool -Clone(JSContext* cx, unsigned argc, jsval* vp) +Clone(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); RootedObject parent(cx); @@ -2327,7 +2327,7 @@ Clone(JSContext* cx, unsigned argc, jsval* vp) } static bool -GetSLX(JSContext* cx, unsigned argc, jsval* vp) +GetSLX(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); RootedScript script(cx); @@ -2340,7 +2340,7 @@ GetSLX(JSContext* cx, unsigned argc, jsval* vp) } static bool -ThrowError(JSContext* cx, unsigned argc, jsval* vp) +ThrowError(JSContext* cx, unsigned argc, Value* vp) { JS_ReportError(cx, "This is an error"); return false; @@ -2418,7 +2418,7 @@ NewSandbox(JSContext* cx, bool lazy) } static bool -EvalInContext(JSContext* cx, unsigned argc, jsval* vp) +EvalInContext(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (!args.requireAtLeast(cx, "evalcx", 1)) @@ -2567,7 +2567,7 @@ WorkerMain(void* arg) Vector workerThreads; static bool -EvalInWorker(JSContext* cx, unsigned argc, jsval* vp) +EvalInWorker(JSContext* cx, unsigned argc, Value* vp) { if (!CanUseExtraThreads()) { JS_ReportError(cx, "Can't create worker threads with --no-threads"); @@ -2863,7 +2863,7 @@ InterruptIf(JSContext* cx, unsigned argc, Value* vp) } static bool -InvokeInterruptCallbackWrapper(JSContext* cx, unsigned argc, jsval* vp) +InvokeInterruptCallbackWrapper(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 1) { @@ -3006,7 +3006,7 @@ StackPointerInfo(JSContext* cx, unsigned argc, Value* vp) static bool -Elapsed(JSContext* cx, unsigned argc, jsval* vp) +Elapsed(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() == 0) { @@ -3022,7 +3022,7 @@ Elapsed(JSContext* cx, unsigned argc, jsval* vp) } static bool -Compile(JSContext* cx, unsigned argc, jsval* vp) +Compile(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() < 1) { @@ -3058,7 +3058,7 @@ Compile(JSContext* cx, unsigned argc, jsval* vp) } static bool -Parse(JSContext* cx, unsigned argc, jsval* vp) +Parse(JSContext* cx, unsigned argc, Value* vp) { using namespace js::frontend; @@ -3106,7 +3106,7 @@ Parse(JSContext* cx, unsigned argc, jsval* vp) } static bool -SyntaxParse(JSContext* cx, unsigned argc, jsval* vp) +SyntaxParse(JSContext* cx, unsigned argc, Value* vp) { using namespace js::frontend; @@ -3241,7 +3241,7 @@ OffThreadCompileScriptCallback(void* token, void* callbackData) } static bool -OffThreadCompileScript(JSContext* cx, unsigned argc, jsval* vp) +OffThreadCompileScript(JSContext* cx, unsigned argc, Value* vp) { if (!CanUseExtraThreads()) { JS_ReportError(cx, "Can't use offThreadCompileScript with --no-threads"); @@ -3331,7 +3331,7 @@ OffThreadCompileScript(JSContext* cx, unsigned argc, jsval* vp) } static bool -runOffThreadScript(JSContext* cx, unsigned argc, jsval* vp) +runOffThreadScript(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -3466,7 +3466,7 @@ PropagateFlagToNestedShells(const char* flag) } static bool -NestedShell(JSContext* cx, unsigned argc, jsval* vp) +NestedShell(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -3614,7 +3614,7 @@ ThisFilename(JSContext* cx, unsigned argc, Value* vp) } static bool -WrapWithProto(JSContext* cx, unsigned argc, jsval* vp) +WrapWithProto(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); Value obj = UndefinedValue(), proto = UndefinedValue(); @@ -3640,7 +3640,7 @@ WrapWithProto(JSContext* cx, unsigned argc, jsval* vp) } static bool -NewGlobal(JSContext* cx, unsigned argc, jsval* vp) +NewGlobal(JSContext* cx, unsigned argc, Value* vp) { JSPrincipals* principals = nullptr; JS::CompartmentOptions options; @@ -3688,7 +3688,7 @@ NewGlobal(JSContext* cx, unsigned argc, jsval* vp) } static bool -GetMaxArgs(JSContext* cx, unsigned argc, jsval* vp) +GetMaxArgs(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); args.rval().setInt32(ARGS_LENGTH_MAX); @@ -3696,7 +3696,7 @@ GetMaxArgs(JSContext* cx, unsigned argc, jsval* vp) } static bool -ObjectEmulatingUndefined(JSContext* cx, unsigned argc, jsval* vp) +ObjectEmulatingUndefined(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -3713,7 +3713,7 @@ ObjectEmulatingUndefined(JSContext* cx, unsigned argc, jsval* vp) } static bool -GetSelfHostedValue(JSContext* cx, unsigned argc, jsval* vp) +GetSelfHostedValue(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -3765,7 +3765,7 @@ class ShellSourceHook: public SourceHook { }; static bool -WithSourceHook(JSContext* cx, unsigned argc, jsval* vp) +WithSourceHook(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); RootedObject callee(cx, &args.callee()); @@ -4907,7 +4907,7 @@ DefineConsole(JSContext* cx, HandleObject global) #undef EXTERNAL_FUNCTION_COUNT static bool -PrintHelpString(JSContext* cx, jsval v) +PrintHelpString(JSContext* cx, Value v) { JSString* str = v.toString(); @@ -4945,7 +4945,7 @@ PrintHelp(JSContext* cx, HandleObject obj) } static bool -Help(JSContext* cx, unsigned argc, jsval* vp) +Help(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); fprintf(gOutFile, "%s\n", JS_GetImplementationVersion()); diff --git a/js/src/vm/StructuredClone.cpp b/js/src/vm/StructuredClone.cpp index 93456902c459..d4eab0157f42 100644 --- a/js/src/vm/StructuredClone.cpp +++ b/js/src/vm/StructuredClone.cpp @@ -264,7 +264,7 @@ struct JSStructuredCloneWriter { explicit JSStructuredCloneWriter(JSContext* cx, const JSStructuredCloneCallbacks* cb, void* cbClosure, - jsval tVal) + Value tVal) : out(cx), objs(out.context()), counts(out.context()), entries(out.context()), memory(out.context()), callbacks(cb), closure(cbClosure), @@ -364,7 +364,7 @@ ReportErrorTransferable(JSContext* cx, const JSStructuredCloneCallbacks* callbac bool WriteStructuredClone(JSContext* cx, HandleValue v, uint64_t** bufp, size_t* nbytesp, const JSStructuredCloneCallbacks* cb, void* cbClosure, - jsval transferable) + Value transferable) { JSStructuredCloneWriter w(cx, cb, cbClosure, transferable); return w.init() && w.write(v) && w.extractBuffer(bufp, nbytesp); @@ -618,7 +618,7 @@ SCOutput::writePair(uint32_t tag, uint32_t data) * This is because exponents occupy the last 2 bytes of doubles on the * little-endian platforms we care most about. * - * For example, JSVAL_TRUE is written using writePair(SCTAG_BOOLEAN, 1). + * For example, TrueValue() is written using writePair(SCTAG_BOOLEAN, 1). * PairToUInt64 produces the number 0xFFFF000200000001. * That is written out as the bytes 01 00 00 00 02 00 FF FF. */ diff --git a/js/src/vm/Value.cpp b/js/src/vm/Value.cpp index 4f47d9a57f2e..9bc22aec60d7 100644 --- a/js/src/vm/Value.cpp +++ b/js/src/vm/Value.cpp @@ -6,10 +6,10 @@ #include "js/Value.h" -static const jsval JSVAL_NULL = IMPL_TO_JSVAL(BUILD_JSVAL(JSVAL_TAG_NULL, 0)); -static const jsval JSVAL_FALSE = IMPL_TO_JSVAL(BUILD_JSVAL(JSVAL_TAG_BOOLEAN, false)); -static const jsval JSVAL_TRUE = IMPL_TO_JSVAL(BUILD_JSVAL(JSVAL_TAG_BOOLEAN, true)); -static const jsval JSVAL_VOID = IMPL_TO_JSVAL(BUILD_JSVAL(JSVAL_TAG_UNDEFINED, 0)); +static const JS::Value JSVAL_NULL = IMPL_TO_JSVAL(BUILD_JSVAL(JSVAL_TAG_NULL, 0)); +static const JS::Value JSVAL_FALSE = IMPL_TO_JSVAL(BUILD_JSVAL(JSVAL_TAG_BOOLEAN, false)); +static const JS::Value JSVAL_TRUE = IMPL_TO_JSVAL(BUILD_JSVAL(JSVAL_TAG_BOOLEAN, true)); +static const JS::Value JSVAL_VOID = IMPL_TO_JSVAL(BUILD_JSVAL(JSVAL_TAG_UNDEFINED, 0)); namespace JS { From 3d45149452640b8c5a380c6c579932a131fecb98 Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Sat, 18 Jul 2015 11:51:00 -0400 Subject: [PATCH 36/69] Bug 1148030 - Correctly reflect object and embed RequestContext values; r=smaug Note that these elements cannot be intercepted for now. See bug 1168676 for the background. --- dom/base/nsObjectLoadingContent.cpp | 10 +++++++--- dom/base/nsObjectLoadingContent.h | 6 ++++++ dom/fetch/InternalRequest.cpp | 5 ++++- dom/fetch/InternalRequest.h | 5 ++--- dom/html/HTMLObjectElement.h | 7 ++++++- dom/html/HTMLSharedObjectElement.cpp | 13 +++++++++++++ dom/html/HTMLSharedObjectElement.h | 2 ++ .../test/serviceworkers/fetch/context/index.html | 3 +-- 8 files changed, 41 insertions(+), 10 deletions(-) diff --git a/dom/base/nsObjectLoadingContent.cpp b/dom/base/nsObjectLoadingContent.cpp index 91d042d48840..a369b961baa0 100644 --- a/dom/base/nsObjectLoadingContent.cpp +++ b/dom/base/nsObjectLoadingContent.cpp @@ -1485,8 +1485,10 @@ nsObjectLoadingContent::CheckLoadPolicy(int16_t *aContentPolicy) nsIDocument* doc = thisContent->OwnerDoc(); + nsContentPolicyType contentPolicyType = GetContentPolicyType(); + *aContentPolicy = nsIContentPolicy::ACCEPT; - nsresult rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_OBJECT, + nsresult rv = NS_CheckContentLoadPolicy(contentPolicyType, mURI, doc->NodePrincipal(), thisContent, @@ -1532,7 +1534,7 @@ nsObjectLoadingContent::CheckProcessPolicy(int16_t *aContentPolicy) objectType = nsIContentPolicy::TYPE_DOCUMENT; break; case eType_Plugin: - objectType = nsIContentPolicy::TYPE_OBJECT; + objectType = GetContentPolicyType(); break; default: NS_NOTREACHED("Calling checkProcessPolicy with a unloadable type"); @@ -2485,11 +2487,13 @@ nsObjectLoadingContent::OpenChannel() securityFlags |= nsILoadInfo::SEC_SANDBOXED; } + nsContentPolicyType contentPolicyType = GetContentPolicyType(); + rv = NS_NewChannel(getter_AddRefs(chan), mURI, thisContent, securityFlags, - nsIContentPolicy::TYPE_OBJECT, + contentPolicyType, group, // aLoadGroup shim, // aCallbacks nsIChannel::LOAD_CALL_CONTENT_SNIFFERS | diff --git a/dom/base/nsObjectLoadingContent.h b/dom/base/nsObjectLoadingContent.h index 8a9de6380848..d246eac042cb 100644 --- a/dom/base/nsObjectLoadingContent.h +++ b/dom/base/nsObjectLoadingContent.h @@ -17,6 +17,7 @@ #include "nsImageLoadingContent.h" #include "nsIStreamListener.h" #include "nsIChannelEventSink.h" +#include "nsIContentPolicy.h" #include "nsIObjectLoadingContent.h" #include "nsIRunnable.h" #include "nsIThreadInternal.h" @@ -332,6 +333,11 @@ class nsObjectLoadingContent : public nsImageLoadingContent void UnbindFromTree(bool aDeep = true, bool aNullParent = true); + /** + * Return the content policy type used for loading the element. + */ + virtual nsContentPolicyType GetContentPolicyType() const = 0; + private: // Object parameter changes returned by UpdateObjectParameters diff --git a/dom/fetch/InternalRequest.cpp b/dom/fetch/InternalRequest.cpp index 74b471fe02fa..998df50d6446 100644 --- a/dom/fetch/InternalRequest.cpp +++ b/dom/fetch/InternalRequest.cpp @@ -128,9 +128,12 @@ InternalRequest::MapContentPolicyTypeToRequestContext(nsContentPolicyType aConte case nsIContentPolicy::TYPE_STYLESHEET: context = RequestContext::Style; break; - case nsIContentPolicy::TYPE_OBJECT: + case nsIContentPolicy::TYPE_INTERNAL_OBJECT: context = RequestContext::Object; break; + case nsIContentPolicy::TYPE_INTERNAL_EMBED: + context = RequestContext::Embed; + break; case nsIContentPolicy::TYPE_DOCUMENT: context = RequestContext::Internal; break; diff --git a/dom/fetch/InternalRequest.h b/dom/fetch/InternalRequest.h index 7a041abd79e4..40a70d49aa67 100644 --- a/dom/fetch/InternalRequest.h +++ b/dom/fetch/InternalRequest.h @@ -34,7 +34,7 @@ namespace dom { * beacon | TYPE_BEACON * cspreport | TYPE_CSP_REPORT * download | - * embed | TYPE_OBJECT + * embed | TYPE_INTERNAL_EMBED * eventsource | * favicon | * fetch | TYPE_FETCH @@ -49,7 +49,7 @@ namespace dom { * internal | TYPE_DOCUMENT, TYPE_XBL, TYPE_OTHER * location | * manifest | TYPE_WEB_MANIFEST - * object | TYPE_OBJECT + * object | TYPE_INTERNAL_OBJECT * ping | TYPE_PING * plugin | TYPE_OBJECT_SUBREQUEST * prefetch | @@ -74,7 +74,6 @@ namespace dom { * TODO: Add a content type for form * TODO: Add a content type for favicon * TODO: Add a content type for download - * TODO: Split TYPE_OBJECT into TYPE_EMBED and TYPE_OBJECT */ class Request; diff --git a/dom/html/HTMLObjectElement.h b/dom/html/HTMLObjectElement.h index 64ec1de99489..1526a7b24ba7 100644 --- a/dom/html/HTMLObjectElement.h +++ b/dom/html/HTMLObjectElement.h @@ -246,7 +246,12 @@ private: * value. This is used to know the default tabindex value. */ bool IsFocusableForTabIndex(); - + + nsContentPolicyType GetContentPolicyType() const override + { + return nsIContentPolicy::TYPE_INTERNAL_OBJECT; + } + virtual void GetItemValueText(DOMString& text) override; virtual void SetItemValueText(const nsAString& text) override; diff --git a/dom/html/HTMLSharedObjectElement.cpp b/dom/html/HTMLSharedObjectElement.cpp index 24da41be3e4b..7317746df37b 100644 --- a/dom/html/HTMLSharedObjectElement.cpp +++ b/dom/html/HTMLSharedObjectElement.cpp @@ -387,5 +387,18 @@ HTMLSharedObjectElement::WrapNode(JSContext* aCx, JS::Handle aGivenPr return rootedObj; } +nsContentPolicyType +HTMLSharedObjectElement::GetContentPolicyType() const +{ + if (mNodeInfo->Equals(nsGkAtoms::applet)) { + // We use TYPE_INTERNAL_OBJECT for applet too, since it is not exposed + // through RequestContext yet. + return nsIContentPolicy::TYPE_INTERNAL_OBJECT; + } else { + MOZ_ASSERT(mNodeInfo->Equals(nsGkAtoms::embed)); + return nsIContentPolicy::TYPE_INTERNAL_EMBED; + } +} + } // namespace dom } // namespace mozilla diff --git a/dom/html/HTMLSharedObjectElement.h b/dom/html/HTMLSharedObjectElement.h index a4df86064ffb..70c3e4b6bed5 100644 --- a/dom/html/HTMLSharedObjectElement.h +++ b/dom/html/HTMLSharedObjectElement.h @@ -207,6 +207,8 @@ private: nsGkAtoms::src; } + nsContentPolicyType GetContentPolicyType() const override; + // mIsDoneAddingChildren is only really used for . This boolean is // always true for , per the documentation in nsIContent.h. bool mIsDoneAddingChildren; diff --git a/dom/workers/test/serviceworkers/fetch/context/index.html b/dom/workers/test/serviceworkers/fetch/context/index.html index 218ead144bc7..c6dfef99c8da 100644 --- a/dom/workers/test/serviceworkers/fetch/context/index.html +++ b/dom/workers/test/serviceworkers/fetch/context/index.html @@ -128,8 +128,7 @@ document.documentElement.appendChild(embed); navigator.serviceWorker.addEventListener("message", function onMessage(e) { if (e.data.data == "embed") { - // FIXME: Bug 1148030: This should be "embed". - is(e.data.context, "object", "Expected the object context on an embed"); + is(e.data.context, "embed", "Expected the object context on an embed"); navigator.serviceWorker.removeEventListener("message", onMessage); resolve(); } From f53ae1b46e6b2d27204d96baf1689f7319f24801 Mon Sep 17 00:00:00 2001 From: Michael Layzell Date: Sat, 18 Jul 2015 17:05:12 -0400 Subject: [PATCH 37/69] Bug 1185239 - Feature-check for the Places API in nsPermissionManager migration code; r=ehsan --- extensions/cookie/nsPermissionManager.cpp | 139 +++++++++++----------- 1 file changed, 71 insertions(+), 68 deletions(-) diff --git a/extensions/cookie/nsPermissionManager.cpp b/extensions/cookie/nsPermissionManager.cpp index 3023a9b9deba..5a901c965ca3 100644 --- a/extensions/cookie/nsPermissionManager.cpp +++ b/extensions/cookie/nsPermissionManager.cpp @@ -340,92 +340,95 @@ UpgradeHostToOriginAndInsert(const nsACString& aHost, const nsAFlatCString& aTyp // to guess what ports and protocols we want to add permissions for. // We find every URI which they have visited with this host (or a subdomain of this host), // and try to add it as a principal. + bool foundHistory = false; + nsCOMPtr histSrv = do_GetService(NS_NAVHISTORYSERVICE_CONTRACTID); - nsCOMPtr histQuery; - rv = histSrv->GetNewQuery(getter_AddRefs(histQuery)); - NS_ENSURE_SUCCESS(rv, rv); + if (histSrv) { + nsCOMPtr histQuery; + rv = histSrv->GetNewQuery(getter_AddRefs(histQuery)); + NS_ENSURE_SUCCESS(rv, rv); - // We want to only find history items for this particular host, and subdomains - rv = histQuery->SetDomain(aHost); - NS_ENSURE_SUCCESS(rv, rv); + // We want to only find history items for this particular host, and subdomains + rv = histQuery->SetDomain(aHost); + NS_ENSURE_SUCCESS(rv, rv); - rv = histQuery->SetDomainIsHost(false); - NS_ENSURE_SUCCESS(rv, rv); + rv = histQuery->SetDomainIsHost(false); + NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr histQueryOpts; - rv = histSrv->GetNewQueryOptions(getter_AddRefs(histQueryOpts)); - NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr histQueryOpts; + rv = histSrv->GetNewQueryOptions(getter_AddRefs(histQueryOpts)); + NS_ENSURE_SUCCESS(rv, rv); - // We want to get the URIs for every item in the user's history with the given host - rv = histQueryOpts->SetResultType(nsINavHistoryQueryOptions::RESULTS_AS_URI); - NS_ENSURE_SUCCESS(rv, rv); + // We want to get the URIs for every item in the user's history with the given host + rv = histQueryOpts->SetResultType(nsINavHistoryQueryOptions::RESULTS_AS_URI); + NS_ENSURE_SUCCESS(rv, rv); - // We only search history, because searching both bookmarks and history - // is not supported, and history tends to be more comprehensive. - rv = histQueryOpts->SetQueryType(nsINavHistoryQueryOptions::QUERY_TYPE_HISTORY); - NS_ENSURE_SUCCESS(rv, rv); + // We only search history, because searching both bookmarks and history + // is not supported, and history tends to be more comprehensive. + rv = histQueryOpts->SetQueryType(nsINavHistoryQueryOptions::QUERY_TYPE_HISTORY); + NS_ENSURE_SUCCESS(rv, rv); - // We include hidden URIs (such as those visited via iFrames) as they may have permissions too - rv = histQueryOpts->SetIncludeHidden(true); - NS_ENSURE_SUCCESS(rv, rv); + // We include hidden URIs (such as those visited via iFrames) as they may have permissions too + rv = histQueryOpts->SetIncludeHidden(true); + NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr histResult; - rv = histSrv->ExecuteQuery(histQuery, histQueryOpts, getter_AddRefs(histResult)); - NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr histResult; + rv = histSrv->ExecuteQuery(histQuery, histQueryOpts, getter_AddRefs(histResult)); + NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr histResultContainer; - rv = histResult->GetRoot(getter_AddRefs(histResultContainer)); - NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr histResultContainer; + rv = histResult->GetRoot(getter_AddRefs(histResultContainer)); + NS_ENSURE_SUCCESS(rv, rv); - rv = histResultContainer->SetContainerOpen(true); - NS_ENSURE_SUCCESS(rv, rv); + rv = histResultContainer->SetContainerOpen(true); + NS_ENSURE_SUCCESS(rv, rv); - uint32_t childCount = 0; - rv = histResultContainer->GetChildCount(&childCount); - NS_ENSURE_SUCCESS(rv, rv); + uint32_t childCount = 0; + rv = histResultContainer->GetChildCount(&childCount); + NS_ENSURE_SUCCESS(rv, rv); - bool foundHistory = false; - for (uint32_t i = 0; i < childCount; i++) { - nsCOMPtr child; - histResultContainer->GetChild(i, getter_AddRefs(child)); - if (NS_FAILED(rv)) continue; + for (uint32_t i = 0; i < childCount; i++) { + nsCOMPtr child; + histResultContainer->GetChild(i, getter_AddRefs(child)); + if (NS_FAILED(rv)) continue; - uint32_t type; - rv = child->GetType(&type); - if (NS_FAILED(rv) || type != nsINavHistoryResultNode::RESULT_TYPE_URI) { - NS_WARNING("Unexpected non-RESULT_TYPE_URI node in " - "UpgradeHostToOriginAndInsert()"); - continue; + uint32_t type; + rv = child->GetType(&type); + if (NS_FAILED(rv) || type != nsINavHistoryResultNode::RESULT_TYPE_URI) { + NS_WARNING("Unexpected non-RESULT_TYPE_URI node in " + "UpgradeHostToOriginAndInsert()"); + continue; + } + + nsAutoCString uriSpec; + rv = child->GetUri(uriSpec); + if (NS_FAILED(rv)) continue; + + nsCOMPtr uri; + rv = NS_NewURI(getter_AddRefs(uri), uriSpec); + if (NS_FAILED(rv)) continue; + + // Use the provided host - this URI may be for a subdomain, rather than the host we care about. + rv = uri->SetHost(aHost); + if (NS_FAILED(rv)) continue; + + // We now have a URI which we can make a nsIPrincipal out of + nsCOMPtr principal; + rv = GetPrincipal(uri, aAppId, aIsInBrowserElement, getter_AddRefs(principal)); + if (NS_FAILED(rv)) continue; + + // Insert it! (The backend should be able to deal with us inserting the same origin repeatedly) + foundHistory = true; + rv = aHelper->Insert(principal, aType, aPermission, + aExpireType, aExpireTime, aModificationTime); + NS_WARN_IF(NS_FAILED(rv)); } - nsAutoCString uriSpec; - rv = child->GetUri(uriSpec); - if (NS_FAILED(rv)) continue; - - nsCOMPtr uri; - rv = NS_NewURI(getter_AddRefs(uri), uriSpec); - if (NS_FAILED(rv)) continue; - - // Use the provided host - this URI may be for a subdomain, rather than the host we care about. - rv = uri->SetHost(aHost); - if (NS_FAILED(rv)) continue; - - // We now have a URI which we can make a nsIPrincipal out of - nsCOMPtr principal; - rv = GetPrincipal(uri, aAppId, aIsInBrowserElement, getter_AddRefs(principal)); - if (NS_FAILED(rv)) continue; - - // Insert it! (The backend should be able to deal with us inserting the same origin repeatedly) - foundHistory = true; - rv = aHelper->Insert(principal, aType, aPermission, - aExpireType, aExpireTime, aModificationTime); - NS_WARN_IF(NS_FAILED(rv)); + rv = histResultContainer->SetContainerOpen(false); + NS_ENSURE_SUCCESS(rv, rv); } - rv = histResultContainer->SetContainerOpen(false); - NS_ENSURE_SUCCESS(rv, rv); - // If we didn't find any origins for this host in the poermissions database, // we can insert the default http:// and https:// permissions into the database. // This has a relatively high liklihood of applying the permission to the correct From b7a55dbc9b32d2b1c17ebdb3f868b77181b9ad66 Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Sun, 19 Jul 2015 00:01:37 +0200 Subject: [PATCH 38/69] Bug 1184564 part 5 - Remove jsval typedef. r=jorendorff --- js/public/Value.h | 7 ------- js/src/builtin/Profilers.cpp | 22 +++++++++++----------- js/src/jit/arm/MacroAssembler-arm.h | 2 +- js/src/jit/mips/MacroAssembler-mips.h | 2 +- 4 files changed, 13 insertions(+), 20 deletions(-) diff --git a/js/public/Value.h b/js/public/Value.h index c30209793d5a..9f7c44369c32 100644 --- a/js/public/Value.h +++ b/js/public/Value.h @@ -1940,13 +1940,6 @@ static_assert(sizeof(LayoutAlignmentTester) == 16, } // namespace JS -/* - * JS::Value and jsval are the same type; jsval is the old name, kept around - * for backwards compatibility along with all the JSVAL_* operations below. - * jsval_layout is an implementation detail and should not be used externally. - */ -typedef JS::Value jsval; - static_assert(sizeof(jsval_layout) == sizeof(JS::Value), "jsval_layout and JS::Value must have identical layouts"); diff --git a/js/src/builtin/Profilers.cpp b/js/src/builtin/Profilers.cpp index 9a36d1672b51..43708372dc72 100644 --- a/js/src/builtin/Profilers.cpp +++ b/js/src/builtin/Profilers.cpp @@ -229,7 +229,7 @@ struct RequiredStringArg { }; static bool -StartProfiling(JSContext* cx, unsigned argc, jsval* vp) +StartProfiling(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() == 0) { @@ -256,7 +256,7 @@ StartProfiling(JSContext* cx, unsigned argc, jsval* vp) } static bool -StopProfiling(JSContext* cx, unsigned argc, jsval* vp) +StopProfiling(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() == 0) { @@ -272,7 +272,7 @@ StopProfiling(JSContext* cx, unsigned argc, jsval* vp) } static bool -PauseProfilers(JSContext* cx, unsigned argc, jsval* vp) +PauseProfilers(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() == 0) { @@ -288,7 +288,7 @@ PauseProfilers(JSContext* cx, unsigned argc, jsval* vp) } static bool -ResumeProfilers(JSContext* cx, unsigned argc, jsval* vp) +ResumeProfilers(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() == 0) { @@ -305,7 +305,7 @@ ResumeProfilers(JSContext* cx, unsigned argc, jsval* vp) /* Usage: DumpProfile([filename[, profileName]]) */ static bool -DumpProfile(JSContext* cx, unsigned argc, jsval* vp) +DumpProfile(JSContext* cx, unsigned argc, Value* vp) { bool ret; CallArgs args = CallArgsFromVp(argc, vp); @@ -332,7 +332,7 @@ DumpProfile(JSContext* cx, unsigned argc, jsval* vp) } static bool -GetMaxGCPauseSinceClear(JSContext* cx, unsigned argc, jsval* vp) +GetMaxGCPauseSinceClear(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); args.rval().setNumber(uint32_t(cx->runtime()->gc.stats.getMaxGCPauseSinceClear())); @@ -340,7 +340,7 @@ GetMaxGCPauseSinceClear(JSContext* cx, unsigned argc, jsval* vp) } static bool -ClearMaxGCPauseAccumulator(JSContext* cx, unsigned argc, jsval* vp) +ClearMaxGCPauseAccumulator(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); args.rval().setNumber(uint32_t(cx->runtime()->gc.stats.clearMaxGCPauseAccumulator())); @@ -350,7 +350,7 @@ ClearMaxGCPauseAccumulator(JSContext* cx, unsigned argc, jsval* vp) #if defined(MOZ_SHARK) || defined(MOZ_INSTRUMENTS) static bool -IgnoreAndReturnTrue(JSContext* cx, unsigned argc, jsval* vp) +IgnoreAndReturnTrue(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); args.rval().setBoolean(true); @@ -361,7 +361,7 @@ IgnoreAndReturnTrue(JSContext* cx, unsigned argc, jsval* vp) #ifdef MOZ_CALLGRIND static bool -StartCallgrind(JSContext* cx, unsigned argc, jsval* vp) +StartCallgrind(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); args.rval().setBoolean(js_StartCallgrind()); @@ -369,7 +369,7 @@ StartCallgrind(JSContext* cx, unsigned argc, jsval* vp) } static bool -StopCallgrind(JSContext* cx, unsigned argc, jsval* vp) +StopCallgrind(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); args.rval().setBoolean(js_StopCallgrind()); @@ -377,7 +377,7 @@ StopCallgrind(JSContext* cx, unsigned argc, jsval* vp) } static bool -DumpCallgrind(JSContext* cx, unsigned argc, jsval* vp) +DumpCallgrind(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() == 0) { diff --git a/js/src/jit/arm/MacroAssembler-arm.h b/js/src/jit/arm/MacroAssembler-arm.h index 08f8f0c249a8..ef5012665b8a 100644 --- a/js/src/jit/arm/MacroAssembler-arm.h +++ b/js/src/jit/arm/MacroAssembler-arm.h @@ -24,7 +24,7 @@ namespace jit { static Register CallReg = ip; static const int defaultShift = 3; -JS_STATIC_ASSERT(1 << defaultShift == sizeof(jsval)); +JS_STATIC_ASSERT(1 << defaultShift == sizeof(JS::Value)); // MacroAssemblerARM is inheriting form Assembler defined in // Assembler-arm.{h,cpp} diff --git a/js/src/jit/mips/MacroAssembler-mips.h b/js/src/jit/mips/MacroAssembler-mips.h index e98c513df44f..465bffe6375b 100644 --- a/js/src/jit/mips/MacroAssembler-mips.h +++ b/js/src/jit/mips/MacroAssembler-mips.h @@ -63,7 +63,7 @@ static const ValueOperand softfpReturnOperand = ValueOperand(v1, v0); static Register CallReg = t9; static const int defaultShift = 3; -static_assert(1 << defaultShift == sizeof(jsval), "The defaultShift is wrong"); +static_assert(1 << defaultShift == sizeof(JS::Value), "The defaultShift is wrong"); class MacroAssemblerMIPS : public Assembler { From e5ea6fe8a3d6c67a08e1a1c7ea8679aee2d0ea6e Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Sun, 19 Jul 2015 10:30:52 +1000 Subject: [PATCH 39/69] Bug 1184443 - Make async ExitFullscreen call ask the window to exit fullscreen first. r=smaug --HG-- extra : source : 237250013b141f622112c0284e0db8a65fc28c3d --- dom/base/Element.cpp | 2 +- dom/base/nsDOMWindowUtils.cpp | 2 +- dom/base/nsDocument.cpp | 83 +++++++++++++++-------------------- dom/base/nsDocument.h | 2 - dom/base/nsFocusManager.cpp | 2 +- dom/base/nsGlobalWindow.cpp | 8 ++-- dom/base/nsIDocument.h | 35 ++++++++------- layout/base/nsPresShell.cpp | 2 +- 8 files changed, 62 insertions(+), 74 deletions(-) diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp index e68e12545e1d..fe4c81ab0c28 100644 --- a/dom/base/Element.cpp +++ b/dom/base/Element.cpp @@ -1680,7 +1680,7 @@ Element::UnbindFromTree(bool aDeep, bool aNullParent) nsContentUtils::eDOM_PROPERTIES, "RemovedFullScreenElement"); // Fully exit full-screen. - nsIDocument::ExitFullscreen(OwnerDoc(), /* async */ false); + nsIDocument::ExitFullscreenInDocTree(OwnerDoc()); } if (HasPointerLock()) { nsIDocument::UnlockPointer(); diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index 7c68528e47d9..7eb4a6867f5a 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -3212,7 +3212,7 @@ nsDOMWindowUtils::ExitFullscreen() nsCOMPtr doc = GetDocument(); NS_ENSURE_STATE(doc); - nsIDocument::ExitFullscreen(doc, /* async */ false); + nsIDocument::ExitFullscreenInDocTree(doc); return NS_OK; } diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index 5f79863ac5ed..a0a2f895b8d7 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -9358,7 +9358,7 @@ nsDocument::OnPageHide(bool aPersisted, // doctree by the time OnPageHide() is called, so we must store a // reference to the root (in nsDocument::mFullscreenRoot) since we can't // just traverse the doctree to get the root. - nsIDocument::ExitFullscreen(this, /* async */ false); + nsIDocument::ExitFullscreenInDocTree(this); // Since the document is removed from the doctree before OnPageHide() is // called, ExitFullscreen() can't traverse from the root down to *this* @@ -11122,31 +11122,43 @@ SetWindowFullScreen(nsIDocument* aDoc, bool aValue, gfx::VRHMDInfo *aVRHMD = nul nsContentUtils::AddScriptRunner(new nsSetWindowFullScreen(aDoc, aValue, aVRHMD)); } -class nsCallExitFullscreen : public nsRunnable { +static void +AskWindowToExitFullscreen(nsIDocument* aDoc) +{ + if (XRE_GetProcessType() == GeckoProcessType_Content) { + nsContentUtils::DispatchEventOnlyToChrome( + aDoc, ToSupports(aDoc), NS_LITERAL_STRING("MozDOMFullscreen:Exit"), + /* Bubbles */ true, /* Cancelable */ false, + /* DefaultAction */ nullptr); + } else { + SetWindowFullScreen(aDoc, false); + } +} + +class nsCallExitFullscreen : public nsRunnable +{ public: explicit nsCallExitFullscreen(nsIDocument* aDoc) : mDoc(aDoc) {} - NS_IMETHOD Run() + + NS_IMETHOD Run() override final { - nsDocument::ExitFullscreen(mDoc); + if (!mDoc) { + FullscreenRoots::ForEach(&AskWindowToExitFullscreen); + } else { + AskWindowToExitFullscreen(mDoc); + } return NS_OK; } + private: nsCOMPtr mDoc; }; -/* static */ -void -nsIDocument::ExitFullscreen(nsIDocument* aDoc, bool aRunAsync) +/* static */ void +nsIDocument::AsyncExitFullscreen(nsIDocument* aDoc) { - if (aDoc && !aDoc->IsFullScreenDoc()) { - return; - } - if (aRunAsync) { - NS_DispatchToCurrentThread(new nsCallExitFullscreen(aDoc)); - return; - } - nsDocument::ExitFullscreen(aDoc); + NS_DispatchToCurrentThread(new nsCallExitFullscreen(aDoc)); } static bool @@ -11193,16 +11205,16 @@ ResetFullScreen(nsIDocument* aDocument, void* aData) return true; } -static void -ExitFullscreenInDocTree(nsIDocument* aMaybeNotARootDoc) +/* static */ void +nsIDocument::ExitFullscreenInDocTree(nsIDocument* aMaybeNotARootDoc) { MOZ_ASSERT(aMaybeNotARootDoc); + + // Unlock the pointer + UnlockPointer(); + nsCOMPtr root = aMaybeNotARootDoc->GetFullscreenRoot(); - NS_ASSERTION(root, "Should have root when in fullscreen!"); - if (!root) { - return; - } - if (!root->IsFullScreenDoc()) { + if (!root || !root->IsFullScreenDoc()) { // If a document was detached before exiting from fullscreen, it is // possible that the root had left fullscreen state. In this case, // we would not get anything from the ResetFullScreen() call. Root's @@ -11246,24 +11258,6 @@ ExitFullscreenInDocTree(nsIDocument* aMaybeNotARootDoc) SetWindowFullScreen(root, false); } -/* static */ -void -nsDocument::ExitFullscreen(nsIDocument* aDoc) -{ - // Unlock the pointer - UnlockPointer(); - - if (aDoc) { - ExitFullscreenInDocTree(aDoc); - return; - } - - // Clear fullscreen stacks in all fullscreen roots' descendant documents. - FullscreenRoots::ForEach(&ExitFullscreenInDocTree); - NS_ASSERTION(FullscreenRoots::IsEmpty(), - "Should have exited all fullscreen roots from fullscreen"); -} - bool GetFullscreenLeaf(nsIDocument* aDoc, void* aData) { @@ -11318,14 +11312,7 @@ nsDocument::RestorePreviousFullScreenState() if (exitingFullscreen) { // If we are fully exiting fullscreen, don't touch anything here, // just wait for the window to get out from fullscreen first. - if (XRE_GetProcessType() == GeckoProcessType_Content) { - nsContentUtils::DispatchEventOnlyToChrome( - this, ToSupports(this), NS_LITERAL_STRING("MozDOMFullscreen:Exit"), - /* Bubbles */ true, /* Cancelable */ false, - /* DefaultAction */ nullptr); - } else { - SetWindowFullScreen(this, false); - } + AskWindowToExitFullscreen(this); return; } diff --git a/dom/base/nsDocument.h b/dom/base/nsDocument.h index 1fe77e78b35e..07fe43d8809b 100644 --- a/dom/base/nsDocument.h +++ b/dom/base/nsDocument.h @@ -1242,8 +1242,6 @@ public: // already_AddRefed BlockedTrackingNodes() const; - static void ExitFullscreen(nsIDocument* aDoc); - // Do the "fullscreen element ready check" from the fullscreen spec. // It returns true if the given element is allowed to go into fullscreen. bool FullscreenElementReadyCheck(Element* aElement, bool aWasCallerChrome); diff --git a/dom/base/nsFocusManager.cpp b/dom/base/nsFocusManager.cpp index d9062250da93..aa3a24a6c883 100644 --- a/dom/base/nsFocusManager.cpp +++ b/dom/base/nsFocusManager.cpp @@ -1249,7 +1249,7 @@ nsFocusManager::SetFocusInner(nsIContent* aNewContent, int32_t aFlags, contentToFocus->OwnerDoc(), nsContentUtils::eDOM_PROPERTIES, "FocusedWindowedPluginWhileFullScreen"); - nsIDocument::ExitFullscreen(contentToFocus->OwnerDoc(), /* async */ true); + nsIDocument::AsyncExitFullscreen(contentToFocus->OwnerDoc()); } #endif diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index dd6f00072d68..65b5c79efc2b 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -6308,11 +6308,9 @@ FinishDOMFullscreenChange(nsIDocument* aDoc, bool aInDOMFullscreen) // Ask the document to handle any pending DOM fullscreen change. nsIDocument::HandlePendingFullscreenRequests(aDoc); } else { - // Force exit from DOM full-screen mode. This is so that if we're in - // DOM full-screen mode and the user exits full-screen mode with - // the browser full-screen mode toggle keyboard-shortcut, we'll detect - // that and leave DOM API full-screen mode too. - nsIDocument::ExitFullscreen(aDoc, /* async */ false); + // If the window is leaving fullscreen state, also ask the document + // to exit from DOM Fullscreen. + nsIDocument::ExitFullscreenInDocTree(aDoc); } } diff --git a/dom/base/nsIDocument.h b/dom/base/nsIDocument.h index 1b519857b544..bca3dbaa62c1 100644 --- a/dom/base/nsIDocument.h +++ b/dom/base/nsIDocument.h @@ -1165,24 +1165,29 @@ public: virtual void SetApprovedForFullscreen(bool aIsApproved) = 0; /** - * Exits documents out of DOM fullscreen mode. + * Synchronously cleans up the fullscreen state on the given document. * - * If aDocument is null, all fullscreen documents in all browser windows - * exit fullscreen. + * Calling this without performing fullscreen transition could lead + * to undesired effect (the transition happens after document state + * flips), hence it should only be called either by nsGlobalWindow + * when we have performed the transition, or when it is necessary to + * clean up the state immediately. Otherwise, AsyncExitFullscreen() + * should be called instead. * - * If aDocument is non null, all documents from aDocument's fullscreen root - * to the fullscreen leaf exit fullscreen. - * - * Note that the fullscreen leaf is the bottom-most document which is - * fullscreen, it may have non-fullscreen child documents. The fullscreen - * root is normally the chrome document. - * - * If aRunAsync is true, fullscreen is executed asynchronously. - * - * Note if aDocument is not fullscreen this function has no effect, even if - * aDocument has fullscreen ancestors. + * aDocument must not be null. */ - static void ExitFullscreen(nsIDocument* aDocument, bool aRunAsync); + static void ExitFullscreenInDocTree(nsIDocument* aDocument); + + /** + * Ask the document to exit fullscreen state asynchronously. + * + * Different from ExitFullscreenInDocTree(), this allows the window + * to perform fullscreen transition first if any. + * + * If aDocument is null, it will exit fullscreen from all documents + * in all windows. + */ + static void AsyncExitFullscreen(nsIDocument* aDocument); /** * Handles one single fullscreen request, updates `aHandled` if the request diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index a5cc1eda4e0c..0c577eddc2b2 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -7809,7 +7809,7 @@ PresShell::HandleEventInternal(WidgetEvent* aEvent, nsEventStatus* aStatus) // ESC key released while in DOM fullscreen mode. // Fully exit all browser windows and documents from // fullscreen mode. - nsIDocument::ExitFullscreen(nullptr, /* async */ true); + nsIDocument::AsyncExitFullscreen(nullptr); } } nsCOMPtr pointerLockedDoc = From 84bc2d11bce1704b1683e88f1de9c72171445877 Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Sun, 19 Jul 2015 02:47:49 +0100 Subject: [PATCH 40/69] Bug 1184972 - We should always use the top window for any audioChannel operation, r=ehsan --- dom/audiochannel/AudioChannelService.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/dom/audiochannel/AudioChannelService.cpp b/dom/audiochannel/AudioChannelService.cpp index 60a7afb45aa0..42374e37a3ef 100644 --- a/dom/audiochannel/AudioChannelService.cpp +++ b/dom/audiochannel/AudioChannelService.cpp @@ -537,7 +537,14 @@ AudioChannelService::RefreshAgentsVolume(nsPIDOMWindow* aWindow) MOZ_ASSERT(aWindow); MOZ_ASSERT(aWindow->IsOuterWindow()); - AudioChannelWindow* winData = GetWindowData(aWindow->WindowID()); + nsCOMPtr topWindow; + aWindow->GetScriptableTop(getter_AddRefs(topWindow)); + nsCOMPtr pTopWindow = do_QueryInterface(topWindow); + if (!pTopWindow) { + return; + } + + AudioChannelWindow* winData = GetWindowData(pTopWindow->WindowID()); if (!winData) { return; } From 97c618f8b91e42ab04b9380ee69d8f1447f7544d Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Sun, 19 Jul 2015 02:49:32 +0100 Subject: [PATCH 41/69] Bug 1184970 - Remove unused struct in AudioChannelService, r=ehsan --- dom/audiochannel/AudioChannelService.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/dom/audiochannel/AudioChannelService.cpp b/dom/audiochannel/AudioChannelService.cpp index 42374e37a3ef..c3b858ab7761 100644 --- a/dom/audiochannel/AudioChannelService.cpp +++ b/dom/audiochannel/AudioChannelService.cpp @@ -521,16 +521,6 @@ AudioChannelService::Observe(nsISupports* aSubject, const char* aTopic, return NS_OK; } -struct RefreshAgentsVolumeData -{ - explicit RefreshAgentsVolumeData(nsPIDOMWindow* aWindow) - : mWindow(aWindow) - {} - - nsPIDOMWindow* mWindow; - nsTArray> mAgents; -}; - void AudioChannelService::RefreshAgentsVolume(nsPIDOMWindow* aWindow) { From 8461bab676c2f43f5d81e00b1f57068d6dd1ab4d Mon Sep 17 00:00:00 2001 From: Mike Conley Date: Fri, 17 Jul 2015 11:30:51 -0400 Subject: [PATCH 42/69] Bug 1114299 - Pass window features up from the content process via nsCString. r=smaug The code that deals with the features is looking for char *, and we were going through the hassle of converting that char * to a UTF16 string, and then back down to UTF8, and then to char *. Really, we just need to send up a nsCString, which simplifies things. --HG-- extra : commitid : HgzV7FFsQCv extra : rebase_source : feabba83d86d732fbac5d1d26c6bf362928c0b9f extra : histedit_source : 5a0cdbbbbd05632d2071de2ecc7771ed71abcbe2 --- dom/ipc/PBrowser.ipdl | 2 +- dom/ipc/TabChild.cpp | 2 +- dom/ipc/TabParent.cpp | 4 ++-- dom/ipc/TabParent.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dom/ipc/PBrowser.ipdl b/dom/ipc/PBrowser.ipdl index 9ad605a95d0b..7c975f64ff5c 100644 --- a/dom/ipc/PBrowser.ipdl +++ b/dom/ipc/PBrowser.ipdl @@ -163,7 +163,7 @@ parent: bool aSizeSpecified, nsString aURI, nsString aName, - nsString aFeatures, + nsCString aFeatures, nsString aBaseURI) returns (nsresult rv, bool windowOpened, diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index 1e8783d45e96..9a76d2f4b45b 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -1606,7 +1606,7 @@ TabChild::ProvideWindowCommon(nsIDOMWindow* aOpener, if (!SendCreateWindow(newChild, aChromeFlags, aCalledFromJS, aPositionSpecified, aSizeSpecified, url, - name, NS_ConvertUTF8toUTF16(features), + name, features, NS_ConvertUTF8toUTF16(baseURIString), &rv, aWindowIsNew, diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index 82f9bac685ac..cc7d513be3ac 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -612,7 +612,7 @@ TabParent::RecvCreateWindow(PBrowserParent* aNewTab, const bool& aSizeSpecified, const nsString& aURI, const nsString& aName, - const nsString& aFeatures, + const nsCString& aFeatures, const nsString& aBaseURI, nsresult* aResult, bool* aWindowIsNew, @@ -737,7 +737,7 @@ TabParent::RecvCreateWindow(PBrowserParent* aNewTab, *aResult = pwwatch->OpenWindow2(parent, finalURIString.get(), NS_ConvertUTF16toUTF8(aName).get(), - NS_ConvertUTF16toUTF8(aFeatures).get(), aCalledFromJS, + aFeatures.get(), aCalledFromJS, false, false, this, nullptr, getter_AddRefs(window)); if (NS_WARN_IF(NS_FAILED(*aResult))) diff --git a/dom/ipc/TabParent.h b/dom/ipc/TabParent.h index 2cc56eebdfcc..d67b07332142 100644 --- a/dom/ipc/TabParent.h +++ b/dom/ipc/TabParent.h @@ -142,7 +142,7 @@ public: const bool& aSizeSpecified, const nsString& aURI, const nsString& aName, - const nsString& aFeatures, + const nsCString& aFeatures, const nsString& aBaseURI, nsresult* aResult, bool* aWindowIsNew, From c86643f748089bc8879b2d01ab07ce367a943ccf Mon Sep 17 00:00:00 2001 From: Mike Conley Date: Fri, 10 Jul 2015 11:40:19 -0400 Subject: [PATCH 43/69] Bug 1114299 - Be more strict about which window chromeFlags we compute from content. r=smaug We don't ever want to accept "private", "non-private", "remote" or "non-remote" from the content process. We only let the parent decide when to open those types of windows. --HG-- extra : commitid : 9MGeXNdb9US extra : rebase_source : 41a4d9785bd667b84c255eda0ac7fedf44733736 extra : histedit_source : 698c707b68c60108e0631b775a98fb4e241c009b --- docshell/base/nsDocShell.cpp | 6 +- dom/ipc/TabChild.cpp | 4 - dom/ipc/TabParent.cpp | 11 ++- .../windowwatcher/nsWindowWatcher.cpp | 74 +++++++++++-------- .../windowwatcher/nsWindowWatcher.h | 1 + 5 files changed, 56 insertions(+), 40 deletions(-) diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 70d5d639177b..46ed81514252 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -9837,13 +9837,9 @@ nsDocShell::InternalLoad(nsIURI* aURI, if (aURI) { aURI->GetSpec(spec); } - nsAutoString features; - if (mInPrivateBrowsing) { - features.AssignLiteral("private"); - } rv = win->OpenNoNavigate(NS_ConvertUTF8toUTF16(spec), name, // window name - features, + EmptyString(), // Features getter_AddRefs(newWin)); // In some cases the Open call doesn't actually result in a new diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index 9a76d2f4b45b..47b6df3751e7 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -1597,10 +1597,6 @@ TabChild::ProvideWindowCommon(nsIDOMWindow* aOpener, nsAutoCString baseURIString; baseURI->GetSpec(baseURIString); - // We can assume that if content is requesting to open a window from a remote - // tab, then we want to enforce that the new window is also a remote tab. - features.AppendLiteral(",remote"); - nsresult rv; if (!SendCreateWindow(newChild, diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index cc7d513be3ac..e5c1440886cf 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -622,6 +622,13 @@ TabParent::RecvCreateWindow(PBrowserParent* aNewTab, // We always expect to open a new window here. If we don't, it's an error. *aWindowIsNew = true; + // The content process should never be in charge of computing whether or + // not a window should be private or remote - the parent will do that. + MOZ_ASSERT(!(aChromeFlags & nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW)); + MOZ_ASSERT(!(aChromeFlags & nsIWebBrowserChrome::CHROME_NON_PRIVATE_WINDOW)); + MOZ_ASSERT(!(aChromeFlags & nsIWebBrowserChrome::CHROME_PRIVATE_LIFETIME)); + MOZ_ASSERT(!(aChromeFlags & nsIWebBrowserChrome::CHROME_REMOTE_WINDOW)); + if (NS_WARN_IF(IsBrowserOrApp())) return false; @@ -735,9 +742,11 @@ TabParent::RecvCreateWindow(PBrowserParent* aNewTab, AutoUseNewTab aunt(newTab, aWindowIsNew, aURLToLoad); + const char* features = aFeatures.Length() ? aFeatures.get() : nullptr; + *aResult = pwwatch->OpenWindow2(parent, finalURIString.get(), NS_ConvertUTF16toUTF8(aName).get(), - aFeatures.get(), aCalledFromJS, + features, aCalledFromJS, false, false, this, nullptr, getter_AddRefs(window)); if (NS_WARN_IF(NS_FAILED(*aResult))) diff --git a/embedding/components/windowwatcher/nsWindowWatcher.cpp b/embedding/components/windowwatcher/nsWindowWatcher.cpp index 6dd50b2c73e4..0f96f1ae4ae8 100644 --- a/embedding/components/windowwatcher/nsWindowWatcher.cpp +++ b/embedding/components/windowwatcher/nsWindowWatcher.cpp @@ -562,7 +562,8 @@ nsWindowWatcher::OpenWindowInternal(nsIDOMWindow* aParent, // security checks. chromeFlags = CalculateChromeFlags(aParent, features.get(), featuresSpecified, aDialog, uriToLoadIsChrome, - hasChromeParent, openedFromRemoteTab); + hasChromeParent, aCalledFromJS, + openedFromRemoteTab); // If we are opening a window from a remote browser, the resulting window // should also be remote. @@ -1466,8 +1467,8 @@ nsWindowWatcher::URIfromURL(const char* aURL, #define NS_CALCULATE_CHROME_FLAG_FOR(feature, flag) \ prefBranch->GetBoolPref(feature, &forceEnable); \ - if (forceEnable && !(aDialog && isCallerChrome) && \ - !(isCallerChrome && aHasChromeParent) && !aChromeURL) { \ + if (forceEnable && !(aDialog && !openedFromContentScript) && \ + !(!openedFromContentScript && aHasChromeParent) && !aChromeURL) { \ chromeFlags |= flag; \ } else { \ chromeFlags |= \ @@ -1491,26 +1492,30 @@ nsWindowWatcher::CalculateChromeFlags(nsIDOMWindow* aParent, bool aDialog, bool aChromeURL, bool aHasChromeParent, + bool aCalledFromJS, bool aOpenedFromRemoteTab) { + const bool inContentProcess = XRE_IsContentProcess(); uint32_t chromeFlags = 0; - bool isCallerChrome = - nsContentUtils::IsCallerChrome() && !aOpenedFromRemoteTab; - bool onlyPrivateFlag = aFeaturesSpecified && aFeatures && isCallerChrome && - nsCRT::strcasecmp(aFeatures, "private") == 0; - if (!aFeaturesSpecified || !aFeatures || onlyPrivateFlag) { + if (!aFeaturesSpecified || !aFeatures) { chromeFlags = nsIWebBrowserChrome::CHROME_ALL; if (aDialog) { chromeFlags |= nsIWebBrowserChrome::CHROME_OPENAS_DIALOG | nsIWebBrowserChrome::CHROME_OPENAS_CHROME; } - if (onlyPrivateFlag) { - chromeFlags |= nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW; + + if (inContentProcess) { + return chromeFlags; } - return chromeFlags; + } else { + chromeFlags = nsIWebBrowserChrome::CHROME_WINDOW_BORDERS; } + bool openedFromContentScript = + aOpenedFromRemoteTab ? aCalledFromJS + : !nsContentUtils::IsCallerChrome(); + /* This function has become complicated since browser windows and dialogs diverged. The difference is, browser windows assume all chrome not explicitly mentioned is off, if the features string @@ -1520,30 +1525,32 @@ nsWindowWatcher::CalculateChromeFlags(nsIDOMWindow* aParent, in the standards-compliant window.(normal)open. */ bool presenceFlag = false; - - chromeFlags = nsIWebBrowserChrome::CHROME_WINDOW_BORDERS; if (aDialog && WinHasOption(aFeatures, "all", 0, &presenceFlag)) { chromeFlags = nsIWebBrowserChrome::CHROME_ALL; } /* Next, allow explicitly named options to override the initial settings */ - // Determine whether the window is a private browsing window - if (isCallerChrome) { + if (!inContentProcess && !openedFromContentScript) { + // Determine whether the window is a private browsing window chromeFlags |= WinHasOption(aFeatures, "private", 0, &presenceFlag) ? nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW : 0; chromeFlags |= WinHasOption(aFeatures, "non-private", 0, &presenceFlag) ? nsIWebBrowserChrome::CHROME_NON_PRIVATE_WINDOW : 0; } - // Determine whether the window should have remote tabs. - if (isCallerChrome || aOpenedFromRemoteTab) { - bool remote; - if (BrowserTabsRemoteAutostart()) { - remote = !WinHasOption(aFeatures, "non-remote", 0, &presenceFlag); - } else { - remote = WinHasOption(aFeatures, "remote", 0, &presenceFlag); + if (!inContentProcess) { + // Determine whether the window should have remote tabs. + bool remote = BrowserTabsRemoteAutostart(); + + if (!openedFromContentScript) { + if (remote) { + remote = !WinHasOption(aFeatures, "non-remote", 0, &presenceFlag); + } else { + remote = WinHasOption(aFeatures, "remote", 0, &presenceFlag); + } } + if (remote) { chromeFlags |= nsIWebBrowserChrome::CHROME_REMOTE_WINDOW; } @@ -1644,7 +1651,7 @@ nsWindowWatcher::CalculateChromeFlags(nsIDOMWindow* aParent, if (aParent) { aParent->GetFullScreen(&isFullScreen); } - if (isFullScreen && !isCallerChrome) { + if (isFullScreen && openedFromContentScript) { // If the parent window is in fullscreen & the caller context is content, // dialog feature is disabled. (see bug 803675) disableDialogFeature = true; @@ -1671,7 +1678,7 @@ nsWindowWatcher::CalculateChromeFlags(nsIDOMWindow* aParent, */ // Check security state for use in determing window dimensions - if (!isCallerChrome || !aHasChromeParent) { + if (openedFromContentScript || !aHasChromeParent) { // If priv check fails (or if we're called from chrome, but the // parent is not a chrome window), set all elements to minimum // reqs., else leave them alone. @@ -2270,12 +2277,19 @@ nsWindowWatcher::GetWindowOpenLocation(nsIDOMWindow* aParent, return nsIBrowserDOMWindow::OPEN_NEWWINDOW; } - if (restrictionPref == 2 && - // Only continue if there are no size/position features and no special - // chrome flags. - (aChromeFlags != nsIWebBrowserChrome::CHROME_ALL || - aPositionSpecified || aSizeSpecified)) { - return nsIBrowserDOMWindow::OPEN_NEWWINDOW; + if (restrictionPref == 2) { + // Only continue if there are no size/position features and no special + // chrome flags - with the exception of the remoteness and private flags, + // which might have been automatically flipped by Gecko. + int32_t uiChromeFlags = aChromeFlags; + uiChromeFlags &= ~(nsIWebBrowserChrome::CHROME_REMOTE_WINDOW | + nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW | + nsIWebBrowserChrome::CHROME_NON_PRIVATE_WINDOW | + nsIWebBrowserChrome::CHROME_PRIVATE_LIFETIME); + if (uiChromeFlags != nsIWebBrowserChrome::CHROME_ALL || + aPositionSpecified || aSizeSpecified) { + return nsIBrowserDOMWindow::OPEN_NEWWINDOW; + } } } diff --git a/embedding/components/windowwatcher/nsWindowWatcher.h b/embedding/components/windowwatcher/nsWindowWatcher.h index 04a025058371..a71bfab805fb 100644 --- a/embedding/components/windowwatcher/nsWindowWatcher.h +++ b/embedding/components/windowwatcher/nsWindowWatcher.h @@ -96,6 +96,7 @@ protected: bool aDialog, bool aChromeURL, bool aHasChromeParent, + bool aCalledFromJS, bool aOpenedFromRemoteTab); static int32_t WinHasOption(const char* aOptions, const char* aName, int32_t aDefault, bool* aPresenceFlag); From d5b13cb522f27d903ab4b9f9166927f2c6c3d874 Mon Sep 17 00:00:00 2001 From: Mike Conley Date: Fri, 17 Jul 2015 13:51:39 -0400 Subject: [PATCH 44/69] Bug 1114299 - Regression test. r=smaug --HG-- extra : commitid : 40IZTx39dDT extra : rebase_source : 7d4406ece9cd1747d526cc065ef124db721a8a20 extra : histedit_source : 3c287ca9ec92a9612de9ddcaf65780547d707510 --- docshell/test/navigation/browser.ini | 1 + .../browser_test-content-chromeflags.js | 45 +++++++++++++++++++ .../BrowserTestUtils/BrowserTestUtils.jsm | 15 +++++++ 3 files changed, 61 insertions(+) create mode 100644 docshell/test/navigation/browser_test-content-chromeflags.js diff --git a/docshell/test/navigation/browser.ini b/docshell/test/navigation/browser.ini index b6c882164ef7..39e4b503c0d0 100644 --- a/docshell/test/navigation/browser.ini +++ b/docshell/test/navigation/browser.ini @@ -9,3 +9,4 @@ support-files = [browser_bug343515.js] skip-if = e10s # Bug ?????? - test directly touches content (tries to QI the content window) +[browser_test-content-chromeflags.js] diff --git a/docshell/test/navigation/browser_test-content-chromeflags.js b/docshell/test/navigation/browser_test-content-chromeflags.js new file mode 100644 index 000000000000..64559897cd4e --- /dev/null +++ b/docshell/test/navigation/browser_test-content-chromeflags.js @@ -0,0 +1,45 @@ +const TEST_PAGE = `data:text/html,Test`; +const CHROME_ALL = Ci.nsIWebBrowserChrome.CHROME_ALL; +const CHROME_REMOTE_WINDOW = Ci.nsIWebBrowserChrome.CHROME_REMOTE_WINDOW; + +/** + * Tests that when we open new browser windows from content they + * get the full browser chrome. + */ +add_task(function* () { + // Make sure that the window.open call will open a new + // window instead of a new tab. + yield new Promise(resolve => { + SpecialPowers.pushPrefEnv({ + "set": [ + ["browser.link.open_newwindow", 2], + ] + }, resolve); + }); + + yield BrowserTestUtils.withNewTab({ + gBrowser, + url: TEST_PAGE + }, function*(browser) { + let openedPromise = BrowserTestUtils.waitForNewWindow(); + BrowserTestUtils.synthesizeMouse("a", 0, 0, {}, browser); + let win = yield openedPromise; + + let chromeFlags = win.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + .QueryInterface(Ci.nsIDocShellTreeItem) + .treeOwner + .QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIXULWindow) + .chromeFlags; + + // In the multi-process case, the new window will have the + // CHROME_REMOTE_WINDOW flag set. + const EXPECTED = gMultiProcessBrowser ? CHROME_ALL | CHROME_REMOTE_WINDOW + : CHROME_ALL; + + is(chromeFlags, EXPECTED, "Window should have opened with all chrome"); + + BrowserTestUtils.closeWindow(win); + }); +}); diff --git a/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm b/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm index 4cbb18aa7903..21eafb27afda 100644 --- a/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm +++ b/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm @@ -188,6 +188,21 @@ this.BrowserTestUtils = { }); }, + /** + * Waits for the next browser window to open and be fully loaded. + * + * @return {Promise} + * A Promise which resolves the next time that a DOM window + * opens and the delayed startup observer notification fires. + */ + waitForNewWindow: Task.async(function* (delayedStartup=true) { + let win = yield this.domWindowOpened(); + + yield TestUtils.topicObserved("browser-delayed-startup-finished", + subject => subject == win); + return win; + }), + /** * Loads a new URI in the given browser and waits until we really started * loading. In e10s browser.loadURI() can be an asynchronous operation due From db5306c0e6fb5aef4b0b34dd06e26bdfb077059b Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Sun, 19 Jul 2015 08:54:41 +0100 Subject: [PATCH 45/69] Bug 1184541 - Create a StructuredCloneHelperInternal and use it in the Console API, r=smaug --- dom/base/Console.cpp | 162 ++++++++++++----------------- dom/base/StructuredCloneHelper.cpp | 158 ++++++++++++++++++++++++++++ dom/base/StructuredCloneHelper.h | 75 +++++++++++++ dom/base/moz.build | 2 + 4 files changed, 302 insertions(+), 95 deletions(-) create mode 100644 dom/base/StructuredCloneHelper.cpp create mode 100644 dom/base/StructuredCloneHelper.h diff --git a/dom/base/Console.cpp b/dom/base/Console.cpp index 6b665e152467..9f33d232b6e5 100644 --- a/dom/base/Console.cpp +++ b/dom/base/Console.cpp @@ -10,6 +10,7 @@ #include "mozilla/dom/BlobBinding.h" #include "mozilla/dom/Exceptions.h" #include "mozilla/dom/File.h" +#include "mozilla/dom/StructuredCloneHelper.h" #include "mozilla/dom/ToJSValue.h" #include "mozilla/Maybe.h" #include "nsCycleCollectionParticipant.h" @@ -74,87 +75,6 @@ ConsoleStructuredCloneData * It's not the best, but at least we are able to show something. */ -// This method is called by the Structured Clone Algorithm when some data has -// to be read. -static JSObject* -ConsoleStructuredCloneCallbacksRead(JSContext* aCx, - JSStructuredCloneReader* /* unused */, - uint32_t aTag, uint32_t aIndex, - void* aClosure) -{ - AssertIsOnMainThread(); - ConsoleStructuredCloneData* data = - static_cast(aClosure); - MOZ_ASSERT(data); - - if (aTag == CONSOLE_TAG_BLOB) { - MOZ_ASSERT(data->mBlobs.Length() > aIndex); - - JS::Rooted val(aCx); - { - nsRefPtr blob = - Blob::Create(data->mParent, data->mBlobs.ElementAt(aIndex)); - if (!ToJSValue(aCx, blob, &val)) { - return nullptr; - } - } - - return &val.toObject(); - } - - MOZ_CRASH("No other tags are supported."); - return nullptr; -} - -// This method is called by the Structured Clone Algorithm when some data has -// to be written. -static bool -ConsoleStructuredCloneCallbacksWrite(JSContext* aCx, - JSStructuredCloneWriter* aWriter, - JS::Handle aObj, - void* aClosure) -{ - ConsoleStructuredCloneData* data = - static_cast(aClosure); - MOZ_ASSERT(data); - - nsRefPtr blob; - if (NS_SUCCEEDED(UNWRAP_OBJECT(Blob, aObj, blob)) && - blob->Impl()->MayBeClonedToOtherThreads()) { - if (!JS_WriteUint32Pair(aWriter, CONSOLE_TAG_BLOB, data->mBlobs.Length())) { - return false; - } - - data->mBlobs.AppendElement(blob->Impl()); - return true; - } - - JS::Rooted value(aCx, JS::ObjectOrNullValue(aObj)); - JS::Rooted jsString(aCx, JS::ToString(aCx, value)); - if (!jsString) { - return false; - } - - if (!JS_WriteString(aWriter, jsString)) { - return false; - } - - return true; -} - -static void -ConsoleStructuredCloneCallbacksError(JSContext* /* aCx */, - uint32_t /* aErrorId */) -{ - NS_WARNING("Failed to clone data for the Console API in workers."); -} - -static const JSStructuredCloneCallbacks gConsoleCallbacks = { - ConsoleStructuredCloneCallbacksRead, - ConsoleStructuredCloneCallbacksWrite, - ConsoleStructuredCloneCallbacksError -}; - class ConsoleCallData final { public: @@ -274,6 +194,7 @@ private: class ConsoleRunnable : public nsRunnable , public WorkerFeature + , public StructuredCloneHelperInternal { public: explicit ConsoleRunnable(Console* aConsole) @@ -431,10 +352,67 @@ protected: RunConsole(JSContext* aCx, nsPIDOMWindow* aOuterWindow, nsPIDOMWindow* aInnerWindow) = 0; + virtual JSObject* ReadCallback(JSContext* aCx, + JSStructuredCloneReader* aReader, + uint32_t aTag, + uint32_t aIndex) override + { + AssertIsOnMainThread(); + + if (aTag == CONSOLE_TAG_BLOB) { + MOZ_ASSERT(mClonedData.mBlobs.Length() > aIndex); + + JS::Rooted val(aCx); + { + nsRefPtr blob = + Blob::Create(mClonedData.mParent, mClonedData.mBlobs.ElementAt(aIndex)); + if (!ToJSValue(aCx, blob, &val)) { + return nullptr; + } + } + + return &val.toObject(); + } + + MOZ_CRASH("No other tags are supported."); + return nullptr; + } + + virtual bool WriteCallback(JSContext* aCx, + JSStructuredCloneWriter* aWriter, + JS::Handle aObj) override + { + nsRefPtr blob; + if (NS_SUCCEEDED(UNWRAP_OBJECT(Blob, aObj, blob)) && + blob->Impl()->MayBeClonedToOtherThreads()) { + if (!JS_WriteUint32Pair(aWriter, CONSOLE_TAG_BLOB, + mClonedData.mBlobs.Length())) { + return false; + } + + mClonedData.mBlobs.AppendElement(blob->Impl()); + return true; + } + + JS::Rooted value(aCx, JS::ObjectOrNullValue(aObj)); + JS::Rooted jsString(aCx, JS::ToString(aCx, value)); + if (!jsString) { + return false; + } + + if (!JS_WriteString(aWriter, jsString)) { + return false; + } + + return true; + } + WorkerPrivate* mWorkerPrivate; // This must be released on the worker thread. nsRefPtr mConsole; + + ConsoleStructuredCloneData mClonedData; }; // This runnable appends a CallData object into the Console queue running on @@ -499,7 +477,7 @@ private: JS::Rooted value(aCx, JS::ObjectValue(*arguments)); - if (!mArguments.write(aCx, value, &gConsoleCallbacks, &mData)) { + if (!Write(aCx, value)) { return false; } @@ -537,12 +515,12 @@ private: } // Now we could have the correct window (if we are not window-less). - mData.mParent = aInnerWindow; + mClonedData.mParent = aInnerWindow; ProcessCallData(aCx); mCallData->CleanupJSObjects(); - mData.mParent = nullptr; + mClonedData.mParent = nullptr; } private: @@ -552,7 +530,7 @@ private: ClearException ce(aCx); JS::Rooted argumentsValue(aCx); - if (!mArguments.read(aCx, &argumentsValue, &gConsoleCallbacks, &mData)) { + if (!Read(aCx, &argumentsValue)) { return; } @@ -582,9 +560,6 @@ private: } nsRefPtr mCallData; - - JSAutoStructuredCloneBuffer mArguments; - ConsoleStructuredCloneData mData; }; // This runnable calls ProfileMethod() on the console on the main-thread. @@ -629,7 +604,7 @@ private: JS::Rooted value(aCx, JS::ObjectValue(*arguments)); - if (!mBuffer.write(aCx, value, &gConsoleCallbacks, &mData)) { + if (!Write(aCx, value)) { return false; } @@ -644,11 +619,11 @@ private: ClearException ce(aCx); // Now we could have the correct window (if we are not window-less). - mData.mParent = aInnerWindow; + mClonedData.mParent = aInnerWindow; JS::Rooted argumentsValue(aCx); - bool ok = mBuffer.read(aCx, &argumentsValue, &gConsoleCallbacks, &mData); - mData.mParent = nullptr; + bool ok = Read(aCx, &argumentsValue); + mClonedData.mParent = nullptr; if (!ok) { return; @@ -682,9 +657,6 @@ private: nsString mAction; Sequence mArguments; - - JSAutoStructuredCloneBuffer mBuffer; - ConsoleStructuredCloneData mData; }; NS_IMPL_CYCLE_COLLECTION_CLASS(Console) diff --git a/dom/base/StructuredCloneHelper.cpp b/dom/base/StructuredCloneHelper.cpp new file mode 100644 index 000000000000..be8306b672c5 --- /dev/null +++ b/dom/base/StructuredCloneHelper.cpp @@ -0,0 +1,158 @@ +/* -*- 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/. */ + +#include "StructuredCloneHelper.h" + +namespace mozilla { +namespace dom { + +namespace { + +JSObject* +StructuredCloneCallbacksRead(JSContext* aCx, + JSStructuredCloneReader* aReader, + uint32_t aTag, uint32_t aIndex, + void* aClosure) +{ + StructuredCloneHelperInternal* helper = + static_cast(aClosure); + MOZ_ASSERT(helper); + return helper->ReadCallback(aCx, aReader, aTag, aIndex); +} + +bool +StructuredCloneCallbacksWrite(JSContext* aCx, + JSStructuredCloneWriter* aWriter, + JS::Handle aObj, + void* aClosure) +{ + StructuredCloneHelperInternal* helper = + static_cast(aClosure); + MOZ_ASSERT(helper); + return helper->WriteCallback(aCx, aWriter, aObj); +} + +bool +StructuredCloneCallbacksReadTransfer(JSContext* aCx, + JSStructuredCloneReader* aReader, + uint32_t aTag, + void* aContent, + uint64_t aExtraData, + void* aClosure, + JS::MutableHandleObject aReturnObject) +{ + StructuredCloneHelperInternal* helper = + static_cast(aClosure); + MOZ_ASSERT(helper); + return helper->ReadTransferCallback(aCx, aReader, aTag, aContent, + aExtraData, aReturnObject); +} + +bool +StructuredCloneCallbacksWriteTransfer(JSContext* aCx, + JS::Handle aObj, + void* aClosure, + // Output: + uint32_t* aTag, + JS::TransferableOwnership* aOwnership, + void** aContent, + uint64_t* aExtraData) +{ + StructuredCloneHelperInternal* helper = + static_cast(aClosure); + MOZ_ASSERT(helper); + return helper->WriteTransferCallback(aCx, aObj, aTag, aOwnership, aContent, + aExtraData); +} + +void +StructuredCloneCallbacksFreeTransfer(uint32_t aTag, + JS::TransferableOwnership aOwnership, + void* aContent, + uint64_t aExtraData, + void* aClosure) +{ + StructuredCloneHelperInternal* helper = + static_cast(aClosure); + MOZ_ASSERT(helper); + return helper->FreeTransferCallback(aTag, aOwnership, aContent, aExtraData); +} + +void +StructuredCloneCallbacksError(JSContext* aCx, + uint32_t aErrorId) +{ + NS_WARNING("Failed to clone data for the Console API in workers."); +} + +const JSStructuredCloneCallbacks gCallbacks = { + StructuredCloneCallbacksRead, + StructuredCloneCallbacksWrite, + StructuredCloneCallbacksError, + StructuredCloneCallbacksReadTransfer, + StructuredCloneCallbacksWriteTransfer, + StructuredCloneCallbacksFreeTransfer +}; + +} // anonymous namespace + +bool +StructuredCloneHelperInternal::Write(JSContext* aCx, + JS::Handle aValue) +{ + MOZ_ASSERT(!mBuffer, "Double Write is not allowed"); + + mBuffer = new JSAutoStructuredCloneBuffer(&gCallbacks, this); + return mBuffer->write(aCx, aValue, &gCallbacks, this); +} + +bool +StructuredCloneHelperInternal::Read(JSContext* aCx, + JS::MutableHandle aValue) +{ + MOZ_ASSERT(mBuffer, "Read() without Write() is not allowed."); + + bool ok = mBuffer->read(aCx, aValue, &gCallbacks, this); + mBuffer = nullptr; + return ok; +} + +bool +StructuredCloneHelperInternal::ReadTransferCallback(JSContext* aCx, + JSStructuredCloneReader* aReader, + uint32_t aTag, + void* aContent, + uint64_t aExtraData, + JS::MutableHandleObject aReturnObject) +{ + MOZ_CRASH("Nothing to read."); + return false; +} + + +bool +StructuredCloneHelperInternal::WriteTransferCallback(JSContext* aCx, + JS::Handle aObj, + uint32_t* aTag, + JS::TransferableOwnership* aOwnership, + void** aContent, + uint64_t* aExtraData) +{ + // No transfers are supported by default. + return false; +} + +void +StructuredCloneHelperInternal::FreeTransferCallback(uint32_t aTag, + JS::TransferableOwnership aOwnership, + void* aContent, + uint64_t aExtraData) +{ + MOZ_CRASH("Nothing to free."); +} + +} // dom namespace +} // mozilla namespace diff --git a/dom/base/StructuredCloneHelper.h b/dom/base/StructuredCloneHelper.h new file mode 100644 index 000000000000..1a508d175de5 --- /dev/null +++ b/dom/base/StructuredCloneHelper.h @@ -0,0 +1,75 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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 mozilla_dom_StructuredCloneHelper_h +#define mozilla_dom_StructuredCloneHelper_h + +#include "js/StructuredClone.h" +#include "nsAutoPtr.h" + +namespace mozilla { +namespace dom { + +class StructuredCloneHelperInternal +{ +public: + // These methods should be implemented in order to clone data. + // Read more documentation in js/public/StructuredClone.h. + + virtual JSObject* ReadCallback(JSContext* aCx, + JSStructuredCloneReader* aReader, + uint32_t aTag, + uint32_t aIndex) = 0; + + virtual bool WriteCallback(JSContext* aCx, + JSStructuredCloneWriter* aWriter, + JS::Handle aObj) = 0; + + // If these 3 methods are not implement, transfering objects will not be + // allowed. + + virtual bool + ReadTransferCallback(JSContext* aCx, + JSStructuredCloneReader* aReader, + uint32_t aTag, + void* aContent, + uint64_t aExtraData, + JS::MutableHandleObject aReturnObject); + + virtual bool + WriteTransferCallback(JSContext* aCx, + JS::Handle aObj, + // Output: + uint32_t* aTag, + JS::TransferableOwnership* aOwnership, + void** aContent, + uint64_t* aExtraData); + + virtual void + FreeTransferCallback(uint32_t aTag, + JS::TransferableOwnership aOwnership, + void* aContent, + uint64_t aExtraData); + + // These methods are what you should use. + + bool Write(JSContext* aCx, + JS::Handle aValue); + + bool Write(JSContext* aCx, + JS::Handle aValue, + JS::Handle aTransfer); + + bool Read(JSContext* aCx, + JS::MutableHandle aValue); + +protected: + nsAutoPtr mBuffer; +}; + +} // dom namespace +} // mozilla namespace + +#endif // mozilla_dom_StructuredCloneHelper_h diff --git a/dom/base/moz.build b/dom/base/moz.build index 92fb71bd3972..d4e4499bdfe5 100644 --- a/dom/base/moz.build +++ b/dom/base/moz.build @@ -195,6 +195,7 @@ EXPORTS.mozilla.dom += [ 'ScreenOrientation.h', 'ScriptSettings.h', 'ShadowRoot.h', + 'StructuredCloneHelper.h', 'StructuredCloneTags.h', 'StyleSheetList.h', 'SubtleCrypto.h', @@ -332,6 +333,7 @@ UNIFIED_SOURCES += [ 'SameProcessMessageQueue.cpp', 'ScriptSettings.cpp', 'ShadowRoot.cpp', + 'StructuredCloneHelper.cpp', 'StyleSheetList.cpp', 'SubtleCrypto.cpp', 'Text.cpp', From 06fe3194ecddd112c38ad68e022bf39d297cc7a0 Mon Sep 17 00:00:00 2001 From: Eric Rahm Date: Sun, 19 Jul 2015 12:27:40 -0700 Subject: [PATCH 46/69] Bug 1183879 - Soften "non-subdocument frame" warning to also allow dummy nsFrames, which exist while subdocument is loading. r=dholbert --- layout/base/nsDocumentViewer.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/layout/base/nsDocumentViewer.cpp b/layout/base/nsDocumentViewer.cpp index a5662e7ce95a..555a28033aa4 100644 --- a/layout/base/nsDocumentViewer.cpp +++ b/layout/base/nsDocumentViewer.cpp @@ -2502,10 +2502,11 @@ nsDocumentViewer::FindContainerView() static_cast(subdocFrame)->EnsureInnerView(); containerView = innerView; } else { - NS_WARNING("Subdocument container has non-subdocument frame"); + NS_WARN_IF_FALSE(!subdocFrame->GetType(), + "Subdocument container has non-subdocument frame"); } } else { - // XXX Silenced by default in bug 117528 + // XXX Silenced by default in bug 1175289 LAYOUT_WARNING("Subdocument container has no frame"); } } From 8bf8e8aa3fc918da5a3fa643a8fa27a2fb004bb2 Mon Sep 17 00:00:00 2001 From: Nicolas Silva Date: Sun, 19 Jul 2015 21:50:17 +0200 Subject: [PATCH 47/69] Bug 1180688 - Reset the appropriate widget states if creating a compositor fails. r=mstange --- widget/nsBaseWidget.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/widget/nsBaseWidget.cpp b/widget/nsBaseWidget.cpp index 0c27bb5ecf0a..087c6a181fff 100644 --- a/widget/nsBaseWidget.cpp +++ b/widget/nsBaseWidget.cpp @@ -1118,6 +1118,10 @@ void nsBaseWidget::CreateCompositor(int aWidth, int aHeight) if (!success || !lf) { NS_WARNING("Failed to create an OMT compositor."); DestroyCompositor(); + mLayerManager = nullptr; + mCompositorChild = nullptr; + mCompositorParent = nullptr; + mCompositorVsyncDispatcher = nullptr; return; } From 28d2dc3e58a5e3f76e7e11051c6231db6dbdc07b Mon Sep 17 00:00:00 2001 From: David Anderson Date: Sun, 19 Jul 2015 14:50:35 -0700 Subject: [PATCH 48/69] Add compositor, layers, and rendering info to nsIGfxInfo. (bug 1179051 part 5, r=mattwoodrow) --- gfx/src/gfxTelemetry.cpp | 36 +++++++++++++ gfx/src/gfxTelemetry.h | 46 +++++++++++++++++ gfx/src/moz.build | 2 + gfx/thebes/gfxPlatform.cpp | 25 +++++++++ gfx/thebes/gfxPlatform.h | 15 ++++++ gfx/thebes/gfxWindowsPlatform.cpp | 85 ++++++++++++++++++++++++------- gfx/thebes/gfxWindowsPlatform.h | 18 ++++++- widget/GfxInfoBase.cpp | 85 +++++++++++++++++++++++++++++++ widget/GfxInfoBase.h | 10 ++++ widget/nsBaseWidget.cpp | 2 + widget/nsIGfxInfo.idl | 28 +++++++++- widget/windows/GfxInfo.cpp | 36 +++++++++++++ widget/windows/GfxInfo.h | 2 + 13 files changed, 369 insertions(+), 21 deletions(-) create mode 100644 gfx/src/gfxTelemetry.cpp create mode 100644 gfx/src/gfxTelemetry.h diff --git a/gfx/src/gfxTelemetry.cpp b/gfx/src/gfxTelemetry.cpp new file mode 100644 index 000000000000..027c6761ed7d --- /dev/null +++ b/gfx/src/gfxTelemetry.cpp @@ -0,0 +1,36 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ +#include "gfxTelemetry.h" + +namespace mozilla { +namespace gfx { + +const char* +FeatureStatusToString(FeatureStatus aStatus) +{ + switch (aStatus) { + case FeatureStatus::Unused: + return "unused"; + case FeatureStatus::Unavailable: + return "unavailable"; + case FeatureStatus::Blocked: + return "blocked"; + case FeatureStatus::Blacklisted: + return "blacklisted"; + case FeatureStatus::Failed: + return "failed"; + case FeatureStatus::Disabled: + return "disabled"; + case FeatureStatus::Available: + return "available"; + default: + MOZ_ASSERT_UNREACHABLE("missing status case"); + return "unknown"; + } +} + +} // namespace gfx +} // namespace mozilla diff --git a/gfx/src/gfxTelemetry.h b/gfx/src/gfxTelemetry.h new file mode 100644 index 000000000000..e65c107c389a --- /dev/null +++ b/gfx/src/gfxTelemetry.h @@ -0,0 +1,46 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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 gfx_src_gfxTelemetry_h__ +#define gfx_src_gfxTelemetry_h__ + +namespace mozilla { +namespace gfx { + +// Describes the status of a graphics feature, in terms of whether or not we've +// attempted to initialize the feature, and if so, whether or not it succeeded +// (and if not, why). +enum class FeatureStatus +{ + // This feature has not been requested. + Unused, + + // This feature is unavailable due to Safe Mode or not being included with + // the operating system. + Unavailable, + + // This feature was blocked for reasons outside the blacklist, such as a + // runtime test failing. + Blocked, + + // This feature has been blocked by the graphics blacklist. + Blacklisted, + + // This feature was attempted but failed to activate. + Failed, + + // This feature was explicitly disabled by the user. + Disabled, + + // This feature is available for use. + Available +}; + +const char* FeatureStatusToString(FeatureStatus aStatus); + +} // namespace gfx +} // namespace mozilla + +#endif // gfx_src_gfxTelemetry_h__ diff --git a/gfx/src/moz.build b/gfx/src/moz.build index 8f9bff14151b..3d26b88016c5 100644 --- a/gfx/src/moz.build +++ b/gfx/src/moz.build @@ -18,6 +18,7 @@ EXPORTS += [ 'FilterSupport.h', 'gfxCore.h', 'gfxCrashReporterUtils.h', + 'gfxTelemetry.h', 'nsBoundingMetrics.h', 'nsColor.h', 'nsColorNameList.h', @@ -56,6 +57,7 @@ UNIFIED_SOURCES += [ 'DriverInitCrashDetection.cpp', 'FilterSupport.cpp', 'gfxCrashReporterUtils.cpp', + 'gfxTelemetry.cpp', 'nsColor.cpp', 'nsFont.cpp', 'nsFontMetrics.cpp', diff --git a/gfx/thebes/gfxPlatform.cpp b/gfx/thebes/gfxPlatform.cpp index c9bb910a078a..041e90d77cfe 100644 --- a/gfx/thebes/gfxPlatform.cpp +++ b/gfx/thebes/gfxPlatform.cpp @@ -379,6 +379,7 @@ gfxPlatform::gfxPlatform() , mTileHeight(-1) , mAzureCanvasBackendCollector(this, &gfxPlatform::GetAzureBackendInfo) , mApzSupportCollector(this, &gfxPlatform::GetApzSupportInfo) + , mCompositorBackend(layers::LayersBackend::LAYERS_NONE) { mAllowDownloadableFonts = UNINITIALIZED_VALUE; mFallbackUsesCmaps = UNINITIALIZED_VALUE; @@ -410,6 +411,12 @@ gfxPlatform::GetPlatform() return gPlatform; } +bool +gfxPlatform::Initialized() +{ + return !!gPlatform; +} + void RecordingPrefChanged(const char *aPrefName, void *aClosure) { if (Preferences::GetBool("gfx.2d.recording", false)) { @@ -2444,3 +2451,21 @@ gfxPlatform::GetCompositorBackends(bool useAcceleration, nsTArray obsvc = services::GetObserverService()) { + obsvc->NotifyObservers(nullptr, "compositor:created", nullptr); + } +} diff --git a/gfx/thebes/gfxPlatform.h b/gfx/thebes/gfxPlatform.h index 1958665aa970..23a57cebdd85 100644 --- a/gfx/thebes/gfxPlatform.h +++ b/gfx/thebes/gfxPlatform.h @@ -159,6 +159,12 @@ public: */ static gfxPlatform *GetPlatform(); + /** + * Returns whether or not graphics has been initialized yet. This is + * intended for Telemetry where we don't necessarily want to initialize + * graphics just to observe its state. + */ + static bool Initialized(); /** * Shut down Thebes. @@ -631,6 +637,11 @@ public: */ static bool PerfWarnings(); + void NotifyCompositorCreated(mozilla::layers::LayersBackend aBackend); + mozilla::layers::LayersBackend GetCompositorBackend() const { + return mCompositorBackend; + } + protected: gfxPlatform(); virtual ~gfxPlatform(); @@ -751,6 +762,10 @@ private: mozilla::RefPtr mRecorder; mozilla::RefPtr mSkiaGlue; + + // Backend that we are compositing with. NONE, if no compositor has been + // created yet. + mozilla::layers::LayersBackend mCompositorBackend; }; #endif /* GFX_PLATFORM_H */ diff --git a/gfx/thebes/gfxWindowsPlatform.cpp b/gfx/thebes/gfxWindowsPlatform.cpp index 0fd2090c1254..0b7d1f59cfe1 100755 --- a/gfx/thebes/gfxWindowsPlatform.cpp +++ b/gfx/thebes/gfxWindowsPlatform.cpp @@ -377,6 +377,8 @@ gfxWindowsPlatform::gfxWindowsPlatform() , mIsWARP(false) , mHasDeviceReset(false) , mDoesD3D11TextureSharingWork(false) + , mD3D11Status(FeatureStatus::Unused) + , mD2DStatus(FeatureStatus::Unused) { mUseClearTypeForDownloadableFonts = UNINITIALIZED_VALUE; mUseClearTypeAlways = UNINITIALIZED_VALUE; @@ -436,7 +438,7 @@ gfxWindowsPlatform::CanUseHardwareVideoDecoding() return !IsWARP() && gfxPlatform::CanUseHardwareVideoDecoding(); } -void +FeatureStatus gfxWindowsPlatform::InitD2DSupport() { #ifdef CAIRO_HAS_D2D_SURFACE @@ -458,30 +460,41 @@ gfxWindowsPlatform::InitD2DSupport() // If D2D is blocked or D3D9 is prefered, and D2D is not force-enabled, then // we don't attempt to use D2D. - if ((d2dBlocked || gfxPrefs::LayersPreferD3D9()) && !gfxPrefs::Direct2DForceEnabled()) { - return; + if (!gfxPrefs::Direct2DForceEnabled()) { + if (d2dBlocked) { + return FeatureStatus::Blacklisted; + } + if (gfxPrefs::LayersPreferD3D9()) { + return FeatureStatus::Disabled; + } } // Do not ever try to use D2D if it's explicitly disabled or if we're not // using DWrite fonts. if (gfxPrefs::Direct2DDisabled() || mUsingGDIFonts) { - return; + return FeatureStatus::Disabled; } - ID3D11Device* device = GetD3D11Device(); - if (IsVistaOrLater() && - !InSafeMode() && - device && - mDoesD3D11TextureSharingWork) - { - VerifyD2DDevice(gfxPrefs::Direct2DForceEnabled()); - if (mD3D10Device && GetD3D11Device()) { - mRenderMode = RENDER_DIRECT2D; - mUseDirectWrite = true; - } - } else { - mD3D10Device = nullptr; + if (!IsVistaOrLater() || !GetD3D11Device()) { + return FeatureStatus::Unavailable; } + if (!mDoesD3D11TextureSharingWork) { + return FeatureStatus::Failed; + } + if (InSafeMode()) { + return FeatureStatus::Blocked; + } + + VerifyD2DDevice(gfxPrefs::Direct2DForceEnabled()); + if (!mD3D10Device || !GetD3D11Device()) { + return FeatureStatus::Failed; + } + + mRenderMode = RENDER_DIRECT2D; + mUseDirectWrite = true; + return FeatureStatus::Available; +#else + return FeatureStatus::Unavailable; #endif } @@ -552,7 +565,7 @@ gfxWindowsPlatform::UpdateRenderMode() mRenderMode = RENDER_GDI; mUseDirectWrite = gfxPrefs::DirectWriteFontRenderingEnabled(); - InitD2DSupport(); + mD2DStatus = InitD2DSupport(); InitDWriteSupport(); uint32_t canvasMask = BackendTypeBit(BackendType::CAIRO); @@ -2056,15 +2069,17 @@ gfxWindowsPlatform::InitD3D11Devices() mD3D11DeviceInitialized = true; mDoesD3D11TextureSharingWork = false; - MOZ_ASSERT(!mD3D11Device); + MOZ_ASSERT(!mD3D11Device); DriverInitCrashDetection detectCrashes; if (InSafeMode() || detectCrashes.DisableAcceleration()) { + mD3D11Status = FeatureStatus::Blocked; return; } D3D11Status status = CheckD3D11Support(); if (status == D3D11Status::Blocked) { + mD3D11Status = FeatureStatus::Blacklisted; return; } @@ -2074,6 +2089,7 @@ gfxWindowsPlatform::InitD3D11Devices() if (!sD3D11CreateDeviceFn) { // We should just be on Windows Vista or XP in this case. + mD3D11Status = FeatureStatus::Unavailable; return; } @@ -2097,6 +2113,7 @@ gfxWindowsPlatform::InitD3D11Devices() (status == D3D11Status::TryWARP || status == D3D11Status::ForceWARP)) { AttemptWARPDeviceCreation(featureLevels); + mD3D11Status = FeatureStatus::Failed; } if (!mD3D11Device) { @@ -2105,6 +2122,7 @@ gfxWindowsPlatform::InitD3D11Devices() } mD3D11Device->SetExceptionMode(0); + mD3D11Status = FeatureStatus::Available; // We create our device for D2D content drawing here. Normally we don't use // D2D content drawing when using WARP. However when WARP is forced by @@ -2409,3 +2427,32 @@ gfxWindowsPlatform::GetAcceleratedCompositorBackends(nsTArray& aB } } } + +FeatureStatus +gfxWindowsPlatform::GetD2D1Status() +{ + if (GetD2DStatus() != FeatureStatus::Available || + !Factory::SupportsD2D1()) + { + return FeatureStatus::Unavailable; + } + + if (!GetD3D11ContentDevice()) { + return FeatureStatus::Failed; + } + + if (!gfxPrefs::Direct2DUse1_1()) { + return FeatureStatus::Disabled; + } + return FeatureStatus::Available; +} + +unsigned +gfxWindowsPlatform::GetD3D11Version() +{ + ID3D11Device* device = GetD3D11Device(); + if (!device) { + return 0; + } + return device->GetFeatureLevel(); +} diff --git a/gfx/thebes/gfxWindowsPlatform.h b/gfx/thebes/gfxWindowsPlatform.h index 24438eb4f10f..eb730b3a8cf0 100644 --- a/gfx/thebes/gfxWindowsPlatform.h +++ b/gfx/thebes/gfxWindowsPlatform.h @@ -20,6 +20,7 @@ #include "gfxDWriteFonts.h" #endif #include "gfxPlatform.h" +#include "gfxTelemetry.h" #include "gfxTypes.h" #include "mozilla/Attributes.h" #include "mozilla/Atomics.h" @@ -261,6 +262,18 @@ public: } bool SupportsApzTouchInput() const override; + // Return the diagnostic status of DirectX initialization. If + // initialization has not been attempted, this returns + // FeatureStatus::Unused. + mozilla::gfx::FeatureStatus GetD3D11Status() const { + return mD3D11Status; + } + mozilla::gfx::FeatureStatus GetD2DStatus() const { + return mD2DStatus; + } + unsigned GetD3D11Version(); + mozilla::gfx::FeatureStatus GetD2D1Status(); + virtual already_AddRefed CreateHardwareVsyncSource() override; static mozilla::Atomic sD3D11MemoryUsed; static mozilla::Atomic sD3D9MemoryUsed; @@ -298,7 +311,7 @@ private: bool AttemptD3D11ContentDeviceCreation(const nsTArray& aFeatureLevels); // Used by UpdateRenderMode(). - void InitD2DSupport(); + mozilla::gfx::FeatureStatus InitD2DSupport(); void InitDWriteSupport(); IDXGIAdapter1 *GetDXGIAdapter(); @@ -326,6 +339,9 @@ private: bool mDoesD3D11TextureSharingWork; DeviceResetReason mDeviceResetReason; + mozilla::gfx::FeatureStatus mD3D11Status; + mozilla::gfx::FeatureStatus mD2DStatus; + virtual void GetPlatformCMSOutputProfile(void* &mem, size_t &size); }; diff --git a/widget/GfxInfoBase.cpp b/widget/GfxInfoBase.cpp index 61cb5c98f92b..93956add779c 100644 --- a/widget/GfxInfoBase.cpp +++ b/widget/GfxInfoBase.cpp @@ -33,6 +33,7 @@ #include "mozilla/gfx/2D.h" #include "mozilla/gfx/Logging.h" #include "gfxPrefs.h" +#include "gfxPlatform.h" #if defined(MOZ_CRASHREPORTER) #include "nsExceptionHandler.h" @@ -1179,6 +1180,90 @@ GfxInfoBase::GetMonitors(JSContext* aCx, JS::MutableHandleValue aResult) return NS_OK; } +static const char* +GetLayersBackendName(layers::LayersBackend aBackend) +{ + switch (aBackend) { + case layers::LayersBackend::LAYERS_NONE: + return "none"; + case layers::LayersBackend::LAYERS_OPENGL: + return "opengl"; + case layers::LayersBackend::LAYERS_D3D9: + return "d3d9"; + case layers::LayersBackend::LAYERS_D3D11: + return "d3d11"; + case layers::LayersBackend::LAYERS_CLIENT: + return "client"; + default: + MOZ_ASSERT_UNREACHABLE("unknown layers backend"); + return "unknown"; + } +} + +nsresult +GfxInfoBase::GetFeatures(JSContext* aCx, JS::MutableHandle aOut) +{ + JS::Rooted obj(aCx, JS_NewPlainObject(aCx)); + if (!obj) { + return NS_ERROR_OUT_OF_MEMORY; + } + aOut.setObject(*obj); + + layers::LayersBackend backend = gfxPlatform::Initialized() + ? gfxPlatform::GetPlatform()->GetCompositorBackend() + : layers::LayersBackend::LAYERS_NONE; + const char* backendName = GetLayersBackendName(backend); + { + JS::Rooted str(aCx, JS_NewStringCopyZ(aCx, backendName)); + JS::Rooted val(aCx, StringValue(str)); + JS_SetProperty(aCx, obj, "compositor", val); + } + + // If graphics isn't initialized yet, just stop now. + if (!gfxPlatform::Initialized()) { + return NS_OK; + } + + DescribeFeatures(aCx, obj); + return NS_OK; +} + +void +GfxInfoBase::DescribeFeatures(JSContext* cx, JS::Handle aOut) +{ +} + +bool +GfxInfoBase::InitFeatureObject(JSContext* aCx, + JS::Handle aContainer, + const char* aName, + mozilla::gfx::FeatureStatus aFeatureStatus, + JS::MutableHandle aOutObj) +{ + JS::Rooted obj(aCx, JS_NewPlainObject(aCx)); + if (!obj) { + return false; + } + + const char* status = FeatureStatusToString(aFeatureStatus); + + // Set "status". + { + JS::Rooted str(aCx, JS_NewStringCopyZ(aCx, status)); + JS::Rooted val(aCx, JS::StringValue(str)); + JS_SetProperty(aCx, obj, "status", val); + } + + // Add the feature object to the container. + { + JS::Rooted val(aCx, JS::ObjectValue(*obj)); + JS_SetProperty(aCx, aContainer, aName, val); + } + + aOutObj.set(obj); + return true; +} + GfxInfoCollectorBase::GfxInfoCollectorBase() { GfxInfoBase::AddCollector(this); diff --git a/widget/GfxInfoBase.h b/widget/GfxInfoBase.h index 4188912ba390..dff9cf0a5899 100644 --- a/widget/GfxInfoBase.h +++ b/widget/GfxInfoBase.h @@ -19,6 +19,7 @@ #include "nsTArray.h" #include "nsString.h" #include "GfxInfoCollector.h" +#include "gfxTelemetry.h" #include "nsIGfxInfoDebug.h" #include "mozilla/Mutex.h" #include "js/Value.h" @@ -58,6 +59,7 @@ public: NS_IMETHOD GetFailures(uint32_t *failureCount, int32_t** indices, char ***failures) override; NS_IMETHOD_(void) LogFailure(const nsACString &failure) override; NS_IMETHOD GetInfo(JSContext*, JS::MutableHandle) override; + NS_IMETHOD GetFeatures(JSContext*, JS::MutableHandle) override; // Initialization function. If you override this, you must call this class's // version of Init first. @@ -103,6 +105,14 @@ protected: // (while subclasses check for more specific ones). virtual const nsTArray& GetGfxDriverInfo() = 0; + virtual void DescribeFeatures(JSContext* aCx, JS::Handle obj); + bool InitFeatureObject( + JSContext* aCx, + JS::Handle aContainer, + const char* aName, + mozilla::gfx::FeatureStatus aFeatureStatus, + JS::MutableHandle aOutObj); + private: virtual int32_t FindBlocklistedDeviceInList(const nsTArray& aDriverInfo, nsAString& aSuggestedVersion, diff --git a/widget/nsBaseWidget.cpp b/widget/nsBaseWidget.cpp index 087c6a181fff..fe4f693bc255 100644 --- a/widget/nsBaseWidget.cpp +++ b/widget/nsBaseWidget.cpp @@ -1131,6 +1131,8 @@ void nsBaseWidget::CreateCompositor(int aWidth, int aHeight) WindowUsesOMTC(); mLayerManager = lm.forget(); + + gfxPlatform::GetPlatform()->NotifyCompositorCreated(mLayerManager->GetCompositorBackendType()); } bool nsBaseWidget::ShouldUseOffMainThreadCompositing() diff --git a/widget/nsIGfxInfo.idl b/widget/nsIGfxInfo.idl index 8b10556b2fa7..1e76c22c897e 100644 --- a/widget/nsIGfxInfo.idl +++ b/widget/nsIGfxInfo.idl @@ -8,7 +8,7 @@ /* NOTE: this interface is completely undesigned, not stable and likely to change */ -[scriptable, uuid(47eedfa0-f7cb-445b-b5cf-a2ca83600560)] +[scriptable, uuid(98690931-c9a5-4675-9ab4-90932ec32bf2)] interface nsIGfxInfo : nsISupports { /* @@ -147,5 +147,31 @@ interface nsIGfxInfo : nsISupports [implicit_jscontext] jsval getInfo(); + + // Returns an object containing information about graphics features. It is + // intended to be directly included into the Telemetry environment. + // + // "layers": + // { + // "compositor": "d3d9", "d3d11", "opengl", "basic", or "none" + // // ("none" indicates no compositors have been created) + // // Feature is one of "d3d9", "d3d11", "opengl", "basic", or "d2d". + // "": { + // // Each backend can have one of the following statuses: + // // "unused" - This feature has not been requested. + // // "unavailable" - OS version or restriction prevents use. + // // "blocked" - An internal condition (such as safe mode) prevents use. + // // "blacklisted" - Blocked due to a blacklist restriction. + // // "disabled" - User explicitly disabled this default feature. + // // "failed" - Feature failed to initialize. + // // "available" - User has this feature available by default. + // "status": "", + // "version": "", + // "warp": true|false, // D3D11 only. + // "textureSharing": true|false, // D3D11 only. + // } + // } + [implicit_jscontext] + jsval getFeatures(); }; diff --git a/widget/windows/GfxInfo.cpp b/widget/windows/GfxInfo.cpp index eb1f4ec81dfa..9400ecbda474 100644 --- a/widget/windows/GfxInfo.cpp +++ b/widget/windows/GfxInfo.cpp @@ -1255,6 +1255,42 @@ GfxInfo::FindMonitors(JSContext* aCx, JS::HandleObject aOutArray) return NS_OK; } +void +GfxInfo::DescribeFeatures(JSContext* aCx, JS::Handle aObj) +{ + JS::Rooted obj(aCx); + + gfxWindowsPlatform* platform = gfxWindowsPlatform::GetPlatform(); + + gfx::FeatureStatus d3d11 = platform->GetD3D11Status(); + if (!InitFeatureObject(aCx, aObj, "d3d11", d3d11, &obj)) { + return; + } + if (d3d11 == gfx::FeatureStatus::Available) { + JS::Rooted val(aCx, JS::Int32Value(platform->GetD3D11Version())); + JS_SetProperty(aCx, obj, "version", val); + + val = JS::BooleanValue(platform->IsWARP()); + JS_SetProperty(aCx, obj, "warp", val); + + val = JS::BooleanValue(platform->DoesD3D11TextureSharingWork()); + JS_SetProperty(aCx, obj, "textureSharing", val); + } + + gfx::FeatureStatus d2d = platform->GetD2DStatus(); + if (!InitFeatureObject(aCx, aObj, "d2d", d2d, &obj)) { + return; + } + { + const char* version = "1.0"; + if (platform->GetD2D1Status() == gfx::FeatureStatus::Available) + version = "1.1"; + JS::Rooted str(aCx, JS_NewStringCopyZ(aCx, version)); + JS::Rooted val(aCx, JS::StringValue(str)); + JS_SetProperty(aCx, obj, "version", val); + } +} + #ifdef DEBUG // Implement nsIGfxInfoDebug diff --git a/widget/windows/GfxInfo.h b/widget/windows/GfxInfo.h index 5fd361900ba2..5d05b149ebe0 100644 --- a/widget/windows/GfxInfo.h +++ b/widget/windows/GfxInfo.h @@ -68,6 +68,8 @@ protected: OperatingSystem* aOS = nullptr); virtual const nsTArray& GetGfxDriverInfo(); + void DescribeFeatures(JSContext* cx, JS::Handle aOut) override; + private: void AddCrashReportAnnotations(); From d67574f90d51b09e07e6ce8c12636774d3140733 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Sun, 19 Jul 2015 14:55:44 -0700 Subject: [PATCH 49/69] Add d3d11/d2d and compositor information to telemetry. (bug 1179051 part 6, r=dexter) --- .../telemetry/TelemetryEnvironment.jsm | 30 +++++++++++++++++++ .../components/telemetry/docs/environment.rst | 22 ++++++++++++++ .../tests/unit/test_TelemetryEnvironment.js | 6 ++++ 3 files changed, 58 insertions(+) diff --git a/toolkit/components/telemetry/TelemetryEnvironment.jsm b/toolkit/components/telemetry/TelemetryEnvironment.jsm index a23fed97f476..87a8d5fae121 100644 --- a/toolkit/components/telemetry/TelemetryEnvironment.jsm +++ b/toolkit/components/telemetry/TelemetryEnvironment.jsm @@ -157,6 +157,7 @@ const PREF_UPDATE_AUTODOWNLOAD = "app.update.auto"; const EXPERIMENTS_CHANGED_TOPIC = "experiments-changed"; const SEARCH_ENGINE_MODIFIED_TOPIC = "browser-search-engine-modified"; const SEARCH_SERVICE_TOPIC = "browser-search-service"; +const COMPOSITOR_CREATED_TOPIC = "compositor:created"; /** * Get the current browser. @@ -809,12 +810,14 @@ EnvironmentCache.prototype = { // Watch the search engine change and service topics. Services.obs.addObserver(this, SEARCH_ENGINE_MODIFIED_TOPIC, false); Services.obs.addObserver(this, SEARCH_SERVICE_TOPIC, false); + Services.obs.addObserver(this, COMPOSITOR_CREATED_TOPIC, false); }, _removeObservers: function () { // Remove the search engine change and service observers. Services.obs.removeObserver(this, SEARCH_ENGINE_MODIFIED_TOPIC); Services.obs.removeObserver(this, SEARCH_SERVICE_TOPIC); + Services.obs.removeObserver(this, COMPOSITOR_CREATED_TOPIC); }, observe: function (aSubject, aTopic, aData) { @@ -834,6 +837,12 @@ EnvironmentCache.prototype = { // Now that the search engine init is complete, record the default search choice. this._updateSearchEngine(); break; + case COMPOSITOR_CREATED_TOPIC: + // Full graphics information is not available until we have created at + // least one off-main-thread-composited window. Thus we wait for the + // first compositor to be created and then query nsIGfxInfo again. + this._onCompositorCreated(); + break; } }, @@ -896,6 +905,19 @@ EnvironmentCache.prototype = { this._onEnvironmentChange("search-engine-changed", oldEnvironment); }, + /** + * Update the graphics features object. + */ + _onCompositorCreated: function () { + let gfxData = this._currentEnvironment.system.gfx; + try { + let gfxInfo = Cc["@mozilla.org/gfx/info;1"].getService(Ci.nsIGfxInfo); + gfxData.features = gfxInfo.getFeatures(); + } catch (e) { + this._log.error("nsIGfxInfo.getFeatures() caught error", e); + } + }, + /** * Get the build data in object form. * @return Object containing the build data. @@ -1128,6 +1150,7 @@ EnvironmentCache.prototype = { //DWriteVersion: getGfxField("DWriteVersion", null), adapters: [], monitors: [], + features: {}, }; #if !defined(MOZ_WIDGET_GONK) && !defined(MOZ_WIDGET_ANDROID) && !defined(MOZ_WIDGET_GTK) @@ -1139,6 +1162,13 @@ EnvironmentCache.prototype = { } #endif + try { + let gfxInfo = Cc["@mozilla.org/gfx/info;1"].getService(Ci.nsIGfxInfo); + gfxData.features = gfxInfo.getFeatures(); + } catch (e) { + this._log.error("nsIGfxInfo.getFeatures() caught error", e); + } + // GfxInfo does not yet expose a way to iterate through all the adapters. gfxData.adapters.push(getGfxAdapter("")); gfxData.adapters[0].GPUActive = true; diff --git a/toolkit/components/telemetry/docs/environment.rst b/toolkit/components/telemetry/docs/environment.rst index e4c891fb70c5..ec9e03613f16 100644 --- a/toolkit/components/telemetry/docs/environment.rst +++ b/toolkit/components/telemetry/docs/environment.rst @@ -145,6 +145,28 @@ Structure:: }, ... ], + features: { + compositor: , // Layers backend for compositing (eg "d3d11", "none", "opengl") + + // Each the following features can have one of the following statuses: + // "unused" - This feature has not been requested. + // "unavailable" - Safe Mode or OS restriction prevents use. + // "blocked" - Blocked due to an internal condition such as safe mode. + // "blacklisted" - Blocked due to a blacklist restriction. + // "disabled" - User explicitly disabled this default feature. + // "failed" - This feature was attempted but failed to initialize. + // "available" - User has this feature available. + "d3d11" { // This feature is Windows-only. + status: , + warp: , // Software rendering (WARP) mode was chosen. + textureSharing: // Whether or not texture sharing works. + version: , // The D3D11 device feature level. + }, + "d2d" { // This feature is Windows-only. + status: , + version: , // Either "1.0" or "1.1". + }, + }, }, }, addons: { diff --git a/toolkit/components/telemetry/tests/unit/test_TelemetryEnvironment.js b/toolkit/components/telemetry/tests/unit/test_TelemetryEnvironment.js index 5e0de56e903c..eabb05ceea2b 100644 --- a/toolkit/components/telemetry/tests/unit/test_TelemetryEnvironment.js +++ b/toolkit/components/telemetry/tests/unit/test_TelemetryEnvironment.js @@ -430,6 +430,9 @@ function checkSystemSection(data) { } } + Assert.equal(typeof gfxData.features, "object"); + Assert.equal(typeof gfxData.features.compositor, "string"); + try { // If we've not got nsIGfxInfoDebug, then this will throw and stop us doing // this test. @@ -439,6 +442,9 @@ function checkSystemSection(data) { Assert.equal(GFX_VENDOR_ID, gfxData.adapters[0].vendorID); Assert.equal(GFX_DEVICE_ID, gfxData.adapters[0].deviceID); } + + let features = gfxInfo.getFeatures(); + Assert.equal(features.compositor, gfxData.features.compositor); } catch (e) {} } From 18068f350e7ac6d555894c0ad1d0b92d7c33a894 Mon Sep 17 00:00:00 2001 From: Sotaro Ikeda Date: Sun, 19 Jul 2015 16:02:51 -0700 Subject: [PATCH 50/69] Bug 1167799 part 1 - Remove size from NewSurfaceDescriptorGralloc r=nical --- gfx/layers/ipc/LayersSurfaces.ipdlh | 6 ------ gfx/layers/opengl/GrallocTextureClient.cpp | 2 +- gfx/layers/opengl/GrallocTextureClient.h | 7 ------- gfx/layers/opengl/GrallocTextureHost.cpp | 5 +++-- gfx/layers/opengl/GrallocTextureHost.h | 4 ++-- 5 files changed, 6 insertions(+), 18 deletions(-) diff --git a/gfx/layers/ipc/LayersSurfaces.ipdlh b/gfx/layers/ipc/LayersSurfaces.ipdlh index 5d6ecaee4be3..03f305c86729 100644 --- a/gfx/layers/ipc/LayersSurfaces.ipdlh +++ b/gfx/layers/ipc/LayersSurfaces.ipdlh @@ -84,12 +84,6 @@ struct EGLImageDescriptor { struct NewSurfaceDescriptorGralloc { MaybeMagicGrallocBufferHandle buffer; - /** - * android::GraphicBuffer has a size information. But there are cases - * that GraphicBuffer's size and actual video's size are different. - * Extra size member is necessary. See Bug 850566. - */ - IntSize size; bool isOpaque; }; diff --git a/gfx/layers/opengl/GrallocTextureClient.cpp b/gfx/layers/opengl/GrallocTextureClient.cpp index 4caf58e49917..ca485f6f8c17 100644 --- a/gfx/layers/opengl/GrallocTextureClient.cpp +++ b/gfx/layers/opengl/GrallocTextureClient.cpp @@ -71,7 +71,7 @@ GrallocTextureClientOGL::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) return false; } - aOutDescriptor = NewSurfaceDescriptorGralloc(mGrallocHandle, mSize, mIsOpaque); + aOutDescriptor = NewSurfaceDescriptorGralloc(mGrallocHandle, mIsOpaque); return true; } diff --git a/gfx/layers/opengl/GrallocTextureClient.h b/gfx/layers/opengl/GrallocTextureClient.h index 71d4defd400c..0276b610c03a 100644 --- a/gfx/layers/opengl/GrallocTextureClient.h +++ b/gfx/layers/opengl/GrallocTextureClient.h @@ -139,13 +139,6 @@ protected: RefPtr mDrawTarget; - /** - * android::GraphicBuffer has a size information. But there are cases - * that GraphicBuffer's size and actual video's size are different. - * Extra size member is necessary. See Bug 850566. - */ - gfx::IntSize mSize; - android::MediaBuffer* mMediaBuffer; bool mIsOpaque; diff --git a/gfx/layers/opengl/GrallocTextureHost.cpp b/gfx/layers/opengl/GrallocTextureHost.cpp index 6caad935d8da..c875259698c7 100644 --- a/gfx/layers/opengl/GrallocTextureHost.cpp +++ b/gfx/layers/opengl/GrallocTextureHost.cpp @@ -103,7 +103,7 @@ GrallocTextureHostOGL::GrallocTextureHostOGL(TextureFlags aFlags, : TextureHost(aFlags) , mGrallocHandle(aDescriptor) , mSize(0, 0) - , mDescriptorSize(aDescriptor.size()) + , mCropSize(0, 0) , mFormat(gfx::SurfaceFormat::UNKNOWN) , mEGLImage(EGL_NO_IMAGE) , mIsOpaque(aDescriptor.isOpaque()) @@ -116,6 +116,7 @@ GrallocTextureHostOGL::GrallocTextureHostOGL(TextureFlags aFlags, SurfaceFormatForAndroidPixelFormat(graphicBuffer->getPixelFormat(), aFlags & TextureFlags::RB_SWAPPED); mSize = gfx::IntSize(graphicBuffer->getWidth(), graphicBuffer->getHeight()); + mCropSize = mSize; } else { printf_stderr("gralloc buffer is nullptr"); } @@ -222,7 +223,7 @@ GrallocTextureHostOGL::GetRenderState() flags |= LayerRenderStateFlags::FORMAT_RB_SWAP; } return LayerRenderState(graphicBuffer, - mDescriptorSize, + mCropSize, flags, this); } diff --git a/gfx/layers/opengl/GrallocTextureHost.h b/gfx/layers/opengl/GrallocTextureHost.h index 0e9d1062edda..35607bde1d35 100644 --- a/gfx/layers/opengl/GrallocTextureHost.h +++ b/gfx/layers/opengl/GrallocTextureHost.h @@ -38,7 +38,7 @@ public: virtual gfx::SurfaceFormat GetFormat() const; - virtual gfx::IntSize GetSize() const override { return mDescriptorSize; } + virtual gfx::IntSize GetSize() const override { return mCropSize; } virtual LayerRenderState GetRenderState() override; @@ -68,7 +68,7 @@ private: gfx::IntSize mSize; // Size reported by TextureClient, can be different in some cases (video?), // used by LayerRenderState. - gfx::IntSize mDescriptorSize; + gfx::IntSize mCropSize; gfx::SurfaceFormat mFormat; EGLImage mEGLImage; bool mIsOpaque; From 53a555bd7249b13305556aea08a18acc2c62c975 Mon Sep 17 00:00:00 2001 From: Sotaro Ikeda Date: Sun, 19 Jul 2015 16:03:10 -0700 Subject: [PATCH 51/69] Bug 1167799 part 2 - Add EGL_ANDROID_image_crop support r=nical,jgilbert --- gfx/gl/GLDefs.h | 6 ++++++ gfx/gl/GLLibraryEGL.cpp | 1 + gfx/gl/GLLibraryEGL.h | 1 + gfx/layers/composite/ImageHost.cpp | 3 +++ gfx/layers/composite/TextureHost.h | 5 +++++ gfx/layers/opengl/EGLImageHelpers.cpp | 21 ++++++++++++++++++--- gfx/layers/opengl/EGLImageHelpers.h | 4 +++- gfx/layers/opengl/GrallocTextureHost.cpp | 23 ++++++++++++++++++++++- gfx/layers/opengl/GrallocTextureHost.h | 2 ++ 9 files changed, 61 insertions(+), 5 deletions(-) diff --git a/gfx/gl/GLDefs.h b/gfx/gl/GLDefs.h index 0cb819a82f73..f0fe552f6e99 100644 --- a/gfx/gl/GLDefs.h +++ b/gfx/gl/GLDefs.h @@ -44,6 +44,12 @@ #define LOCAL_GL_ATC_RGBA_EXPLICIT_ALPHA 0x8C93 #define LOCAL_GL_ATC_RGBA_INTERPOLATED_ALPHA 0x87EE +// EGL_ANDROID_image_crop +#define LOCAL_EGL_IMAGE_CROP_LEFT_ANDROID 0x3148 +#define LOCAL_EGL_IMAGE_CROP_TOP_ANDROID 0x3149 +#define LOCAL_EGL_IMAGE_CROP_RIGHT_ANDROID 0x314A +#define LOCAL_EGL_IMAGE_CROP_BOTTOM_ANDROID 0x314B + // Others #define LOCAL_EGL_PRESERVED_RESOURCES 0x3030 #define LOCAL_EGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_EXT 0x3138 diff --git a/gfx/gl/GLLibraryEGL.cpp b/gfx/gl/GLLibraryEGL.cpp index 3affc6cb923d..761c698650ce 100644 --- a/gfx/gl/GLLibraryEGL.cpp +++ b/gfx/gl/GLLibraryEGL.cpp @@ -36,6 +36,7 @@ static const char *sEGLExtensionNames[] = { "EGL_KHR_image", "EGL_KHR_fence_sync", "EGL_ANDROID_native_fence_sync", + "EGL_ANDROID_image_crop", "ANGLE_platform_angle", "ANGLE_platform_angle_d3d" }; diff --git a/gfx/gl/GLLibraryEGL.h b/gfx/gl/GLLibraryEGL.h index 135289de2a85..58459f07df03 100644 --- a/gfx/gl/GLLibraryEGL.h +++ b/gfx/gl/GLLibraryEGL.h @@ -131,6 +131,7 @@ public: KHR_image, KHR_fence_sync, ANDROID_native_fence_sync, + EGL_ANDROID_image_crop, ANGLE_platform_angle, ANGLE_platform_angle_d3d, Extensions_Max diff --git a/gfx/layers/composite/ImageHost.cpp b/gfx/layers/composite/ImageHost.cpp index cc2b93699d7a..2979bc5858cf 100644 --- a/gfx/layers/composite/ImageHost.cpp +++ b/gfx/layers/composite/ImageHost.cpp @@ -95,6 +95,9 @@ ImageHost::UseTextureHost(const nsTArray& aTextures) img.mTextureSource = mImages.LastElement().mTextureSource; mImages.RemoveElementAt(mImages.Length() - 1); } + // SetCropRect() affects only on a specific platform. + // If it is not implemented, it does nothing. + img.mFrontBuffer->SetCropRect(img.mPictureRect); img.mFrontBuffer->Updated(); img.mFrontBuffer->PrepareTextureSource(img.mTextureSource); } diff --git a/gfx/layers/composite/TextureHost.h b/gfx/layers/composite/TextureHost.h index 94532bf298d5..f03368d4081e 100644 --- a/gfx/layers/composite/TextureHost.h +++ b/gfx/layers/composite/TextureHost.h @@ -417,6 +417,11 @@ public: virtual gfx::IntSize GetSize() const = 0; + /** + * Should be overridden if TextureHost supports crop rect. + */ + virtual void SetCropRect(nsIntRect aCropRect) {} + /** * Debug facility. * XXX - cool kids use Moz2D. See bug 882113. diff --git a/gfx/layers/opengl/EGLImageHelpers.cpp b/gfx/layers/opengl/EGLImageHelpers.cpp index 6b9a6b6ca553..4a720302f03e 100644 --- a/gfx/layers/opengl/EGLImageHelpers.cpp +++ b/gfx/layers/opengl/EGLImageHelpers.cpp @@ -15,17 +15,32 @@ namespace layers { using namespace gl; EGLImage -EGLImageCreateFromNativeBuffer(GLContext* aGL, void* aBuffer) +EGLImageCreateFromNativeBuffer(GLContext* aGL, void* aBuffer, const gfx::IntSize& aCropSize) { EGLint attrs[] = { LOCAL_EGL_IMAGE_PRESERVED, LOCAL_EGL_TRUE, - LOCAL_EGL_NONE, LOCAL_EGL_NONE + LOCAL_EGL_NONE, LOCAL_EGL_NONE, }; + EGLint cropAttrs[] = { + LOCAL_EGL_IMAGE_PRESERVED, LOCAL_EGL_TRUE, + LOCAL_EGL_IMAGE_CROP_LEFT_ANDROID, 0, + LOCAL_EGL_IMAGE_CROP_TOP_ANDROID, 0, + LOCAL_EGL_IMAGE_CROP_RIGHT_ANDROID, aCropSize.width, + LOCAL_EGL_IMAGE_CROP_BOTTOM_ANDROID, aCropSize.height, + LOCAL_EGL_NONE, LOCAL_EGL_NONE, + }; + + bool hasCropRect = (aCropSize.width != 0 && aCropSize.height != 0); + EGLint* usedAttrs = attrs; + if (hasCropRect && sEGLLibrary.IsExtensionSupported(GLLibraryEGL::EGL_ANDROID_image_crop)) { + usedAttrs = cropAttrs; + } + return sEGLLibrary.fCreateImage(sEGLLibrary.Display(), EGL_NO_CONTEXT, LOCAL_EGL_NATIVE_BUFFER_ANDROID, - aBuffer, attrs); + aBuffer, usedAttrs); } void diff --git a/gfx/layers/opengl/EGLImageHelpers.h b/gfx/layers/opengl/EGLImageHelpers.h index ba38dfdd1451..3e03a499ca56 100644 --- a/gfx/layers/opengl/EGLImageHelpers.h +++ b/gfx/layers/opengl/EGLImageHelpers.h @@ -7,6 +7,8 @@ #ifndef EGLIMAGEHELPERS_H_ #define EGLIMAGEHELPERS_H_ +#include "mozilla/gfx/Point.h" + typedef void* EGLImage; namespace mozilla { @@ -16,7 +18,7 @@ namespace gl { namespace layers { -EGLImage EGLImageCreateFromNativeBuffer(gl::GLContext* aGL, void* aBuffer); +EGLImage EGLImageCreateFromNativeBuffer(gl::GLContext* aGL, void* aBuffer, const gfx::IntSize& aCropSize); void EGLImageDestroy(gl::GLContext* aGL, EGLImage aImage); } // namespace layers diff --git a/gfx/layers/opengl/GrallocTextureHost.cpp b/gfx/layers/opengl/GrallocTextureHost.cpp index c875259698c7..1a9f52a69d58 100644 --- a/gfx/layers/opengl/GrallocTextureHost.cpp +++ b/gfx/layers/opengl/GrallocTextureHost.cpp @@ -345,8 +345,12 @@ GrallocTextureHostOGL::PrepareTextureSource(CompositableTextureSourceRef& aTextu } if (mEGLImage == EGL_NO_IMAGE) { + gfx::IntSize cropSize(0, 0); + if (mCropSize != mSize) { + cropSize = mCropSize; + } // Should only happen the first time. - mEGLImage = EGLImageCreateFromNativeBuffer(gl, graphicBuffer->getNativeBuffer()); + mEGLImage = EGLImageCreateFromNativeBuffer(gl, graphicBuffer->getNativeBuffer(), cropSize); } GLenum textureTarget = GetTextureTarget(gl, graphicBuffer->getPixelFormat()); @@ -415,6 +419,23 @@ GrallocTextureHostOGL::WaitAcquireFenceHandleSyncComplete() MOZ_ALWAYS_TRUE( sEGLLibrary.fDestroySync(EGL_DISPLAY(), sync) ); } +void +GrallocTextureHostOGL::SetCropRect(nsIntRect aCropRect) +{ + MOZ_ASSERT(aCropRect.TopLeft() == IntPoint(0, 0)); + MOZ_ASSERT(!aCropRect.IsEmpty()); + MOZ_ASSERT(aCropRect.width <= mSize.width); + MOZ_ASSERT(aCropRect.height <= mSize.height); + + gfx::IntSize cropSize(aCropRect.width, aCropRect.height); + if (mCropSize == cropSize) { + return; + } + + mCropSize = cropSize; + mGLTextureSource = nullptr; +} + bool GrallocTextureHostOGL::BindTextureSource(CompositableTextureSourceRef& aTextureSource) { diff --git a/gfx/layers/opengl/GrallocTextureHost.h b/gfx/layers/opengl/GrallocTextureHost.h index 35607bde1d35..a258a1e427f2 100644 --- a/gfx/layers/opengl/GrallocTextureHost.h +++ b/gfx/layers/opengl/GrallocTextureHost.h @@ -52,6 +52,8 @@ public: virtual void WaitAcquireFenceHandleSyncComplete() override; + virtual void SetCropRect(nsIntRect aCropRect) override; + bool IsValid() const; virtual const char* Name() override { return "GrallocTextureHostOGL"; } From 2751f97bb38cd64c05cc0bc092adf03982dbecd5 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sun, 19 Jul 2015 18:07:43 -0700 Subject: [PATCH 52/69] no bug - fix typo and grammar in comment r=me DONTBUILD --- security/manager/ssl/SSLServerCertVerification.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security/manager/ssl/SSLServerCertVerification.cpp b/security/manager/ssl/SSLServerCertVerification.cpp index 149ee92c6065..5fc9aef055b2 100644 --- a/security/manager/ssl/SSLServerCertVerification.cpp +++ b/security/manager/ssl/SSLServerCertVerification.cpp @@ -31,7 +31,7 @@ // transport service thread, we must always call the CERT_*Verify* cert // functions on another thread. To accomplish this, our auth cert hook // dispatches a SSLServerCertVerificationJob to a pool of background threads, -// and then immediatley return SECWouldBlock to libssl. These jobs are where +// and then immediately returns SECWouldBlock to libssl. These jobs are where // the CERT_*Verify* functions are actually called. // // When our auth cert hook returns SECWouldBlock, libssl will carry on the From 5d3cfb8d11b2a8747b7ce6d2b1a7881ae1ffceba Mon Sep 17 00:00:00 2001 From: Seth Fowler Date: Sun, 19 Jul 2015 18:39:40 -0700 Subject: [PATCH 53/69] Bug 1176124 (Part 1) - Add a MatchType enum to LookupResult to let Lookup*() return more detailed information. r=dholbert --- image/FrameAnimator.cpp | 3 +-- image/LookupResult.h | 43 ++++++++++++++++++++++++++++++----------- image/RasterImage.cpp | 5 +++-- image/SurfaceCache.cpp | 26 ++++++++++++++++--------- 4 files changed, 53 insertions(+), 24 deletions(-) diff --git a/image/FrameAnimator.cpp b/image/FrameAnimator.cpp index 6cfb100013aa..942c6a142d6f 100644 --- a/image/FrameAnimator.cpp +++ b/image/FrameAnimator.cpp @@ -273,8 +273,7 @@ FrameAnimator::GetCompositedFrame(uint32_t aFrameNum) // If we have a composited version of this frame, return that. if (mLastCompositedFrameIndex == int32_t(aFrameNum)) { - return LookupResult(mCompositingFrame->DrawableRef(), - /* aIsExactMatch = */ true); + return LookupResult(mCompositingFrame->DrawableRef(), MatchType::EXACT); } // Otherwise return the raw frame. DoBlend is required to ensure that we only diff --git a/image/LookupResult.h b/image/LookupResult.h index 91fb2b4033ae..67aebf576fe9 100644 --- a/image/LookupResult.h +++ b/image/LookupResult.h @@ -18,6 +18,16 @@ namespace mozilla { namespace image { +enum class MatchType : uint8_t +{ + NOT_FOUND, // No matching surface and no placeholder. + PENDING, // Found a matching placeholder, but no surface. + EXACT, // Found a surface that matches exactly. + SUBSTITUTE_BECAUSE_NOT_FOUND, // No exact match, but found a similar one. + SUBSTITUTE_BECAUSE_PENDING // Found a similar surface and a placeholder + // for an exact match. +}; + /** * LookupResult is the return type of SurfaceCache's Lookup*() functions. It * combines a surface with relevant metadata tracked by SurfaceCache. @@ -25,25 +35,36 @@ namespace image { class MOZ_STACK_CLASS LookupResult { public: - LookupResult() - : mIsExactMatch(false) - { } + explicit LookupResult(MatchType aMatchType) + : mMatchType(aMatchType) + { + MOZ_ASSERT(mMatchType == MatchType::NOT_FOUND || + mMatchType == MatchType::PENDING, + "Only NOT_FOUND or PENDING make sense with no surface"); + } LookupResult(LookupResult&& aOther) : mDrawableRef(Move(aOther.mDrawableRef)) - , mIsExactMatch(aOther.mIsExactMatch) + , mMatchType(aOther.mMatchType) { } - LookupResult(DrawableFrameRef&& aDrawableRef, bool aIsExactMatch) + LookupResult(DrawableFrameRef&& aDrawableRef, MatchType aMatchType) : mDrawableRef(Move(aDrawableRef)) - , mIsExactMatch(aIsExactMatch) - { } + , mMatchType(aMatchType) + { + MOZ_ASSERT(!mDrawableRef || !(mMatchType == MatchType::NOT_FOUND || + mMatchType == MatchType::PENDING), + "Only NOT_FOUND or PENDING make sense with no surface"); + MOZ_ASSERT(mDrawableRef || mMatchType == MatchType::NOT_FOUND || + mMatchType == MatchType::PENDING, + "NOT_FOUND or PENDING do not make sense with a surface"); + } LookupResult& operator=(LookupResult&& aOther) { MOZ_ASSERT(&aOther != this, "Self-move-assignment is not supported"); mDrawableRef = Move(aOther.mDrawableRef); - mIsExactMatch = aOther.mIsExactMatch; + mMatchType = aOther.mMatchType; return *this; } @@ -53,14 +74,14 @@ public: /// @return true if this LookupResult contains a surface. explicit operator bool() const { return bool(mDrawableRef); } - /// @return true if the surface is an exact match for the Lookup*() arguments. - bool IsExactMatch() const { return mIsExactMatch; } + /// @return what kind of match this is (exact, substitute, etc.) + MatchType Type() const { return mMatchType; } private: LookupResult(const LookupResult&) = delete; DrawableFrameRef mDrawableRef; - bool mIsExactMatch; + MatchType mMatchType; }; } // namespace image diff --git a/image/RasterImage.cpp b/image/RasterImage.cpp index 01b238a8a866..85e541fd992e 100644 --- a/image/RasterImage.cpp +++ b/image/RasterImage.cpp @@ -526,8 +526,9 @@ RasterImage::LookupFrame(uint32_t aFrameNum, return DrawableFrameRef(); } - if (!result || !result.IsExactMatch()) { - // The OS threw this frame away. We need to redecode if we can. + if (!result || result.Type() == MatchType::SUBSTITUTE_BECAUSE_NOT_FOUND) { + // We don't have a copy of this frame, and there's no decoder working on + // one. Trigger decoding so it'll be available next time. MOZ_ASSERT(!mAnim, "Animated frames should be locked"); Decode(Some(requestedSize), aFlags); diff --git a/image/SurfaceCache.cpp b/image/SurfaceCache.cpp index c6c6c2b9827c..c2206d62f77c 100644 --- a/image/SurfaceCache.cpp +++ b/image/SurfaceCache.cpp @@ -550,12 +550,14 @@ public: { nsRefPtr cache = GetImageCache(aImageKey); if (!cache) { - return LookupResult(); // No cached surfaces for this image. + // No cached surfaces for this image. + return LookupResult(MatchType::NOT_FOUND); } nsRefPtr surface = cache->Lookup(aSurfaceKey); if (!surface) { - return LookupResult(); // Lookup in the per-image cache missed. + // Lookup in the per-image cache missed. + return LookupResult(MatchType::NOT_FOUND); } DrawableFrameRef ref = surface->DrawableRef(); @@ -563,14 +565,16 @@ public: // The surface was released by the operating system. Remove the cache // entry as well. Remove(surface); - return LookupResult(); + return LookupResult(MatchType::NOT_FOUND); } if (aMarkUsed) { MarkUsed(surface, cache); } - return LookupResult(Move(ref), /* aIsExactMatch = */ true); + MOZ_ASSERT(surface->GetSurfaceKey() == aSurfaceKey, + "Lookup() not returning an exact match?"); + return LookupResult(Move(ref), MatchType::EXACT); } LookupResult LookupBestMatch(const ImageKey aImageKey, @@ -579,7 +583,8 @@ public: { nsRefPtr cache = GetImageCache(aImageKey); if (!cache) { - return LookupResult(); // No cached surfaces for this image. + // No cached surfaces for this image. + return LookupResult(MatchType::NOT_FOUND); } // Repeatedly look up the best match, trying again if the resulting surface @@ -593,7 +598,8 @@ public: while (true) { surface = cache->LookupBestMatch(aSurfaceKey, aAlternateFlags); if (!surface) { - return LookupResult(); // Lookup in the per-image cache missed. + // Lookup in the per-image cache missed. + return LookupResult(MatchType::NOT_FOUND); } ref = surface->DrawableRef(); @@ -619,7 +625,9 @@ public: MarkUsed(surface, cache); } - return LookupResult(Move(ref), isExactMatch); + MatchType matchType = isExactMatch ? MatchType::EXACT + : MatchType::SUBSTITUTE_BECAUSE_NOT_FOUND; + return LookupResult(Move(ref), matchType); } void RemoveSurface(const ImageKey aImageKey, @@ -992,7 +1000,7 @@ SurfaceCache::Lookup(const ImageKey aImageKey, const Maybe& aAlternateFlags /* = Nothing() */) { if (!sInstance) { - return LookupResult(); + return LookupResult(MatchType::NOT_FOUND); } MutexAutoLock lock(sInstance->GetMutex()); @@ -1013,7 +1021,7 @@ SurfaceCache::LookupBestMatch(const ImageKey aImageKey, /* = Nothing() */) { if (!sInstance) { - return LookupResult(); + return LookupResult(MatchType::NOT_FOUND); } MutexAutoLock lock(sInstance->GetMutex()); From d2b9501e7696f969f46ecdf84bc7406dba1677e6 Mon Sep 17 00:00:00 2001 From: Seth Fowler Date: Sun, 19 Jul 2015 18:39:44 -0700 Subject: [PATCH 54/69] Bug 1176124 (Part 2) - Add placeholder support to the SurfaceCache so we can avoid launching redundant decoders. r=dholbert --- image/RasterImage.cpp | 20 ++++++- image/SurfaceCache.cpp | 128 +++++++++++++++++++++++++++++++++-------- image/SurfaceCache.h | 37 ++++++++++-- 3 files changed, 156 insertions(+), 29 deletions(-) diff --git a/image/RasterImage.cpp b/image/RasterImage.cpp index 85e541fd992e..802a32f8c9a4 100644 --- a/image/RasterImage.cpp +++ b/image/RasterImage.cpp @@ -526,9 +526,12 @@ RasterImage::LookupFrame(uint32_t aFrameNum, return DrawableFrameRef(); } - if (!result || result.Type() == MatchType::SUBSTITUTE_BECAUSE_NOT_FOUND) { + if (result.Type() == MatchType::NOT_FOUND || + result.Type() == MatchType::SUBSTITUTE_BECAUSE_NOT_FOUND || + ((aFlags & FLAG_SYNC_DECODE) && !result)) { // We don't have a copy of this frame, and there's no decoder working on - // one. Trigger decoding so it'll be available next time. + // one. (Or we're sync decoding and the existing decoder hasn't even started + // yet.) Trigger decoding so it'll be available next time. MOZ_ASSERT(!mAnim, "Animated frames should be locked"); Decode(Some(requestedSize), aFlags); @@ -1500,6 +1503,19 @@ RasterImage::CreateDecoder(const Maybe& aSize, uint32_t aFlags) return nullptr; } + if (aSize) { + // Add a placeholder for the first frame to the SurfaceCache so we won't + // trigger any more decoders with the same parameters. + InsertOutcome outcome = + SurfaceCache::InsertPlaceholder(ImageKey(this), + RasterSurfaceKey(*aSize, + decoder->GetDecodeFlags(), + /* aFrameNum = */ 0)); + if (outcome != InsertOutcome::SUCCESS) { + return nullptr; + } + } + if (!aSize) { Telemetry::GetHistogramById( Telemetry::IMAGE_DECODE_COUNT)->Subtract(mDecodeCount); diff --git a/image/SurfaceCache.cpp b/image/SurfaceCache.cpp index c2206d62f77c..d791b1f776b0 100644 --- a/image/SurfaceCache.cpp +++ b/image/SurfaceCache.cpp @@ -16,6 +16,7 @@ #include "mozilla/Likely.h" #include "mozilla/Move.h" #include "mozilla/Mutex.h" +#include "mozilla/Pair.h" #include "mozilla/RefPtr.h" #include "mozilla/StaticPtr.h" #include "nsIMemoryReporter.h" @@ -67,6 +68,10 @@ static StaticRefPtr sInstance; */ typedef size_t Cost; +// Placeholders do not have surfaces, but need to be given a trivial cost for +// our invariants to hold. +static const Cost sPlaceholderCost = 1; + static Cost ComputeCost(const IntSize& aSize, uint32_t aBytesPerPixel) { @@ -137,17 +142,28 @@ public: , mSurfaceKey(aSurfaceKey) , mLifetime(aLifetime) { - MOZ_ASSERT(mSurface, "Must have a valid surface"); + MOZ_ASSERT(!IsPlaceholder() || + (mCost == sPlaceholderCost && mLifetime == Lifetime::Transient), + "Placeholder should have trivial cost and transient lifetime"); MOZ_ASSERT(mImageKey, "Must have a valid image key"); } DrawableFrameRef DrawableRef() const { + if (MOZ_UNLIKELY(IsPlaceholder())) { + MOZ_ASSERT_UNREACHABLE("Shouldn't call DrawableRef() on a placeholder"); + return DrawableFrameRef(); + } + return mSurface->DrawableRef(); } void SetLocked(bool aLocked) { + if (IsPlaceholder()) { + return; // Can't lock a placeholder. + } + if (aLocked && mLifetime == Lifetime::Persistent) { // This may fail, and that's OK. We make no guarantees about whether // locking is successful if you call SurfaceCache::LockImage() after @@ -158,6 +174,7 @@ public: } } + bool IsPlaceholder() const { return !bool(mSurface); } bool IsLocked() const { return bool(mDrawableRef); } ImageKey GetImageKey() const { return mImageKey; } @@ -165,7 +182,11 @@ public: CostEntry GetCostEntry() { return image::CostEntry(this, mCost); } nsExpirationState* GetExpirationState() { return &mExpirationState; } Lifetime GetLifetime() const { return mLifetime; } - bool IsDecoded() const { return mSurface->IsImageComplete(); } + + bool IsDecoded() const + { + return !IsPlaceholder() && mSurface->IsImageComplete(); + } // A helper type used by SurfaceCacheImpl::CollectSizeOfSurfaces. struct MOZ_STACK_CLASS SurfaceMemoryReport @@ -262,21 +283,47 @@ public: return surface.forget(); } - already_AddRefed + MOZ_WARN_UNUSED_RESULT // See bug 1185044. + Pair, MatchType> LookupBestMatch(const SurfaceKey& aSurfaceKey, const Maybe& aAlternateFlags) { - // Try for a perfect match first. - nsRefPtr surface; - mSurfaces.Get(aSurfaceKey, getter_AddRefs(surface)); - if (surface && surface->IsDecoded()) { - return surface.forget(); + // Try for an exact match first. + nsRefPtr exactMatch; + mSurfaces.Get(aSurfaceKey, getter_AddRefs(exactMatch)); + if (exactMatch && exactMatch->IsDecoded()) { + return MakePair(exactMatch.forget(), MatchType::EXACT); } // There's no perfect match, so find the best match we can. MatchContext matchContext(aSurfaceKey, aAlternateFlags); ForEach(TryToImproveMatch, &matchContext); - return matchContext.mBestMatch.forget(); + + MatchType matchType; + if (matchContext.mBestMatch) { + if (!exactMatch) { + // No exact match, but we found a substitute. + matchType = MatchType::SUBSTITUTE_BECAUSE_NOT_FOUND; + } else if (exactMatch != matchContext.mBestMatch) { + // The exact match is still decoding, but we found a substitute. + matchType = MatchType::SUBSTITUTE_BECAUSE_PENDING; + } else { + // The exact match is still decoding, but it's the best we've got. + matchType = MatchType::EXACT; + } + } else { + if (exactMatch) { + // We found an "exact match", but since TryToImproveMatch didn't return + // it, it must have been a placeholder. + MOZ_ASSERT(exactMatch->IsPlaceholder()); + matchType = MatchType::PENDING; + } else { + // We couldn't find an exact match *or* a substitute. + matchType = MatchType::NOT_FOUND; + } + } + + return MakePair(matchContext.mBestMatch.forget(), matchType); } void ForEach(SurfaceTable::EnumReadFunction aFunction, void* aData) @@ -308,6 +355,11 @@ private: auto context = static_cast(aContext); const SurfaceKey& idealKey = context->mIdealKey; + // We never match a placeholder. + if (aSurface->IsPlaceholder()) { + return PL_DHASH_NEXT; + } + // Matching the animation time and SVG context is required. if (aSurfaceKey.AnimationTime() != idealKey.AnimationTime() || aSurfaceKey.SVGContext() != idealKey.SVGContext()) { @@ -425,10 +477,21 @@ public: Lifetime aLifetime) { // If this is a duplicate surface, refuse to replace the original. - if (MOZ_UNLIKELY(Lookup(aImageKey, aSurfaceKey, /* aMarkUsed = */ false))) { + // XXX(seth): Calling Lookup() and then RemoveSurface() does the lookup + // twice. We'll make this more efficient in bug 1185137. + LookupResult result = Lookup(aImageKey, aSurfaceKey, /* aMarkUsed = */ false); + if (MOZ_UNLIKELY(result)) { return InsertOutcome::FAILURE_ALREADY_PRESENT; } + if (result.Type() == MatchType::PENDING) { + RemoveSurface(aImageKey, aSurfaceKey); + } + + MOZ_ASSERT(result.Type() == MatchType::NOT_FOUND || + result.Type() == MatchType::PENDING, + "A LookupResult with no surface should be NOT_FOUND or PENDING"); + // If this is bigger than we can hold after discarding everything we can, // refuse to cache it. if (MOZ_UNLIKELY(!CanHoldAfterDiscarding(aCost))) { @@ -458,6 +521,7 @@ public: // We require that locking succeed if the image is locked and the surface is // persistent; the caller may need to know this to handle errors correctly. if (cache->IsLocked() && aLifetime == Lifetime::Persistent) { + MOZ_ASSERT(!surface->IsPlaceholder(), "Placeholders should be transient"); surface->SetLocked(true); if (!surface->IsLocked()) { return InsertOutcome::FAILURE; @@ -560,6 +624,10 @@ public: return LookupResult(MatchType::NOT_FOUND); } + if (surface->IsPlaceholder()) { + return LookupResult(MatchType::PENDING); + } + DrawableFrameRef ref = surface->DrawableRef(); if (!ref) { // The surface was released by the operating system. Remove the cache @@ -595,11 +663,16 @@ public: nsRefPtr surface; DrawableFrameRef ref; + MatchType matchType = MatchType::NOT_FOUND; while (true) { - surface = cache->LookupBestMatch(aSurfaceKey, aAlternateFlags); + // XXX(seth): This code is begging for std::tie. See bug 1184385. + Pair, MatchType> lookupResult = + cache->LookupBestMatch(aSurfaceKey, aAlternateFlags); + surface = lookupResult.first(); + matchType = lookupResult.second(); + if (!surface) { - // Lookup in the per-image cache missed. - return LookupResult(MatchType::NOT_FOUND); + return LookupResult(matchType); // Lookup in the per-image cache missed. } ref = surface->DrawableRef(); @@ -612,21 +685,17 @@ public: Remove(surface); } - SurfaceKey key = surface->GetSurfaceKey(); - const bool isExactMatch = key.Size() == aSurfaceKey.Size(); - - MOZ_ASSERT(isExactMatch == - (key == aSurfaceKey || - (aAlternateFlags && key == aSurfaceKey.WithNewFlags(*aAlternateFlags))), + MOZ_ASSERT((matchType == MatchType::EXACT) == + (surface->GetSurfaceKey() == aSurfaceKey || + (aAlternateFlags && + surface->GetSurfaceKey() == + aSurfaceKey.WithNewFlags(*aAlternateFlags))), "Result differs in a way other than size or alternate flags"); - - if (isExactMatch) { + if (matchType == MatchType::EXACT) { MarkUsed(surface, cache); } - MatchType matchType = isExactMatch ? MatchType::EXACT - : MatchType::SUBSTITUTE_BECAUSE_NOT_FOUND; return LookupResult(Move(ref), matchType); } @@ -1048,6 +1117,19 @@ SurfaceCache::Insert(imgFrame* aSurface, return sInstance->Insert(aSurface, cost, aImageKey, aSurfaceKey, aLifetime); } +/* static */ InsertOutcome +SurfaceCache::InsertPlaceholder(const ImageKey aImageKey, + const SurfaceKey& aSurfaceKey) +{ + if (!sInstance) { + return InsertOutcome::FAILURE; + } + + MutexAutoLock lock(sInstance->GetMutex()); + return sInstance->Insert(nullptr, sPlaceholderCost, aImageKey, aSurfaceKey, + Lifetime::Transient); +} + /* static */ bool SurfaceCache::CanHold(const IntSize& aSize, uint32_t aBytesPerPixel /* = 4 */) { diff --git a/image/SurfaceCache.h b/image/SurfaceCache.h index cedf38d08374..32d61b068ca1 100644 --- a/image/SurfaceCache.h +++ b/image/SurfaceCache.h @@ -230,6 +230,7 @@ struct SurfaceCache /** * Insert a surface into the cache. If a surface with the same ImageKey and * SurfaceKey is already in the cache, Insert returns FAILURE_ALREADY_PRESENT. + * If a matching placeholder is already present, the placeholder is removed. * * Each surface in the cache has a lifetime, either Transient or Persistent. * Transient surfaces can expire from the cache at any time. Persistent @@ -280,6 +281,33 @@ struct SurfaceCache const SurfaceKey& aSurfaceKey, Lifetime aLifetime); + /** + * Insert a placeholder for a surface into the cache. If a surface with the + * same ImageKey and SurfaceKey is already in the cache, InsertPlaceholder() + * returns FAILURE_ALREADY_PRESENT. + * + * Placeholders exist to allow lazy allocation of surfaces. The Lookup*() + * methods will report whether a placeholder for an exactly matching surface + * existed by returning a MatchType of PENDING or SUBSTITUTE_BECAUSE_PENDING, + * but they will never return a placeholder directly. (They couldn't, since + * placeholders don't have an associated surface.) + * + * Once inserted, placeholders can be removed using RemoveSurface() or + * RemoveImage(), just like a surface. They're automatically removed when a + * real surface that matches the placeholder is inserted with Insert(). + * + * @param aImageKey Key data identifying which image the placeholder + * belongs to. + * @param aSurfaceKey Key data which uniquely identifies the surface the + * placeholder stands in for. + * @return SUCCESS if the placeholder was inserted successfully. + * FAILURE if the placeholder could not be inserted for some reason. + * FAILURE_ALREADY_PRESENT if a surface with the same ImageKey and + * SurfaceKey already exists in the cache. + */ + static InsertOutcome InsertPlaceholder(const ImageKey aImageKey, + const SurfaceKey& aSurfaceKey); + /** * Checks if a surface of a given size could possibly be stored in the cache. * If CanHold() returns false, Insert() will always fail to insert the @@ -362,8 +390,8 @@ struct SurfaceCache static void UnlockSurfaces(const ImageKey aImageKey); /** - * Removes a surface from the cache, if it's present. If it's not present, - * RemoveSurface() has no effect. + * Removes a surface or placeholder from the cache, if it's present. If it's + * not present, RemoveSurface() has no effect. * * Use this function to remove individual surfaces that have become invalid. * Prefer RemoveImage() or DiscardAll() when they're applicable, as they have @@ -378,8 +406,9 @@ struct SurfaceCache const SurfaceKey& aSurfaceKey); /** - * Removes all cached surfaces associated with the given image from the cache. - * If the image is locked, it is automatically unlocked. + * Removes all cached surfaces and placeholders associated with the given + * image from the cache. If the image is locked, it is automatically + * unlocked. * * This MUST be called, at a minimum, when an Image which could be storing * surfaces in the surface cache is destroyed. If another image were allocated From 16d9df4f7144d724351aae4e4eb4c40d42b5be9a Mon Sep 17 00:00:00 2001 From: Dan Glastonbury Date: Fri, 17 Jul 2015 10:14:12 +1000 Subject: [PATCH 55/69] Bug 1184786 - Fix LastColorAttachment(). r=jgilbert --- dom/canvas/WebGLContext.h | 4 +--- dom/canvas/WebGLContextValidate.cpp | 12 +----------- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/dom/canvas/WebGLContext.h b/dom/canvas/WebGLContext.h index edf469e4890f..ffbe754b8632 100644 --- a/dom/canvas/WebGLContext.h +++ b/dom/canvas/WebGLContext.h @@ -1403,10 +1403,8 @@ protected: WebGLRefPtr mCurrentProgram; RefPtr mActiveProgramLinkInfo; - uint32_t mMaxFramebufferColorAttachments; - GLenum LastColorAttachment() const { - return LOCAL_GL_COLOR_ATTACHMENT0 + mMaxFramebufferColorAttachments - 1; + return LOCAL_GL_COLOR_ATTACHMENT0 + mGLMaxColorAttachments - 1; } bool ValidateFramebufferTarget(GLenum target, const char* const info); diff --git a/dom/canvas/WebGLContextValidate.cpp b/dom/canvas/WebGLContextValidate.cpp index 51292042c7c1..bd2a1349df7b 100644 --- a/dom/canvas/WebGLContextValidate.cpp +++ b/dom/canvas/WebGLContextValidate.cpp @@ -401,15 +401,8 @@ WebGLContext::ValidateFramebufferAttachment(const WebGLFramebuffer* fb, GLenum a return true; } - GLenum colorAttachCount = 1; - if (IsExtensionEnabled(WebGLExtensionID::WEBGL_draw_buffers)) - colorAttachCount = mGLMaxColorAttachments; - - if (attachment >= LOCAL_GL_COLOR_ATTACHMENT0 && - attachment < GLenum(LOCAL_GL_COLOR_ATTACHMENT0 + colorAttachCount)) - { + if (attachment >= LOCAL_GL_COLOR_ATTACHMENT0 && attachment <= LastColorAttachment()) return true; - } ErrorInvalidEnum("%s: attachment: invalid enum value 0x%x.", funcName, attachment); @@ -1885,9 +1878,6 @@ WebGLContext::InitAndValidateGL() } } - // Always 1 for GLES2 - mMaxFramebufferColorAttachments = 1; - if (gl->IsCompatibilityProfile()) { // gl_PointSize is always available in ES2 GLSL, but has to be // specifically enabled on desktop GLSL. From 7b3c3fd488009f5f4cf5bd8919daac5c1681d9c7 Mon Sep 17 00:00:00 2001 From: Dan Glastonbury Date: Mon, 20 Jul 2015 10:31:19 +1000 Subject: [PATCH 56/69] Bug 1184786 - Fix ReadBuffer parameter validation. r=jgilbert --- dom/canvas/WebGL2ContextFramebuffers.cpp | 25 +++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/dom/canvas/WebGL2ContextFramebuffers.cpp b/dom/canvas/WebGL2ContextFramebuffers.cpp index eeb7cd5e28ff..47356b4a96b6 100644 --- a/dom/canvas/WebGL2ContextFramebuffers.cpp +++ b/dom/canvas/WebGL2ContextFramebuffers.cpp @@ -498,31 +498,38 @@ WebGL2Context::ReadBuffer(GLenum mode) if (IsContextLost()) return; - MakeContextCurrent(); + const bool isColorAttachment = (mode >= LOCAL_GL_COLOR_ATTACHMENT0 && + mode <= LastColorAttachment()); + + if (mode != LOCAL_GL_NONE && mode != LOCAL_GL_BACK && !isColorAttachment) { + ErrorInvalidEnum("readBuffer: `mode` must be one of NONE, BACK, or " + "COLOR_ATTACHMENTi. Was %s", + EnumName(mode)); + return; + } if (mBoundReadFramebuffer) { - bool isColorAttachment = (mode >= LOCAL_GL_COLOR_ATTACHMENT0 && - mode <= LastColorAttachment()); if (mode != LOCAL_GL_NONE && !isColorAttachment) { - ErrorInvalidEnumInfo("readBuffer: If READ_FRAMEBUFFER is non-null," - " `mode` must be COLOR_ATTACHMENTN or NONE." - " Was:", mode); + ErrorInvalidOperation("readBuffer: If READ_FRAMEBUFFER is non-null, `mode` " + "must be COLOR_ATTACHMENTi or NONE. Was %s", + EnumName(mode)); return; } + MakeContextCurrent(); gl->fReadBuffer(mode); return; } // Operating on the default framebuffer. - if (mode != LOCAL_GL_NONE && mode != LOCAL_GL_BACK) { - ErrorInvalidEnumInfo("readBuffer: If READ_FRAMEBUFFER is null, `mode`" - " must be BACK or NONE. Was:", mode); + ErrorInvalidOperation("readBuffer: If READ_FRAMEBUFFER is null, `mode`" + " must be BACK or NONE. Was %s", + EnumName(mode)); return; } From faeeebcacd26ecf42824d53b56844e8a43d6575d Mon Sep 17 00:00:00 2001 From: Seth Fowler Date: Sun, 19 Jul 2015 19:30:35 -0700 Subject: [PATCH 57/69] Bug 1151359 (Part 1) - Predict the size of nsImageFrame images before drawing. r=tn --- dom/base/nsImageLoadingContent.cpp | 9 +++ layout/base/Units.h | 4 ++ layout/generic/nsImageFrame.cpp | 107 ++++++++++++++++++++++++----- layout/generic/nsImageFrame.h | 15 ++++ 4 files changed, 118 insertions(+), 17 deletions(-) diff --git a/dom/base/nsImageLoadingContent.cpp b/dom/base/nsImageLoadingContent.cpp index 5db21a16237e..39e94d356e5a 100644 --- a/dom/base/nsImageLoadingContent.cpp +++ b/dom/base/nsImageLoadingContent.cpp @@ -1512,6 +1512,15 @@ nsImageLoadingContent::TrackImage(imgIRequest* aImage) nsIDocument* doc = GetOurCurrentDoc(); if (doc && (mFrameCreateCalled || GetOurPrimaryFrame()) && (mVisibleCount > 0)) { + + if (mVisibleCount == 1) { + // Since we're becoming visible, request a decode. + nsImageFrame* f = do_QueryFrame(GetOurPrimaryFrame()); + if (f) { + f->MaybeDecodeForPredictedSize(); + } + } + if (aImage == mCurrentRequest && !(mCurrentRequestFlags & REQUEST_IS_TRACKED)) { mCurrentRequestFlags |= REQUEST_IS_TRACKED; doc->AddImage(mCurrentRequest); diff --git a/layout/base/Units.h b/layout/base/Units.h index 93410d2579ca..d40ad4bbb3bc 100644 --- a/layout/base/Units.h +++ b/layout/base/Units.h @@ -373,6 +373,10 @@ struct RenderTargetPixel { * generally be represented in ScreenPixel units. */ struct ScreenPixel { + static nsIntSize ToUntyped(const ScreenIntSize& aSize) { + return nsIntSize(aSize.width, aSize.height); + } + static ScreenIntPoint FromUntyped(const nsIntPoint& aPoint) { return ScreenIntPoint(aPoint.x, aPoint.y); } diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp index d8df0809e515..8e96f18c6987 100644 --- a/layout/generic/nsImageFrame.cpp +++ b/layout/generic/nsImageFrame.cpp @@ -577,6 +577,10 @@ nsImageFrame::OnSizeAvailable(imgIRequest* aRequest, imgIContainer* aImage) presShell->FrameNeedsReflow(this, nsIPresShell::eStyleChange, NS_FRAME_IS_DIRTY); } + } else { + // We've already gotten the initial reflow, and our size hasn't changed, + // so we're ready to request a decode. + MaybeDecodeForPredictedSize(); } } @@ -682,12 +686,93 @@ nsImageFrame::NotifyNewCurrentRequest(imgIRequest *aRequest, presShell->FrameNeedsReflow(this, nsIPresShell::eStyleChange, NS_FRAME_IS_DIRTY); } + } else { + // We've already gotten the initial reflow, and our size hasn't changed, + // so we're ready to request a decode. + MaybeDecodeForPredictedSize(); } // Update border+content to account for image change InvalidateFrame(); } } +void +nsImageFrame::MaybeDecodeForPredictedSize() +{ + // Check that we're ready to decode. + if (!mImage) { + return; // Nothing to do yet. + } + + if (mComputedSize.IsEmpty()) { + return; // We won't draw anything, so no point in decoding. + } + + nsCOMPtr imageLoader = do_QueryInterface(mContent); + MOZ_ASSERT(imageLoader); + if (imageLoader->GetVisibleCount() == 0) { + return; // We're not visible, so don't decode. + } + + // OK, we're ready to decode. Compute the scale to the screen... + nsIPresShell* presShell = PresContext()->GetPresShell(); + LayoutDeviceToScreenScale2D resolutionToScreen( + presShell->GetCumulativeResolution() + * nsLayoutUtils::GetTransformToAncestorScale(this)); + + // ...and this frame's content box... + const nsPoint offset = + GetOffsetToCrossDoc(nsLayoutUtils::GetReferenceFrame(this)); + const nsRect frameContentBox = GetInnerArea() + offset; + + // ...and our predicted dest rect... + const int32_t factor = PresContext()->AppUnitsPerDevPixel(); + const LayoutDeviceRect destRect = + LayoutDeviceRect::FromAppUnits(PredictedDestRect(frameContentBox), factor); + + // ...and use them to compute our predicted size in screen pixels. + const ScreenSize predictedScreenSize = destRect.Size() * resolutionToScreen; + const ScreenIntSize predictedScreenIntSize = RoundedToInt(predictedScreenSize); + if (predictedScreenIntSize.IsEmpty()) { + return; + } + + // Determine the optimal image size to use. + uint32_t flags = imgIContainer::FLAG_HIGH_QUALITY_SCALING + | imgIContainer::FLAG_ASYNC_NOTIFY; + GraphicsFilter filter = nsLayoutUtils::GetGraphicsFilterForFrame(this); + gfxSize gfxPredictedScreenSize = gfxSize(predictedScreenIntSize.width, + predictedScreenIntSize.height); + nsIntSize predictedImageSize = + mImage->OptimalImageSizeForDest(gfxPredictedScreenSize, + imgIContainer::FRAME_CURRENT, + filter, flags); + + // Request a decode. + mImage->RequestDecodeForSize(predictedImageSize, flags); +} + +nsRect +nsImageFrame::PredictedDestRect(const nsRect& aFrameContentBox) +{ + // What is the rect painted by the image? It's the image's "dest rect" (the + // rect where a full copy of the image is mapped), clipped to the container's + // content box. So, we intersect those rects. + + // Note: To get the "dest rect", we have to provide the "constraint rect" + // (which is the content-box, with the effects of fragmentation undone). + nsRect constraintRect(aFrameContentBox.TopLeft(), mComputedSize); + constraintRect.y -= GetContinuationOffset(); + + const nsRect destRect = + nsLayoutUtils::ComputeObjectDestRect(constraintRect, + mIntrinsicSize, + mIntrinsicRatio, + StylePosition()); + + return destRect.Intersect(aFrameContentBox); +} + void nsImageFrame::EnsureIntrinsicSizeAndRatio() { @@ -935,6 +1020,10 @@ nsImageFrame::Reflow(nsPresContext* aPresContext, static_assert(eOverflowType_LENGTH == 2, "Unknown overflow types?"); nsRect& visualOverflow = aMetrics.VisualOverflow(); visualOverflow.UnionRect(visualOverflow, altFeedbackSize); + } else { + // We've just reflowed and we should have an accurate size, so we're ready + // to request a decode. + MaybeDecodeForPredictedSize(); } FinishAndStoreOverflow(&aMetrics); @@ -1475,30 +1564,14 @@ nsDisplayImage::GetContainer(LayerManager* aManager, nsRect nsDisplayImage::GetDestRect(bool* aSnap) { - // OK, we want to return the entire region painted by the image. But what is - // that region? It's the image's "dest rect" (the rect where a full copy of - // the image is mapped), clipped to the container's content box (which is what - // GetBounds() returns). So, we grab those rects and intersect them. bool snap = true; const nsRect frameContentBox = GetBounds(&snap); if (aSnap) { *aSnap = snap; } - // Note: To get the "dest rect", we have to provide the "constraint rect" - // (which is the content-box, with the effects of fragmentation undone). nsImageFrame* imageFrame = static_cast(mFrame); - nsRect constraintRect(frameContentBox.TopLeft(), - imageFrame->mComputedSize); - constraintRect.y -= imageFrame->GetContinuationOffset(); - - const nsRect destRect = - nsLayoutUtils::ComputeObjectDestRect(constraintRect, - imageFrame->mIntrinsicSize, - imageFrame->mIntrinsicRatio, - imageFrame->StylePosition()); - - return destRect.Intersect(frameContentBox); + return imageFrame->PredictedDestRect(frameContentBox); } LayerState diff --git a/layout/generic/nsImageFrame.h b/layout/generic/nsImageFrame.h index a3ce60f940f1..155e7669d667 100644 --- a/layout/generic/nsImageFrame.h +++ b/layout/generic/nsImageFrame.h @@ -219,6 +219,14 @@ protected: const nsRect& aDirtyRect, imgIContainer* aImage, uint32_t aFlags); + /** + * If we're ready to decode - that is, if our current request's image is + * available and our decoding heuristics are satisfied - then trigger a decode + * for our image at the size we predict it will be drawn next time it's + * painted. + */ + void MaybeDecodeForPredictedSize(); + protected: friend class nsImageListener; friend class nsImageLoadingContent; @@ -235,6 +243,13 @@ protected: /// Always sync decode our image when painting if @aForce is true. void SetForceSyncDecoding(bool aForce) { mForceSyncDecoding = aForce; } + /** + * Computes the predicted dest rect that we'll draw into, in app units, based + * upon the provided frame content box. (The content box is what + * nsDisplayImage::GetBounds() returns.) + */ + nsRect PredictedDestRect(const nsRect& aFrameContentBox); + private: // random helpers inline void SpecToURI(const nsAString& aSpec, nsIIOService *aIOService, From 310598d7949727c766e640e882545ea96f6baa02 Mon Sep 17 00:00:00 2001 From: Seth Fowler Date: Sun, 19 Jul 2015 19:30:37 -0700 Subject: [PATCH 58/69] Bug 1151359 (Part 2) - Add support for detecting transform property changes that affect scale to ActiveLayerTracker. r=mstange --- layout/base/ActiveLayerTracker.cpp | 52 ++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/layout/base/ActiveLayerTracker.cpp b/layout/base/ActiveLayerTracker.cpp index eaefc102a901..d6a47c65e01a 100644 --- a/layout/base/ActiveLayerTracker.cpp +++ b/layout/base/ActiveLayerTracker.cpp @@ -5,6 +5,7 @@ #include "ActiveLayerTracker.h" #include "mozilla/ArrayUtils.h" +#include "mozilla/gfx/Matrix.h" #include "nsExpirationTracker.h" #include "nsContainerFrame.h" #include "nsIContent.h" @@ -12,11 +13,14 @@ #include "nsPIDOMWindow.h" #include "nsIDocument.h" #include "nsAnimationManager.h" +#include "nsStyleTransformMatrix.h" #include "nsTransitionManager.h" #include "nsDisplayList.h" namespace mozilla { +using namespace gfx; + /** * This tracks the state of a frame that may need active layers due to * ongoing content changes or style changes that indicate animation. @@ -34,6 +38,7 @@ public: , mContent(nullptr) , mOpacityRestyleCount(0) , mTransformRestyleCount(0) + , mScaleRestyleCount(0) , mLeftRestyleCount(0) , mTopRestyleCount(0) , mRightRestyleCount(0) @@ -71,9 +76,14 @@ public: nsIContent* mContent; nsExpirationState mState; + + // Previous scale due to the CSS transform property. + Maybe mPreviousTransformScale; + // Number of restyle operations detected uint8_t mOpacityRestyleCount; uint8_t mTransformRestyleCount; + uint8_t mScaleRestyleCount; uint8_t mLeftRestyleCount; uint8_t mTopRestyleCount; uint8_t mRightRestyleCount; @@ -206,12 +216,54 @@ ActiveLayerTracker::TransferActivityToFrame(nsIContent* aContent, nsIFrame* aFra aFrame->Properties().Set(LayerActivityProperty(), layerActivity); } +static void +IncrementScaleRestyleCountIfNeeded(nsIFrame* aFrame, LayerActivity* aActivity) +{ + const nsStyleDisplay* display = aFrame->StyleDisplay(); + if (!display->mSpecifiedTransform) { + // The transform was removed. + aActivity->mPreviousTransformScale = Nothing(); + IncrementMutationCount(&aActivity->mScaleRestyleCount); + return; + } + + // Compute the new scale due to the CSS transform property. + nsPresContext* presContext = aFrame->PresContext(); + RuleNodeCacheConditions dummy; + nsStyleTransformMatrix::TransformReferenceBox refBox(aFrame); + Matrix4x4 transform = ToMatrix4x4( + nsStyleTransformMatrix::ReadTransforms(display->mSpecifiedTransform->mHead, + aFrame->StyleContext(), + presContext, + dummy, refBox, + presContext->AppUnitsPerCSSPixel())); + Matrix transform2D; + if (!transform.Is2D(&transform2D)) { + // We don't attempt to handle 3D transforms; just assume the scale changed. + aActivity->mPreviousTransformScale = Nothing(); + IncrementMutationCount(&aActivity->mScaleRestyleCount); + return; + } + + gfxSize scale = ThebesMatrix(transform2D).ScaleFactors(true); + if (aActivity->mPreviousTransformScale == Some(scale)) { + return; // Nothing changed. + } + + aActivity->mPreviousTransformScale = Some(scale); + IncrementMutationCount(&aActivity->mScaleRestyleCount); +} + /* static */ void ActiveLayerTracker::NotifyRestyle(nsIFrame* aFrame, nsCSSProperty aProperty) { LayerActivity* layerActivity = GetLayerActivityForUpdate(aFrame); uint8_t& mutationCount = layerActivity->RestyleCountForProperty(aProperty); IncrementMutationCount(&mutationCount); + + if (aProperty == eCSSProperty_transform) { + IncrementScaleRestyleCountIfNeeded(aFrame, layerActivity); + } } /* static */ void From ec3068806882bd30e0a7b5cfffc398cd0da00a98 Mon Sep 17 00:00:00 2001 From: Seth Fowler Date: Sun, 19 Jul 2015 19:30:40 -0700 Subject: [PATCH 59/69] Bug 1151359 (Part 3) - Treat nsImageFrames subject to scale animation as having an identity scale when predicting size. r=tn,birtles --- layout/base/ActiveLayerTracker.cpp | 70 +++++++++++++++++++++++++++ layout/base/ActiveLayerTracker.h | 8 ++++ layout/base/nsLayoutUtils.cpp | 72 +++++++++++++++------------- layout/base/nsLayoutUtils.h | 8 ++++ layout/generic/nsImageFrame.cpp | 2 +- layout/style/StyleAnimationValue.cpp | 27 +++++++++++ layout/style/StyleAnimationValue.h | 4 ++ 7 files changed, 156 insertions(+), 35 deletions(-) diff --git a/layout/base/ActiveLayerTracker.cpp b/layout/base/ActiveLayerTracker.cpp index d6a47c65e01a..9e6a30961ec0 100644 --- a/layout/base/ActiveLayerTracker.cpp +++ b/layout/base/ActiveLayerTracker.cpp @@ -365,6 +365,76 @@ ActiveLayerTracker::IsOffsetOrMarginStyleAnimated(nsIFrame* aFrame) return false; } +// A helper function for IsScaleSubjectToAnimation which returns true if the +// given AnimationCollection contains a current effect that animates scale. +static bool +ContainsAnimatedScale(AnimationCollection* aCollection, nsIFrame* aFrame) +{ + if (!aCollection) { + return false; + } + + for (dom::Animation* anim : aCollection->mAnimations) { + if (!anim->HasCurrentEffect()) { + continue; + } + KeyframeEffectReadOnly* effect = anim->GetEffect(); + for (const AnimationProperty& prop : effect->Properties()) { + if (prop.mProperty != eCSSProperty_transform) { + continue; + } + for (AnimationPropertySegment segment : prop.mSegments) { + gfxSize from = segment.mFromValue.GetScaleValue(aFrame); + if (from != gfxSize(1.0f, 1.0f)) { + return true; + } + gfxSize to = segment.mToValue.GetScaleValue(aFrame); + if (to != gfxSize(1.0f, 1.0f)) { + return true; + } + } + } + } + + return false; +} + +/* static */ bool +ActiveLayerTracker::IsScaleSubjectToAnimation(nsIFrame* aFrame) +{ + // Check whether JavaScript is animating this frame's scale. + LayerActivity* layerActivity = GetLayerActivity(aFrame); + if (layerActivity && layerActivity->mScaleRestyleCount >= 2) { + return true; + } + + nsIContent* content = aFrame->GetContent(); + if (!content || !content->IsElement()) { + return false; + } + + nsCSSPseudoElements::Type pseudoType = + aFrame->StyleContext()->GetPseudoType(); + + // Check if any transitions associated with this frame may animate its scale. + AnimationCollection* transitions = + aFrame->PresContext()->TransitionManager()->GetAnimations( + content->AsElement(), pseudoType, false /* don't create */); + if (ContainsAnimatedScale(transitions, aFrame)) { + return true; + } + + // Check if any animations associated with this frame may animate its scale. + AnimationCollection* animations = + aFrame->PresContext()->AnimationManager()->GetAnimations( + content->AsElement(), pseudoType, false /* don't create */); + if (ContainsAnimatedScale(animations, aFrame)) { + return true; + } + + return false; +} + /* static */ void ActiveLayerTracker::NotifyContentChange(nsIFrame* aFrame) { diff --git a/layout/base/ActiveLayerTracker.h b/layout/base/ActiveLayerTracker.h index 7ac336faa91e..92d2736611e1 100644 --- a/layout/base/ActiveLayerTracker.h +++ b/layout/base/ActiveLayerTracker.h @@ -72,6 +72,14 @@ public: * as being animated for constructing active layers. */ static bool IsOffsetOrMarginStyleAnimated(nsIFrame* aFrame); + + /** + * Return true if aFrame either has an animated scale now, or is likely to + * have one in the future because it has a CSS animation or transition + * (which may not be playing right now) that affects its scale. + */ + static bool IsScaleSubjectToAnimation(nsIFrame* aFrame); + /** * Transfer the LayerActivity property to the frame's content node when the * frame is about to be destroyed so that layer activity can be tracked diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 97b9c8cf56c3..2c3614ef90f3 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -443,38 +443,6 @@ nsLayoutUtils::HasCurrentAnimationsForProperties(const nsIFrame* aFrame, return false; } -static gfxSize -GetScaleForValue(const StyleAnimationValue& aValue, const nsIFrame* aFrame) -{ - if (!aFrame) { - NS_WARNING("No frame."); - return gfxSize(); - } - if (aValue.GetUnit() != StyleAnimationValue::eUnit_Transform) { - NS_WARNING("Expected a transform."); - return gfxSize(); - } - - nsCSSValueSharedList* list = aValue.GetCSSValueSharedListValue(); - MOZ_ASSERT(list->mHead); - - RuleNodeCacheConditions dontCare; - TransformReferenceBox refBox(aFrame); - gfx3DMatrix transform = nsStyleTransformMatrix::ReadTransforms( - list->mHead, - aFrame->StyleContext(), - aFrame->PresContext(), dontCare, refBox, - aFrame->PresContext()->AppUnitsPerDevPixel()); - - gfxMatrix transform2d; - bool canDraw2D = transform.CanDraw2D(&transform2d); - if (!canDraw2D) { - return gfxSize(); - } - - return transform2d.ScaleFactors(true); -} - static float GetSuitableScale(float aMaxScale, float aMinScale, nscoord aVisibleDimension, nscoord aDisplayDimension) @@ -505,12 +473,12 @@ GetMinAndMaxScaleForAnimationProperty(const nsIFrame* aFrame, if (prop.mProperty == eCSSProperty_transform) { for (uint32_t segIdx = prop.mSegments.Length(); segIdx-- != 0; ) { AnimationPropertySegment& segment = prop.mSegments[segIdx]; - gfxSize from = GetScaleForValue(segment.mFromValue, aFrame); + gfxSize from = segment.mFromValue.GetScaleValue(aFrame); aMaxScale.width = std::max(aMaxScale.width, from.width); aMaxScale.height = std::max(aMaxScale.height, from.height); aMinScale.width = std::min(aMinScale.width, from.width); aMinScale.height = std::min(aMinScale.height, from.height); - gfxSize to = GetScaleForValue(segment.mToValue, aFrame); + gfxSize to = segment.mToValue.GetScaleValue(aFrame); aMaxScale.width = std::max(aMaxScale.width, to.width); aMaxScale.height = std::max(aMaxScale.height, to.height); aMinScale.width = std::min(aMinScale.width, to.width); @@ -2406,6 +2374,42 @@ nsLayoutUtils::GetTransformToAncestorScale(nsIFrame* aFrame) return gfxSize(1, 1); } +static Matrix4x4 +GetTransformToAncestorExcludingAnimated(nsIFrame* aFrame, + const nsIFrame* aAncestor) +{ + nsIFrame* parent; + Matrix4x4 ctm; + if (aFrame == aAncestor) { + return ctm; + } + if (ActiveLayerTracker::IsScaleSubjectToAnimation(aFrame)) { + return ctm; + } + ctm = aFrame->GetTransformMatrix(aAncestor, &parent); + while (parent && parent != aAncestor) { + if (ActiveLayerTracker::IsScaleSubjectToAnimation(parent)) { + return Matrix4x4(); + } + if (!parent->Preserves3DChildren()) { + ctm.ProjectTo2D(); + } + ctm = ctm * parent->GetTransformMatrix(aAncestor, &parent); + } + return ctm; +} + +gfxSize +nsLayoutUtils::GetTransformToAncestorScaleExcludingAnimated(nsIFrame* aFrame) +{ + Matrix4x4 transform = GetTransformToAncestorExcludingAnimated(aFrame, + nsLayoutUtils::GetDisplayRootFrame(aFrame)); + Matrix transform2D; + if (transform.Is2D(&transform2D)) { + return ThebesMatrix(transform2D).ScaleFactors(true); + } + return gfxSize(1, 1); +} nsIFrame* nsLayoutUtils::FindNearestCommonAncestorFrame(nsIFrame* aFrame1, nsIFrame* aFrame2) diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index 45d04a13a908..3391d66d2cce 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -808,6 +808,14 @@ public: */ static gfxSize GetTransformToAncestorScale(nsIFrame* aFrame); + /** + * Gets the scale factors of the transform for aFrame relative to the root + * frame if this transform is 2D, or the identity scale factors otherwise. + * If some frame on the path from aFrame to the display root frame may have an + * animated scale, returns the identity scale factors. + */ + static gfxSize GetTransformToAncestorScaleExcludingAnimated(nsIFrame* aFrame); + /** * Find the nearest common ancestor frame for aFrame1 and aFrame2. The * ancestor frame could be cross-doc. diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp index 8e96f18c6987..a720d422888d 100644 --- a/layout/generic/nsImageFrame.cpp +++ b/layout/generic/nsImageFrame.cpp @@ -718,7 +718,7 @@ nsImageFrame::MaybeDecodeForPredictedSize() nsIPresShell* presShell = PresContext()->GetPresShell(); LayoutDeviceToScreenScale2D resolutionToScreen( presShell->GetCumulativeResolution() - * nsLayoutUtils::GetTransformToAncestorScale(this)); + * nsLayoutUtils::GetTransformToAncestorScaleExcludingAnimated(this)); // ...and this frame's content box... const nsPoint offset = diff --git a/layout/style/StyleAnimationValue.cpp b/layout/style/StyleAnimationValue.cpp index c50cdf1a518f..3a68c4054e4c 100644 --- a/layout/style/StyleAnimationValue.cpp +++ b/layout/style/StyleAnimationValue.cpp @@ -25,6 +25,7 @@ #include "gfxMatrix.h" #include "gfxQuaternion.h" #include "nsIDocument.h" +#include "nsIFrame.h" #include "gfx2DGlue.h" using namespace mozilla; @@ -3526,6 +3527,32 @@ StyleAnimationValue::ExtractComputedValue(nsCSSProperty aProperty, return false; } +gfxSize +StyleAnimationValue::GetScaleValue(const nsIFrame* aForFrame) const +{ + MOZ_ASSERT(aForFrame); + MOZ_ASSERT(GetUnit() == StyleAnimationValue::eUnit_Transform); + + nsCSSValueSharedList* list = GetCSSValueSharedListValue(); + MOZ_ASSERT(list->mHead); + + RuleNodeCacheConditions dontCare; + nsStyleTransformMatrix::TransformReferenceBox refBox(aForFrame); + gfx3DMatrix transform = nsStyleTransformMatrix::ReadTransforms( + list->mHead, + aForFrame->StyleContext(), + aForFrame->PresContext(), dontCare, refBox, + aForFrame->PresContext()->AppUnitsPerDevPixel()); + + gfxMatrix transform2d; + bool canDraw2D = transform.CanDraw2D(&transform2d); + if (!canDraw2D) { + return gfxSize(); + } + + return transform2d.ScaleFactors(true); +} + StyleAnimationValue::StyleAnimationValue(int32_t aInt, Unit aUnit, IntegerConstructorType) { diff --git a/layout/style/StyleAnimationValue.h b/layout/style/StyleAnimationValue.h index e95f802e3fa8..d232b38779b0 100644 --- a/layout/style/StyleAnimationValue.h +++ b/layout/style/StyleAnimationValue.h @@ -15,6 +15,7 @@ #include "nsColor.h" #include "nsCSSValue.h" +class nsIFrame; class nsStyleContext; class gfx3DMatrix; @@ -317,6 +318,9 @@ public: mValue.mString->ToString(len, aBuffer); } + /// @return the scale for this value, calculated with reference to @aForFrame. + gfxSize GetScaleValue(const nsIFrame* aForFrame) const; + explicit StyleAnimationValue(Unit aUnit = eUnit_Null) : mUnit(aUnit) { NS_ASSERTION(aUnit == eUnit_Null || aUnit == eUnit_Normal || aUnit == eUnit_Auto || aUnit == eUnit_None, From 734c9eb563eb43f823bf40fa00aa3c4bd96de9c9 Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Sun, 19 Jul 2015 22:39:20 -0400 Subject: [PATCH 60/69] Backed out changesets 90446493d402 and c4f4027f9f3a (bug 1179051) for crashes. --- gfx/src/gfxTelemetry.cpp | 36 -------- gfx/src/gfxTelemetry.h | 46 ---------- gfx/src/moz.build | 2 - gfx/thebes/gfxPlatform.cpp | 25 ------ gfx/thebes/gfxPlatform.h | 15 ---- gfx/thebes/gfxWindowsPlatform.cpp | 85 +++++-------------- gfx/thebes/gfxWindowsPlatform.h | 18 +--- .../telemetry/TelemetryEnvironment.jsm | 30 ------- .../components/telemetry/docs/environment.rst | 22 ----- .../tests/unit/test_TelemetryEnvironment.js | 6 -- widget/GfxInfoBase.cpp | 85 ------------------- widget/GfxInfoBase.h | 10 --- widget/nsBaseWidget.cpp | 2 - widget/nsIGfxInfo.idl | 28 +----- widget/windows/GfxInfo.cpp | 36 -------- widget/windows/GfxInfo.h | 2 - 16 files changed, 21 insertions(+), 427 deletions(-) delete mode 100644 gfx/src/gfxTelemetry.cpp delete mode 100644 gfx/src/gfxTelemetry.h diff --git a/gfx/src/gfxTelemetry.cpp b/gfx/src/gfxTelemetry.cpp deleted file mode 100644 index 027c6761ed7d..000000000000 --- a/gfx/src/gfxTelemetry.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * 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/. */ -#include "gfxTelemetry.h" - -namespace mozilla { -namespace gfx { - -const char* -FeatureStatusToString(FeatureStatus aStatus) -{ - switch (aStatus) { - case FeatureStatus::Unused: - return "unused"; - case FeatureStatus::Unavailable: - return "unavailable"; - case FeatureStatus::Blocked: - return "blocked"; - case FeatureStatus::Blacklisted: - return "blacklisted"; - case FeatureStatus::Failed: - return "failed"; - case FeatureStatus::Disabled: - return "disabled"; - case FeatureStatus::Available: - return "available"; - default: - MOZ_ASSERT_UNREACHABLE("missing status case"); - return "unknown"; - } -} - -} // namespace gfx -} // namespace mozilla diff --git a/gfx/src/gfxTelemetry.h b/gfx/src/gfxTelemetry.h deleted file mode 100644 index e65c107c389a..000000000000 --- a/gfx/src/gfxTelemetry.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * 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 gfx_src_gfxTelemetry_h__ -#define gfx_src_gfxTelemetry_h__ - -namespace mozilla { -namespace gfx { - -// Describes the status of a graphics feature, in terms of whether or not we've -// attempted to initialize the feature, and if so, whether or not it succeeded -// (and if not, why). -enum class FeatureStatus -{ - // This feature has not been requested. - Unused, - - // This feature is unavailable due to Safe Mode or not being included with - // the operating system. - Unavailable, - - // This feature was blocked for reasons outside the blacklist, such as a - // runtime test failing. - Blocked, - - // This feature has been blocked by the graphics blacklist. - Blacklisted, - - // This feature was attempted but failed to activate. - Failed, - - // This feature was explicitly disabled by the user. - Disabled, - - // This feature is available for use. - Available -}; - -const char* FeatureStatusToString(FeatureStatus aStatus); - -} // namespace gfx -} // namespace mozilla - -#endif // gfx_src_gfxTelemetry_h__ diff --git a/gfx/src/moz.build b/gfx/src/moz.build index 3d26b88016c5..8f9bff14151b 100644 --- a/gfx/src/moz.build +++ b/gfx/src/moz.build @@ -18,7 +18,6 @@ EXPORTS += [ 'FilterSupport.h', 'gfxCore.h', 'gfxCrashReporterUtils.h', - 'gfxTelemetry.h', 'nsBoundingMetrics.h', 'nsColor.h', 'nsColorNameList.h', @@ -57,7 +56,6 @@ UNIFIED_SOURCES += [ 'DriverInitCrashDetection.cpp', 'FilterSupport.cpp', 'gfxCrashReporterUtils.cpp', - 'gfxTelemetry.cpp', 'nsColor.cpp', 'nsFont.cpp', 'nsFontMetrics.cpp', diff --git a/gfx/thebes/gfxPlatform.cpp b/gfx/thebes/gfxPlatform.cpp index 041e90d77cfe..c9bb910a078a 100644 --- a/gfx/thebes/gfxPlatform.cpp +++ b/gfx/thebes/gfxPlatform.cpp @@ -379,7 +379,6 @@ gfxPlatform::gfxPlatform() , mTileHeight(-1) , mAzureCanvasBackendCollector(this, &gfxPlatform::GetAzureBackendInfo) , mApzSupportCollector(this, &gfxPlatform::GetApzSupportInfo) - , mCompositorBackend(layers::LayersBackend::LAYERS_NONE) { mAllowDownloadableFonts = UNINITIALIZED_VALUE; mFallbackUsesCmaps = UNINITIALIZED_VALUE; @@ -411,12 +410,6 @@ gfxPlatform::GetPlatform() return gPlatform; } -bool -gfxPlatform::Initialized() -{ - return !!gPlatform; -} - void RecordingPrefChanged(const char *aPrefName, void *aClosure) { if (Preferences::GetBool("gfx.2d.recording", false)) { @@ -2451,21 +2444,3 @@ gfxPlatform::GetCompositorBackends(bool useAcceleration, nsTArray obsvc = services::GetObserverService()) { - obsvc->NotifyObservers(nullptr, "compositor:created", nullptr); - } -} diff --git a/gfx/thebes/gfxPlatform.h b/gfx/thebes/gfxPlatform.h index 23a57cebdd85..1958665aa970 100644 --- a/gfx/thebes/gfxPlatform.h +++ b/gfx/thebes/gfxPlatform.h @@ -159,12 +159,6 @@ public: */ static gfxPlatform *GetPlatform(); - /** - * Returns whether or not graphics has been initialized yet. This is - * intended for Telemetry where we don't necessarily want to initialize - * graphics just to observe its state. - */ - static bool Initialized(); /** * Shut down Thebes. @@ -637,11 +631,6 @@ public: */ static bool PerfWarnings(); - void NotifyCompositorCreated(mozilla::layers::LayersBackend aBackend); - mozilla::layers::LayersBackend GetCompositorBackend() const { - return mCompositorBackend; - } - protected: gfxPlatform(); virtual ~gfxPlatform(); @@ -762,10 +751,6 @@ private: mozilla::RefPtr mRecorder; mozilla::RefPtr mSkiaGlue; - - // Backend that we are compositing with. NONE, if no compositor has been - // created yet. - mozilla::layers::LayersBackend mCompositorBackend; }; #endif /* GFX_PLATFORM_H */ diff --git a/gfx/thebes/gfxWindowsPlatform.cpp b/gfx/thebes/gfxWindowsPlatform.cpp index 0b7d1f59cfe1..0fd2090c1254 100755 --- a/gfx/thebes/gfxWindowsPlatform.cpp +++ b/gfx/thebes/gfxWindowsPlatform.cpp @@ -377,8 +377,6 @@ gfxWindowsPlatform::gfxWindowsPlatform() , mIsWARP(false) , mHasDeviceReset(false) , mDoesD3D11TextureSharingWork(false) - , mD3D11Status(FeatureStatus::Unused) - , mD2DStatus(FeatureStatus::Unused) { mUseClearTypeForDownloadableFonts = UNINITIALIZED_VALUE; mUseClearTypeAlways = UNINITIALIZED_VALUE; @@ -438,7 +436,7 @@ gfxWindowsPlatform::CanUseHardwareVideoDecoding() return !IsWARP() && gfxPlatform::CanUseHardwareVideoDecoding(); } -FeatureStatus +void gfxWindowsPlatform::InitD2DSupport() { #ifdef CAIRO_HAS_D2D_SURFACE @@ -460,41 +458,30 @@ gfxWindowsPlatform::InitD2DSupport() // If D2D is blocked or D3D9 is prefered, and D2D is not force-enabled, then // we don't attempt to use D2D. - if (!gfxPrefs::Direct2DForceEnabled()) { - if (d2dBlocked) { - return FeatureStatus::Blacklisted; - } - if (gfxPrefs::LayersPreferD3D9()) { - return FeatureStatus::Disabled; - } + if ((d2dBlocked || gfxPrefs::LayersPreferD3D9()) && !gfxPrefs::Direct2DForceEnabled()) { + return; } // Do not ever try to use D2D if it's explicitly disabled or if we're not // using DWrite fonts. if (gfxPrefs::Direct2DDisabled() || mUsingGDIFonts) { - return FeatureStatus::Disabled; + return; } - if (!IsVistaOrLater() || !GetD3D11Device()) { - return FeatureStatus::Unavailable; + ID3D11Device* device = GetD3D11Device(); + if (IsVistaOrLater() && + !InSafeMode() && + device && + mDoesD3D11TextureSharingWork) + { + VerifyD2DDevice(gfxPrefs::Direct2DForceEnabled()); + if (mD3D10Device && GetD3D11Device()) { + mRenderMode = RENDER_DIRECT2D; + mUseDirectWrite = true; + } + } else { + mD3D10Device = nullptr; } - if (!mDoesD3D11TextureSharingWork) { - return FeatureStatus::Failed; - } - if (InSafeMode()) { - return FeatureStatus::Blocked; - } - - VerifyD2DDevice(gfxPrefs::Direct2DForceEnabled()); - if (!mD3D10Device || !GetD3D11Device()) { - return FeatureStatus::Failed; - } - - mRenderMode = RENDER_DIRECT2D; - mUseDirectWrite = true; - return FeatureStatus::Available; -#else - return FeatureStatus::Unavailable; #endif } @@ -565,7 +552,7 @@ gfxWindowsPlatform::UpdateRenderMode() mRenderMode = RENDER_GDI; mUseDirectWrite = gfxPrefs::DirectWriteFontRenderingEnabled(); - mD2DStatus = InitD2DSupport(); + InitD2DSupport(); InitDWriteSupport(); uint32_t canvasMask = BackendTypeBit(BackendType::CAIRO); @@ -2069,17 +2056,15 @@ gfxWindowsPlatform::InitD3D11Devices() mD3D11DeviceInitialized = true; mDoesD3D11TextureSharingWork = false; - MOZ_ASSERT(!mD3D11Device); + MOZ_ASSERT(!mD3D11Device); DriverInitCrashDetection detectCrashes; if (InSafeMode() || detectCrashes.DisableAcceleration()) { - mD3D11Status = FeatureStatus::Blocked; return; } D3D11Status status = CheckD3D11Support(); if (status == D3D11Status::Blocked) { - mD3D11Status = FeatureStatus::Blacklisted; return; } @@ -2089,7 +2074,6 @@ gfxWindowsPlatform::InitD3D11Devices() if (!sD3D11CreateDeviceFn) { // We should just be on Windows Vista or XP in this case. - mD3D11Status = FeatureStatus::Unavailable; return; } @@ -2113,7 +2097,6 @@ gfxWindowsPlatform::InitD3D11Devices() (status == D3D11Status::TryWARP || status == D3D11Status::ForceWARP)) { AttemptWARPDeviceCreation(featureLevels); - mD3D11Status = FeatureStatus::Failed; } if (!mD3D11Device) { @@ -2122,7 +2105,6 @@ gfxWindowsPlatform::InitD3D11Devices() } mD3D11Device->SetExceptionMode(0); - mD3D11Status = FeatureStatus::Available; // We create our device for D2D content drawing here. Normally we don't use // D2D content drawing when using WARP. However when WARP is forced by @@ -2427,32 +2409,3 @@ gfxWindowsPlatform::GetAcceleratedCompositorBackends(nsTArray& aB } } } - -FeatureStatus -gfxWindowsPlatform::GetD2D1Status() -{ - if (GetD2DStatus() != FeatureStatus::Available || - !Factory::SupportsD2D1()) - { - return FeatureStatus::Unavailable; - } - - if (!GetD3D11ContentDevice()) { - return FeatureStatus::Failed; - } - - if (!gfxPrefs::Direct2DUse1_1()) { - return FeatureStatus::Disabled; - } - return FeatureStatus::Available; -} - -unsigned -gfxWindowsPlatform::GetD3D11Version() -{ - ID3D11Device* device = GetD3D11Device(); - if (!device) { - return 0; - } - return device->GetFeatureLevel(); -} diff --git a/gfx/thebes/gfxWindowsPlatform.h b/gfx/thebes/gfxWindowsPlatform.h index eb730b3a8cf0..24438eb4f10f 100644 --- a/gfx/thebes/gfxWindowsPlatform.h +++ b/gfx/thebes/gfxWindowsPlatform.h @@ -20,7 +20,6 @@ #include "gfxDWriteFonts.h" #endif #include "gfxPlatform.h" -#include "gfxTelemetry.h" #include "gfxTypes.h" #include "mozilla/Attributes.h" #include "mozilla/Atomics.h" @@ -262,18 +261,6 @@ public: } bool SupportsApzTouchInput() const override; - // Return the diagnostic status of DirectX initialization. If - // initialization has not been attempted, this returns - // FeatureStatus::Unused. - mozilla::gfx::FeatureStatus GetD3D11Status() const { - return mD3D11Status; - } - mozilla::gfx::FeatureStatus GetD2DStatus() const { - return mD2DStatus; - } - unsigned GetD3D11Version(); - mozilla::gfx::FeatureStatus GetD2D1Status(); - virtual already_AddRefed CreateHardwareVsyncSource() override; static mozilla::Atomic sD3D11MemoryUsed; static mozilla::Atomic sD3D9MemoryUsed; @@ -311,7 +298,7 @@ private: bool AttemptD3D11ContentDeviceCreation(const nsTArray& aFeatureLevels); // Used by UpdateRenderMode(). - mozilla::gfx::FeatureStatus InitD2DSupport(); + void InitD2DSupport(); void InitDWriteSupport(); IDXGIAdapter1 *GetDXGIAdapter(); @@ -339,9 +326,6 @@ private: bool mDoesD3D11TextureSharingWork; DeviceResetReason mDeviceResetReason; - mozilla::gfx::FeatureStatus mD3D11Status; - mozilla::gfx::FeatureStatus mD2DStatus; - virtual void GetPlatformCMSOutputProfile(void* &mem, size_t &size); }; diff --git a/toolkit/components/telemetry/TelemetryEnvironment.jsm b/toolkit/components/telemetry/TelemetryEnvironment.jsm index 87a8d5fae121..a23fed97f476 100644 --- a/toolkit/components/telemetry/TelemetryEnvironment.jsm +++ b/toolkit/components/telemetry/TelemetryEnvironment.jsm @@ -157,7 +157,6 @@ const PREF_UPDATE_AUTODOWNLOAD = "app.update.auto"; const EXPERIMENTS_CHANGED_TOPIC = "experiments-changed"; const SEARCH_ENGINE_MODIFIED_TOPIC = "browser-search-engine-modified"; const SEARCH_SERVICE_TOPIC = "browser-search-service"; -const COMPOSITOR_CREATED_TOPIC = "compositor:created"; /** * Get the current browser. @@ -810,14 +809,12 @@ EnvironmentCache.prototype = { // Watch the search engine change and service topics. Services.obs.addObserver(this, SEARCH_ENGINE_MODIFIED_TOPIC, false); Services.obs.addObserver(this, SEARCH_SERVICE_TOPIC, false); - Services.obs.addObserver(this, COMPOSITOR_CREATED_TOPIC, false); }, _removeObservers: function () { // Remove the search engine change and service observers. Services.obs.removeObserver(this, SEARCH_ENGINE_MODIFIED_TOPIC); Services.obs.removeObserver(this, SEARCH_SERVICE_TOPIC); - Services.obs.removeObserver(this, COMPOSITOR_CREATED_TOPIC); }, observe: function (aSubject, aTopic, aData) { @@ -837,12 +834,6 @@ EnvironmentCache.prototype = { // Now that the search engine init is complete, record the default search choice. this._updateSearchEngine(); break; - case COMPOSITOR_CREATED_TOPIC: - // Full graphics information is not available until we have created at - // least one off-main-thread-composited window. Thus we wait for the - // first compositor to be created and then query nsIGfxInfo again. - this._onCompositorCreated(); - break; } }, @@ -905,19 +896,6 @@ EnvironmentCache.prototype = { this._onEnvironmentChange("search-engine-changed", oldEnvironment); }, - /** - * Update the graphics features object. - */ - _onCompositorCreated: function () { - let gfxData = this._currentEnvironment.system.gfx; - try { - let gfxInfo = Cc["@mozilla.org/gfx/info;1"].getService(Ci.nsIGfxInfo); - gfxData.features = gfxInfo.getFeatures(); - } catch (e) { - this._log.error("nsIGfxInfo.getFeatures() caught error", e); - } - }, - /** * Get the build data in object form. * @return Object containing the build data. @@ -1150,7 +1128,6 @@ EnvironmentCache.prototype = { //DWriteVersion: getGfxField("DWriteVersion", null), adapters: [], monitors: [], - features: {}, }; #if !defined(MOZ_WIDGET_GONK) && !defined(MOZ_WIDGET_ANDROID) && !defined(MOZ_WIDGET_GTK) @@ -1162,13 +1139,6 @@ EnvironmentCache.prototype = { } #endif - try { - let gfxInfo = Cc["@mozilla.org/gfx/info;1"].getService(Ci.nsIGfxInfo); - gfxData.features = gfxInfo.getFeatures(); - } catch (e) { - this._log.error("nsIGfxInfo.getFeatures() caught error", e); - } - // GfxInfo does not yet expose a way to iterate through all the adapters. gfxData.adapters.push(getGfxAdapter("")); gfxData.adapters[0].GPUActive = true; diff --git a/toolkit/components/telemetry/docs/environment.rst b/toolkit/components/telemetry/docs/environment.rst index ec9e03613f16..e4c891fb70c5 100644 --- a/toolkit/components/telemetry/docs/environment.rst +++ b/toolkit/components/telemetry/docs/environment.rst @@ -145,28 +145,6 @@ Structure:: }, ... ], - features: { - compositor: , // Layers backend for compositing (eg "d3d11", "none", "opengl") - - // Each the following features can have one of the following statuses: - // "unused" - This feature has not been requested. - // "unavailable" - Safe Mode or OS restriction prevents use. - // "blocked" - Blocked due to an internal condition such as safe mode. - // "blacklisted" - Blocked due to a blacklist restriction. - // "disabled" - User explicitly disabled this default feature. - // "failed" - This feature was attempted but failed to initialize. - // "available" - User has this feature available. - "d3d11" { // This feature is Windows-only. - status: , - warp: , // Software rendering (WARP) mode was chosen. - textureSharing: // Whether or not texture sharing works. - version: , // The D3D11 device feature level. - }, - "d2d" { // This feature is Windows-only. - status: , - version: , // Either "1.0" or "1.1". - }, - }, }, }, addons: { diff --git a/toolkit/components/telemetry/tests/unit/test_TelemetryEnvironment.js b/toolkit/components/telemetry/tests/unit/test_TelemetryEnvironment.js index eabb05ceea2b..5e0de56e903c 100644 --- a/toolkit/components/telemetry/tests/unit/test_TelemetryEnvironment.js +++ b/toolkit/components/telemetry/tests/unit/test_TelemetryEnvironment.js @@ -430,9 +430,6 @@ function checkSystemSection(data) { } } - Assert.equal(typeof gfxData.features, "object"); - Assert.equal(typeof gfxData.features.compositor, "string"); - try { // If we've not got nsIGfxInfoDebug, then this will throw and stop us doing // this test. @@ -442,9 +439,6 @@ function checkSystemSection(data) { Assert.equal(GFX_VENDOR_ID, gfxData.adapters[0].vendorID); Assert.equal(GFX_DEVICE_ID, gfxData.adapters[0].deviceID); } - - let features = gfxInfo.getFeatures(); - Assert.equal(features.compositor, gfxData.features.compositor); } catch (e) {} } diff --git a/widget/GfxInfoBase.cpp b/widget/GfxInfoBase.cpp index 93956add779c..61cb5c98f92b 100644 --- a/widget/GfxInfoBase.cpp +++ b/widget/GfxInfoBase.cpp @@ -33,7 +33,6 @@ #include "mozilla/gfx/2D.h" #include "mozilla/gfx/Logging.h" #include "gfxPrefs.h" -#include "gfxPlatform.h" #if defined(MOZ_CRASHREPORTER) #include "nsExceptionHandler.h" @@ -1180,90 +1179,6 @@ GfxInfoBase::GetMonitors(JSContext* aCx, JS::MutableHandleValue aResult) return NS_OK; } -static const char* -GetLayersBackendName(layers::LayersBackend aBackend) -{ - switch (aBackend) { - case layers::LayersBackend::LAYERS_NONE: - return "none"; - case layers::LayersBackend::LAYERS_OPENGL: - return "opengl"; - case layers::LayersBackend::LAYERS_D3D9: - return "d3d9"; - case layers::LayersBackend::LAYERS_D3D11: - return "d3d11"; - case layers::LayersBackend::LAYERS_CLIENT: - return "client"; - default: - MOZ_ASSERT_UNREACHABLE("unknown layers backend"); - return "unknown"; - } -} - -nsresult -GfxInfoBase::GetFeatures(JSContext* aCx, JS::MutableHandle aOut) -{ - JS::Rooted obj(aCx, JS_NewPlainObject(aCx)); - if (!obj) { - return NS_ERROR_OUT_OF_MEMORY; - } - aOut.setObject(*obj); - - layers::LayersBackend backend = gfxPlatform::Initialized() - ? gfxPlatform::GetPlatform()->GetCompositorBackend() - : layers::LayersBackend::LAYERS_NONE; - const char* backendName = GetLayersBackendName(backend); - { - JS::Rooted str(aCx, JS_NewStringCopyZ(aCx, backendName)); - JS::Rooted val(aCx, StringValue(str)); - JS_SetProperty(aCx, obj, "compositor", val); - } - - // If graphics isn't initialized yet, just stop now. - if (!gfxPlatform::Initialized()) { - return NS_OK; - } - - DescribeFeatures(aCx, obj); - return NS_OK; -} - -void -GfxInfoBase::DescribeFeatures(JSContext* cx, JS::Handle aOut) -{ -} - -bool -GfxInfoBase::InitFeatureObject(JSContext* aCx, - JS::Handle aContainer, - const char* aName, - mozilla::gfx::FeatureStatus aFeatureStatus, - JS::MutableHandle aOutObj) -{ - JS::Rooted obj(aCx, JS_NewPlainObject(aCx)); - if (!obj) { - return false; - } - - const char* status = FeatureStatusToString(aFeatureStatus); - - // Set "status". - { - JS::Rooted str(aCx, JS_NewStringCopyZ(aCx, status)); - JS::Rooted val(aCx, JS::StringValue(str)); - JS_SetProperty(aCx, obj, "status", val); - } - - // Add the feature object to the container. - { - JS::Rooted val(aCx, JS::ObjectValue(*obj)); - JS_SetProperty(aCx, aContainer, aName, val); - } - - aOutObj.set(obj); - return true; -} - GfxInfoCollectorBase::GfxInfoCollectorBase() { GfxInfoBase::AddCollector(this); diff --git a/widget/GfxInfoBase.h b/widget/GfxInfoBase.h index dff9cf0a5899..4188912ba390 100644 --- a/widget/GfxInfoBase.h +++ b/widget/GfxInfoBase.h @@ -19,7 +19,6 @@ #include "nsTArray.h" #include "nsString.h" #include "GfxInfoCollector.h" -#include "gfxTelemetry.h" #include "nsIGfxInfoDebug.h" #include "mozilla/Mutex.h" #include "js/Value.h" @@ -59,7 +58,6 @@ public: NS_IMETHOD GetFailures(uint32_t *failureCount, int32_t** indices, char ***failures) override; NS_IMETHOD_(void) LogFailure(const nsACString &failure) override; NS_IMETHOD GetInfo(JSContext*, JS::MutableHandle) override; - NS_IMETHOD GetFeatures(JSContext*, JS::MutableHandle) override; // Initialization function. If you override this, you must call this class's // version of Init first. @@ -105,14 +103,6 @@ protected: // (while subclasses check for more specific ones). virtual const nsTArray& GetGfxDriverInfo() = 0; - virtual void DescribeFeatures(JSContext* aCx, JS::Handle obj); - bool InitFeatureObject( - JSContext* aCx, - JS::Handle aContainer, - const char* aName, - mozilla::gfx::FeatureStatus aFeatureStatus, - JS::MutableHandle aOutObj); - private: virtual int32_t FindBlocklistedDeviceInList(const nsTArray& aDriverInfo, nsAString& aSuggestedVersion, diff --git a/widget/nsBaseWidget.cpp b/widget/nsBaseWidget.cpp index fe4f693bc255..087c6a181fff 100644 --- a/widget/nsBaseWidget.cpp +++ b/widget/nsBaseWidget.cpp @@ -1131,8 +1131,6 @@ void nsBaseWidget::CreateCompositor(int aWidth, int aHeight) WindowUsesOMTC(); mLayerManager = lm.forget(); - - gfxPlatform::GetPlatform()->NotifyCompositorCreated(mLayerManager->GetCompositorBackendType()); } bool nsBaseWidget::ShouldUseOffMainThreadCompositing() diff --git a/widget/nsIGfxInfo.idl b/widget/nsIGfxInfo.idl index 1e76c22c897e..8b10556b2fa7 100644 --- a/widget/nsIGfxInfo.idl +++ b/widget/nsIGfxInfo.idl @@ -8,7 +8,7 @@ /* NOTE: this interface is completely undesigned, not stable and likely to change */ -[scriptable, uuid(98690931-c9a5-4675-9ab4-90932ec32bf2)] +[scriptable, uuid(47eedfa0-f7cb-445b-b5cf-a2ca83600560)] interface nsIGfxInfo : nsISupports { /* @@ -147,31 +147,5 @@ interface nsIGfxInfo : nsISupports [implicit_jscontext] jsval getInfo(); - - // Returns an object containing information about graphics features. It is - // intended to be directly included into the Telemetry environment. - // - // "layers": - // { - // "compositor": "d3d9", "d3d11", "opengl", "basic", or "none" - // // ("none" indicates no compositors have been created) - // // Feature is one of "d3d9", "d3d11", "opengl", "basic", or "d2d". - // "": { - // // Each backend can have one of the following statuses: - // // "unused" - This feature has not been requested. - // // "unavailable" - OS version or restriction prevents use. - // // "blocked" - An internal condition (such as safe mode) prevents use. - // // "blacklisted" - Blocked due to a blacklist restriction. - // // "disabled" - User explicitly disabled this default feature. - // // "failed" - Feature failed to initialize. - // // "available" - User has this feature available by default. - // "status": "", - // "version": "", - // "warp": true|false, // D3D11 only. - // "textureSharing": true|false, // D3D11 only. - // } - // } - [implicit_jscontext] - jsval getFeatures(); }; diff --git a/widget/windows/GfxInfo.cpp b/widget/windows/GfxInfo.cpp index 9400ecbda474..eb1f4ec81dfa 100644 --- a/widget/windows/GfxInfo.cpp +++ b/widget/windows/GfxInfo.cpp @@ -1255,42 +1255,6 @@ GfxInfo::FindMonitors(JSContext* aCx, JS::HandleObject aOutArray) return NS_OK; } -void -GfxInfo::DescribeFeatures(JSContext* aCx, JS::Handle aObj) -{ - JS::Rooted obj(aCx); - - gfxWindowsPlatform* platform = gfxWindowsPlatform::GetPlatform(); - - gfx::FeatureStatus d3d11 = platform->GetD3D11Status(); - if (!InitFeatureObject(aCx, aObj, "d3d11", d3d11, &obj)) { - return; - } - if (d3d11 == gfx::FeatureStatus::Available) { - JS::Rooted val(aCx, JS::Int32Value(platform->GetD3D11Version())); - JS_SetProperty(aCx, obj, "version", val); - - val = JS::BooleanValue(platform->IsWARP()); - JS_SetProperty(aCx, obj, "warp", val); - - val = JS::BooleanValue(platform->DoesD3D11TextureSharingWork()); - JS_SetProperty(aCx, obj, "textureSharing", val); - } - - gfx::FeatureStatus d2d = platform->GetD2DStatus(); - if (!InitFeatureObject(aCx, aObj, "d2d", d2d, &obj)) { - return; - } - { - const char* version = "1.0"; - if (platform->GetD2D1Status() == gfx::FeatureStatus::Available) - version = "1.1"; - JS::Rooted str(aCx, JS_NewStringCopyZ(aCx, version)); - JS::Rooted val(aCx, JS::StringValue(str)); - JS_SetProperty(aCx, obj, "version", val); - } -} - #ifdef DEBUG // Implement nsIGfxInfoDebug diff --git a/widget/windows/GfxInfo.h b/widget/windows/GfxInfo.h index 5d05b149ebe0..5fd361900ba2 100644 --- a/widget/windows/GfxInfo.h +++ b/widget/windows/GfxInfo.h @@ -68,8 +68,6 @@ protected: OperatingSystem* aOS = nullptr); virtual const nsTArray& GetGfxDriverInfo(); - void DescribeFeatures(JSContext* cx, JS::Handle aOut) override; - private: void AddCrashReportAnnotations(); From c0cc3c561488fef6200e19e22fced1c428fb296b Mon Sep 17 00:00:00 2001 From: Christoph Kerschbaumer Date: Sun, 19 Jul 2015 19:11:03 -0700 Subject: [PATCH 61/69] Bug 1175803 - Store redirect chain within loadInfo - part 1 (r=sicking,mayhemer) --- ipc/glue/BackgroundUtils.cpp | 21 +++++++++++++++-- netwerk/base/LoadInfo.cpp | 29 ++++++++++++++++++++++- netwerk/base/LoadInfo.h | 6 ++++- netwerk/base/nsILoadInfo.idl | 35 ++++++++++++++++++++++++++-- netwerk/ipc/NeckoChannelParams.ipdlh | 17 +++++++------- 5 files changed, 94 insertions(+), 14 deletions(-) diff --git a/ipc/glue/BackgroundUtils.cpp b/ipc/glue/BackgroundUtils.cpp index 19dc5580aa96..0d0ba2f8c7ae 100644 --- a/ipc/glue/BackgroundUtils.cpp +++ b/ipc/glue/BackgroundUtils.cpp @@ -16,6 +16,7 @@ #include "nsNullPrincipal.h" #include "nsServiceManagerUtils.h" #include "nsString.h" +#include "nsTArray.h" namespace mozilla { namespace net { @@ -244,6 +245,12 @@ LoadInfoToLoadInfoArgs(nsILoadInfo *aLoadInfo, rv = PrincipalToPrincipalInfo(aLoadInfo->TriggeringPrincipal(), &triggeringPrincipalInfo); + nsTArray redirectChain; + for (const nsCOMPtr& principal : aLoadInfo->RedirectChain()) { + rv = PrincipalToPrincipalInfo(principal, redirectChain.AppendElement()); + NS_ENSURE_SUCCESS(rv, rv); + } + *aOptionalLoadInfoArgs = LoadInfoArgs( requestingPrincipalInfo, @@ -253,7 +260,8 @@ LoadInfoToLoadInfoArgs(nsILoadInfo *aLoadInfo, aLoadInfo->GetUpgradeInsecureRequests(), aLoadInfo->GetInnerWindowID(), aLoadInfo->GetOuterWindowID(), - aLoadInfo->GetParentOuterWindowID()); + aLoadInfo->GetParentOuterWindowID(), + redirectChain); return NS_OK; } @@ -278,6 +286,14 @@ LoadInfoArgsToLoadInfo(const OptionalLoadInfoArgs& aOptionalLoadInfoArgs, PrincipalInfoToPrincipal(loadInfoArgs.triggeringPrincipalInfo(), &rv); NS_ENSURE_SUCCESS(rv, rv); + nsTArray> redirectChain; + for (const PrincipalInfo& principalInfo : loadInfoArgs.redirectChain()) { + nsCOMPtr redirectedPrincipal = + PrincipalInfoToPrincipal(principalInfo, &rv); + NS_ENSURE_SUCCESS(rv, rv); + redirectChain.AppendElement(redirectedPrincipal.forget()); + } + nsCOMPtr loadInfo = new mozilla::LoadInfo(requestingPrincipal, triggeringPrincipal, @@ -286,7 +302,8 @@ LoadInfoArgsToLoadInfo(const OptionalLoadInfoArgs& aOptionalLoadInfoArgs, loadInfoArgs.upgradeInsecureRequests(), loadInfoArgs.innerWindowID(), loadInfoArgs.outerWindowID(), - loadInfoArgs.parentOuterWindowID()); + loadInfoArgs.parentOuterWindowID(), + redirectChain); loadInfo.forget(outLoadInfo); return NS_OK; diff --git a/netwerk/base/LoadInfo.cpp b/netwerk/base/LoadInfo.cpp index 11107b266d4c..6b2f47acdfac 100644 --- a/netwerk/base/LoadInfo.cpp +++ b/netwerk/base/LoadInfo.cpp @@ -7,6 +7,7 @@ #include "mozilla/LoadInfo.h" #include "mozilla/Assertions.h" +#include "mozilla/dom/ToJSValue.h" #include "nsFrameLoader.h" #include "nsIDocShell.h" #include "nsIDocument.h" @@ -89,7 +90,8 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal, bool aUpgradeInsecureRequests, uint64_t aInnerWindowID, uint64_t aOuterWindowID, - uint64_t aParentOuterWindowID) + uint64_t aParentOuterWindowID, + nsTArray>& aRedirectChain) : mLoadingPrincipal(aLoadingPrincipal) , mTriggeringPrincipal(aTriggeringPrincipal) , mSecurityFlags(aSecurityFlags) @@ -101,6 +103,8 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal, { MOZ_ASSERT(mLoadingPrincipal); MOZ_ASSERT(mTriggeringPrincipal); + + mRedirectChain.SwapElements(aRedirectChain); } LoadInfo::~LoadInfo() @@ -230,4 +234,27 @@ LoadInfo::GetParentOuterWindowID(uint64_t* aResult) return NS_OK; } +NS_IMETHODIMP +LoadInfo::AppendRedirectedPrincipal(nsIPrincipal* aPrincipal) +{ + NS_ENSURE_ARG(aPrincipal); + mRedirectChain.AppendElement(aPrincipal); + return NS_OK; +} + +NS_IMETHODIMP +LoadInfo::GetRedirectChain(JSContext* aCx, JS::MutableHandle aChain) +{ + if (!ToJSValue(aCx, mRedirectChain, aChain)) { + return NS_ERROR_OUT_OF_MEMORY; + } + return NS_OK; +} + +const nsTArray>& +LoadInfo::RedirectChain() +{ + return mRedirectChain; +} + } // namespace mozilla diff --git a/netwerk/base/LoadInfo.h b/netwerk/base/LoadInfo.h index 11540469a91a..f4d05eab654d 100644 --- a/netwerk/base/LoadInfo.h +++ b/netwerk/base/LoadInfo.h @@ -12,6 +12,7 @@ #include "nsIPrincipal.h" #include "nsIWeakReferenceUtils.h" // for nsWeakPtr #include "nsIURI.h" +#include "nsTArray.h" class nsINode; @@ -54,6 +55,7 @@ private: // private constructor that is only allowed to be called from within // HttpChannelParent and FTPChannelParent declared as friends undeneath. // In e10s we can not serialize nsINode, hence we store the innerWindowID. + // Please note that aRedirectChain uses swapElements. LoadInfo(nsIPrincipal* aLoadingPrincipal, nsIPrincipal* aTriggeringPrincipal, nsSecurityFlags aSecurityFlags, @@ -61,7 +63,8 @@ private: bool aUpgradeInsecureRequests, uint64_t aInnerWindowID, uint64_t aOuterWindowID, - uint64_t aParentOuterWindowID); + uint64_t aParentOuterWindowID, + nsTArray>& aRedirectChain); friend nsresult mozilla::ipc::LoadInfoArgsToLoadInfo( @@ -80,6 +83,7 @@ private: uint64_t mInnerWindowID; uint64_t mOuterWindowID; uint64_t mParentOuterWindowID; + nsTArray> mRedirectChain; }; } // namespace mozilla diff --git a/netwerk/base/nsILoadInfo.idl b/netwerk/base/nsILoadInfo.idl index 9b9d5f98349d..8e59bcb29831 100644 --- a/netwerk/base/nsILoadInfo.idl +++ b/netwerk/base/nsILoadInfo.idl @@ -12,12 +12,18 @@ interface nsINode; interface nsIPrincipal; interface nsIURI; +%{C++ +#include "nsTArray.h" +%} + +[ref] native const_nsIPrincipalArray(const nsTArray>); + typedef unsigned long nsSecurityFlags; /** * An nsILoadOwner represents per-load information about who started the load. */ -[scriptable, builtinclass, uuid(6b7f8798-3c28-44fc-8b1a-cd613eb826c5)] +[scriptable, builtinclass, uuid(5c724690-7ba9-49c4-af9c-c9c4f6776871)] interface nsILoadInfo : nsISupports { /** @@ -258,5 +264,30 @@ interface nsILoadInfo : nsISupports MOZ_ASSERT(NS_SUCCEEDED(rv)); return result; } - %} +%} + + /** + * Whenever a channel gets redirected, append the principal of the + * channel [before the channels got redirected] to the loadinfo, + * so that at every point this array lets us reason about all the + * redirects this channel went through. + */ + void appendRedirectedPrincipal(in nsIPrincipal aPrincipal); + + /** + * An array of nsIPrincipal that store the redirects associated with this + * channel. This array is filled whether or not the channel has ever been + * opened. The last element of the array is associated with the most recent + * channel. + */ + [implicit_jscontext] + readonly attribute jsval redirectChain; + + /** + * A C++-friendly version of redirectChain. + * Please note that this array has the same lifetime as the + * loadInfo object - use with caution! + */ + [noscript, notxpcom, nostdcall, binaryname(RedirectChain)] + const_nsIPrincipalArray binaryRedirectChain(); }; diff --git a/netwerk/ipc/NeckoChannelParams.ipdlh b/netwerk/ipc/NeckoChannelParams.ipdlh index 195cd6aecd7d..3065d23ba09b 100644 --- a/netwerk/ipc/NeckoChannelParams.ipdlh +++ b/netwerk/ipc/NeckoChannelParams.ipdlh @@ -26,14 +26,15 @@ namespace net { struct LoadInfoArgs { - PrincipalInfo requestingPrincipalInfo; - PrincipalInfo triggeringPrincipalInfo; - uint32_t securityFlags; - uint32_t contentPolicyType; - bool upgradeInsecureRequests; - uint64_t innerWindowID; - uint64_t outerWindowID; - uint64_t parentOuterWindowID; + PrincipalInfo requestingPrincipalInfo; + PrincipalInfo triggeringPrincipalInfo; + uint32_t securityFlags; + uint32_t contentPolicyType; + bool upgradeInsecureRequests; + uint64_t innerWindowID; + uint64_t outerWindowID; + uint64_t parentOuterWindowID; + PrincipalInfo[] redirectChain; }; /** From bcc6bfffb4ffada4d8c6c805376d88f55c1a9d0c Mon Sep 17 00:00:00 2001 From: Christoph Kerschbaumer Date: Sun, 19 Jul 2015 19:43:09 -0700 Subject: [PATCH 62/69] Bug 1175803 - Store redirect chain within loadInfo - part 2 (r=sicking,mayhemer) --- netwerk/base/moz.build | 1 - netwerk/base/nsBaseChannel.cpp | 13 ++++- netwerk/base/nsIRedirectHistory.idl | 25 ---------- netwerk/protocol/http/HttpBaseChannel.cpp | 48 ------------------- netwerk/protocol/http/HttpBaseChannel.h | 6 --- netwerk/protocol/http/nsHttpChannel.cpp | 5 ++ .../protocol/http/nsIHttpChannelInternal.idl | 8 +--- netwerk/test/unit/test_redirect_history.js | 8 ++-- .../exthandler/nsExternalHelperAppService.cpp | 24 ++++++---- 9 files changed, 36 insertions(+), 102 deletions(-) delete mode 100644 netwerk/base/nsIRedirectHistory.idl diff --git a/netwerk/base/moz.build b/netwerk/base/moz.build index 3c9f829728cb..fa452156888d 100644 --- a/netwerk/base/moz.build +++ b/netwerk/base/moz.build @@ -86,7 +86,6 @@ XPIDL_SOURCES += [ 'nsIProxyInfo.idl', 'nsIRandomGenerator.idl', 'nsIRedirectChannelRegistrar.idl', - 'nsIRedirectHistory.idl', 'nsIRedirectResultListener.idl', 'nsIRequest.idl', 'nsIRequestObserver.idl', diff --git a/netwerk/base/nsBaseChannel.cpp b/netwerk/base/nsBaseChannel.cpp index 3f8a49d9e23c..542cd2eab686 100644 --- a/netwerk/base/nsBaseChannel.cpp +++ b/netwerk/base/nsBaseChannel.cpp @@ -5,10 +5,12 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsBaseChannel.h" +#include "nsContentUtils.h" #include "nsURLHelper.h" #include "nsNetCID.h" #include "nsMimeTypes.h" #include "nsIContentSniffer.h" +#include "nsIScriptSecurityManager.h" #include "nsMimeTypes.h" #include "nsIHttpEventSink.h" #include "nsIHttpChannel.h" @@ -152,8 +154,15 @@ nsBaseChannel::ContinueRedirect() if (mOpenRedirectChannel) { nsresult rv = mRedirectChannel->AsyncOpen(mListener, mListenerContext); - if (NS_FAILED(rv)) - return rv; + NS_ENSURE_SUCCESS(rv, rv); + // Append the initial uri of the channel to the redirectChain + // after the channel got openend successfully. + if (mLoadInfo) { + nsCOMPtr uriPrincipal; + nsIScriptSecurityManager *sm = nsContentUtils::GetSecurityManager(); + sm->GetChannelURIPrincipal(this, getter_AddRefs(uriPrincipal)); + mLoadInfo->AppendRedirectedPrincipal(uriPrincipal); + } } mRedirectChannel = nullptr; diff --git a/netwerk/base/nsIRedirectHistory.idl b/netwerk/base/nsIRedirectHistory.idl deleted file mode 100644 index 4c59e7e7cc6b..000000000000 --- a/netwerk/base/nsIRedirectHistory.idl +++ /dev/null @@ -1,25 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=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/. */ -/** - * Allows keeping track of channel redirects. Currently nsHttpChannel is the - * only implementor. - */ -#include "nsISupports.idl" - -interface nsIArray; -interface nsIPrincipal; - -[scriptable, uuid(ab87eabf-d0c4-40a9-b4b2-a1191108d4c0)] -interface nsIRedirectHistory : nsISupports -{ - /** - * An array of nsIPrincipal that store the redirects associated with this - * channel. This array is filled whether or not the channel has ever been - * opened. The last element of the array is associated with the most recent - * channel. - */ - readonly attribute nsIArray redirects; -}; diff --git a/netwerk/protocol/http/HttpBaseChannel.cpp b/netwerk/protocol/http/HttpBaseChannel.cpp index 59cbb742daa7..044f1487c4b8 100644 --- a/netwerk/protocol/http/HttpBaseChannel.cpp +++ b/netwerk/protocol/http/HttpBaseChannel.cpp @@ -188,7 +188,6 @@ NS_INTERFACE_MAP_BEGIN(HttpBaseChannel) NS_INTERFACE_MAP_ENTRY(nsIHttpChannel) NS_INTERFACE_MAP_ENTRY(nsIHttpChannelInternal) NS_INTERFACE_MAP_ENTRY(nsIForcePendingChannel) - NS_INTERFACE_MAP_ENTRY(nsIRedirectHistory) NS_INTERFACE_MAP_ENTRY(nsIUploadChannel) NS_INTERFACE_MAP_ENTRY(nsIUploadChannel2) NS_INTERFACE_MAP_ENTRY(nsISupportsPriority) @@ -1921,13 +1920,6 @@ HttpBaseChannel::SetResponseTimeoutEnabled(bool aEnable) return NS_OK; } -NS_IMETHODIMP -HttpBaseChannel::AddRedirect(nsIPrincipal *aRedirect) -{ - mRedirects.AppendObject(aRedirect); - return NS_OK; -} - NS_IMETHODIMP HttpBaseChannel::ForcePending(bool aForcePending) { @@ -2094,24 +2086,6 @@ HttpBaseChannel::ShouldIntercept() return shouldIntercept; } -// nsIRedirectHistory -NS_IMETHODIMP -HttpBaseChannel::GetRedirects(nsIArray * *aRedirects) -{ - nsresult rv; - nsCOMPtr redirects = - do_CreateInstance(NS_ARRAY_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, rv); - - for (int i = 0; i < mRedirects.Count(); ++i) { - rv = redirects->AppendElement(mRedirects[i], false); - NS_ENSURE_SUCCESS(rv, rv); - } - *aRedirects = redirects; - NS_IF_ADDREF(*aRedirects); - return NS_OK; -} - //----------------------------------------------------------------------------- // nsHttpChannel::nsITraceableChannel //----------------------------------------------------------------------------- @@ -2379,28 +2353,6 @@ HttpBaseChannel::SetupReplacementChannel(nsIURI *newURI, "[this=%p] transferring chain of redirect cache-keys", this)); httpInternal->SetCacheKeysRedirectChain(mRedirectedCachekeys.forget()); } - // Transfer existing redirect information. Add all of our existing - // redirects to the new channel. - for (int32_t i = 0; i < mRedirects.Count(); ++i) { - if (LOG_ENABLED()) { - nsCOMPtr uri; - mRedirects[i]->GetURI(getter_AddRefs(uri)); - nsCString spec; - if (uri) { - uri->GetSpec(spec); - } - LOG(("HttpBaseChannel::SetupReplacementChannel adding redirect \'%s\' " - "[this=%p]", spec.get(), this)); - } - - httpInternal->AddRedirect(mRedirects[i]); - } - - // Add our own principal to the redirect information on the new channel. If - // the redirect is vetoed, then newChannel->AsyncOpen won't be called. - // However, the new channel's redirect chain will still be complete. - nsCOMPtr principal = GetURIPrincipal(); - httpInternal->AddRedirect(principal); } // transfer application cache information diff --git a/netwerk/protocol/http/HttpBaseChannel.h b/netwerk/protocol/http/HttpBaseChannel.h index f8cf860ae597..9650e5a9ea24 100644 --- a/netwerk/protocol/http/HttpBaseChannel.h +++ b/netwerk/protocol/http/HttpBaseChannel.h @@ -20,7 +20,6 @@ #include "nsHttpHandler.h" #include "nsIHttpChannelInternal.h" #include "nsIForcePendingChannel.h" -#include "nsIRedirectHistory.h" #include "nsIUploadChannel.h" #include "nsIUploadChannel2.h" #include "nsIProgressEventSink.h" @@ -62,7 +61,6 @@ class HttpBaseChannel : public nsHashPropertyBag , public nsIEncodedChannel , public nsIHttpChannel , public nsIHttpChannelInternal - , public nsIRedirectHistory , public nsIUploadChannel , public nsIUploadChannel2 , public nsISupportsPriority @@ -82,7 +80,6 @@ public: NS_DECL_NSIUPLOADCHANNEL2 NS_DECL_NSITRACEABLECHANNEL NS_DECL_NSITIMEDCHANNEL - NS_DECL_NSIREDIRECTHISTORY HttpBaseChannel(); @@ -188,7 +185,6 @@ public: NS_IMETHOD SetResponseTimeoutEnabled(bool aEnable) override; NS_IMETHOD GetNetworkInterfaceId(nsACString& aNetworkInterfaceId) override; NS_IMETHOD SetNetworkInterfaceId(const nsACString& aNetworkInterfaceId) override; - NS_IMETHOD AddRedirect(nsIPrincipal *aRedirect) override; NS_IMETHOD ForcePending(bool aForcePending) override; NS_IMETHOD GetLastModifiedTime(PRTime* lastModifiedTime) override; NS_IMETHOD ForceNoIntercept() override; @@ -387,8 +383,6 @@ protected: nsCOMPtr mAPIRedirectToURI; nsAutoPtr > mRedirectedCachekeys; - // Redirects added by previous channels. - nsCOMArray mRedirects; uint32_t mProxyResolveFlags; nsCOMPtr mProxyURI; diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp index 6d2e8b84730a..e6ecc3bf503f 100644 --- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -205,6 +205,11 @@ AutoRedirectVetoNotifier::ReportRedirectResult(bool succeeded) if (!mChannel) return; + // Append the initial uri of the channel to the redirectChain + if (succeeded && mChannel->mLoadInfo) { + mChannel->mLoadInfo->AppendRedirectedPrincipal(mChannel->GetURIPrincipal()); + } + mChannel->mRedirectChannel = nullptr; nsCOMPtr vetoHook; diff --git a/netwerk/protocol/http/nsIHttpChannelInternal.idl b/netwerk/protocol/http/nsIHttpChannelInternal.idl index cfc9ef59554b..99654c8c43ee 100644 --- a/netwerk/protocol/http/nsIHttpChannelInternal.idl +++ b/netwerk/protocol/http/nsIHttpChannelInternal.idl @@ -38,7 +38,7 @@ interface nsIHttpUpgradeListener : nsISupports * using any feature exposed by this interface, be aware that this interface * will change and you will be broken. You have been warned. */ -[scriptable, uuid(c025c35a-dda3-4a1d-9e6c-e02d7149ac79)] +[scriptable, uuid(4c9e681e-efd8-4ed2-b57f-20d48c9b3c3b)] interface nsIHttpChannelInternal : nsISupports { @@ -213,12 +213,6 @@ interface nsIHttpChannelInternal : nsISupports */ attribute boolean allowAltSvc; - /** - * Add a new nsIPrincipal to the redirect chain. This is the only way to - * write to nsIRedirectHistory.redirects. - */ - void addRedirect(in nsIPrincipal aPrincipal); - readonly attribute PRTime lastModifiedTime; /** diff --git a/netwerk/test/unit/test_redirect_history.js b/netwerk/test/unit/test_redirect_history.js index a5c9a4cd0241..d56691cec84e 100644 --- a/netwerk/test/unit/test_redirect_history.js +++ b/netwerk/test/unit/test_redirect_history.js @@ -34,10 +34,12 @@ function contentHandler(request, response) function finish_test(request, buffer) { do_check_eq(buffer, responseBody); - let chan = request.QueryInterface(Ci.nsIRedirectHistory); - do_check_eq(numRedirects - 1, chan.redirects.length); + let chan = request.QueryInterface(Ci.nsIChannel); + let redirectChain = chan.loadInfo.redirectChain; + + do_check_eq(numRedirects - 1, redirectChain.length); for (let i = 0; i < numRedirects - 1; ++i) { - let principal = chan.redirects.queryElementAt(i, Ci.nsIPrincipal); + let principal = redirectChain[i]; do_check_eq(URL + redirects[i], principal.URI.spec); } httpServer.stop(do_test_finished); diff --git a/uriloader/exthandler/nsExternalHelperAppService.cpp b/uriloader/exthandler/nsExternalHelperAppService.cpp index 7004803256d1..8027fd93ae70 100644 --- a/uriloader/exthandler/nsExternalHelperAppService.cpp +++ b/uriloader/exthandler/nsExternalHelperAppService.cpp @@ -21,7 +21,6 @@ #include "nsIFile.h" #include "nsIFileURL.h" #include "nsIChannel.h" -#include "nsIRedirectHistory.h" #include "nsIDirectoryService.h" #include "nsAppDirectoryServiceDefs.h" #include "nsICategoryManager.h" @@ -1986,14 +1985,20 @@ nsExternalAppHandler::OnSaveComplete(nsIBackgroundFileSaver *aSaver, mSaver = nullptr; // Save the redirect information. - nsCOMPtr history = do_QueryInterface(mRequest); - if (history) { - (void)history->GetRedirects(getter_AddRefs(mRedirects)); - uint32_t length = 0; - mRedirects->GetLength(&length); - LOG(("nsExternalAppHandler: Got %u redirects\n", length)); - } else { - LOG(("nsExternalAppHandler: No redirects\n")); + nsCOMPtr channel = do_QueryInterface(mRequest); + if (channel) { + nsCOMPtr loadInfo = channel->GetLoadInfo(); + if (loadInfo) { + nsresult rv = NS_OK; + nsCOMPtr redirectChain = + do_CreateInstance(NS_ARRAY_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + LOG(("nsExternalAppHandler: Got %u redirects\n", loadInfo->RedirectChain().Length())); + for (nsIPrincipal* principal : loadInfo->RedirectChain()) { + redirectChain->AppendElement(principal, false); + } + mRedirects = redirectChain; + } } if (NS_FAILED(aStatus)) { @@ -2006,7 +2011,6 @@ nsExternalAppHandler::OnSaveComplete(nsIBackgroundFileSaver *aSaver, // for us, we'll fall back to using the prompt service if we absolutely // have to. if (!mTransfer) { - nsCOMPtr channel = do_QueryInterface(mRequest); // We don't care if this fails. CreateFailedTransfer(channel && NS_UsePrivateBrowsing(channel)); } From 35a8c1bb0592fe35e54cdebae7df4924a12279c6 Mon Sep 17 00:00:00 2001 From: Christoph Kerschbaumer Date: Sun, 19 Jul 2015 19:11:38 -0700 Subject: [PATCH 63/69] Bug 1175803 - Store redirect chain within loadInfo - part 3 e10s (r=mrbkap,mayhemer) --- netwerk/protocol/http/HttpChannelChild.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/HttpChannelChild.cpp index 633c8564031e..9c4be34a5f40 100644 --- a/netwerk/protocol/http/HttpChannelChild.cpp +++ b/netwerk/protocol/http/HttpChannelChild.cpp @@ -1238,8 +1238,14 @@ HttpChannelChild::Redirect3Complete() if (mLoadGroup) mLoadGroup->RemoveRequest(this, nullptr, NS_BINDING_ABORTED); - if (NS_FAILED(rv)) + if (NS_SUCCEEDED(rv)) { + if (mLoadInfo) { + mLoadInfo->AppendRedirectedPrincipal(GetURIPrincipal()); + } + } + else { NS_WARNING("CompleteRedirectSetup failed, HttpChannelChild already open?"); + } // Release ref to new channel. mRedirectChannelChild = nullptr; From bf53f62d807845ac9900c76917eec0f3ea0fb436 Mon Sep 17 00:00:00 2001 From: Christoph Kerschbaumer Date: Sun, 19 Jul 2015 19:11:57 -0700 Subject: [PATCH 64/69] Bug 1143922 - Add AsyncOpen2 to nsIChannel and perform security checks when opening a channel - loadinfo changes (r=sicking,tanvi,sworkman) --- ipc/glue/BackgroundUtils.cpp | 4 + netwerk/base/LoadInfo.cpp | 71 ++++++++++++++ netwerk/base/LoadInfo.h | 24 +++-- netwerk/base/nsILoadInfo.idl | 136 ++++++++++++++++++++++++++- netwerk/ipc/NeckoChannelParams.ipdlh | 2 + 5 files changed, 224 insertions(+), 13 deletions(-) diff --git a/ipc/glue/BackgroundUtils.cpp b/ipc/glue/BackgroundUtils.cpp index 0d0ba2f8c7ae..1db7fee623db 100644 --- a/ipc/glue/BackgroundUtils.cpp +++ b/ipc/glue/BackgroundUtils.cpp @@ -261,6 +261,8 @@ LoadInfoToLoadInfoArgs(nsILoadInfo *aLoadInfo, aLoadInfo->GetInnerWindowID(), aLoadInfo->GetOuterWindowID(), aLoadInfo->GetParentOuterWindowID(), + aLoadInfo->GetEnforceSecurity(), + aLoadInfo->GetInitialSecurityCheckDone(), redirectChain); return NS_OK; @@ -303,6 +305,8 @@ LoadInfoArgsToLoadInfo(const OptionalLoadInfoArgs& aOptionalLoadInfoArgs, loadInfoArgs.innerWindowID(), loadInfoArgs.outerWindowID(), loadInfoArgs.parentOuterWindowID(), + loadInfoArgs.enforceSecurity(), + loadInfoArgs.initialSecurityCheckDone(), redirectChain); loadInfo.forget(outLoadInfo); diff --git a/netwerk/base/LoadInfo.cpp b/netwerk/base/LoadInfo.cpp index 6b2f47acdfac..c4465a07fd9d 100644 --- a/netwerk/base/LoadInfo.cpp +++ b/netwerk/base/LoadInfo.cpp @@ -37,6 +37,8 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal, , mInnerWindowID(0) , mOuterWindowID(0) , mParentOuterWindowID(0) + , mEnforceSecurity(false) + , mInitialSecurityCheckDone(false) { MOZ_ASSERT(mLoadingPrincipal); MOZ_ASSERT(mTriggeringPrincipal); @@ -91,6 +93,8 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal, uint64_t aInnerWindowID, uint64_t aOuterWindowID, uint64_t aParentOuterWindowID, + bool aEnforceSecurity, + bool aInitialSecurityCheckDone, nsTArray>& aRedirectChain) : mLoadingPrincipal(aLoadingPrincipal) , mTriggeringPrincipal(aTriggeringPrincipal) @@ -100,6 +104,8 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal, , mInnerWindowID(aInnerWindowID) , mOuterWindowID(aOuterWindowID) , mParentOuterWindowID(aParentOuterWindowID) + , mEnforceSecurity(aEnforceSecurity) + , mInitialSecurityCheckDone(aInitialSecurityCheckDone) { MOZ_ASSERT(mLoadingPrincipal); MOZ_ASSERT(mTriggeringPrincipal); @@ -164,6 +170,26 @@ LoadInfo::GetSecurityFlags(nsSecurityFlags* aResult) return NS_OK; } +NS_IMETHODIMP +LoadInfo::GetSecurityMode(uint32_t *aFlags) +{ + *aFlags = (mSecurityFlags & + (nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS | + nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED | + nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS | + nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL | + nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS)); + return NS_OK; +} + +NS_IMETHODIMP +LoadInfo::GetRequireCorsWithCredentials(bool* aResult) +{ + *aResult = + (mSecurityFlags & nsILoadInfo::SEC_REQUIRE_CORS_WITH_CREDENTIALS); + return NS_OK; +} + NS_IMETHODIMP LoadInfo::GetForceInheritPrincipal(bool* aInheritPrincipal) { @@ -179,6 +205,14 @@ LoadInfo::GetLoadingSandboxed(bool* aLoadingSandboxed) return NS_OK; } +NS_IMETHODIMP +LoadInfo::GetAboutBlankInherits(bool* aResult) +{ + *aResult = + (mSecurityFlags & nsILoadInfo::SEC_ABOUT_BLANK_INHERITS); + return NS_OK; +} + NS_IMETHODIMP LoadInfo::GetContentPolicyType(nsContentPolicyType* aResult) { @@ -234,6 +268,43 @@ LoadInfo::GetParentOuterWindowID(uint64_t* aResult) return NS_OK; } +NS_IMETHODIMP +LoadInfo::SetEnforceSecurity(bool aEnforceSecurity) +{ + // Indicates whether the channel was openend using AsyncOpen2. Once set + // to true, it must remain true throughout the lifetime of the channel. + // Setting it to anything else than true will be discarded. + MOZ_ASSERT(aEnforceSecurity, "aEnforceSecurity must be true"); + mEnforceSecurity = mEnforceSecurity || aEnforceSecurity; + return NS_OK; +} + +NS_IMETHODIMP +LoadInfo::GetEnforceSecurity(bool* aResult) +{ + *aResult = mEnforceSecurity; + return NS_OK; +} + +NS_IMETHODIMP +LoadInfo::SetInitialSecurityCheckDone(bool aInitialSecurityCheckDone) +{ + // Indicates whether the channel was ever evaluated by the + // ContentSecurityManager. Once set to true, this flag must + // remain true throughout the lifetime of the channel. + // Setting it to anything else than true will be discarded. + MOZ_ASSERT(aInitialSecurityCheckDone, "aInitialSecurityCheckDone must be true"); + mInitialSecurityCheckDone = mInitialSecurityCheckDone || aInitialSecurityCheckDone; + return NS_OK; +} + +NS_IMETHODIMP +LoadInfo::GetInitialSecurityCheckDone(bool* aResult) +{ + *aResult = mInitialSecurityCheckDone; + return NS_OK; +} + NS_IMETHODIMP LoadInfo::AppendRedirectedPrincipal(nsIPrincipal* aPrincipal) { diff --git a/netwerk/base/LoadInfo.h b/netwerk/base/LoadInfo.h index f4d05eab654d..23f096245f7e 100644 --- a/netwerk/base/LoadInfo.h +++ b/netwerk/base/LoadInfo.h @@ -64,6 +64,8 @@ private: uint64_t aInnerWindowID, uint64_t aOuterWindowID, uint64_t aParentOuterWindowID, + bool aEnforceSecurity, + bool aInitialSecurityCheckDone, nsTArray>& aRedirectChain); friend nsresult @@ -73,16 +75,18 @@ private: ~LoadInfo(); - nsCOMPtr mLoadingPrincipal; - nsCOMPtr mTriggeringPrincipal; - nsWeakPtr mLoadingContext; - nsSecurityFlags mSecurityFlags; - nsContentPolicyType mContentPolicyType; - nsCOMPtr mBaseURI; - bool mUpgradeInsecureRequests; - uint64_t mInnerWindowID; - uint64_t mOuterWindowID; - uint64_t mParentOuterWindowID; + nsCOMPtr mLoadingPrincipal; + nsCOMPtr mTriggeringPrincipal; + nsWeakPtr mLoadingContext; + nsSecurityFlags mSecurityFlags; + nsContentPolicyType mContentPolicyType; + nsCOMPtr mBaseURI; + bool mUpgradeInsecureRequests; + uint64_t mInnerWindowID; + uint64_t mOuterWindowID; + uint64_t mParentOuterWindowID; + bool mEnforceSecurity; + bool mInitialSecurityCheckDone; nsTArray> mRedirectChain; }; diff --git a/netwerk/base/nsILoadInfo.idl b/netwerk/base/nsILoadInfo.idl index 8e59bcb29831..66efc5a85b0b 100644 --- a/netwerk/base/nsILoadInfo.idl +++ b/netwerk/base/nsILoadInfo.idl @@ -23,7 +23,7 @@ typedef unsigned long nsSecurityFlags; /** * An nsILoadOwner represents per-load information about who started the load. */ -[scriptable, builtinclass, uuid(5c724690-7ba9-49c4-af9c-c9c4f6776871)] +[scriptable, builtinclass, uuid(cc51498e-f8f8-469d-85ba-6dcba17027e4)] interface nsILoadInfo : nsISupports { /** @@ -31,6 +31,64 @@ interface nsILoadInfo : nsISupports */ const unsigned long SEC_NORMAL = 0; + /** + * The following five flags determine the security mode and hence what kind of + * security checks should be performed throughout the lifetime of the channel. + * + * * SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS + * * SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED + * * SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS + * * SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL + * * SEC_REQUIRE_CORS_DATA_INHERITS + * + * Exactly one of these flags are required to be set in order to allow + * the channel to perform the correct security checks (SOP, CORS, ...) and + * return the correct result principal. If none or more than one of these + * flags are set AsyncOpen2 will fail. + */ + + /* + * Enforce the same origin policy where data: loads inherit + * the principal. + */ + const unsigned long SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS = (1<<0); + + /* + * Enforce the same origin policy but data: loads are blocked. + */ + const unsigned long SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED = (1<<1); + + /** + * Allow loads from other origins. Loads from data: will inherit + * the principal of the origin that triggered the load. + * Commonly used by plain ,