зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to mozilla-inbound
This commit is contained in:
Коммит
6b1cb3dcc9
|
@ -6,7 +6,6 @@
|
|||
|
||||
#include "CryptoKey.h"
|
||||
|
||||
#include "ScopedNSSTypes.h"
|
||||
#include "cryptohi.h"
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/dom/SubtleCryptoBinding.h"
|
||||
|
@ -85,19 +84,21 @@ PrivateKeyFromPrivateKeyTemplate(CK_ATTRIBUTE* aTemplate,
|
|||
CK_ULONG aTemplateSize)
|
||||
{
|
||||
// Create a generic object with the contents of the key
|
||||
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
|
||||
UniquePK11SlotInfo slot(PK11_GetInternalSlot());
|
||||
if (!slot) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Generate a random 160-bit object ID. This ID must be unique.
|
||||
ScopedSECItem objID(::SECITEM_AllocItem(nullptr, nullptr, 20));
|
||||
SECStatus rv = PK11_GenerateRandomOnSlot(slot, objID->data, objID->len);
|
||||
UniqueSECItem objID(::SECITEM_AllocItem(nullptr, nullptr, 20));
|
||||
SECStatus rv = PK11_GenerateRandomOnSlot(slot.get(), objID->data, objID->len);
|
||||
if (rv != SECSuccess) {
|
||||
return nullptr;
|
||||
}
|
||||
// Check if something is already using this ID.
|
||||
SECKEYPrivateKey* preexistingKey = PK11_FindKeyByKeyID(slot, objID, nullptr);
|
||||
SECKEYPrivateKey* preexistingKey = PK11_FindKeyByKeyID(slot.get(),
|
||||
objID.get(),
|
||||
nullptr);
|
||||
if (preexistingKey) {
|
||||
// Note that we can't just call SECKEY_DestroyPrivateKey here because that
|
||||
// will destroy the PKCS#11 object that is backing a preexisting key (that
|
||||
|
@ -106,11 +107,11 @@ PrivateKeyFromPrivateKeyTemplate(CK_ATTRIBUTE* aTemplate,
|
|||
// fail.
|
||||
DestroyPrivateKeyWithoutDestroyingPKCS11Object(preexistingKey);
|
||||
// Try again with a new ID (but only once - collisions are very unlikely).
|
||||
rv = PK11_GenerateRandomOnSlot(slot, objID->data, objID->len);
|
||||
rv = PK11_GenerateRandomOnSlot(slot.get(), objID->data, objID->len);
|
||||
if (rv != SECSuccess) {
|
||||
return nullptr;
|
||||
}
|
||||
preexistingKey = PK11_FindKeyByKeyID(slot, objID, nullptr);
|
||||
preexistingKey = PK11_FindKeyByKeyID(slot.get(), objID.get(), nullptr);
|
||||
if (preexistingKey) {
|
||||
DestroyPrivateKeyWithoutDestroyingPKCS11Object(preexistingKey);
|
||||
return nullptr;
|
||||
|
@ -133,7 +134,7 @@ PrivateKeyFromPrivateKeyTemplate(CK_ATTRIBUTE* aTemplate,
|
|||
|
||||
idAttributeSlot->pValue = objID->data;
|
||||
idAttributeSlot->ulValueLen = objID->len;
|
||||
ScopedPK11GenericObject obj(PK11_CreateGenericObject(slot,
|
||||
UniquePK11GenericObject obj(PK11_CreateGenericObject(slot.get(),
|
||||
aTemplate,
|
||||
aTemplateSize,
|
||||
PR_FALSE));
|
||||
|
@ -146,7 +147,7 @@ PrivateKeyFromPrivateKeyTemplate(CK_ATTRIBUTE* aTemplate,
|
|||
}
|
||||
|
||||
// Have NSS translate the object to a private key.
|
||||
return PK11_FindKeyByKeyID(slot, objID, nullptr);
|
||||
return PK11_FindKeyByKeyID(slot.get(), objID.get(), nullptr);
|
||||
}
|
||||
|
||||
CryptoKey::CryptoKey(nsIGlobalObject* aGlobal)
|
||||
|
@ -331,7 +332,7 @@ CryptoKey::AddPublicKeyData(SECKEYPublicKey* aPublicKey)
|
|||
|
||||
// Read EC params.
|
||||
ScopedAutoSECItem params;
|
||||
SECStatus rv = PK11_ReadRawAttribute(PK11_TypePrivKey, mPrivateKey,
|
||||
SECStatus rv = PK11_ReadRawAttribute(PK11_TypePrivKey, mPrivateKey.get(),
|
||||
CKA_EC_PARAMS, ¶ms);
|
||||
if (rv != SECSuccess) {
|
||||
return NS_ERROR_DOM_OPERATION_ERR;
|
||||
|
@ -339,7 +340,8 @@ CryptoKey::AddPublicKeyData(SECKEYPublicKey* aPublicKey)
|
|||
|
||||
// Read private value.
|
||||
ScopedAutoSECItem value;
|
||||
rv = PK11_ReadRawAttribute(PK11_TypePrivKey, mPrivateKey, CKA_VALUE, &value);
|
||||
rv = PK11_ReadRawAttribute(PK11_TypePrivKey, mPrivateKey.get(), CKA_VALUE,
|
||||
&value);
|
||||
if (rv != SECSuccess) {
|
||||
return NS_ERROR_DOM_OPERATION_ERR;
|
||||
}
|
||||
|
@ -362,8 +364,8 @@ CryptoKey::AddPublicKeyData(SECKEYPublicKey* aPublicKey)
|
|||
{ CKA_VALUE, value.data, value.len },
|
||||
};
|
||||
|
||||
mPrivateKey = PrivateKeyFromPrivateKeyTemplate(keyTemplate,
|
||||
ArrayLength(keyTemplate));
|
||||
mPrivateKey = UniqueSECKEYPrivateKey(
|
||||
PrivateKeyFromPrivateKeyTemplate(keyTemplate, ArrayLength(keyTemplate)));
|
||||
NS_ENSURE_TRUE(mPrivateKey, NS_ERROR_DOM_OPERATION_ERR);
|
||||
|
||||
return NS_OK;
|
||||
|
@ -459,7 +461,7 @@ CryptoKey::SetPrivateKey(SECKEYPrivateKey* aPrivateKey)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
mPrivateKey = SECKEY_CopyPrivateKey(aPrivateKey);
|
||||
mPrivateKey = UniqueSECKEYPrivateKey(SECKEY_CopyPrivateKey(aPrivateKey));
|
||||
return mPrivateKey ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
@ -473,7 +475,7 @@ CryptoKey::SetPublicKey(SECKEYPublicKey* aPublicKey)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
mPublicKey = SECKEY_CopyPublicKey(aPublicKey);
|
||||
mPublicKey = UniqueSECKEYPublicKey(SECKEY_CopyPublicKey(aPublicKey));
|
||||
return mPublicKey ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
@ -510,8 +512,8 @@ void CryptoKey::virtualDestroyNSSReference()
|
|||
|
||||
void CryptoKey::destructorSafeDestroyNSSReference()
|
||||
{
|
||||
mPrivateKey.dispose();
|
||||
mPublicKey.dispose();
|
||||
mPrivateKey = nullptr;
|
||||
mPublicKey = nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
@ -522,18 +524,18 @@ CryptoKey::PrivateKeyFromPkcs8(CryptoBuffer& aKeyData,
|
|||
const nsNSSShutDownPreventionLock& /*proofOfLock*/)
|
||||
{
|
||||
SECKEYPrivateKey* privKey;
|
||||
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
|
||||
UniquePK11SlotInfo slot(PK11_GetInternalSlot());
|
||||
if (!slot) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
|
||||
UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
|
||||
if (!arena) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SECItem pkcs8Item = { siBuffer, nullptr, 0 };
|
||||
if (!aKeyData.ToSECItem(arena, &pkcs8Item)) {
|
||||
if (!aKeyData.ToSECItem(arena.get(), &pkcs8Item)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -554,17 +556,18 @@ SECKEYPublicKey*
|
|||
CryptoKey::PublicKeyFromSpki(CryptoBuffer& aKeyData,
|
||||
const nsNSSShutDownPreventionLock& /*proofOfLock*/)
|
||||
{
|
||||
ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
|
||||
UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
|
||||
if (!arena) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SECItem spkiItem = { siBuffer, nullptr, 0 };
|
||||
if (!aKeyData.ToSECItem(arena, &spkiItem)) {
|
||||
if (!aKeyData.ToSECItem(arena.get(), &spkiItem)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ScopedCERTSubjectPublicKeyInfo spki(SECKEY_DecodeDERSubjectPublicKeyInfo(&spkiItem));
|
||||
UniqueCERTSubjectPublicKeyInfo spki(
|
||||
SECKEY_DecodeDERSubjectPublicKeyInfo(&spkiItem));
|
||||
if (!spki) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -599,12 +602,12 @@ CryptoKey::PublicKeyFromSpki(CryptoBuffer& aKeyData,
|
|||
}
|
||||
}
|
||||
|
||||
ScopedSECKEYPublicKey tmp(SECKEY_ExtractPublicKey(spki.get()));
|
||||
UniqueSECKEYPublicKey tmp(SECKEY_ExtractPublicKey(spki.get()));
|
||||
if (!tmp.get() || !PublicKeyValid(tmp.get())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return SECKEY_CopyPublicKey(tmp);
|
||||
return SECKEY_CopyPublicKey(tmp.get());
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -612,7 +615,7 @@ CryptoKey::PrivateKeyToPkcs8(SECKEYPrivateKey* aPrivKey,
|
|||
CryptoBuffer& aRetVal,
|
||||
const nsNSSShutDownPreventionLock& /*proofOfLock*/)
|
||||
{
|
||||
ScopedSECItem pkcs8Item(PK11_ExportDERPrivateKeyInfo(aPrivKey, nullptr));
|
||||
UniqueSECItem pkcs8Item(PK11_ExportDERPrivateKeyInfo(aPrivKey, nullptr));
|
||||
if (!pkcs8Item.get()) {
|
||||
return NS_ERROR_DOM_INVALID_ACCESS_ERR;
|
||||
}
|
||||
|
@ -661,18 +664,18 @@ CryptoKey::PublicKeyToSpki(SECKEYPublicKey* aPubKey,
|
|||
CryptoBuffer& aRetVal,
|
||||
const nsNSSShutDownPreventionLock& /*proofOfLock*/)
|
||||
{
|
||||
ScopedCERTSubjectPublicKeyInfo spki;
|
||||
UniqueCERTSubjectPublicKeyInfo spki;
|
||||
|
||||
// NSS doesn't support exporting DH public keys.
|
||||
if (aPubKey->keyType == dhKey) {
|
||||
// Mimic the behavior of SECKEY_CreateSubjectPublicKeyInfo() and create
|
||||
// a new arena for the SPKI object.
|
||||
ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
|
||||
UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
|
||||
if (!arena) {
|
||||
return NS_ERROR_DOM_OPERATION_ERR;
|
||||
}
|
||||
|
||||
spki = PORT_ArenaZNew(arena, CERTSubjectPublicKeyInfo);
|
||||
spki.reset(PORT_ArenaZNew(arena.get(), CERTSubjectPublicKeyInfo));
|
||||
if (!spki) {
|
||||
return NS_ERROR_DOM_OPERATION_ERR;
|
||||
}
|
||||
|
@ -680,12 +683,12 @@ CryptoKey::PublicKeyToSpki(SECKEYPublicKey* aPubKey,
|
|||
// Assign |arena| to |spki| and null the variable afterwards so that the
|
||||
// arena created above that holds the SPKI object is free'd when |spki|
|
||||
// goes out of scope, not when |arena| does.
|
||||
spki->arena = arena.forget();
|
||||
spki->arena = arena.release();
|
||||
|
||||
nsresult rv = PublicDhKeyToSpki(aPubKey, spki);
|
||||
nsresult rv = PublicDhKeyToSpki(aPubKey, spki.get());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else {
|
||||
spki = SECKEY_CreateSubjectPublicKeyInfo(aPubKey);
|
||||
spki.reset(SECKEY_CreateSubjectPublicKeyInfo(aPubKey));
|
||||
if (!spki) {
|
||||
return NS_ERROR_DOM_OPERATION_ERR;
|
||||
}
|
||||
|
@ -713,7 +716,7 @@ CryptoKey::PublicKeyToSpki(SECKEYPublicKey* aPubKey,
|
|||
}
|
||||
|
||||
const SEC_ASN1Template* tpl = SEC_ASN1_GET(CERT_SubjectPublicKeyInfoTemplate);
|
||||
ScopedSECItem spkiItem(SEC_ASN1EncodeItem(nullptr, nullptr, spki, tpl));
|
||||
UniqueSECItem spkiItem(SEC_ASN1EncodeItem(nullptr, nullptr, spki.get(), tpl));
|
||||
|
||||
if (!aRetVal.Assign(spkiItem.get())) {
|
||||
return NS_ERROR_DOM_OPERATION_ERR;
|
||||
|
@ -767,7 +770,7 @@ CryptoKey::PrivateKeyFromJwk(const JsonWebKey& aJwk,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
|
||||
UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
|
||||
if (!arena) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -816,11 +819,6 @@ CryptoKey::PrivateKeyFromJwk(const JsonWebKey& aJwk,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
|
||||
if (!arena) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Populate template from parameters
|
||||
CK_KEY_TYPE rsaValue = CKK_RSA;
|
||||
CK_ATTRIBUTE keyTemplate[14] = {
|
||||
|
@ -915,8 +913,8 @@ ECKeyToJwk(const PK11ObjectType aKeyType, void* aKey, const SECItem* aEcParams,
|
|||
return false;
|
||||
}
|
||||
|
||||
ScopedSECItem ecPointX(::SECITEM_AllocItem(nullptr, nullptr, flen));
|
||||
ScopedSECItem ecPointY(::SECITEM_AllocItem(nullptr, nullptr, flen));
|
||||
UniqueSECItem ecPointX(::SECITEM_AllocItem(nullptr, nullptr, flen));
|
||||
UniqueSECItem ecPointY(::SECITEM_AllocItem(nullptr, nullptr, flen));
|
||||
if (!ecPointX || !ecPointY) {
|
||||
return false;
|
||||
}
|
||||
|
@ -926,8 +924,10 @@ ECKeyToJwk(const PK11ObjectType aKeyType, void* aKey, const SECItem* aEcParams,
|
|||
memcpy(ecPointY->data, aPublicValue->data + 1 + flen, flen);
|
||||
|
||||
CryptoBuffer x, y;
|
||||
if (!x.Assign(ecPointX) || NS_FAILED(x.ToJwkBase64(aRetVal.mX.Value())) ||
|
||||
!y.Assign(ecPointY) || NS_FAILED(y.ToJwkBase64(aRetVal.mY.Value()))) {
|
||||
if (!x.Assign(ecPointX.get()) ||
|
||||
NS_FAILED(x.ToJwkBase64(aRetVal.mX.Value())) ||
|
||||
!y.Assign(ecPointY.get()) ||
|
||||
NS_FAILED(y.ToJwkBase64(aRetVal.mY.Value()))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1003,16 +1003,16 @@ CryptoKey::PrivateKeyToJwk(SECKEYPrivateKey* aPrivKey,
|
|||
SECKEYPublicKey*
|
||||
CreateECPublicKey(const SECItem* aKeyData, const nsString& aNamedCurve)
|
||||
{
|
||||
ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
|
||||
UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
|
||||
if (!arena) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// It's important that this be a ScopedSECKEYPublicKey, as this ensures that
|
||||
// It's important that this be a UniqueSECKEYPublicKey, as this ensures that
|
||||
// SECKEY_DestroyPublicKey will be called on it. If this doesn't happen, when
|
||||
// CryptoKey::PublicKeyValid is called on it and it gets moved to the internal
|
||||
// PKCS#11 slot, it will leak a reference to the slot.
|
||||
ScopedSECKEYPublicKey key(PORT_ArenaZNew(arena, SECKEYPublicKey));
|
||||
UniqueSECKEYPublicKey key(PORT_ArenaZNew(arena.get(), SECKEYPublicKey));
|
||||
if (!key) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -1023,7 +1023,7 @@ CreateECPublicKey(const SECItem* aKeyData, const nsString& aNamedCurve)
|
|||
key->pkcs11ID = CK_INVALID_HANDLE;
|
||||
|
||||
// Create curve parameters.
|
||||
SECItem* params = CreateECParamsForCurve(aNamedCurve, arena);
|
||||
SECItem* params = CreateECParamsForCurve(aNamedCurve, arena.get());
|
||||
if (!params) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -1033,11 +1033,11 @@ CreateECPublicKey(const SECItem* aKeyData, const nsString& aNamedCurve)
|
|||
key->u.ec.publicValue = *aKeyData;
|
||||
|
||||
// Ensure the given point is on the curve.
|
||||
if (!CryptoKey::PublicKeyValid(key)) {
|
||||
if (!CryptoKey::PublicKeyValid(key.get())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return SECKEY_CopyPublicKey(key);
|
||||
return SECKEY_CopyPublicKey(key.get());
|
||||
}
|
||||
|
||||
SECKEYPublicKey*
|
||||
|
@ -1068,7 +1068,7 @@ CryptoKey::PublicKeyFromJwk(const JsonWebKey& aJwk,
|
|||
{0,}
|
||||
};
|
||||
|
||||
ScopedSECItem pkDer(SEC_ASN1EncodeItem(nullptr, nullptr, &input,
|
||||
UniqueSECItem pkDer(SEC_ASN1EncodeItem(nullptr, nullptr, &input,
|
||||
rsaPublicKeyTemplate));
|
||||
if (!pkDer.get()) {
|
||||
return nullptr;
|
||||
|
@ -1086,7 +1086,7 @@ CryptoKey::PublicKeyFromJwk(const JsonWebKey& aJwk,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
|
||||
UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
|
||||
if (!arena) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -1146,12 +1146,12 @@ CryptoKey::PublicDhKeyFromRaw(CryptoBuffer& aKeyData,
|
|||
const CryptoBuffer& aGenerator,
|
||||
const nsNSSShutDownPreventionLock& /*proofOfLock*/)
|
||||
{
|
||||
ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
|
||||
UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
|
||||
if (!arena) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SECKEYPublicKey* key = PORT_ArenaZNew(arena, SECKEYPublicKey);
|
||||
SECKEYPublicKey* key = PORT_ArenaZNew(arena.get(), SECKEYPublicKey);
|
||||
if (!key) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -1161,9 +1161,9 @@ CryptoKey::PublicDhKeyFromRaw(CryptoBuffer& aKeyData,
|
|||
key->pkcs11ID = CK_INVALID_HANDLE;
|
||||
|
||||
// Set DH public key params.
|
||||
if (!aPrime.ToSECItem(arena, &key->u.dh.prime) ||
|
||||
!aGenerator.ToSECItem(arena, &key->u.dh.base) ||
|
||||
!aKeyData.ToSECItem(arena, &key->u.dh.publicValue)) {
|
||||
if (!aPrime.ToSECItem(arena.get(), &key->u.dh.prime) ||
|
||||
!aGenerator.ToSECItem(arena.get(), &key->u.dh.base) ||
|
||||
!aKeyData.ToSECItem(arena.get(), &key->u.dh.publicValue)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -1190,13 +1190,13 @@ CryptoKey::PublicECKeyFromRaw(CryptoBuffer& aKeyData,
|
|||
const nsString& aNamedCurve,
|
||||
const nsNSSShutDownPreventionLock& /*proofOfLock*/)
|
||||
{
|
||||
ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
|
||||
UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
|
||||
if (!arena) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SECItem rawItem = { siBuffer, nullptr, 0 };
|
||||
if (!aKeyData.ToSECItem(arena, &rawItem)) {
|
||||
if (!aKeyData.ToSECItem(arena.get(), &rawItem)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -1239,7 +1239,7 @@ CryptoKey::PublicECKeyToRaw(SECKEYPublicKey* aPubKey,
|
|||
bool
|
||||
CryptoKey::PublicKeyValid(SECKEYPublicKey* aPubKey)
|
||||
{
|
||||
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
|
||||
UniquePK11SlotInfo slot(PK11_GetInternalSlot());
|
||||
if (!slot.get()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1247,12 +1247,12 @@ CryptoKey::PublicKeyValid(SECKEYPublicKey* aPubKey)
|
|||
// This assumes that NSS checks the validity of a public key when
|
||||
// it is imported into a PKCS#11 module, and returns CK_INVALID_HANDLE
|
||||
// if it is invalid.
|
||||
CK_OBJECT_HANDLE id = PK11_ImportPublicKey(slot, aPubKey, PR_FALSE);
|
||||
CK_OBJECT_HANDLE id = PK11_ImportPublicKey(slot.get(), aPubKey, PR_FALSE);
|
||||
if (id == CK_INVALID_HANDLE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SECStatus rv = PK11_DestroyObject(slot, id);
|
||||
SECStatus rv = PK11_DestroyObject(slot.get(), id);
|
||||
return (rv == SECSuccess);
|
||||
}
|
||||
|
||||
|
@ -1273,13 +1273,14 @@ CryptoKey::WriteStructuredClone(JSStructuredCloneWriter* aWriter) const
|
|||
CryptoBuffer priv, pub;
|
||||
|
||||
if (mPrivateKey) {
|
||||
if (NS_FAILED(CryptoKey::PrivateKeyToPkcs8(mPrivateKey, priv, locker))) {
|
||||
if (NS_FAILED(CryptoKey::PrivateKeyToPkcs8(mPrivateKey.get(), priv,
|
||||
locker))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (mPublicKey) {
|
||||
if (NS_FAILED(CryptoKey::PublicKeyToSpki(mPublicKey, pub, locker))) {
|
||||
if (NS_FAILED(CryptoKey::PublicKeyToSpki(mPublicKey.get(), pub, locker))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1321,10 +1322,12 @@ CryptoKey::ReadStructuredClone(JSStructuredCloneReader* aReader)
|
|||
return false;
|
||||
}
|
||||
if (priv.Length() > 0) {
|
||||
mPrivateKey = CryptoKey::PrivateKeyFromPkcs8(priv, locker);
|
||||
mPrivateKey = UniqueSECKEYPrivateKey(
|
||||
CryptoKey::PrivateKeyFromPkcs8(priv, locker));
|
||||
}
|
||||
if (pub.Length() > 0) {
|
||||
mPublicKey = CryptoKey::PublicKeyFromSpki(pub, locker);
|
||||
mPublicKey = UniqueSECKEYPublicKey(
|
||||
CryptoKey::PublicKeyFromSpki(pub, locker));
|
||||
}
|
||||
|
||||
// Ensure that what we've read is consistent
|
||||
|
|
|
@ -202,8 +202,8 @@ private:
|
|||
|
||||
// Only one key handle should be set, according to the KeyType
|
||||
CryptoBuffer mSymKey;
|
||||
ScopedSECKEYPrivateKey mPrivateKey;
|
||||
ScopedSECKEYPublicKey mPublicKey;
|
||||
UniqueSECKEYPrivateKey mPrivateKey;
|
||||
UniqueSECKEYPublicKey mPublicKey;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -352,7 +352,7 @@ pref("media.wmf.low-latency.enabled", false);
|
|||
pref("media.wmf.skip-blacklist", false);
|
||||
pref("media.wmf.vp9.enabled", true);
|
||||
pref("media.windows-media-foundation.allow-d3d11-dxva", true);
|
||||
pref("media.wmf.disable-d3d11-for-dlls", "igd10iumd32.dll: 20.19.15.4444, 20.19.15.4424, 20.19.15.4409, 20.19.15.4390, 20.19.15.4380, 20.19.15.4360, 10.18.10.4358, 20.19.15.4331, 20.19.15.4312, 20.19.15.4300, 10.18.15.4281, 10.18.15.4279, 10.18.10.4276, 10.18.15.4268, 10.18.15.4256, 10.18.10.4252, 10.18.15.4248, 10.18.14.4112, 10.18.10.3958, 10.18.10.3496, 10.18.10.3431, 10.18.10.3412, 10.18.10.3355, 9.18.10.3234, 9.18.10.3071, 9.18.10.3055, 9.18.10.3006; igd10umd32.dll: 9.17.10.4229, 9.17.10.3040, 9.17.10.2857, 8.15.10.2274, 8.15.10.2272, 8.15.10.2246, 8.15.10.1840, 8.15.10.1808; igd10umd64.dll: 9.17.10.4229, 9.17.10.2857, 10.18.10.3496; isonyvideoprocessor.dll: 4.1.2247.8090, 4.1.2153.6200; tosqep.dll: 1.2.15.526, 1.1.12.201, 1.0.11.318, 1.0.11.215, 1.0.10.1224; tosqep64.dll: 1.1.12.201, 1.0.11.215; nvwgf2um.dll: 10.18.13.6510, 10.18.13.5891, 10.18.13.5887, 10.18.13.5582, 10.18.13.5382, 9.18.13.4195, 9.18.13.3165; atidxx32.dll: 21.19.151.3, 21.19.137.1, 21.19.134.1, 20.19.0.32837, 20.19.0.32832, 8.17.10.682, 8.17.10.671, 8.17.10.661, 8.17.10.648, 8.17.10.644, 8.17.10.625, 8.17.10.605, 8.17.10.581, 8.17.10.569, 8.17.10.560, 8.17.10.545, 8.17.10.539, 8.17.10.531, 8.17.10.525, 8.17.10.520, 8.17.10.519, 8.17.10.514, 8.17.10.511, 8.17.10.494, 8.17.10.489, 8.17.10.483, 8.17.10.453, 8.17.10.451, 8.17.10.441, 8.17.10.436, 8.17.10.432, 8.17.10.425, 8.17.10.418, 8.17.10.414, 8.17.10.401, 8.17.10.395, 8.17.10.385, 8.17.10.378, 8.17.10.362, 8.17.10.355, 8.17.10.342, 8.17.10.331, 8.17.10.318, 8.17.10.310, 8.17.10.286, 8.17.10.269, 8.17.10.261, 8.17.10.247, 8.17.10.240, 8.15.10.212; atidxx64.dll: 21.19.151.3, 21.19.137.1, 21.19.134.1, 20.19.0.32832, 8.17.10.682, 8.17.10.661, 8.17.10.644, 8.17.10.625; nvumdshim.dll: 10.18.13.6822");
|
||||
pref("media.wmf.disable-d3d11-for-dlls", "igd11dxva64.dll: 20.19.15.4463, 20.19.15.4454, 20.19.15.4444, 20.19.15.4416, 20.19.15.4390, 20.19.15.4380, 20.19.15.4377, 20.19.15.4364, 20.19.15.4360, 20.19.15.4352, 20.19.15.4331, 20.19.15.4326, 20.19.15.4300; igd10iumd32.dll: 20.19.15.4444, 20.19.15.4424, 20.19.15.4409, 20.19.15.4390, 20.19.15.4380, 20.19.15.4360, 10.18.10.4358, 20.19.15.4331, 20.19.15.4312, 20.19.15.4300, 10.18.15.4281, 10.18.15.4279, 10.18.10.4276, 10.18.15.4268, 10.18.15.4256, 10.18.10.4252, 10.18.15.4248, 10.18.14.4112, 10.18.10.3958, 10.18.10.3496, 10.18.10.3431, 10.18.10.3412, 10.18.10.3355, 9.18.10.3234, 9.18.10.3071, 9.18.10.3055, 9.18.10.3006; igd10umd32.dll: 9.17.10.4229, 9.17.10.3040, 9.17.10.2857, 8.15.10.2274, 8.15.10.2272, 8.15.10.2246, 8.15.10.1840, 8.15.10.1808; igd10umd64.dll: 9.17.10.4229, 9.17.10.2857, 10.18.10.3496; isonyvideoprocessor.dll: 4.1.2247.8090, 4.1.2153.6200; tosqep.dll: 1.2.15.526, 1.1.12.201, 1.0.11.318, 1.0.11.215, 1.0.10.1224; tosqep64.dll: 1.1.12.201, 1.0.11.215; nvwgf2um.dll: 10.18.13.6510, 10.18.13.5891, 10.18.13.5887, 10.18.13.5582, 10.18.13.5382, 9.18.13.4195, 9.18.13.3165; atidxx32.dll: 21.19.151.3, 21.19.137.1, 21.19.134.1, 20.19.0.32837, 20.19.0.32832, 8.17.10.682, 8.17.10.671, 8.17.10.661, 8.17.10.648, 8.17.10.644, 8.17.10.625, 8.17.10.605, 8.17.10.581, 8.17.10.569, 8.17.10.560, 8.17.10.545, 8.17.10.539, 8.17.10.531, 8.17.10.525, 8.17.10.520, 8.17.10.519, 8.17.10.514, 8.17.10.511, 8.17.10.494, 8.17.10.489, 8.17.10.483, 8.17.10.453, 8.17.10.451, 8.17.10.441, 8.17.10.436, 8.17.10.432, 8.17.10.425, 8.17.10.418, 8.17.10.414, 8.17.10.401, 8.17.10.395, 8.17.10.385, 8.17.10.378, 8.17.10.362, 8.17.10.355, 8.17.10.342, 8.17.10.331, 8.17.10.318, 8.17.10.310, 8.17.10.286, 8.17.10.269, 8.17.10.261, 8.17.10.247, 8.17.10.240, 8.15.10.212; atidxx64.dll: 21.19.151.3, 21.19.137.1, 21.19.134.1, 20.19.0.32832, 8.17.10.682, 8.17.10.661, 8.17.10.644, 8.17.10.625; nvumdshim.dll: 10.18.13.6822");
|
||||
pref("media.wmf.disable-d3d9-for-dlls", "igdumd64.dll: 8.15.10.2189, 8.15.10.2119, 8.15.10.2104, 8.15.10.2102, 8.771.1.0; atiumd64.dll: 7.14.10.833, 7.14.10.867, 7.14.10.885, 7.14.10.903, 7.14.10.911, 8.14.10.768, 9.14.10.1001, 9.14.10.1017, 9.14.10.1080, 9.14.10.1128, 9.14.10.1162, 9.14.10.1171, 9.14.10.1183, 9.14.10.1197, 9.14.10.945, 9.14.10.972, 9.14.10.984, 9.14.10.996");
|
||||
#endif
|
||||
#if defined(MOZ_FFMPEG)
|
||||
|
|
|
@ -62,9 +62,6 @@ MapSECStatus(SECStatus rv)
|
|||
MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedCERTCertificate,
|
||||
CERTCertificate,
|
||||
CERT_DestroyCertificate)
|
||||
MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedCERTSubjectPublicKeyInfo,
|
||||
CERTSubjectPublicKeyInfo,
|
||||
SECKEY_DestroySubjectPublicKeyInfo)
|
||||
|
||||
namespace internal {
|
||||
|
||||
|
@ -186,9 +183,6 @@ MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPK11SlotInfo,
|
|||
MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPK11SymKey,
|
||||
PK11SymKey,
|
||||
PK11_FreeSymKey)
|
||||
MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPK11GenericObject,
|
||||
PK11GenericObject,
|
||||
PK11_DestroyGenericObject)
|
||||
namespace internal {
|
||||
|
||||
inline void
|
||||
|
@ -201,11 +195,6 @@ PORT_FreeArena_false(PLArenaPool* arena)
|
|||
|
||||
} // namespace internal
|
||||
|
||||
// Deprecated: use the equivalent UniquePtr templates instead.
|
||||
MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPLArenaPool,
|
||||
PLArenaPool,
|
||||
internal::PORT_FreeArena_false)
|
||||
|
||||
// Wrapper around NSS's SECItem_AllocItem that handles OOM the same way as
|
||||
// other allocators.
|
||||
inline void
|
||||
|
@ -340,6 +329,9 @@ MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniqueNSSCMSSignedData,
|
|||
NSSCMSSignedData,
|
||||
NSS_CMSSignedData_Destroy)
|
||||
|
||||
MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniquePK11GenericObject,
|
||||
PK11GenericObject,
|
||||
PK11_DestroyGenericObject)
|
||||
MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniquePK11SlotInfo,
|
||||
PK11SlotInfo,
|
||||
PK11_FreeSlot)
|
||||
|
|
|
@ -36,6 +36,7 @@ function advance_test() {
|
|||
reconciler.saveState(null, cb);
|
||||
cb.wait();
|
||||
|
||||
tracker.clearChangedIDs();
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
|
|
|
@ -199,6 +199,7 @@ add_test(function test_properties() {
|
|||
equal(engine.lastRecordUpload, Math.floor(now / 1000));
|
||||
} finally {
|
||||
Svc.Prefs.resetBranch("");
|
||||
engine._tracker.clearChangedIDs();
|
||||
run_next_test();
|
||||
}
|
||||
});
|
||||
|
@ -359,6 +360,7 @@ add_test(function test_client_name_change() {
|
|||
|
||||
Svc.Obs.notify("weave:engine:stop-tracking");
|
||||
|
||||
engine._tracker.clearChangedIDs();
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
|
@ -390,6 +392,7 @@ add_test(function test_send_command() {
|
|||
|
||||
notEqual(tracker.changedIDs[remoteId], undefined);
|
||||
|
||||
engine._tracker.clearChangedIDs();
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
|
@ -446,6 +449,7 @@ add_test(function test_command_validation() {
|
|||
}
|
||||
|
||||
}
|
||||
engine._tracker.clearChangedIDs();
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
|
@ -481,6 +485,7 @@ add_test(function test_command_duplication() {
|
|||
clientCommands = engine._readCommands()[remoteId];
|
||||
equal(clientCommands.length, 2);
|
||||
|
||||
engine._tracker.clearChangedIDs();
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
|
@ -498,6 +503,7 @@ add_test(function test_command_invalid_client() {
|
|||
|
||||
equal(error.message.indexOf("Unknown remote client ID: "), 0);
|
||||
|
||||
engine._tracker.clearChangedIDs();
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
|
@ -515,6 +521,7 @@ add_test(function test_process_incoming_commands() {
|
|||
Service.recordManager.clearCache();
|
||||
engine._resetClient();
|
||||
|
||||
engine._tracker.clearChangedIDs();
|
||||
run_next_test();
|
||||
};
|
||||
|
||||
|
@ -809,6 +816,7 @@ add_test(function test_send_uri_to_client_for_display() {
|
|||
Service.recordManager.clearCache();
|
||||
engine._resetClient();
|
||||
|
||||
engine._tracker.clearChangedIDs();
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
|
@ -841,6 +849,7 @@ add_test(function test_receive_display_uri() {
|
|||
equal(subject[0].title, title);
|
||||
equal(data, null);
|
||||
|
||||
engine._tracker.clearChangedIDs();
|
||||
run_next_test();
|
||||
};
|
||||
|
||||
|
@ -877,6 +886,7 @@ add_test(function test_optional_client_fields() {
|
|||
// See Bug 1100722, Bug 1100723.
|
||||
|
||||
engine._resetClient();
|
||||
engine._tracker.clearChangedIDs();
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
|
@ -1433,6 +1443,7 @@ add_task(async function test_command_sync() {
|
|||
} finally {
|
||||
Svc.Prefs.resetBranch("");
|
||||
Service.recordManager.clearCache();
|
||||
engine._tracker.clearChangedIDs();
|
||||
|
||||
try {
|
||||
server.deleteCollections("foo");
|
||||
|
|
|
@ -102,6 +102,7 @@ add_task(async function test_resetClient() {
|
|||
|
||||
engine.wasReset = false;
|
||||
engineObserver.reset();
|
||||
engine._tracker.clearChangedIDs();
|
||||
});
|
||||
|
||||
add_task(async function test_invalidChangedIDs() {
|
||||
|
@ -120,6 +121,7 @@ add_task(async function test_invalidChangedIDs() {
|
|||
ok(tracker._storage.dataReady);
|
||||
|
||||
do_check_true(tracker.changedIDs.placeholder);
|
||||
engine._tracker.clearChangedIDs();
|
||||
});
|
||||
|
||||
add_task(async function test_wipeClient() {
|
||||
|
@ -142,6 +144,7 @@ add_task(async function test_wipeClient() {
|
|||
engine.wasReset = false;
|
||||
engine._store.wasWiped = false;
|
||||
engineObserver.reset();
|
||||
engine._tracker.clearChangedIDs();
|
||||
});
|
||||
|
||||
add_task(async function test_enabled() {
|
||||
|
@ -180,6 +183,7 @@ add_task(async function test_sync() {
|
|||
Svc.Prefs.resetBranch("");
|
||||
engine.wasSynced = false;
|
||||
engineObserver.reset();
|
||||
engine._tracker.clearChangedIDs();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -208,4 +212,6 @@ add_task(async function test_disabled_no_track() {
|
|||
Svc.Prefs.set("engine." + engine.prefName, false);
|
||||
do_check_false(tracker._isTracking);
|
||||
do_check_empty(tracker.changedIDs);
|
||||
|
||||
engine._tracker.clearChangedIDs();
|
||||
});
|
||||
|
|
|
@ -231,6 +231,7 @@ add_task(async function hmac_error_during_node_reassignment() {
|
|||
|
||||
Svc.Prefs.resetBranch("");
|
||||
Service.recordManager.clearCache();
|
||||
engine._tracker.clearChangedIDs();
|
||||
server.stop(resolve);
|
||||
};
|
||||
|
||||
|
|
|
@ -15,19 +15,20 @@ function makeRotaryEngine() {
|
|||
return new RotaryEngine(Service);
|
||||
}
|
||||
|
||||
function clean() {
|
||||
function clean(engine) {
|
||||
Svc.Prefs.resetBranch("");
|
||||
Svc.Prefs.set("log.logger.engine.rotary", "Trace");
|
||||
Service.recordManager.clearCache();
|
||||
engine._tracker.clearChangedIDs();
|
||||
}
|
||||
|
||||
async function cleanAndGo(server) {
|
||||
clean();
|
||||
async function cleanAndGo(engine, server) {
|
||||
clean(engine);
|
||||
await promiseStopServer(server);
|
||||
}
|
||||
|
||||
async function promiseClean(server) {
|
||||
clean();
|
||||
async function promiseClean(engine, server) {
|
||||
clean(engine);
|
||||
await promiseStopServer(server);
|
||||
}
|
||||
|
||||
|
@ -128,7 +129,7 @@ add_task(async function test_syncStartup_emptyOrOutdatedGlobalsResetsSync() {
|
|||
do_check_eq(collection.payload("scotsman"), undefined);
|
||||
|
||||
} finally {
|
||||
await cleanAndGo(server);
|
||||
await cleanAndGo(engine, server);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -157,7 +158,7 @@ add_task(async function test_syncStartup_serverHasNewerVersion() {
|
|||
do_check_eq(error.failureCode, VERSION_OUT_OF_DATE);
|
||||
|
||||
} finally {
|
||||
await cleanAndGo(server);
|
||||
await cleanAndGo(engine, server);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -193,7 +194,7 @@ add_task(async function test_syncStartup_syncIDMismatchResetsClient() {
|
|||
do_check_eq(engine.lastSync, 0);
|
||||
|
||||
} finally {
|
||||
await cleanAndGo(server);
|
||||
await cleanAndGo(engine, server);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -217,7 +218,7 @@ add_task(async function test_processIncoming_emptyServer() {
|
|||
do_check_eq(engine.lastSync, 0);
|
||||
|
||||
} finally {
|
||||
await cleanAndGo(server);
|
||||
await cleanAndGo(engine, server);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -278,7 +279,7 @@ add_task(async function test_processIncoming_createFromServer() {
|
|||
do_check_eq(engine._store.items['../pathological'], "Pathological Case");
|
||||
|
||||
} finally {
|
||||
await cleanAndGo(server);
|
||||
await cleanAndGo(engine, server);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -389,7 +390,7 @@ add_task(async function test_processIncoming_reconcile() {
|
|||
// The 'nukeme' record marked as deleted is removed.
|
||||
do_check_eq(engine._store.items.nukeme, undefined);
|
||||
} finally {
|
||||
await cleanAndGo(server);
|
||||
await cleanAndGo(engine, server);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -425,7 +426,7 @@ add_task(async function test_processIncoming_reconcile_local_deleted() {
|
|||
do_check_eq(1, collection.count());
|
||||
do_check_neq(undefined, collection.wbo("DUPE_INCOMING"));
|
||||
|
||||
await cleanAndGo(server);
|
||||
await cleanAndGo(engine, server);
|
||||
});
|
||||
|
||||
add_task(async function test_processIncoming_reconcile_equivalent() {
|
||||
|
@ -448,7 +449,7 @@ add_task(async function test_processIncoming_reconcile_equivalent() {
|
|||
|
||||
do_check_attribute_count(engine._store.items, 1);
|
||||
|
||||
await cleanAndGo(server);
|
||||
await cleanAndGo(engine, server);
|
||||
});
|
||||
|
||||
add_task(async function test_processIncoming_reconcile_locally_deleted_dupe_new() {
|
||||
|
@ -487,7 +488,7 @@ add_task(async function test_processIncoming_reconcile_locally_deleted_dupe_new(
|
|||
let payload = JSON.parse(JSON.parse(wbo.payload).ciphertext);
|
||||
do_check_true(payload.deleted);
|
||||
|
||||
await cleanAndGo(server);
|
||||
await cleanAndGo(engine, server);
|
||||
});
|
||||
|
||||
add_task(async function test_processIncoming_reconcile_locally_deleted_dupe_old() {
|
||||
|
@ -526,7 +527,7 @@ add_task(async function test_processIncoming_reconcile_locally_deleted_dupe_old(
|
|||
let payload = JSON.parse(JSON.parse(wbo.payload).ciphertext);
|
||||
do_check_eq("incoming", payload.denomination);
|
||||
|
||||
await cleanAndGo(server);
|
||||
await cleanAndGo(engine, server);
|
||||
});
|
||||
|
||||
add_task(async function test_processIncoming_reconcile_changed_dupe() {
|
||||
|
@ -563,7 +564,7 @@ add_task(async function test_processIncoming_reconcile_changed_dupe() {
|
|||
let payload = JSON.parse(JSON.parse(wbo.payload).ciphertext);
|
||||
do_check_eq("local", payload.denomination);
|
||||
|
||||
await cleanAndGo(server);
|
||||
await cleanAndGo(engine, server);
|
||||
});
|
||||
|
||||
add_task(async function test_processIncoming_reconcile_changed_dupe_new() {
|
||||
|
@ -600,7 +601,7 @@ add_task(async function test_processIncoming_reconcile_changed_dupe_new() {
|
|||
do_check_neq(undefined, wbo);
|
||||
let payload = JSON.parse(JSON.parse(wbo.payload).ciphertext);
|
||||
do_check_eq("incoming", payload.denomination);
|
||||
await cleanAndGo(server);
|
||||
await cleanAndGo(engine, server);
|
||||
});
|
||||
|
||||
add_task(async function test_processIncoming_mobile_batchSize() {
|
||||
|
@ -669,7 +670,7 @@ add_task(async function test_processIncoming_mobile_batchSize() {
|
|||
}
|
||||
|
||||
} finally {
|
||||
await cleanAndGo(server);
|
||||
await cleanAndGo(engine, server);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -736,7 +737,7 @@ add_task(async function test_processIncoming_store_toFetch() {
|
|||
do_check_eq(engine.lastSync, collection.wbo("record-no-99").modified);
|
||||
|
||||
} finally {
|
||||
await promiseClean(server);
|
||||
await promiseClean(engine, server);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -805,7 +806,7 @@ add_task(async function test_processIncoming_resume_toFetch() {
|
|||
do_check_eq(engine._store.items.failed2, "Record No. 2");
|
||||
do_check_eq(engine.previousFailed.length, 0);
|
||||
} finally {
|
||||
await cleanAndGo(server);
|
||||
await cleanAndGo(engine, server);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -860,7 +861,7 @@ add_task(async function test_processIncoming_applyIncomingBatchSize_smaller() {
|
|||
do_check_eq(engine.previousFailed[1], "record-no-8");
|
||||
|
||||
} finally {
|
||||
await cleanAndGo(server);
|
||||
await cleanAndGo(engine, server);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -913,7 +914,7 @@ add_task(async function test_processIncoming_applyIncomingBatchSize_multiple() {
|
|||
do_check_attribute_count(engine._store.items, APPLY_BATCH_SIZE * 3);
|
||||
|
||||
} finally {
|
||||
await cleanAndGo(server);
|
||||
await cleanAndGo(engine, server);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1002,7 +1003,7 @@ add_task(async function test_processIncoming_notify_count() {
|
|||
|
||||
Svc.Obs.remove("weave:engine:sync:applied", onApplied);
|
||||
} finally {
|
||||
await cleanAndGo(server);
|
||||
await cleanAndGo(engine, server);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1088,7 +1089,7 @@ add_task(async function test_processIncoming_previousFailed() {
|
|||
do_check_eq(engine._store.items['record-no-12'], "Record No. 12");
|
||||
do_check_eq(engine._store.items['record-no-13'], "Record No. 13");
|
||||
} finally {
|
||||
await cleanAndGo(server);
|
||||
await cleanAndGo(engine, server);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1222,7 +1223,7 @@ add_task(async function test_processIncoming_failed_records() {
|
|||
do_check_eq(batchDownload(BOGUS_RECORDS.length), 4);
|
||||
|
||||
} finally {
|
||||
await cleanAndGo(server);
|
||||
await cleanAndGo(engine, server);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1303,7 +1304,7 @@ add_task(async function test_processIncoming_decrypt_failed() {
|
|||
do_check_eq(observerSubject.failed, 4);
|
||||
|
||||
} finally {
|
||||
await promiseClean(server);
|
||||
await promiseClean(engine, server);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1362,7 +1363,7 @@ add_task(async function test_uploadOutgoing_toEmptyServer() {
|
|||
do_check_eq(collection.payload("flying"), undefined);
|
||||
|
||||
} finally {
|
||||
await cleanAndGo(server);
|
||||
await cleanAndGo(engine, server);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1409,7 +1410,7 @@ add_task(async function test_uploadOutgoing_huge() {
|
|||
do_check_eq(engine._tracker.changedIDs["flying"], undefined);
|
||||
|
||||
} finally {
|
||||
cleanAndGo(server);
|
||||
await cleanAndGo(engine, server);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1472,7 +1473,7 @@ add_task(async function test_uploadOutgoing_failed() {
|
|||
do_check_eq(engine._tracker.changedIDs['peppercorn'], PEPPERCORN_CHANGED);
|
||||
|
||||
} finally {
|
||||
await promiseClean(server);
|
||||
await promiseClean(engine, server);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1541,7 +1542,7 @@ add_task(async function test_uploadOutgoing_MAX_UPLOAD_RECORDS() {
|
|||
do_check_eq(noOfUploads, Math.ceil(234/MAX_UPLOAD_RECORDS));
|
||||
|
||||
} finally {
|
||||
await cleanAndGo(server);
|
||||
await cleanAndGo(engine, server);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1579,7 +1580,7 @@ add_task(async function test_uploadOutgoing_largeRecords() {
|
|||
}
|
||||
ok(!!error);
|
||||
} finally {
|
||||
await cleanAndGo(server);
|
||||
await cleanAndGo(engine, server);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1636,7 +1637,7 @@ add_task(async function test_syncFinish_deleteByIds() {
|
|||
do_check_eq(engine._delete.ids, undefined);
|
||||
|
||||
} finally {
|
||||
await cleanAndGo(server);
|
||||
await cleanAndGo(engine, server);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1707,7 +1708,7 @@ add_task(async function test_syncFinish_deleteLotsInBatches() {
|
|||
do_check_eq(engine._delete.ids, undefined);
|
||||
|
||||
} finally {
|
||||
await cleanAndGo(server);
|
||||
await cleanAndGo(engine, server);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1783,7 +1784,7 @@ add_task(async function test_sync_partialUpload() {
|
|||
}
|
||||
|
||||
} finally {
|
||||
await promiseClean(server);
|
||||
await promiseClean(engine, server);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1810,7 +1811,7 @@ add_task(async function test_canDecrypt_noCryptoKeys() {
|
|||
do_check_false(engine.canDecrypt());
|
||||
|
||||
} finally {
|
||||
await cleanAndGo(server);
|
||||
await cleanAndGo(engine, server);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1836,7 +1837,7 @@ add_task(async function test_canDecrypt_true() {
|
|||
do_check_true(engine.canDecrypt());
|
||||
|
||||
} finally {
|
||||
await cleanAndGo(server);
|
||||
await cleanAndGo(engine, server);
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -1893,7 +1894,7 @@ add_task(async function test_syncapplied_observer() {
|
|||
|
||||
do_check_true(Service.scheduler.hasIncomingItems);
|
||||
} finally {
|
||||
await cleanAndGo(server);
|
||||
await cleanAndGo(engine, server);
|
||||
Service.scheduler.hasIncomingItems = false;
|
||||
Svc.Obs.remove("weave:engine:sync:applied", onApplied);
|
||||
}
|
||||
|
|
|
@ -58,10 +58,11 @@ function BogusEngine(service) {
|
|||
|
||||
BogusEngine.prototype = Object.create(SteamEngine.prototype);
|
||||
|
||||
async function cleanAndGo(server) {
|
||||
async function cleanAndGo(engine, server) {
|
||||
Svc.Prefs.resetBranch("");
|
||||
Svc.Prefs.set("log.logger.engine.rotary", "Trace");
|
||||
Service.recordManager.clearCache();
|
||||
engine._tracker.clearChangedIDs();
|
||||
await promiseStopServer(server);
|
||||
}
|
||||
|
||||
|
@ -139,7 +140,7 @@ add_task(async function test_processIncoming_error() {
|
|||
|
||||
} finally {
|
||||
store.wipe();
|
||||
await cleanAndGo(server);
|
||||
await cleanAndGo(engine, server);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -187,7 +188,7 @@ add_task(async function test_uploading() {
|
|||
} finally {
|
||||
// Clean up.
|
||||
store.wipe();
|
||||
await cleanAndGo(server);
|
||||
await cleanAndGo(engine, server);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -237,7 +238,7 @@ add_task(async function test_upload_failed() {
|
|||
deepEqual(ping.engines[0].outgoing, [{ sent: 2, failed: 2 }]);
|
||||
|
||||
} finally {
|
||||
await cleanAndGo(server);
|
||||
await cleanAndGo(engine, server);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -317,7 +318,7 @@ add_task(async function test_sync_partialUpload() {
|
|||
deepEqual(ping.engines[0].failureReason, uploadFailureError);
|
||||
|
||||
} finally {
|
||||
await cleanAndGo(server);
|
||||
await cleanAndGo(engine, server);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -344,7 +345,7 @@ add_task(async function test_generic_engine_fail() {
|
|||
});
|
||||
} finally {
|
||||
Service.engineManager.unregister(engine);
|
||||
await cleanAndGo(server);
|
||||
await cleanAndGo(engine, server);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -380,7 +381,7 @@ add_task(async function test_engine_fail_ioerror() {
|
|||
ok(failureReason.error.includes("[profileDir]"), failureReason.error);
|
||||
} finally {
|
||||
Service.engineManager.unregister(engine);
|
||||
await cleanAndGo(server);
|
||||
await cleanAndGo(engine, server);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -417,7 +418,7 @@ add_task(async function test_initial_sync_engines() {
|
|||
equal(e.outgoing[0].failed, undefined);
|
||||
}
|
||||
} finally {
|
||||
await cleanAndGo(server);
|
||||
await cleanAndGo(engine, server);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -446,7 +447,7 @@ add_task(async function test_nserror() {
|
|||
});
|
||||
} finally {
|
||||
Service.engineManager.unregister(engine);
|
||||
await cleanAndGo(server);
|
||||
await cleanAndGo(engine, server);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -512,7 +513,7 @@ add_task(async function test_no_foreign_engines_in_error_ping() {
|
|||
ok(ping.engines.every(e => e.name !== "bogus"));
|
||||
} finally {
|
||||
Service.engineManager.unregister(engine);
|
||||
await cleanAndGo(server);
|
||||
await cleanAndGo(engine, server);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -538,7 +539,7 @@ add_task(async function test_sql_error() {
|
|||
deepEqual(enginePing.failureReason, { name: "sqlerror", code: 1 });
|
||||
} finally {
|
||||
Service.engineManager.unregister(engine);
|
||||
await cleanAndGo(server);
|
||||
await cleanAndGo(engine, server);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -558,6 +559,6 @@ add_task(async function test_no_foreign_engines_in_success_ping() {
|
|||
ok(ping.engines.every(e => e.name !== "bogus"));
|
||||
} finally {
|
||||
Service.engineManager.unregister(engine);
|
||||
await cleanAndGo(server);
|
||||
await cleanAndGo(engine, server);
|
||||
}
|
||||
});
|
|
@ -433,15 +433,6 @@ CreateScrolledWindowWidget()
|
|||
return widget;
|
||||
}
|
||||
|
||||
static GtkWidget*
|
||||
CreateTextViewWidget()
|
||||
{
|
||||
GtkWidget* widget = gtk_text_view_new();
|
||||
gtk_container_add(GTK_CONTAINER(GetWidget(MOZ_GTK_SCROLLED_WINDOW)),
|
||||
widget);
|
||||
return widget;
|
||||
}
|
||||
|
||||
static GtkWidget*
|
||||
CreateMenuSeparatorWidget()
|
||||
{
|
||||
|
@ -591,8 +582,6 @@ CreateWidget(WidgetNodeType aWidgetType)
|
|||
return CreateEntryWidget();
|
||||
case MOZ_GTK_SCROLLED_WINDOW:
|
||||
return CreateScrolledWindowWidget();
|
||||
case MOZ_GTK_TEXT_VIEW:
|
||||
return CreateTextViewWidget();
|
||||
case MOZ_GTK_TREEVIEW:
|
||||
return CreateTreeViewWidget();
|
||||
case MOZ_GTK_TREE_HEADER_CELL:
|
||||
|
@ -751,6 +740,10 @@ GetWidgetRootStyle(WidgetNodeType aNodeType)
|
|||
style = CreateStyleForWidget(gtk_radio_menu_item_new(nullptr),
|
||||
MOZ_GTK_MENUPOPUP);
|
||||
break;
|
||||
case MOZ_GTK_TEXT_VIEW:
|
||||
style = CreateStyleForWidget(gtk_text_view_new(),
|
||||
MOZ_GTK_SCROLLED_WINDOW);
|
||||
break;
|
||||
case MOZ_GTK_TOOLTIP:
|
||||
if (gtk_check_version(3, 20, 0) != nullptr) {
|
||||
// The tooltip style class is added first in CreateTooltipWidget()
|
||||
|
@ -878,10 +871,28 @@ GetCssNodeStyleInternal(WidgetNodeType aNodeType)
|
|||
// TODO - create from CSS node
|
||||
return GetWidgetStyleWithClass(MOZ_GTK_SCROLLED_WINDOW,
|
||||
GTK_STYLE_CLASS_FRAME);
|
||||
case MOZ_GTK_TEXT_VIEW:
|
||||
// TODO - create from CSS node
|
||||
return GetWidgetStyleWithClass(MOZ_GTK_TEXT_VIEW,
|
||||
GTK_STYLE_CLASS_VIEW);
|
||||
case MOZ_GTK_TEXT_VIEW_TEXT:
|
||||
case MOZ_GTK_RESIZER:
|
||||
style = CreateChildCSSNode("text", MOZ_GTK_TEXT_VIEW);
|
||||
if (aNodeType == MOZ_GTK_RESIZER) {
|
||||
// The "grip" class provides the correct builtin icon from
|
||||
// gtk_render_handle(). The icon is drawn with shaded variants of
|
||||
// the background color, and so a transparent background would lead to
|
||||
// a transparent resizer. gtk_render_handle() also uses the
|
||||
// background color to draw a background, and so this style otherwise
|
||||
// matches what is used in GtkTextView to match the background with
|
||||
// textarea elements.
|
||||
GdkRGBA color;
|
||||
gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL,
|
||||
&color);
|
||||
if (color.alpha == 0.0) {
|
||||
g_object_unref(style);
|
||||
style = CreateStyleForWidget(gtk_text_view_new(),
|
||||
MOZ_GTK_SCROLLED_WINDOW);
|
||||
}
|
||||
gtk_style_context_add_class(style, GTK_STYLE_CLASS_GRIP);
|
||||
}
|
||||
break;
|
||||
case MOZ_GTK_FRAME_BORDER:
|
||||
style = CreateChildCSSNode("border", MOZ_GTK_FRAME);
|
||||
break;
|
||||
|
@ -1012,9 +1023,25 @@ GetWidgetStyleInternal(WidgetNodeType aNodeType)
|
|||
case MOZ_GTK_SCROLLED_WINDOW:
|
||||
return GetWidgetStyleWithClass(MOZ_GTK_SCROLLED_WINDOW,
|
||||
GTK_STYLE_CLASS_FRAME);
|
||||
case MOZ_GTK_TEXT_VIEW:
|
||||
return GetWidgetStyleWithClass(MOZ_GTK_TEXT_VIEW,
|
||||
GTK_STYLE_CLASS_VIEW);
|
||||
case MOZ_GTK_TEXT_VIEW_TEXT:
|
||||
case MOZ_GTK_RESIZER: {
|
||||
// GTK versions prior to 3.20 do not have the view class on the root
|
||||
// node, but add this to determine the background for the text window.
|
||||
GtkStyleContext* style =
|
||||
GetWidgetStyleWithClass(MOZ_GTK_TEXT_VIEW, GTK_STYLE_CLASS_VIEW);
|
||||
if (aNodeType == MOZ_GTK_RESIZER) {
|
||||
// The "grip" class provides the correct builtin icon from
|
||||
// gtk_render_handle(). The icon is drawn with shaded variants of
|
||||
// the background color, and so a transparent background would lead to
|
||||
// a transparent resizer. gtk_render_handle() also uses the
|
||||
// background color to draw a background, and so this style otherwise
|
||||
// matches MOZ_GTK_TEXT_VIEW_TEXT to match the background with
|
||||
// textarea elements. GtkTextView creates a separate text window and
|
||||
// so the background should not be transparent.
|
||||
gtk_style_context_add_class(style, GTK_STYLE_CLASS_GRIP);
|
||||
}
|
||||
return style;
|
||||
}
|
||||
case MOZ_GTK_FRAME_BORDER:
|
||||
return GetWidgetRootStyle(MOZ_GTK_FRAME);
|
||||
case MOZ_GTK_TREEVIEW_VIEW:
|
||||
|
|
|
@ -870,7 +870,7 @@ moz_gtk_entry_paint(cairo_t *cr, GdkRectangle* rect,
|
|||
}
|
||||
|
||||
static gint
|
||||
moz_gtk_text_view_paint(cairo_t *cr, GdkRectangle* rect,
|
||||
moz_gtk_text_view_paint(cairo_t *cr, GdkRectangle* aRect,
|
||||
GtkWidgetState* state,
|
||||
GtkTextDirection direction)
|
||||
{
|
||||
|
@ -878,24 +878,24 @@ moz_gtk_text_view_paint(cairo_t *cr, GdkRectangle* rect,
|
|||
|
||||
GtkStyleContext* style_frame =
|
||||
ClaimStyleContext(MOZ_GTK_SCROLLED_WINDOW, direction, state_flags);
|
||||
gtk_render_frame(style_frame, cr, rect->x, rect->y, rect->width, rect->height);
|
||||
gtk_render_frame(style_frame, cr,
|
||||
aRect->x, aRect->y, aRect->width, aRect->height);
|
||||
|
||||
GdkRectangle rect = *aRect;
|
||||
InsetByBorderPadding(&rect, style_frame);
|
||||
|
||||
GtkBorder border, padding;
|
||||
gtk_style_context_get_border(style_frame, state_flags, &border);
|
||||
gtk_style_context_get_padding(style_frame, state_flags, &padding);
|
||||
ReleaseStyleContext(style_frame);
|
||||
|
||||
GtkStyleContext* style =
|
||||
ClaimStyleContext(MOZ_GTK_TEXT_VIEW, direction, state_flags);
|
||||
|
||||
gint xthickness = border.left + padding.left;
|
||||
gint ythickness = border.top + padding.top;
|
||||
|
||||
gtk_render_background(style, cr,
|
||||
rect->x + xthickness, rect->y + ythickness,
|
||||
rect->width - 2 * xthickness,
|
||||
rect->height - 2 * ythickness);
|
||||
|
||||
gtk_render_background(style, cr, rect.x, rect.y, rect.width, rect.height);
|
||||
ReleaseStyleContext(style);
|
||||
// There is a separate "text" window, which usually provides the
|
||||
// background behind the text. However, this is transparent in Ambiance
|
||||
// for GTK 3.20, in which case the MOZ_GTK_TEXT_VIEW background is
|
||||
// visible.
|
||||
style = ClaimStyleContext(MOZ_GTK_TEXT_VIEW_TEXT, direction, state_flags);
|
||||
gtk_render_background(style, cr, rect.x, rect.y, rect.width, rect.height);
|
||||
ReleaseStyleContext(style);
|
||||
|
||||
return MOZ_GTK_SUCCESS;
|
||||
|
@ -1325,17 +1325,9 @@ moz_gtk_resizer_paint(cairo_t *cr, GdkRectangle* rect,
|
|||
GtkWidgetState* state,
|
||||
GtkTextDirection direction)
|
||||
{
|
||||
GtkStyleContext* style;
|
||||
|
||||
// gtk_render_handle() draws a background, so use GtkTextView and its
|
||||
// GTK_STYLE_CLASS_VIEW to match the background with textarea elements.
|
||||
// The resizer is drawn with shaded variants of the background color, and
|
||||
// so a transparent background would lead to a transparent resizer.
|
||||
style = ClaimStyleContext(MOZ_GTK_TEXT_VIEW, GTK_TEXT_DIR_LTR,
|
||||
GetStateFlagsFromGtkWidgetState(state));
|
||||
// TODO - we need to save/restore style when gtk 3.20 CSS node path
|
||||
// is used
|
||||
gtk_style_context_add_class(style, GTK_STYLE_CLASS_GRIP);
|
||||
GtkStyleContext* style =
|
||||
ClaimStyleContext(MOZ_GTK_RESIZER, GTK_TEXT_DIR_LTR,
|
||||
GetStateFlagsFromGtkWidgetState(state));
|
||||
|
||||
// Workaround unico not respecting the text direction for resizers.
|
||||
// See bug 1174248.
|
||||
|
|
|
@ -145,8 +145,11 @@ typedef enum {
|
|||
MOZ_GTK_ENTRY,
|
||||
/* Paints a GtkExpander. */
|
||||
MOZ_GTK_EXPANDER,
|
||||
/* Paints a GtkTextView. */
|
||||
/* Paints a GtkTextView or gets the style context corresponding to the
|
||||
root node of a GtkTextView. */
|
||||
MOZ_GTK_TEXT_VIEW,
|
||||
/* The "text" window or node of a GtkTextView */
|
||||
MOZ_GTK_TEXT_VIEW_TEXT,
|
||||
/* Paints a GtkOptionMenu. */
|
||||
MOZ_GTK_DROPDOWN,
|
||||
/* Paints a dropdown arrow (a GtkButton containing a down GtkArrow). */
|
||||
|
@ -168,7 +171,7 @@ typedef enum {
|
|||
MOZ_GTK_FRAME,
|
||||
/* Paints the border of a GtkFrame */
|
||||
MOZ_GTK_FRAME_BORDER,
|
||||
/* Paints a resize grip for a GtkWindow */
|
||||
/* Paints a resize grip for a GtkTextView */
|
||||
MOZ_GTK_RESIZER,
|
||||
/* Paints a GtkProgressBar. */
|
||||
MOZ_GTK_PROGRESSBAR,
|
||||
|
|
|
@ -62,6 +62,22 @@ nsLookAndFeel::~nsLookAndFeel()
|
|||
}
|
||||
|
||||
#if MOZ_WIDGET_GTK != 2
|
||||
// Modifies color |*aDest| as if a pattern of color |aSource| was painted with
|
||||
// CAIRO_OPERATOR_OVER to a surface with color |*aDest|.
|
||||
static void
|
||||
ApplyColorOver(const GdkRGBA& aSource, GdkRGBA* aDest) {
|
||||
gdouble sourceCoef = aSource.alpha;
|
||||
gdouble destCoef = aDest->alpha * (1.0 - sourceCoef);
|
||||
gdouble resultAlpha = sourceCoef + destCoef;
|
||||
if (resultAlpha != 0.0) { // don't divide by zero
|
||||
destCoef /= resultAlpha;
|
||||
sourceCoef /= resultAlpha;
|
||||
aDest->red = sourceCoef * aSource.red + destCoef * aDest->red;
|
||||
aDest->green = sourceCoef * aSource.green + destCoef * aDest->green;
|
||||
aDest->blue = sourceCoef * aSource.blue + destCoef * aDest->blue;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
GetLightAndDarkness(const GdkRGBA& aColor,
|
||||
double* aLightness, double* aDarkness)
|
||||
|
@ -1284,9 +1300,19 @@ nsLookAndFeel::Init()
|
|||
}
|
||||
#else
|
||||
// Text colors
|
||||
GdkRGBA bgColor;
|
||||
// If the text window background is translucent, then the background of
|
||||
// the textview root node is visible.
|
||||
style = ClaimStyleContext(MOZ_GTK_TEXT_VIEW);
|
||||
gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
|
||||
sMozFieldBackground = GDK_RGBA_TO_NS_RGBA(color);
|
||||
gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL,
|
||||
&bgColor);
|
||||
ReleaseStyleContext(style);
|
||||
|
||||
style = ClaimStyleContext(MOZ_GTK_TEXT_VIEW_TEXT);
|
||||
gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL,
|
||||
&color);
|
||||
ApplyColorOver(color, &bgColor);
|
||||
sMozFieldBackground = GDK_RGBA_TO_NS_RGBA(bgColor);
|
||||
gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
|
||||
sMozFieldText = GDK_RGBA_TO_NS_RGBA(color);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче