From 9e344e02562ff24890b61a392e87b022cb5f6a68 Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Fri, 3 Oct 2014 15:52:38 -0700 Subject: [PATCH 01/84] Bug 1077859: Make ENCODING_FAILED safe to use in static initializers, r=mmc --HG-- extra : rebase_source : 78e1410ab6c94bd6b20a78208a2421db338aed94 --- .../tests/unit/tlsserver/lib/OCSPCommon.cpp | 2 +- security/pkix/test/gtest/pkixbuild_tests.cpp | 22 +- .../test/gtest/pkixcert_extension_tests.cpp | 20 +- ...kixocsp_CreateEncodedOCSPRequest_tests.cpp | 2 +- .../pkixocsp_VerifyEncodedOCSPResponse.cpp | 38 ++-- security/pkix/test/lib/pkixtestnss.cpp | 4 +- security/pkix/test/lib/pkixtestutil.cpp | 212 +++++++----------- security/pkix/test/lib/pkixtestutil.h | 4 +- 8 files changed, 119 insertions(+), 185 deletions(-) diff --git a/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp b/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp index e24957888a6e..0c1c8a54c56c 100644 --- a/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp +++ b/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp @@ -199,7 +199,7 @@ GetOCSPResponseForType(OCSPResponseType aORT, CERTCertificate *aCert, } ByteString response(CreateEncodedOCSPResponse(context)); - if (response == ENCODING_FAILED) { + if (ENCODING_FAILED(response)) { PrintPRError("CreateEncodedOCSPResponse failed"); return nullptr; } diff --git a/security/pkix/test/gtest/pkixbuild_tests.cpp b/security/pkix/test/gtest/pkixbuild_tests.cpp index a7ac7dd4e49a..3c14ca13e31e 100644 --- a/security/pkix/test/gtest/pkixbuild_tests.cpp +++ b/security/pkix/test/gtest/pkixbuild_tests.cpp @@ -47,19 +47,17 @@ CreateCert(const char* issuerCN, static long serialNumberValue = 0; ++serialNumberValue; ByteString serialNumber(CreateEncodedSerialNumber(serialNumberValue)); - EXPECT_NE(ENCODING_FAILED, serialNumber); + EXPECT_FALSE(ENCODING_FAILED(serialNumber)); ByteString issuerDER(CNToDERName(issuerCN)); - EXPECT_NE(ENCODING_FAILED, issuerDER); ByteString subjectDER(CNToDERName(subjectCN)); - EXPECT_NE(ENCODING_FAILED, subjectDER); ByteString extensions[2]; if (endEntityOrCA == EndEntityOrCA::MustBeCA) { extensions[0] = CreateEncodedBasicConstraints(true, nullptr, ExtensionCriticality::Critical); - EXPECT_NE(ENCODING_FAILED, extensions[0]); + EXPECT_FALSE(ENCODING_FAILED(extensions[0])); } ByteString certDER(CreateEncodedCertificate( @@ -69,7 +67,7 @@ CreateCert(const char* issuerCN, subjectDER, extensions, issuerKey, SignatureAlgorithm::rsa_pkcs1_with_sha256, subjectKey)); - EXPECT_NE(ENCODING_FAILED, certDER); + EXPECT_FALSE(ENCODING_FAILED(certDER)); if (subjectCert) { SECItem certDERItem = { siBuffer, @@ -245,7 +243,7 @@ TEST_F(pkixbuild, MaxAcceptableCertChainLength) ByteString certDER(CreateCert("CA7", "Direct End-Entity", EndEntityOrCA::MustBeEndEntity, trustDomain.leafCAKey.get(), unusedKeyPair)); - ASSERT_NE(ENCODING_FAILED, certDER); + ASSERT_FALSE(ENCODING_FAILED(certDER)); Input certDERInput; ASSERT_EQ(Success, certDERInput.Init(certDER.data(), certDER.length())); ASSERT_EQ(Success, @@ -271,7 +269,7 @@ TEST_F(pkixbuild, BeyondMaxAcceptableCertChainLength) ByteString certDER(CreateCert("CA7", caCertName, EndEntityOrCA::MustBeCA, trustDomain.leafCAKey.get(), caKeyPair, &caCert)); - ASSERT_NE(ENCODING_FAILED, certDER); + ASSERT_FALSE(ENCODING_FAILED(certDER)); Input certDERInput; ASSERT_EQ(Success, certDERInput.Init(certDER.data(), certDER.length())); ASSERT_EQ(Result::ERROR_UNKNOWN_ISSUER, @@ -288,7 +286,7 @@ TEST_F(pkixbuild, BeyondMaxAcceptableCertChainLength) ByteString certDER(CreateCert(caCertName, "End-Entity Too Far", EndEntityOrCA::MustBeEndEntity, caKeyPair.get(), unusedKeyPair)); - ASSERT_NE(ENCODING_FAILED, certDER); + ASSERT_FALSE(ENCODING_FAILED(certDER)); Input certDERInput; ASSERT_EQ(Success, certDERInput.Init(certDER.data(), certDER.length())); ASSERT_EQ(Result::ERROR_UNKNOWN_ISSUER, @@ -388,15 +386,13 @@ TEST_F(pkixbuild, NoRevocationCheckingForExpiredCert) ScopedTestKeyPair rootKey; ByteString rootDER(CreateCert(rootCN, rootCN, EndEntityOrCA::MustBeCA, nullptr, rootKey, nullptr)); - EXPECT_NE(ENCODING_FAILED, rootDER); + EXPECT_FALSE(ENCODING_FAILED(rootDER)); ExpiredCertTrustDomain expiredCertTrustDomain(rootDER); ByteString serialNumber(CreateEncodedSerialNumber(100)); - EXPECT_NE(ENCODING_FAILED, serialNumber); + EXPECT_FALSE(ENCODING_FAILED(serialNumber)); ByteString issuerDER(CNToDERName(rootCN)); - EXPECT_NE(ENCODING_FAILED, issuerDER); ByteString subjectDER(CNToDERName("Expired End-Entity Cert")); - EXPECT_NE(ENCODING_FAILED, subjectDER); ScopedTestKeyPair unusedSubjectKey; ByteString certDER(CreateEncodedCertificate( v3, sha256WithRSAEncryption, @@ -406,7 +402,7 @@ TEST_F(pkixbuild, NoRevocationCheckingForExpiredCert) subjectDER, nullptr, rootKey.get(), SignatureAlgorithm::rsa_pkcs1_with_sha256, unusedSubjectKey)); - EXPECT_NE(ENCODING_FAILED, certDER); + EXPECT_FALSE(ENCODING_FAILED(certDER)); Input cert; ASSERT_EQ(Success, cert.Init(certDER.data(), certDER.length())); diff --git a/security/pkix/test/gtest/pkixcert_extension_tests.cpp b/security/pkix/test/gtest/pkixcert_extension_tests.cpp index 3a2d7d67e274..371928e1379c 100644 --- a/security/pkix/test/gtest/pkixcert_extension_tests.cpp +++ b/security/pkix/test/gtest/pkixcert_extension_tests.cpp @@ -38,11 +38,11 @@ CreateCert(const char* subjectCN, static long serialNumberValue = 0; ++serialNumberValue; ByteString serialNumber(CreateEncodedSerialNumber(serialNumberValue)); - EXPECT_NE(ENCODING_FAILED, serialNumber); + EXPECT_FALSE(ENCODING_FAILED(serialNumber)); ByteString issuerDER(CNToDERName(subjectCN)); - EXPECT_NE(ENCODING_FAILED, issuerDER); + EXPECT_FALSE(ENCODING_FAILED(issuerDER)); ByteString subjectDER(CNToDERName(subjectCN)); - EXPECT_NE(ENCODING_FAILED, subjectDER); + EXPECT_FALSE(ENCODING_FAILED(subjectDER)); return CreateEncodedCertificate(v3, sha256WithRSAEncryption, serialNumber, issuerDER, oneDayBeforeNow, oneDayAfterNow, @@ -138,7 +138,7 @@ TEST_F(pkixcert_extension, UnknownCriticalExtension) const char* certCN = "Cert With Unknown Critical Extension"; ScopedTestKeyPair key; ByteString cert(CreateCert(certCN, unknownCriticalExtension, key)); - ASSERT_NE(ENCODING_FAILED, cert); + ASSERT_FALSE(ENCODING_FAILED(cert)); Input certInput; ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length())); ASSERT_EQ(Result::ERROR_UNKNOWN_CRITICAL_EXTENSION, @@ -168,7 +168,7 @@ TEST_F(pkixcert_extension, UnknownNonCriticalExtension) const char* certCN = "Cert With Unknown NonCritical Extension"; ScopedTestKeyPair key; ByteString cert(CreateCert(certCN, unknownNonCriticalExtension, key)); - ASSERT_NE(ENCODING_FAILED, cert); + ASSERT_FALSE(ENCODING_FAILED(cert)); Input certInput; ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length())); ASSERT_EQ(Success, @@ -199,7 +199,7 @@ TEST_F(pkixcert_extension, WrongOIDCriticalExtension) const char* certCN = "Cert With Critical Wrong OID Extension"; ScopedTestKeyPair key; ByteString cert(CreateCert(certCN, wrongOIDCriticalExtension, key)); - ASSERT_NE(ENCODING_FAILED, cert); + ASSERT_FALSE(ENCODING_FAILED(cert)); Input certInput; ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length())); ASSERT_EQ(Result::ERROR_UNKNOWN_CRITICAL_EXTENSION, @@ -232,7 +232,7 @@ TEST_F(pkixcert_extension, CriticalAIAExtension) const char* certCN = "Cert With Critical AIA Extension"; ScopedTestKeyPair key; ByteString cert(CreateCert(certCN, criticalAIAExtension, key)); - ASSERT_NE(ENCODING_FAILED, cert); + ASSERT_FALSE(ENCODING_FAILED(cert)); Input certInput; ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length())); ASSERT_EQ(Success, @@ -262,7 +262,7 @@ TEST_F(pkixcert_extension, UnknownCriticalCEExtension) const char* certCN = "Cert With Unknown Critical id-ce Extension"; ScopedTestKeyPair key; ByteString cert(CreateCert(certCN, unknownCriticalCEExtension, key)); - ASSERT_NE(ENCODING_FAILED, cert); + ASSERT_FALSE(ENCODING_FAILED(cert)); Input certInput; ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length())); ASSERT_EQ(Result::ERROR_UNKNOWN_CRITICAL_EXTENSION, @@ -292,7 +292,7 @@ TEST_F(pkixcert_extension, KnownCriticalCEExtension) const char* certCN = "Cert With Known Critical id-ce Extension"; ScopedTestKeyPair key; ByteString cert(CreateCert(certCN, criticalCEExtension, key)); - ASSERT_NE(ENCODING_FAILED, cert); + ASSERT_FALSE(ENCODING_FAILED(cert)); Input certInput; ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length())); ASSERT_EQ(Success, @@ -321,7 +321,7 @@ TEST_F(pkixcert_extension, DuplicateSubjectAltName) static const char* certCN = "Cert With Duplicate subjectAltName"; ScopedTestKeyPair key; ByteString cert(CreateCert(certCN, extensions, key)); - ASSERT_NE(ENCODING_FAILED, cert); + ASSERT_FALSE(ENCODING_FAILED(cert)); Input certInput; ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length())); ASSERT_EQ(Result::ERROR_EXTENSION_VALUE_INVALID, diff --git a/security/pkix/test/gtest/pkixocsp_CreateEncodedOCSPRequest_tests.cpp b/security/pkix/test/gtest/pkixocsp_CreateEncodedOCSPRequest_tests.cpp index c8e93b6bb3ba..f8d8560aae29 100644 --- a/security/pkix/test/gtest/pkixocsp_CreateEncodedOCSPRequest_tests.cpp +++ b/security/pkix/test/gtest/pkixocsp_CreateEncodedOCSPRequest_tests.cpp @@ -87,7 +87,7 @@ protected: /*out*/ ByteString& issuerSPKI) { issuerDER = CNToDERName(issuerASCII); - ASSERT_NE(ENCODING_FAILED, issuerDER); + ASSERT_FALSE(ENCODING_FAILED(issuerDER)); ScopedTestKeyPair keyPair(GenerateKeyPair()); ASSERT_TRUE(keyPair); diff --git a/security/pkix/test/gtest/pkixocsp_VerifyEncodedOCSPResponse.cpp b/security/pkix/test/gtest/pkixocsp_VerifyEncodedOCSPResponse.cpp index 75320ecce931..27ccf630bb75 100644 --- a/security/pkix/test/gtest/pkixocsp_VerifyEncodedOCSPResponse.cpp +++ b/security/pkix/test/gtest/pkixocsp_VerifyEncodedOCSPResponse.cpp @@ -110,7 +110,7 @@ public: void SetUp() { rootNameDER = CNToDERName(rootName); - if (rootNameDER == ENCODING_FAILED) { + if (ENCODING_FAILED(rootNameDER)) { abort(); } Input rootNameDERInput; @@ -120,7 +120,7 @@ public: } serialNumberDER = CreateEncodedSerialNumber(++rootIssuedCount); - if (serialNumberDER == ENCODING_FAILED) { + if (ENCODING_FAILED(serialNumberDER)) { abort(); } Input serialNumberDERInput; @@ -248,7 +248,7 @@ public: OCSPResponseContext context(certID, producedAt); if (signerName) { context.signerNameDER = CNToDERName(signerName); - EXPECT_NE(ENCODING_FAILED, context.signerNameDER); + EXPECT_FALSE(ENCODING_FAILED(context.signerNameDER)); } context.signerKeyPair = signerKeyPair.Clone(); EXPECT_TRUE(context.signerKeyPair); @@ -398,7 +398,7 @@ protected: oneDayBeforeNow, oneDayAfterNow, certSubjectName, signerEKUDER ? extensions : nullptr, rootKeyPair.get(), signerKeyPair)); - EXPECT_NE(ENCODING_FAILED, signerDER); + EXPECT_FALSE(ENCODING_FAILED(signerDER)); if (signerDEROut) { *signerDEROut = signerDER; } @@ -406,7 +406,7 @@ protected: ByteString signerNameDER; if (signerName) { signerNameDER = CNToDERName(signerName); - EXPECT_NE(ENCODING_FAILED, signerNameDER); + EXPECT_FALSE(ENCODING_FAILED(signerNameDER)); } ByteString certs[] = { signerDER, ByteString() }; return CreateEncodedOCSPSuccessfulResponse(certStatus, *endEntityCertID, @@ -426,16 +426,16 @@ protected: /*out*/ ScopedTestKeyPair& keyPair) { ByteString serialNumberDER(CreateEncodedSerialNumber(serialNumber)); - if (serialNumberDER == ENCODING_FAILED) { - return ENCODING_FAILED; + if (ENCODING_FAILED(serialNumberDER)) { + return ByteString(); } ByteString issuerDER(CNToDERName(issuer)); - if (issuerDER == ENCODING_FAILED) { - return ENCODING_FAILED; + if (ENCODING_FAILED(issuerDER)) { + return ByteString(); } ByteString subjectDER(CNToDERName(subject)); - if (subjectDER == ENCODING_FAILED) { - return ENCODING_FAILED; + if (ENCODING_FAILED(subjectDER)) { + return ByteString(); } return ::mozilla::pkix::test::CreateEncodedCertificate( v3, @@ -547,7 +547,7 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, good_expired) now - (2 * Time::ONE_DAY_IN_SECONDS), signerName, extensions, rootKeyPair.get(), signerKeyPair)); - ASSERT_NE(ENCODING_FAILED, signerDER); + ASSERT_FALSE(ENCODING_FAILED(signerDER)); ByteString certs[] = { signerDER, ByteString() }; ByteString responseString( @@ -582,7 +582,7 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, good_future) now + (10 * Time::ONE_DAY_IN_SECONDS), signerName, extensions, rootKeyPair.get(), signerKeyPair)); - ASSERT_NE(ENCODING_FAILED, signerDER); + ASSERT_FALSE(ENCODING_FAILED(signerDER)); ByteString certs[] = { signerDER, ByteString() }; ByteString responseString( @@ -682,7 +682,7 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, good_unknown_issuer) 1, subCAName, oneDayBeforeNow, oneDayAfterNow, signerName, extensions, unknownKeyPair.get(), signerKeyPair)); - ASSERT_NE(ENCODING_FAILED, signerDER); + ASSERT_FALSE(ENCODING_FAILED(signerDER)); // OCSP response signed by that delegated responder ByteString certs[] = { signerDER, ByteString() }; @@ -722,7 +722,7 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, oneDayBeforeNow, oneDayAfterNow, subCAName, subCAExtensions, rootKeyPair.get(), subCAKeyPair)); - ASSERT_NE(ENCODING_FAILED, subCADER); + ASSERT_FALSE(ENCODING_FAILED(subCADER)); // Delegated responder cert signed by that sub-CA const ByteString extensions[] = { @@ -735,7 +735,7 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, 1, subCAName, oneDayBeforeNow, oneDayAfterNow, signerName, extensions, subCAKeyPair.get(), signerKeyPair)); - ASSERT_NE(ENCODING_FAILED, signerDER); + ASSERT_FALSE(ENCODING_FAILED(signerDER)); // OCSP response signed by the delegated responder issued by the sub-CA // that is trying to impersonate the root. @@ -776,7 +776,7 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, subCAName, subCAExtensions, rootKeyPair.get(), subCAKeyPair)); - ASSERT_NE(ENCODING_FAILED, subCADER); + ASSERT_FALSE(ENCODING_FAILED(subCADER)); // Delegated responder cert signed by that sub-CA const ByteString extensions[] = { @@ -789,7 +789,7 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, 1, subCAName, oneDayBeforeNow, oneDayAfterNow, signerName, extensions, subCAKeyPair.get(), signerKeyPair)); - ASSERT_NE(ENCODING_FAILED, signerDER); + ASSERT_FALSE(ENCODING_FAILED(signerDER)); // OCSP response signed by the delegated responder issued by the sub-CA // that is trying to impersonate the root. @@ -821,7 +821,7 @@ public: CreateEncodedIndirectOCSPSuccessfulResponse( "OCSPGetCertTrustTest Signer", OCSPResponseContext::good, byKey, &OCSPSigningEKUDER, &signerCertDER); - if (responseString == ENCODING_FAILED) { + if (ENCODING_FAILED(responseString)) { abort(); } if (response.Init(responseString.data(), responseString.length()) diff --git a/security/pkix/test/lib/pkixtestnss.cpp b/security/pkix/test/lib/pkixtestnss.cpp index 41452a1c0256..2ba33b529982 100644 --- a/security/pkix/test/lib/pkixtestnss.cpp +++ b/security/pkix/test/lib/pkixtestnss.cpp @@ -191,14 +191,14 @@ ByteString SHA1(const ByteString& toHash) { if (InitNSSIfNeeded() != Success) { - return ENCODING_FAILED; + return ByteString(); } uint8_t digestBuf[SHA1_LENGTH]; SECStatus srv = PK11_HashBuf(SEC_OID_SHA1, digestBuf, toHash.data(), static_cast(toHash.length())); if (srv != SECSuccess) { - return ENCODING_FAILED; + return ByteString(); } return ByteString(digestBuf, sizeof(digestBuf)); } diff --git a/security/pkix/test/lib/pkixtestutil.cpp b/security/pkix/test/lib/pkixtestutil.cpp index 7066e213e5ad..708d13720da7 100644 --- a/security/pkix/test/lib/pkixtestutil.cpp +++ b/security/pkix/test/lib/pkixtestutil.cpp @@ -97,11 +97,8 @@ TamperOnce(/*in/out*/ ByteString& item, const ByteString& from, return Success; } -// An empty string returned from an encoding function signifies failure. -const ByteString ENCODING_FAILED; - // Given a tag and a value, generates a DER-encoded tag-length-value item. -static ByteString +ByteString TLV(uint8_t tag, const ByteString& value) { ByteString result; @@ -117,8 +114,9 @@ TLV(uint8_t tag, const ByteString& value) result.push_back(static_cast(value.length() / 256)); result.push_back(static_cast(value.length() % 256)); } else { - assert(false); - return ENCODING_FAILED; + // It is MUCH more convenient for TLV to be infallible than for it to have + // "proper" error handling. + abort(); } result.append(value); return result; @@ -155,8 +153,8 @@ static ByteString HashedOctetString(const ByteString& bytes) { ByteString digest(SHA1(bytes)); - if (digest == ENCODING_FAILED) { - return ENCODING_FAILED; + if (ENCODING_FAILED(digest)) { + return ByteString(); } return TLV(der::OCTET_STRING, digest); } @@ -190,7 +188,9 @@ Integer(long value) { if (value < 0 || value > 127) { // TODO: add encoding of larger values - return ENCODING_FAILED; + // It is MUCH more convenient for Integer to be infallible than for it to + // have "proper" error handling. + abort(); } ByteString encodedValue; @@ -225,7 +225,7 @@ TimeToEncodedTime(time_t time, TimeEncoding encoding) tm exploded; if (!gmtime_r(&time, &exploded)) { - return ENCODING_FAILED; + return ByteString(); } if (exploded.tm_sec >= 60) { @@ -237,7 +237,7 @@ TimeToEncodedTime(time_t time, TimeEncoding encoding) int year = exploded.tm_year + 1900; if (encoding == UTCTime && (year < 1950 || year >= 2050)) { - return ENCODING_FAILED; + return ByteString(); } ByteString value; @@ -281,7 +281,7 @@ TimeToTimeChoice(time_t time) { tm exploded; if (!gmtime_r(&time, &exploded)) { - return ENCODING_FAILED; + return ByteString(); } TimeEncoding encoding = (exploded.tm_year + 1900 >= 1950 && exploded.tm_year + 1900 < 2050) @@ -341,14 +341,17 @@ YMDHMS(int16_t year, int16_t month, int16_t day, static ByteString SignedData(const ByteString& tbsData, - TestKeyPair& keyPair, + /*optional*/ TestKeyPair* keyPair, SignatureAlgorithm signatureAlgorithm, bool corrupt, /*optional*/ const ByteString* certs) { ByteString signature; - if (keyPair.SignData(tbsData, signatureAlgorithm, signature) != Success) { - return ENCODING_FAILED; - } + if (keyPair) { + if (keyPair->SignData(tbsData, signatureAlgorithm, signature) + != Success) { + return ByteString(); + } + } ByteString signatureAlgorithmDER; switch (signatureAlgorithm) { @@ -357,14 +360,14 @@ SignedData(const ByteString& tbsData, sizeof(alg_sha256WithRSAEncryption)); break; default: - return ENCODING_FAILED; + return ByteString(); } // TODO: add ability to have signatures of bit length not divisible by 8, // resulting in unused bits in the bitstring encoding ByteString signatureNested(BitString(signature, corrupt)); - if (signatureNested == ENCODING_FAILED) { - return ENCODING_FAILED; + if (ENCODING_FAILED(signatureNested)) { + return ByteString(); } ByteString certsNested; @@ -375,14 +378,8 @@ SignedData(const ByteString& tbsData, ++certs; } ByteString certsSequence(TLV(der::SEQUENCE, certsSequenceValue)); - if (certsSequence == ENCODING_FAILED) { - return ENCODING_FAILED; - } certsNested = TLV(der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 0, certsSequence); - if (certsNested == ENCODING_FAILED) { - return ENCODING_FAILED; - } } ByteString value; @@ -411,20 +408,11 @@ Extension(Input extnID, ExtensionCriticality criticality, if (criticality == ExtensionCriticality::Critical) { ByteString critical(Boolean(true)); - if (critical == ENCODING_FAILED) { - return ENCODING_FAILED; - } encoded.append(critical); } ByteString extnValueSequence(TLV(der::SEQUENCE, extnValueBytes)); - if (extnValueBytes == ENCODING_FAILED) { - return ENCODING_FAILED; - } ByteString extnValue(TLV(der::OCTET_STRING, extnValueSequence)); - if (extnValue == ENCODING_FAILED) { - return ENCODING_FAILED; - } encoded.append(extnValue); return TLV(der::SEQUENCE, encoded); } @@ -487,7 +475,7 @@ CreateEncodedCertificate(long version, Input signature, // with issuerKeyPair. ScopedTestKeyPair subjectKeyPair(GenerateKeyPair()); if (!subjectKeyPair) { - return ENCODING_FAILED; + return ByteString(); } ByteString tbsCertificate(TBSCertificate(version, serialNumber, @@ -495,16 +483,16 @@ CreateEncodedCertificate(long version, Input signature, notAfter, subjectNameDER, subjectKeyPair->subjectPublicKeyInfo, extensions)); - if (tbsCertificate == ENCODING_FAILED) { - return ENCODING_FAILED; + if (ENCODING_FAILED(tbsCertificate)) { + return ByteString(); } ByteString result(SignedData(tbsCertificate, - issuerKeyPair ? *issuerKeyPair - : *subjectKeyPair, + issuerKeyPair ? issuerKeyPair + : subjectKeyPair.get(), signatureAlgorithm, false, nullptr)); - if (result == ENCODING_FAILED) { - return ENCODING_FAILED; + if (ENCODING_FAILED(result)) { + return ByteString(); } MaybeLogOutput(result, "cert"); @@ -540,14 +528,8 @@ TBSCertificate(long versionValue, if (versionValue != static_cast(der::Version::v1)) { ByteString versionInteger(Integer(versionValue)); - if (versionInteger == ENCODING_FAILED) { - return ENCODING_FAILED; - } ByteString version(TLV(der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 0, versionInteger)); - if (version == ENCODING_FAILED) { - return ENCODING_FAILED; - } value.append(version); } @@ -561,19 +543,19 @@ TBSCertificate(long versionValue, ByteString validity; { ByteString notBefore(TimeToTimeChoice(notBeforeTime)); - if (notBefore == ENCODING_FAILED) { - return ENCODING_FAILED; + if (ENCODING_FAILED(notBefore)) { + return ByteString(); } ByteString notAfter(TimeToTimeChoice(notAfterTime)); - if (notAfter == ENCODING_FAILED) { - return ENCODING_FAILED; + if (ENCODING_FAILED(notAfter)) { + return ByteString(); } ByteString validityValue; validityValue.append(notBefore); validityValue.append(notAfter); validity = TLV(der::SEQUENCE, validityValue); - if (validity == ENCODING_FAILED) { - return ENCODING_FAILED; + if (ENCODING_FAILED(validity)) { + return ByteString(); } } value.append(validity); @@ -589,13 +571,13 @@ TBSCertificate(long versionValue, ++extensions; } ByteString extensionsSequence(TLV(der::SEQUENCE, extensionsValue)); - if (extensionsSequence == ENCODING_FAILED) { - return ENCODING_FAILED; + if (ENCODING_FAILED(extensionsSequence)) { + return ByteString(); } ByteString extensionsWrapped( TLV(der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 3, extensionsSequence)); - if (extensionsWrapped == ENCODING_FAILED) { - return ENCODING_FAILED; + if (ENCODING_FAILED(extensionsWrapped)) { + return ByteString(); } value.append(extensionsWrapped); } @@ -644,15 +626,7 @@ CNToDERName(const char* cn) ava.append(tlv_id_at_commonName, sizeof(tlv_id_at_commonName)); ava.append(value); ava = TLV(der::SEQUENCE, ava); - if (ava == ENCODING_FAILED) { - return ENCODING_FAILED; - } - ByteString rdn(TLV(der::SET, ava)); - if (rdn == ENCODING_FAILED) { - return ENCODING_FAILED; - } - return TLV(der::SEQUENCE, rdn); } @@ -674,17 +648,11 @@ CreateEncodedBasicConstraints(bool isCA, if (isCA) { ByteString cA(Boolean(true)); - if (cA == ENCODING_FAILED) { - return ENCODING_FAILED; - } value.append(cA); } if (pathLenConstraintValue) { ByteString pathLenConstraint(Integer(*pathLenConstraintValue)); - if (pathLenConstraint == ENCODING_FAILED) { - return ENCODING_FAILED; - } value.append(pathLenConstraint); } @@ -718,7 +686,7 @@ CreateEncodedOCSPResponse(OCSPResponseContext& context) { if (!context.skipResponseBytes) { if (!context.signerKeyPair) { - return ENCODING_FAILED; + return ByteString(); } } @@ -738,31 +706,22 @@ CreateEncodedOCSPResponse(OCSPResponseContext& context) ByteString reponseStatusValue; reponseStatusValue.push_back(context.responseStatus); ByteString responseStatus(TLV(der::ENUMERATED, reponseStatusValue)); - if (responseStatus == ENCODING_FAILED) { - return ENCODING_FAILED; - } ByteString responseBytesNested; if (!context.skipResponseBytes) { ByteString responseBytes(ResponseBytes(context)); - if (responseBytes == ENCODING_FAILED) { - return ENCODING_FAILED; + if (ENCODING_FAILED(responseBytes)) { + return ByteString(); } responseBytesNested = TLV(der::CONSTRUCTED | der::CONTEXT_SPECIFIC, responseBytes); - if (responseBytesNested == ENCODING_FAILED) { - return ENCODING_FAILED; - } } ByteString value; value.append(responseStatus); value.append(responseBytesNested); ByteString result(TLV(der::SEQUENCE, value)); - if (result == ENCODING_FAILED) { - return ENCODING_FAILED; - } MaybeLogOutput(result, "ocsp"); @@ -780,13 +739,10 @@ ResponseBytes(OCSPResponseContext& context) 0x06, 0x09, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01 }; ByteString response(BasicOCSPResponse(context)); - if (response == ENCODING_FAILED) { - return ENCODING_FAILED; + if (ENCODING_FAILED(response)) { + return ByteString(); } ByteString responseNested = TLV(der::OCTET_STRING, response); - if (responseNested == ENCODING_FAILED) { - return ENCODING_FAILED; - } ByteString value; value.append(id_pkix_ocsp_basic_encoded, @@ -804,12 +760,12 @@ ByteString BasicOCSPResponse(OCSPResponseContext& context) { ByteString tbsResponseData(ResponseData(context)); - if (tbsResponseData == ENCODING_FAILED) { - return ENCODING_FAILED; + if (ENCODING_FAILED(tbsResponseData)) { + return ByteString(); } // TODO(bug 980538): certs - return SignedData(tbsResponseData, *context.signerKeyPair, + return SignedData(tbsResponseData, context.signerKeyPair.get(), SignatureAlgorithm::rsa_pkcs1_with_sha256, context.badSignature, context.certs); } @@ -826,15 +782,9 @@ OCSPExtension(OCSPResponseContext& context, OCSPResponseExtension& extension) encoded.append(extension.id); if (extension.critical) { ByteString critical(Boolean(true)); - if (critical == ENCODING_FAILED) { - return ENCODING_FAILED; - } encoded.append(critical); } ByteString value(TLV(der::OCTET_STRING, extension.value)); - if (value == ENCODING_FAILED) { - return ENCODING_FAILED; - } encoded.append(value); return TLV(der::SEQUENCE, encoded); } @@ -849,15 +799,12 @@ Extensions(OCSPResponseContext& context) for (OCSPResponseExtension* extension = context.extensions; extension; extension = extension->next) { ByteString extensionEncoded(OCSPExtension(context, *extension)); - if (extensionEncoded == ENCODING_FAILED) { - return ENCODING_FAILED; + if (ENCODING_FAILED(extensionEncoded)) { + return ByteString(); } value.append(extensionEncoded); } ByteString sequence(TLV(der::SEQUENCE, value)); - if (sequence == ENCODING_FAILED) { - return ENCODING_FAILED; - } return TLV(der::CONSTRUCTED | der::CONTEXT_SPECIFIC | 1, sequence); } @@ -871,21 +818,18 @@ ByteString ResponseData(OCSPResponseContext& context) { ByteString responderID(ResponderID(context)); - if (responderID == ENCODING_FAILED) { - return ENCODING_FAILED; + if (ENCODING_FAILED(responderID)) { + return ByteString(); } ByteString producedAtEncoded(TimeToGeneralizedTime(context.producedAt)); - if (producedAtEncoded == ENCODING_FAILED) { - return ENCODING_FAILED; + if (ENCODING_FAILED(producedAtEncoded)) { + return ByteString(); } ByteString response(SingleResponse(context)); - if (response == ENCODING_FAILED) { - return ENCODING_FAILED; + if (ENCODING_FAILED(response)) { + return ByteString(); } ByteString responses(TLV(der::SEQUENCE, response)); - if (responses == ENCODING_FAILED) { - return ENCODING_FAILED; - } ByteString responseExtensions; if (context.extensions || context.includeEmptyExtensions) { responseExtensions = Extensions(context); @@ -913,8 +857,8 @@ ResponderID(OCSPResponseContext& context) responderIDType = 1; // byName } else { contents = KeyHash(context.signerKeyPair->subjectPublicKey); - if (contents == ENCODING_FAILED) { - return ENCODING_FAILED; + if (ENCODING_FAILED(contents)) { + return ByteString(); } responderIDType = 2; // byKey } @@ -944,28 +888,25 @@ ByteString SingleResponse(OCSPResponseContext& context) { ByteString certID(CertID(context)); - if (certID == ENCODING_FAILED) { - return ENCODING_FAILED; + if (ENCODING_FAILED(certID)) { + return ByteString(); } ByteString certStatus(CertStatus(context)); - if (certStatus == ENCODING_FAILED) { - return ENCODING_FAILED; + if (ENCODING_FAILED(certStatus)) { + return ByteString(); } ByteString thisUpdateEncoded(TimeToGeneralizedTime(context.thisUpdate)); - if (thisUpdateEncoded == ENCODING_FAILED) { - return ENCODING_FAILED; + if (ENCODING_FAILED(thisUpdateEncoded)) { + return ByteString(); } ByteString nextUpdateEncodedNested; if (context.includeNextUpdate) { ByteString nextUpdateEncoded(TimeToGeneralizedTime(context.nextUpdate)); - if (nextUpdateEncoded == ENCODING_FAILED) { - return ENCODING_FAILED; + if (ENCODING_FAILED(nextUpdateEncoded)) { + return ByteString(); } nextUpdateEncodedNested = TLV(der::CONSTRUCTED | der::CONTEXT_SPECIFIC | 0, nextUpdateEncoded); - if (nextUpdateEncodedNested == ENCODING_FAILED) { - return ENCODING_FAILED; - } } ByteString value; @@ -987,8 +928,8 @@ CertID(OCSPResponseContext& context) ByteString issuerName(context.certID.issuer.UnsafeGetData(), context.certID.issuer.GetLength()); ByteString issuerNameHash(HashedOctetString(issuerName)); - if (issuerNameHash == ENCODING_FAILED) { - return ENCODING_FAILED; + if (ENCODING_FAILED(issuerNameHash)) { + return ByteString(); } ByteString issuerKeyHash; @@ -999,30 +940,27 @@ CertID(OCSPResponseContext& context) Reader input(context.certID.issuerSubjectPublicKeyInfo); Reader contents; if (der::ExpectTagAndGetValue(input, der::SEQUENCE, contents) != Success) { - return ENCODING_FAILED; + return ByteString(); } // Skip AlgorithmIdentifier if (der::ExpectTagAndSkipValue(contents, der::SEQUENCE) != Success) { - return ENCODING_FAILED; + return ByteString(); } Input subjectPublicKey; if (der::BitStringWithNoUnusedBits(contents, subjectPublicKey) != Success) { - return ENCODING_FAILED; + return ByteString(); } issuerKeyHash = KeyHash(ByteString(subjectPublicKey.UnsafeGetData(), subjectPublicKey.GetLength())); - if (issuerKeyHash == ENCODING_FAILED) { - return ENCODING_FAILED; + if (ENCODING_FAILED(issuerKeyHash)) { + return ByteString(); } } ByteString serialNumberValue(context.certID.serialNumber.UnsafeGetData(), context.certID.serialNumber.GetLength()); ByteString serialNumber(TLV(der::INTEGER, serialNumberValue)); - if (serialNumber == ENCODING_FAILED) { - return ENCODING_FAILED; - } // python DottedOIDToCode.py --alg id-sha1 1.3.14.3.2.26 static const uint8_t alg_id_sha1[] = { @@ -1062,8 +1000,8 @@ CertStatus(OCSPResponseContext& context) case 1: { ByteString revocationTime(TimeToGeneralizedTime(context.revocationTime)); - if (revocationTime == ENCODING_FAILED) { - return ENCODING_FAILED; + if (ENCODING_FAILED(revocationTime)) { + return ByteString(); } // TODO(bug 980536): add support for revocationReason return TLV(der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 1, revocationTime); @@ -1072,7 +1010,7 @@ CertStatus(OCSPResponseContext& context) assert(false); // fall through } - return ENCODING_FAILED; + return ByteString(); } } } } // namespace mozilla::pkix::test diff --git a/security/pkix/test/lib/pkixtestutil.h b/security/pkix/test/lib/pkixtestutil.h index 57cf057ac9cd..411221c51ea5 100644 --- a/security/pkix/test/lib/pkixtestutil.h +++ b/security/pkix/test/lib/pkixtestutil.h @@ -36,7 +36,8 @@ namespace mozilla { namespace pkix { namespace test { typedef std::basic_string ByteString; -extern const ByteString ENCODING_FAILED; + +inline bool ENCODING_FAILED(const ByteString& bs) { return bs.empty(); } // XXX: Ideally, we should define this instead: // @@ -79,7 +80,6 @@ extern const Input sha256WithRSAEncryption; mozilla::pkix::Time YMDHMS(int16_t year, int16_t month, int16_t day, int16_t hour, int16_t minutes, int16_t seconds); - ByteString CNToDERName(const char* cn); class TestKeyPair From 1fc729071e15d4d815fca6adb76327e46ced2c0c Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Sat, 4 Oct 2014 18:45:31 -0700 Subject: [PATCH 02/84] Bug 1077887: Work around old GCC "enum class" bug, r=mmc --HG-- extra : rebase_source : ce707672dfc0587760c09701fd6adbe26c874916 --- security/pkix/include/pkix/Result.h | 8 ++++---- security/pkix/include/pkix/enumclass.h | 10 ++++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/security/pkix/include/pkix/Result.h b/security/pkix/include/pkix/Result.h index e82e6428d341..ff76b5ab6715 100644 --- a/security/pkix/include/pkix/Result.h +++ b/security/pkix/include/pkix/Result.h @@ -149,10 +149,10 @@ const char* MapResultToName(Result result); // those comparisons clearer, especially because the shortened name often // results in less line wrapping. // -// Visual Studio before VS2013 does not support "enum class," so -// Result::Success will already be visible in this scope, and compilation will -// fail if we try to define a variable with that name here. -#if !defined(_MSC_VER) || (_MSC_VER >= 1700) +// If MOZILLA_PKIX_ENUM_CLASS doesn't expand to "enum class" then +// Result::Success will already be in scope, and compilation would fail if we +// were to try to define a variable named "Success" here. +#ifdef MOZILLA_PKIX_ENUM_CLASS_REALLY_IS_ENUM_CLASS static const Result Success = Result::Success; #endif diff --git a/security/pkix/include/pkix/enumclass.h b/security/pkix/include/pkix/enumclass.h index e3dd58220d75..40d5b840a016 100644 --- a/security/pkix/include/pkix/enumclass.h +++ b/security/pkix/include/pkix/enumclass.h @@ -22,10 +22,6 @@ * limitations under the License. */ -// Work around missing std::bind, std::ref, std::cref in older compilers. This -// implementation isn't intended to be complete; rather, it is the minimal -// implementation needed to make our use of std::bind work. - #ifndef mozilla_pkix__enumclass_h #define mozilla_pkix__enumclass_h @@ -35,8 +31,14 @@ // enums results in C4480: nonstandard extension used: specifying underlying // type for enum. #define MOZILLA_PKIX_ENUM_CLASS __pragma(warning(suppress: 4480)) enum +#elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 407) +// GCC before version 4.7 may crash when compiling code that static_casts a +// value of scoped typed enum type. See +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48106. +#define MOZILLA_PKIX_ENUM_CLASS enum #else #define MOZILLA_PKIX_ENUM_CLASS enum class +#define MOZILLA_PKIX_ENUM_CLASS_REALLY_IS_ENUM_CLASS #endif #endif // mozilla_pkix__enumclass_h From 655ade7a8b033cd6d74fd24bf6b5fb7c91679b98 Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Sun, 5 Oct 2014 00:29:43 -0700 Subject: [PATCH 03/84] Bug 1077926: Make test certificate generation faster by reusing key, r=keeler --HG-- extra : rebase_source : 360fe925397688c1d0a2386c4974def6b571f0d4 --- security/pkix/test/gtest/pkixbuild_tests.cpp | 36 ++++------ .../test/gtest/pkixcert_extension_tests.cpp | 8 +-- .../pkixocsp_VerifyEncodedOCSPResponse.cpp | 60 +++++++++-------- security/pkix/test/lib/pkixtestnss.cpp | 65 ++++++++++++++++--- security/pkix/test/lib/pkixtestutil.cpp | 34 +++------- security/pkix/test/lib/pkixtestutil.h | 15 +++-- 6 files changed, 117 insertions(+), 101 deletions(-) diff --git a/security/pkix/test/gtest/pkixbuild_tests.cpp b/security/pkix/test/gtest/pkixbuild_tests.cpp index 3c14ca13e31e..07582f74807d 100644 --- a/security/pkix/test/gtest/pkixbuild_tests.cpp +++ b/security/pkix/test/gtest/pkixbuild_tests.cpp @@ -40,8 +40,6 @@ static ByteString CreateCert(const char* issuerCN, const char* subjectCN, EndEntityOrCA endEntityOrCA, - /*optional*/ TestKeyPair* issuerKey, - /*out*/ ScopedTestKeyPair& subjectKey, /*out*/ ScopedCERTCertificate* subjectCert = nullptr) { static long serialNumberValue = 0; @@ -60,13 +58,12 @@ CreateCert(const char* issuerCN, EXPECT_FALSE(ENCODING_FAILED(extensions[0])); } + ScopedTestKeyPair reusedKey(CloneReusedKeyPair()); ByteString certDER(CreateEncodedCertificate( - v3, sha256WithRSAEncryption, - serialNumber, issuerDER, - oneDayBeforeNow, oneDayAfterNow, - subjectDER, extensions, issuerKey, - SignatureAlgorithm::rsa_pkcs1_with_sha256, - subjectKey)); + v3, sha256WithRSAEncryption, serialNumber, issuerDER, + oneDayBeforeNow, oneDayAfterNow, subjectDER, + *reusedKey, extensions, *reusedKey, + SignatureAlgorithm::rsa_pkcs1_with_sha256)); EXPECT_FALSE(ENCODING_FAILED(certDER)); if (subjectCert) { SECItem certDERItem = { @@ -100,7 +97,7 @@ public: for (size_t i = 0; i < MOZILLA_PKIX_ARRAY_LENGTH(names); ++i) { const char* issuerName = i == 0 ? names[0] : names[i-1]; (void) CreateCert(issuerName, names[i], EndEntityOrCA::MustBeCA, - leafCAKey.get(), leafCAKey, &certChainTail[i]); + &certChainTail[i]); } return true; @@ -192,7 +189,6 @@ private: ScopedCERTCertificate certChainTail[7]; public: - ScopedTestKeyPair leafCAKey; CERTCertificate* GetLeafCACert() const { return certChainTail[MOZILLA_PKIX_ARRAY_LENGTH(certChainTail) - 1].get(); @@ -238,11 +234,9 @@ TEST_F(pkixbuild, MaxAcceptableCertChainLength) } { - ScopedTestKeyPair unusedKeyPair; ScopedCERTCertificate cert; ByteString certDER(CreateCert("CA7", "Direct End-Entity", - EndEntityOrCA::MustBeEndEntity, - trustDomain.leafCAKey.get(), unusedKeyPair)); + EndEntityOrCA::MustBeEndEntity)); ASSERT_FALSE(ENCODING_FAILED(certDER)); Input certDERInput; ASSERT_EQ(Success, certDERInput.Init(certDER.data(), certDER.length())); @@ -259,7 +253,6 @@ TEST_F(pkixbuild, MaxAcceptableCertChainLength) TEST_F(pkixbuild, BeyondMaxAcceptableCertChainLength) { static char const* const caCertName = "CA Too Far"; - ScopedTestKeyPair caKeyPair; // We need a CERTCertificate for caCert so that the trustdomain's FindIssuer // method can find it through the NSS cert DB. @@ -267,7 +260,6 @@ TEST_F(pkixbuild, BeyondMaxAcceptableCertChainLength) { ByteString certDER(CreateCert("CA7", caCertName, EndEntityOrCA::MustBeCA, - trustDomain.leafCAKey.get(), caKeyPair, &caCert)); ASSERT_FALSE(ENCODING_FAILED(certDER)); Input certDERInput; @@ -282,10 +274,8 @@ TEST_F(pkixbuild, BeyondMaxAcceptableCertChainLength) } { - ScopedTestKeyPair unusedKeyPair; ByteString certDER(CreateCert(caCertName, "End-Entity Too Far", - EndEntityOrCA::MustBeEndEntity, - caKeyPair.get(), unusedKeyPair)); + EndEntityOrCA::MustBeEndEntity)); ASSERT_FALSE(ENCODING_FAILED(certDER)); Input certDERInput; ASSERT_EQ(Success, certDERInput.Init(certDER.data(), certDER.length())); @@ -383,9 +373,8 @@ private: TEST_F(pkixbuild, NoRevocationCheckingForExpiredCert) { const char* rootCN = "Root CA"; - ScopedTestKeyPair rootKey; ByteString rootDER(CreateCert(rootCN, rootCN, EndEntityOrCA::MustBeCA, - nullptr, rootKey, nullptr)); + nullptr)); EXPECT_FALSE(ENCODING_FAILED(rootDER)); ExpiredCertTrustDomain expiredCertTrustDomain(rootDER); @@ -393,15 +382,14 @@ TEST_F(pkixbuild, NoRevocationCheckingForExpiredCert) EXPECT_FALSE(ENCODING_FAILED(serialNumber)); ByteString issuerDER(CNToDERName(rootCN)); ByteString subjectDER(CNToDERName("Expired End-Entity Cert")); - ScopedTestKeyPair unusedSubjectKey; + ScopedTestKeyPair reusedKey(CloneReusedKeyPair()); ByteString certDER(CreateEncodedCertificate( v3, sha256WithRSAEncryption, serialNumber, issuerDER, oneDayBeforeNow - Time::ONE_DAY_IN_SECONDS, oneDayBeforeNow, - subjectDER, nullptr, rootKey.get(), - SignatureAlgorithm::rsa_pkcs1_with_sha256, - unusedSubjectKey)); + subjectDER, *reusedKey, nullptr, *reusedKey, + SignatureAlgorithm::rsa_pkcs1_with_sha256)); EXPECT_FALSE(ENCODING_FAILED(certDER)); Input cert; diff --git a/security/pkix/test/gtest/pkixcert_extension_tests.cpp b/security/pkix/test/gtest/pkixcert_extension_tests.cpp index 371928e1379c..d988e1045448 100644 --- a/security/pkix/test/gtest/pkixcert_extension_tests.cpp +++ b/security/pkix/test/gtest/pkixcert_extension_tests.cpp @@ -43,13 +43,13 @@ CreateCert(const char* subjectCN, EXPECT_FALSE(ENCODING_FAILED(issuerDER)); ByteString subjectDER(CNToDERName(subjectCN)); EXPECT_FALSE(ENCODING_FAILED(subjectDER)); + subjectKey = CloneReusedKeyPair(); return CreateEncodedCertificate(v3, sha256WithRSAEncryption, serialNumber, issuerDER, oneDayBeforeNow, oneDayAfterNow, - subjectDER, extensions, - nullptr, - SignatureAlgorithm::rsa_pkcs1_with_sha256, - subjectKey); + subjectDER, *subjectKey, extensions, + *subjectKey, + SignatureAlgorithm::rsa_pkcs1_with_sha256); } // Creates a self-signed certificate with the given extension. diff --git a/security/pkix/test/gtest/pkixocsp_VerifyEncodedOCSPResponse.cpp b/security/pkix/test/gtest/pkixocsp_VerifyEncodedOCSPResponse.cpp index 27ccf630bb75..962c30d75e5f 100644 --- a/security/pkix/test/gtest/pkixocsp_VerifyEncodedOCSPResponse.cpp +++ b/security/pkix/test/gtest/pkixocsp_VerifyEncodedOCSPResponse.cpp @@ -392,12 +392,12 @@ protected: : ByteString(), ByteString() }; - ScopedTestKeyPair signerKeyPair; + ScopedTestKeyPair signerKeyPair(GenerateKeyPair()); ByteString signerDER(CreateEncodedCertificate( ++rootIssuedCount, rootName, oneDayBeforeNow, oneDayAfterNow, certSubjectName, - signerEKUDER ? extensions : nullptr, - rootKeyPair.get(), signerKeyPair)); + *signerKeyPair, signerEKUDER ? extensions : nullptr, + *rootKeyPair)); EXPECT_FALSE(ENCODING_FAILED(signerDER)); if (signerDEROut) { *signerDEROut = signerDER; @@ -421,9 +421,9 @@ protected: time_t notBefore, time_t notAfter, const char* subject, + const TestKeyPair& subjectKeyPair, /*optional*/ const ByteString* extensions, - /*optional*/ TestKeyPair* signerKeyPair, - /*out*/ ScopedTestKeyPair& keyPair) + const TestKeyPair& signerKeyPair) { ByteString serialNumberDER(CreateEncodedSerialNumber(serialNumber)); if (ENCODING_FAILED(serialNumberDER)) { @@ -441,10 +441,9 @@ protected: v3, sha256WithRSAEncryption, serialNumberDER, issuerDER, notBefore, - notAfter, subjectDER, extensions, - signerKeyPair, - SignatureAlgorithm::rsa_pkcs1_with_sha256, - keyPair); + notAfter, subjectDER, subjectKeyPair, + extensions, signerKeyPair, + SignatureAlgorithm::rsa_pkcs1_with_sha256); } static const Input OCSPSigningEKUDER; @@ -540,13 +539,13 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, good_expired) ByteString() }; - ScopedTestKeyPair signerKeyPair; + ScopedTestKeyPair signerKeyPair(GenerateKeyPair()); ByteString signerDER(CreateEncodedCertificate( ++rootIssuedCount, rootName, now - (10 * Time::ONE_DAY_IN_SECONDS), now - (2 * Time::ONE_DAY_IN_SECONDS), - signerName, extensions, rootKeyPair.get(), - signerKeyPair)); + signerName, *signerKeyPair, extensions, + *rootKeyPair)); ASSERT_FALSE(ENCODING_FAILED(signerDER)); ByteString certs[] = { signerDER, ByteString() }; @@ -575,13 +574,13 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, good_future) ByteString() }; - ScopedTestKeyPair signerKeyPair; + ScopedTestKeyPair signerKeyPair(GenerateKeyPair()); ByteString signerDER(CreateEncodedCertificate( ++rootIssuedCount, rootName, now + (2 * Time::ONE_DAY_IN_SECONDS), now + (10 * Time::ONE_DAY_IN_SECONDS), - signerName, extensions, rootKeyPair.get(), - signerKeyPair)); + signerName, *signerKeyPair, extensions, + *rootKeyPair)); ASSERT_FALSE(ENCODING_FAILED(signerDER)); ByteString certs[] = { signerDER, ByteString() }; @@ -677,11 +676,11 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, good_unknown_issuer) ExtensionCriticality::NotCritical), ByteString() }; - ScopedTestKeyPair signerKeyPair; + ScopedTestKeyPair signerKeyPair(GenerateKeyPair()); ByteString signerDER(CreateEncodedCertificate( 1, subCAName, oneDayBeforeNow, oneDayAfterNow, - signerName, extensions, unknownKeyPair.get(), - signerKeyPair)); + signerName, *signerKeyPair, extensions, + *unknownKeyPair)); ASSERT_FALSE(ENCODING_FAILED(signerDER)); // OCSP response signed by that delegated responder @@ -716,12 +715,12 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, CreateEncodedBasicConstraints(true, 0, ExtensionCriticality::NotCritical), ByteString() }; - ScopedTestKeyPair subCAKeyPair; + ScopedTestKeyPair subCAKeyPair(GenerateKeyPair()); ByteString subCADER(CreateEncodedCertificate( ++rootIssuedCount, rootName, oneDayBeforeNow, oneDayAfterNow, - subCAName, subCAExtensions, rootKeyPair.get(), - subCAKeyPair)); + subCAName, *subCAKeyPair, subCAExtensions, + *rootKeyPair)); ASSERT_FALSE(ENCODING_FAILED(subCADER)); // Delegated responder cert signed by that sub-CA @@ -730,11 +729,11 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, ExtensionCriticality::NotCritical), ByteString(), }; - ScopedTestKeyPair signerKeyPair; + ScopedTestKeyPair signerKeyPair(GenerateKeyPair()); ByteString signerDER(CreateEncodedCertificate( 1, subCAName, oneDayBeforeNow, oneDayAfterNow, - signerName, extensions, subCAKeyPair.get(), - signerKeyPair)); + signerName, *signerKeyPair, extensions, + *subCAKeyPair)); ASSERT_FALSE(ENCODING_FAILED(signerDER)); // OCSP response signed by the delegated responder issued by the sub-CA @@ -770,12 +769,11 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, CreateEncodedBasicConstraints(true, 0, ExtensionCriticality::NotCritical), ByteString() }; - ScopedTestKeyPair subCAKeyPair; + ScopedTestKeyPair subCAKeyPair(GenerateKeyPair()); ByteString subCADER(CreateEncodedCertificate(++rootIssuedCount, rootName, oneDayBeforeNow, oneDayAfterNow, - subCAName, subCAExtensions, - rootKeyPair.get(), - subCAKeyPair)); + subCAName, *subCAKeyPair, + subCAExtensions, *rootKeyPair)); ASSERT_FALSE(ENCODING_FAILED(subCADER)); // Delegated responder cert signed by that sub-CA @@ -784,11 +782,11 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, ExtensionCriticality::NotCritical), ByteString() }; - ScopedTestKeyPair signerKeyPair; + ScopedTestKeyPair signerKeyPair(GenerateKeyPair()); ByteString signerDER(CreateEncodedCertificate( 1, subCAName, oneDayBeforeNow, oneDayAfterNow, - signerName, extensions, subCAKeyPair.get(), - signerKeyPair)); + signerName, *signerKeyPair, extensions, + *subCAKeyPair)); ASSERT_FALSE(ENCODING_FAILED(signerDER)); // OCSP response signed by the delegated responder issued by the sub-CA diff --git a/security/pkix/test/lib/pkixtestnss.cpp b/security/pkix/test/lib/pkixtestnss.cpp index 2ba33b529982..0648000a69be 100644 --- a/security/pkix/test/lib/pkixtestnss.cpp +++ b/security/pkix/test/lib/pkixtestnss.cpp @@ -31,6 +31,7 @@ #include "nss.h" #include "pk11pub.h" #include "pkix/pkixnss.h" +#include "prinit.h" #include "secerr.h" #include "secitem.h" @@ -51,10 +52,28 @@ SECITEM_FreeItem_true(SECItem* item) typedef mozilla::pkix::ScopedPtr ScopedSECItem; +TestKeyPair* GenerateKeyPairInner(); + +static ScopedTestKeyPair reusedKeyPair; + +PRStatus +init() +{ + if (NSS_NoDB_Init(nullptr) != SECSuccess) { + abort(); + } + + reusedKeyPair = GenerateKeyPairInner(); + assert(reusedKeyPair); + + return PR_SUCCESS; +} + Result InitNSSIfNeeded() { - if (NSS_NoDB_Init(nullptr) != SECSuccess) { + static PRCallOnceType initCallOnce; + if (PR_CallOnce(&initCallOnce, init) != PR_SUCCESS) { return MapPRErrorCodeToResult(PR_GetError()); } return Success; @@ -125,16 +144,14 @@ TestKeyPair* CreateTestKeyPair(const ByteString& spki, return new (std::nothrow) NSSTestKeyPair(spki, spk, privateKey); } -TestKeyPair* -GenerateKeyPair() -{ - if (InitNSSIfNeeded() != Success) { - return nullptr; - } +namespace { +TestKeyPair* +GenerateKeyPairInner() +{ ScopedPtr slot(PK11_GetInternalSlot()); if (!slot) { - return nullptr; + abort(); } // Bug 1012786: PK11_GenerateKeyPair can fail if there is insufficient @@ -154,12 +171,12 @@ GenerateKeyPair() ScopedSECItem spkiDER(SECKEY_EncodeDERSubjectPublicKeyInfo(publicKey.get())); if (!spkiDER) { - return nullptr; + break; } ScopedPtr spki(SECKEY_CreateSubjectPublicKeyInfo(publicKey.get())); if (!spki) { - return nullptr; + break; } SECItem spkDER = spki->subjectPublicKey; DER_ConvertBitString(&spkDER); // bits to bytes @@ -184,7 +201,35 @@ GenerateKeyPair() } } + abort(); +#if defined(_MSC_VER) && (_MSC_VER < 1700) + // Older versions of MSVC don't know that abort() never returns, so silence + // its warning by adding a redundant and never-reached return. But, only do + // it for that ancient compiler, because some other compilers will rightly + // warn that the return statement is unreachable. return nullptr; +#endif +} + +} // unnamed namespace + +TestKeyPair* +GenerateKeyPair() +{ + if (InitNSSIfNeeded() != Success) { + abort(); + } + return GenerateKeyPairInner(); +} + +TestKeyPair* +CloneReusedKeyPair() +{ + if (InitNSSIfNeeded() != Success) { + abort(); + } + assert(reusedKeyPair); + return reusedKeyPair->Clone(); } ByteString diff --git a/security/pkix/test/lib/pkixtestutil.cpp b/security/pkix/test/lib/pkixtestutil.cpp index 708d13720da7..3e0d09857be8 100644 --- a/security/pkix/test/lib/pkixtestutil.cpp +++ b/security/pkix/test/lib/pkixtestutil.cpp @@ -341,16 +341,13 @@ YMDHMS(int16_t year, int16_t month, int16_t day, static ByteString SignedData(const ByteString& tbsData, - /*optional*/ TestKeyPair* keyPair, + const TestKeyPair& keyPair, SignatureAlgorithm signatureAlgorithm, bool corrupt, /*optional*/ const ByteString* certs) { ByteString signature; - if (keyPair) { - if (keyPair->SignData(tbsData, signatureAlgorithm, signature) - != Success) { - return ByteString(); - } + if (keyPair.SignData(tbsData, signatureAlgorithm, signature) != Success) { + return ByteString(); } ByteString signatureAlgorithmDER; @@ -465,31 +462,21 @@ CreateEncodedCertificate(long version, Input signature, const ByteString& issuerNameDER, time_t notBefore, time_t notAfter, const ByteString& subjectNameDER, + const TestKeyPair& subjectKeyPair, /*optional*/ const ByteString* extensions, - /*optional*/ TestKeyPair* issuerKeyPair, - SignatureAlgorithm signatureAlgorithm, - /*out*/ ScopedTestKeyPair& keyPairResult) + const TestKeyPair& issuerKeyPair, + SignatureAlgorithm signatureAlgorithm) { - // It may be the case that privateKeyResult references the same TestKeyPair - // as issuerKeyPair. Thus, we can't set keyPairResult until after we're done - // with issuerKeyPair. - ScopedTestKeyPair subjectKeyPair(GenerateKeyPair()); - if (!subjectKeyPair) { - return ByteString(); - } - ByteString tbsCertificate(TBSCertificate(version, serialNumber, signature, issuerNameDER, notBefore, notAfter, subjectNameDER, - subjectKeyPair->subjectPublicKeyInfo, + subjectKeyPair.subjectPublicKeyInfo, extensions)); if (ENCODING_FAILED(tbsCertificate)) { return ByteString(); } - ByteString result(SignedData(tbsCertificate, - issuerKeyPair ? issuerKeyPair - : subjectKeyPair.get(), + ByteString result(SignedData(tbsCertificate, issuerKeyPair, signatureAlgorithm, false, nullptr)); if (ENCODING_FAILED(result)) { return ByteString(); @@ -497,8 +484,6 @@ CreateEncodedCertificate(long version, Input signature, MaybeLogOutput(result, "cert"); - keyPairResult = subjectKeyPair.release(); - return result; } @@ -764,8 +749,7 @@ BasicOCSPResponse(OCSPResponseContext& context) return ByteString(); } - // TODO(bug 980538): certs - return SignedData(tbsResponseData, context.signerKeyPair.get(), + return SignedData(tbsResponseData, *context.signerKeyPair, SignatureAlgorithm::rsa_pkcs1_with_sha256, context.badSignature, context.certs); } diff --git a/security/pkix/test/lib/pkixtestutil.h b/security/pkix/test/lib/pkixtestutil.h index 411221c51ea5..c4d3cdaa7806 100644 --- a/security/pkix/test/lib/pkixtestutil.h +++ b/security/pkix/test/lib/pkixtestutil.h @@ -111,6 +111,11 @@ protected: void operator=(const TestKeyPair&) /*= delete*/; }; +// If the objective of the test doesn't involve verifying that signature +// verification is done correctly then use the keypair returned from +// CloneReusedKeyPair to make the test run much faster. +TestKeyPair* CloneReusedKeyPair(); + TestKeyPair* GenerateKeyPair(); inline void DeleteTestKeyPair(TestKeyPair* keyPair) { delete keyPair; } typedef ScopedPtr ScopedTestKeyPair; @@ -146,19 +151,15 @@ enum Version { v1 = 0, v2 = 1, v3 = 2 }; // extensions must point to an array of ByteStrings, terminated with an empty // ByteString. (If the first item of the array is empty then an empty // Extensions sequence will be encoded.) -// -// If issuerPrivateKey is null, then the certificate will be self-signed. -// Parameter order is based on the order of the attributes of the certificate -// in RFC 5280. ByteString CreateEncodedCertificate(long version, Input signature, const ByteString& serialNumber, const ByteString& issuerNameDER, time_t notBefore, time_t notAfter, const ByteString& subjectNameDER, + const TestKeyPair& subjectKeyPair, /*optional*/ const ByteString* extensions, - /*optional*/ TestKeyPair* issuerKeyPair, - SignatureAlgorithm signatureAlgorithm, - /*out*/ ScopedTestKeyPair& keyPairResult); + const TestKeyPair& issuerKeyPair, + SignatureAlgorithm signatureAlgorithm); ByteString CreateEncodedSerialNumber(long value); From f6f2410dba871bb8311ca61a39f2561fc94455e6 Mon Sep 17 00:00:00 2001 From: James Long Date: Mon, 6 Oct 2014 11:42:00 +0200 Subject: [PATCH 04/84] Bug 1056409 - move the sourceMapURL property from Debugger.Script to Debugger.Source. r=jorendorff --- content/base/test/chrome/test_bug765993.html | 2 +- js/src/doc/Debugger/Debugger.Script.md | 11 ----- js/src/doc/Debugger/Debugger.Source.md | 11 +++++ .../jit-test/tests/debug/Source-displayURL.js | 4 +- ...d.js => Source-sourceMapURL-deprecated.js} | 6 +-- ...sourceMapURL.js => Source-sourceMapURL.js} | 6 +-- js/src/vm/Debugger.cpp | 42 +++++++++---------- toolkit/devtools/server/actors/script.js | 6 +-- 8 files changed, 44 insertions(+), 44 deletions(-) rename js/src/jit-test/tests/debug/{Script-sourceMapURL-deprecated.js => Source-sourceMapURL-deprecated.js} (92%) rename js/src/jit-test/tests/debug/{Script-sourceMapURL.js => Source-sourceMapURL.js} (92%) diff --git a/content/base/test/chrome/test_bug765993.html b/content/base/test/chrome/test_bug765993.html index 650b1bee1656..26c39d0f2c38 100644 --- a/content/base/test/chrome/test_bug765993.html +++ b/content/base/test/chrome/test_bug765993.html @@ -46,7 +46,7 @@ window.onload = function () { }); ok(scripts.length > 0, "Should be able to find script"); - is(scripts[0].sourceMapURL, "foo.js.map"); + is(scripts[0].source.sourceMapURL, "foo.js.map"); SimpleTest.finish(); } diff --git a/js/src/doc/Debugger/Debugger.Script.md b/js/src/doc/Debugger/Debugger.Script.md index b0bd786c51f2..80ac2fd009a2 100644 --- a/js/src/doc/Debugger/Debugger.Script.md +++ b/js/src/doc/Debugger/Debugger.Script.md @@ -115,17 +115,6 @@ from its prototype: : This is `true` if this script's code is ECMAScript strict mode code, and `false` otherwise. -`sourceMapURL` -: If this script was produced by a minimizer or translated from some other - language, and we know the URL of a source map document relating - the source positions in this script to the corresponding source - positions in the original source, then this property's value is that - URL. Otherwise, this is `null`. - - (On the web, the translator may provide the source map URL in a - specially formatted comment in the JavaScript source code, or via a - header in the HTTP reply that carried the generated JavaScript.) - ## Function Properties of the Debugger.Script Prototype Object The functions described below may only be called with a `this` value diff --git a/js/src/doc/Debugger/Debugger.Source.md b/js/src/doc/Debugger/Debugger.Source.md index 70e80ffd4429..91e6a4ae31bb 100644 --- a/js/src/doc/Debugger/Debugger.Source.md +++ b/js/src/doc/Debugger/Debugger.Source.md @@ -74,6 +74,17 @@ from its prototype: `url` accessor on `Debugger.Source` instances for such sources should return `undefined`.) +`sourceMapURL` +: If this source was produced by a minimizer or translated from some other + language, and we know the URL of a source map document relating + the source positions in this source to the corresponding source + positions in the original source, then this property's value is that + URL. Otherwise, this is `null`. + + (On the web, the translator may provide the source map URL in a + specially formatted comment in the JavaScript source code, or via a + header in the HTTP reply that carried the generated JavaScript.) + `element` : The [`Debugger.Object`][object] instance referring to the DOM element to which this source code belongs, if any, or `undefined` if it belongs to no DOM diff --git a/js/src/jit-test/tests/debug/Source-displayURL.js b/js/src/jit-test/tests/debug/Source-displayURL.js index 51536d813889..a16a761860a4 100644 --- a/js/src/jit-test/tests/debug/Source-displayURL.js +++ b/js/src/jit-test/tests/debug/Source-displayURL.js @@ -78,7 +78,7 @@ var capturedSourceMapURL; dbg.onNewScript = function (script) { capturedScript = script; capturedDisplayURL = script.source.displayURL; - capturedSourceMapURL = script.sourceMapURL; + capturedSourceMapURL = script.source.sourceMapURL; dbg.onNewScript = undefined; }; var fun = gw.makeDebuggeeValue(g.Function('//# sourceURL=munge.js\n//# sourceMappingURL=grunge.map\n')); @@ -87,5 +87,5 @@ assertEq(capturedScript, fun.script); assertEq(capturedDisplayURL, fun.script.source.displayURL); assertEq(capturedDisplayURL, 'munge.js'); -assertEq(capturedSourceMapURL, fun.script.sourceMapURL); +assertEq(capturedSourceMapURL, fun.script.source.sourceMapURL); assertEq(capturedSourceMapURL, 'grunge.map'); diff --git a/js/src/jit-test/tests/debug/Script-sourceMapURL-deprecated.js b/js/src/jit-test/tests/debug/Source-sourceMapURL-deprecated.js similarity index 92% rename from js/src/jit-test/tests/debug/Script-sourceMapURL-deprecated.js rename to js/src/jit-test/tests/debug/Source-sourceMapURL-deprecated.js index 7e9e59971f43..fb01ccb0a67b 100644 --- a/js/src/jit-test/tests/debug/Script-sourceMapURL-deprecated.js +++ b/js/src/jit-test/tests/debug/Source-sourceMapURL-deprecated.js @@ -1,4 +1,4 @@ -// Script.prototype.sourceMapURL can be a string or null. +// Source.prototype.sourceMapURL can be a string or null. let g = newGlobal(); let dbg = new Debugger; @@ -6,7 +6,7 @@ let gw = dbg.addDebuggee(g); function getSourceMapURL() { let fw = gw.makeDebuggeeValue(g.f); - return fw.script.sourceMapURL; + return fw.script.source.sourceMapURL; } // Without a source map @@ -21,7 +21,7 @@ assertEq(getSourceMapURL(), 'file:///var/foo.js.map'); let fired = false; dbg.onDebuggerStatement = function (frame) { fired = true; - assertEq(frame.script.sourceMapURL, 'file:///var/bar.js.map'); + assertEq(frame.script.source.sourceMapURL, 'file:///var/bar.js.map'); }; g.evaluate('(function () { (function () { debugger; })(); })();', {sourceMapURL: 'file:///var/bar.js.map'}); diff --git a/js/src/jit-test/tests/debug/Script-sourceMapURL.js b/js/src/jit-test/tests/debug/Source-sourceMapURL.js similarity index 92% rename from js/src/jit-test/tests/debug/Script-sourceMapURL.js rename to js/src/jit-test/tests/debug/Source-sourceMapURL.js index 512b5205dc3e..c14004e9431d 100644 --- a/js/src/jit-test/tests/debug/Script-sourceMapURL.js +++ b/js/src/jit-test/tests/debug/Source-sourceMapURL.js @@ -1,4 +1,4 @@ -// Script.prototype.sourceMapURL can be a string or null. +// Source.prototype.sourceMapURL can be a string or null. let g = newGlobal(); let dbg = new Debugger; @@ -6,7 +6,7 @@ let gw = dbg.addDebuggee(g); function getSourceMapURL() { let fw = gw.makeDebuggeeValue(g.f); - return fw.script.sourceMapURL; + return fw.script.source.sourceMapURL; } // Without a source map @@ -21,7 +21,7 @@ assertEq(getSourceMapURL(), 'file:///var/foo.js.map'); let fired = false; dbg.onDebuggerStatement = function (frame) { fired = true; - assertEq(frame.script.sourceMapURL, 'file:///var/bar.js.map'); + assertEq(frame.script.source.sourceMapURL, 'file:///var/bar.js.map'); }; g.evaluate('(function () { (function () { debugger; })(); })();', {sourceMapURL: 'file:///var/bar.js.map'}); diff --git a/js/src/vm/Debugger.cpp b/js/src/vm/Debugger.cpp index 3d136fd9952d..29e4bc573910 100644 --- a/js/src/vm/Debugger.cpp +++ b/js/src/vm/Debugger.cpp @@ -3261,26 +3261,6 @@ DebuggerScript_getStaticLevel(JSContext *cx, unsigned argc, Value *vp) return true; } -static bool -DebuggerScript_getSourceMapUrl(JSContext *cx, unsigned argc, Value *vp) -{ - THIS_DEBUGSCRIPT_SCRIPT(cx, argc, vp, "(get sourceMapURL)", args, obj, script); - - ScriptSource *source = script->scriptSource(); - MOZ_ASSERT(source); - - if (source->hasSourceMapURL()) { - JSString *str = JS_NewUCStringCopyZ(cx, source->sourceMapURL()); - if (!str) - return false; - args.rval().setString(str); - } else { - args.rval().setNull(); - } - - return true; -} - static bool DebuggerScript_getGlobal(JSContext *cx, unsigned argc, Value *vp) { @@ -4011,7 +3991,6 @@ static const JSPropertySpec DebuggerScript_properties[] = { JS_PSG("sourceStart", DebuggerScript_getSourceStart, 0), JS_PSG("sourceLength", DebuggerScript_getSourceLength, 0), JS_PSG("staticLevel", DebuggerScript_getStaticLevel, 0), - JS_PSG("sourceMapURL", DebuggerScript_getSourceMapUrl, 0), JS_PSG("global", DebuggerScript_getGlobal, 0), JS_PS_END }; @@ -4280,6 +4259,26 @@ DebuggerSource_getIntroductionType(JSContext *cx, unsigned argc, Value *vp) return true; } +static bool +DebuggerSource_getSourceMapUrl(JSContext *cx, unsigned argc, Value *vp) +{ + THIS_DEBUGSOURCE_REFERENT(cx, argc, vp, "(get sourceMapURL)", args, obj, sourceObject); + + ScriptSource *ss = sourceObject->source(); + MOZ_ASSERT(ss); + + if (ss->hasSourceMapURL()) { + JSString *str = JS_NewUCStringCopyZ(cx, ss->sourceMapURL()); + if (!str) + return false; + args.rval().setString(str); + } else { + args.rval().setNull(); + } + + return true; +} + static const JSPropertySpec DebuggerSource_properties[] = { JS_PSG("text", DebuggerSource_getText, 0), JS_PSG("url", DebuggerSource_getUrl, 0), @@ -4289,6 +4288,7 @@ static const JSPropertySpec DebuggerSource_properties[] = { JS_PSG("introductionOffset", DebuggerSource_getIntroductionOffset, 0), JS_PSG("introductionType", DebuggerSource_getIntroductionType, 0), JS_PSG("elementAttributeName", DebuggerSource_getElementProperty, 0), + JS_PSG("sourceMapURL", DebuggerSource_getSourceMapUrl, 0), JS_PS_END }; diff --git a/toolkit/devtools/server/actors/script.js b/toolkit/devtools/server/actors/script.js index 480f47419250..780720c36124 100644 --- a/toolkit/devtools/server/actors/script.js +++ b/toolkit/devtools/server/actors/script.js @@ -5026,7 +5026,7 @@ ThreadSources.prototype = { * of an array of source actors for those. */ sourcesForScript: function (aScript) { - if (!this._useSourceMaps || !aScript.sourceMapURL) { + if (!this._useSourceMaps || !aScript.source.sourceMapURL) { return resolve([this._sourceForScript(aScript)].filter(isNotNull)); } @@ -5053,8 +5053,8 @@ ThreadSources.prototype = { * |aScript| must have a non-null sourceMapURL. */ sourceMap: function (aScript) { - dbg_assert(aScript.sourceMapURL, "Script should have a sourceMapURL"); - let sourceMapURL = this._normalize(aScript.sourceMapURL, aScript.url); + dbg_assert(aScript.source.sourceMapURL, "Script should have a sourceMapURL"); + let sourceMapURL = this._normalize(aScript.source.sourceMapURL, aScript.url); let map = this._fetchSourceMap(sourceMapURL, aScript.url) .then(aSourceMap => this.saveSourceMap(aSourceMap, aScript.url)); this._sourceMapsByGeneratedSource[aScript.url] = map; From 1b908f5252ed5f3d848ce799e966bd7c003cf009 Mon Sep 17 00:00:00 2001 From: Eitan Isaacson Date: Fri, 3 Oct 2014 17:27:00 +0200 Subject: [PATCH 05/84] Bug 981363 - Don't automove when the DOCUMENT_LOAD_COMPLETE is emitted for the actual document. r=yzenevich --- accessible/jsat/EventManager.jsm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/accessible/jsat/EventManager.jsm b/accessible/jsat/EventManager.jsm index c9f72ec6f3b5..b074469c7407 100644 --- a/accessible/jsat/EventManager.jsm +++ b/accessible/jsat/EventManager.jsm @@ -266,7 +266,8 @@ this.EventManager.prototype = { case Events.DOCUMENT_LOAD_COMPLETE: { let position = this.contentControl.vc.position; - if (position && Utils.isInSubtree(position, aEvent.accessible)) { + if (aEvent.accessible === aEvent.accessibleDocument || + (position && Utils.isInSubtree(position, aEvent.accessible))) { // Do not automove into the document if the virtual cursor is already // positioned inside it. break; From 23deb5d7c04678157c4c07f16d77b2f611f91055 Mon Sep 17 00:00:00 2001 From: Andrei Eftimie Date: Tue, 7 Oct 2014 10:41:59 +0200 Subject: [PATCH 06/84] Bug 1056037 - Bump manifestparser version to 0.7. r=hskupin --- testing/mozbase/manifestparser/setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/mozbase/manifestparser/setup.py b/testing/mozbase/manifestparser/setup.py index e22e564588dd..574d5a5b7a74 100644 --- a/testing/mozbase/manifestparser/setup.py +++ b/testing/mozbase/manifestparser/setup.py @@ -5,7 +5,7 @@ from setuptools import setup PACKAGE_NAME = "manifestparser" -PACKAGE_VERSION = '0.6' +PACKAGE_VERSION = '0.7' setup(name=PACKAGE_NAME, version=PACKAGE_VERSION, From f16d5017859eb580bed945c6f2941d2f473df210 Mon Sep 17 00:00:00 2001 From: Nicolas Silva Date: Tue, 7 Oct 2014 10:45:04 +0200 Subject: [PATCH 07/84] Bug 1016540 - GrallocTextureSource::DeallocateDeviceData must assert that it has a compositor, rather than a gl context. r=sotaro --- gfx/layers/RotatedBuffer.cpp | 2 +- gfx/layers/opengl/GrallocTextureHost.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gfx/layers/RotatedBuffer.cpp b/gfx/layers/RotatedBuffer.cpp index adbe8a222f98..f0c678db1a55 100644 --- a/gfx/layers/RotatedBuffer.cpp +++ b/gfx/layers/RotatedBuffer.cpp @@ -727,11 +727,11 @@ RotatedContentBuffer::BorrowDrawTargetForPainting(PaintState& aPaintState, } if (aPaintState.mMode == SurfaceMode::SURFACE_COMPONENT_ALPHA) { - MOZ_ASSERT(mDTBuffer && mDTBufferOnWhite); if (!mDTBuffer || !mDTBufferOnWhite) { // This can happen in release builds if allocating one of the two buffers // failed. This is pretty bad and the reason for the failure is already // reported through gfxCriticalError. + MOZ_ASSERT(false); return nullptr; } nsIntRegionRectIterator iter(*drawPtr); diff --git a/gfx/layers/opengl/GrallocTextureHost.cpp b/gfx/layers/opengl/GrallocTextureHost.cpp index 0931005a952e..dca0cf47b14b 100644 --- a/gfx/layers/opengl/GrallocTextureHost.cpp +++ b/gfx/layers/opengl/GrallocTextureHost.cpp @@ -295,7 +295,7 @@ void GrallocTextureSourceOGL::DeallocateDeviceData() { if (mEGLImage) { - MOZ_ASSERT(gl()); + MOZ_ASSERT(mCompositor); if (!gl() || !gl()->MakeCurrent()) { return; } From 09aed1e55d7bdaa64156f4d7d83b3ca2aa869f17 Mon Sep 17 00:00:00 2001 From: "Patrick Wang (Chih-Kai Wang)" Date: Tue, 7 Oct 2014 17:24:57 +0800 Subject: [PATCH 08/84] Bug 951677 - Part 1: Add Bind function to SocketTransport. r=honzab --- netwerk/base/public/nsISocketTransport.idl | 8 ++++++- netwerk/base/src/nsSocketTransport2.cpp | 28 ++++++++++++++++++++++ netwerk/base/src/nsSocketTransport2.h | 2 ++ netwerk/protocol/http/TunnelUtils.cpp | 6 +++++ 4 files changed, 43 insertions(+), 1 deletion(-) diff --git a/netwerk/base/public/nsISocketTransport.idl b/netwerk/base/public/nsISocketTransport.idl index 8b75e39ccc70..7df679cf4952 100644 --- a/netwerk/base/public/nsISocketTransport.idl +++ b/netwerk/base/public/nsISocketTransport.idl @@ -16,6 +16,7 @@ union NetAddr; } %} native NetAddr(mozilla::net::NetAddr); +[ptr] native NetAddrPtr(mozilla::net::NetAddr); /** * nsISocketTransport @@ -27,7 +28,7 @@ native NetAddr(mozilla::net::NetAddr); * NOTE: This is a free-threaded interface, meaning that the methods on * this interface may be called from any thread. */ -[scriptable, uuid(3F41704C-CD5D-4537-8C4C-7B2EBFC5D972)] +[scriptable, uuid(a0b3b547-d6f0-4b65-a3de-a99ffa368840)] interface nsISocketTransport : nsITransport { /** @@ -55,6 +56,11 @@ interface nsISocketTransport : nsITransport */ [noscript] NetAddr getSelfAddr(); + /** + * Bind to a specific local address. + */ + [noscript] void bind(in NetAddrPtr aLocalAddr); + /** * Returns a scriptable version of getPeerAddr. This attribute is defined * only once a connection has been established. diff --git a/netwerk/base/src/nsSocketTransport2.cpp b/netwerk/base/src/nsSocketTransport2.cpp index 19233f554e0e..e6894b9ada39 100644 --- a/netwerk/base/src/nsSocketTransport2.cpp +++ b/netwerk/base/src/nsSocketTransport2.cpp @@ -1355,6 +1355,18 @@ nsSocketTransport::InitiateSocket() // Initiate the connect() to the host... // PRNetAddr prAddr; + { + if (mBindAddr) { + MutexAutoLock lock(mLock); + NetAddrToPRNetAddr(mBindAddr.get(), &prAddr); + status = PR_Bind(fd, &prAddr); + if (status != PR_SUCCESS) { + return NS_ERROR_FAILURE; + } + mBindAddr = nullptr; + } + } + NetAddrToPRNetAddr(&mNetAddr, &prAddr); MOZ_EVENT_TRACER_EXEC(this, "net::tcp::connect"); @@ -2221,6 +2233,22 @@ nsSocketTransport::GetSelfAddr(NetAddr *addr) return rv; } +NS_IMETHODIMP +nsSocketTransport::Bind(NetAddr *aLocalAddr) +{ + NS_ENSURE_ARG(aLocalAddr); + + MutexAutoLock lock(mLock); + if (mAttached) { + return NS_ERROR_FAILURE; + } + + mBindAddr = new NetAddr(); + memcpy(mBindAddr.get(), aLocalAddr, sizeof(NetAddr)); + + return NS_OK; +} + /* nsINetAddr getScriptablePeerAddr (); */ NS_IMETHODIMP nsSocketTransport::GetScriptablePeerAddr(nsINetAddr * *addr) diff --git a/netwerk/base/src/nsSocketTransport2.h b/netwerk/base/src/nsSocketTransport2.h index 6bd3d5d85fde..52caccf595ab 100644 --- a/netwerk/base/src/nsSocketTransport2.h +++ b/netwerk/base/src/nsSocketTransport2.h @@ -305,6 +305,8 @@ private: mozilla::net::NetAddr mNetAddr; bool mNetAddrIsSet; + nsAutoPtr mBindAddr; + // socket methods (these can only be called on the socket thread): void SendStatus(nsresult status); diff --git a/netwerk/protocol/http/TunnelUtils.cpp b/netwerk/protocol/http/TunnelUtils.cpp index 5e369543f4ab..bc190a67a852 100644 --- a/netwerk/protocol/http/TunnelUtils.cpp +++ b/netwerk/protocol/http/TunnelUtils.cpp @@ -1544,6 +1544,12 @@ SocketTransportShim::SetEventSink(nsITransportEventSink *aSink, nsIEventTarget * return NS_ERROR_NOT_IMPLEMENTED; } +NS_IMETHODIMP +SocketTransportShim::Bind(NetAddr *aLocalAddr) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + #define FWD_TS_PTR(fx, ts) NS_IMETHODIMP \ SocketTransportShim::fx(ts *arg) { return mWrapped->fx(arg); } From 90d0d29b1f402cbd64a1b690fea5e1976ffaa49a Mon Sep 17 00:00:00 2001 From: "Patrick Wang (Chih-Kai Wang)" Date: Tue, 7 Oct 2014 17:25:54 +0800 Subject: [PATCH 09/84] Bug 951677 - Part 2: test case. r=honzab --- netwerk/test/TestBind.cpp | 214 ++++++++++++++++++++++++++++++++++++++ netwerk/test/moz.build | 1 + 2 files changed, 215 insertions(+) create mode 100644 netwerk/test/TestBind.cpp diff --git a/netwerk/test/TestBind.cpp b/netwerk/test/TestBind.cpp new file mode 100644 index 000000000000..1bd9e42efc23 --- /dev/null +++ b/netwerk/test/TestBind.cpp @@ -0,0 +1,214 @@ +/* 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 "TestCommon.h" +#include "TestHarness.h" +#include "nsISocketTransportService.h" +#include "nsISocketTransport.h" +#include "nsIServerSocket.h" +#include "nsIAsyncInputStream.h" +#include "nsINetAddr.h" +#include "mozilla/net/DNS.h" +#include "prerror.h" + +using namespace mozilla::net; +using namespace mozilla; + +class ServerListener: public nsIServerSocketListener +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSISERVERSOCKETLISTENER + + ServerListener(); + + // Port that is got from server side will be store here. + uint32_t mClientPort; + bool mFailed; +private: + virtual ~ServerListener(); +}; + +NS_IMPL_ISUPPORTS(ServerListener, nsIServerSocketListener) + +ServerListener::ServerListener() + : mClientPort(-1) + , mFailed(false) +{ +} + +ServerListener::~ServerListener() +{ +} + +NS_IMETHODIMP +ServerListener::OnSocketAccepted(nsIServerSocket *aServ, + nsISocketTransport *aTransport) +{ + // Run on STS thread. + NetAddr peerAddr; + nsresult rv = aTransport->GetPeerAddr(&peerAddr); + if (NS_FAILED(rv)) { + mFailed = true; + fail("Server: not able to get peer address."); + QuitPumpingEvents(); + return NS_OK; + } + mClientPort = PR_ntohs(peerAddr.inet.port); + passed("Server: received connection"); + QuitPumpingEvents(); + return NS_OK; +} + +NS_IMETHODIMP +ServerListener::OnStopListening(nsIServerSocket *aServ, + nsresult aStatus) +{ + return NS_OK; +} + +class ClientInputCallback : public nsIInputStreamCallback +{ +public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIINPUTSTREAMCALLBACK + + ClientInputCallback(); + + bool mFailed; +private: + virtual ~ClientInputCallback(); +}; + +NS_IMPL_ISUPPORTS(ClientInputCallback, nsIInputStreamCallback) + +ClientInputCallback::ClientInputCallback() + : mFailed(false) +{ +} + +ClientInputCallback::~ClientInputCallback() +{ +} + +NS_IMETHODIMP +ClientInputCallback::OnInputStreamReady(nsIAsyncInputStream *aStream) +{ + // Server doesn't send. That means if we are here, we probably have run into + // an error. + uint64_t avail; + nsresult rv = aStream->Available(&avail); + if (NS_FAILED(rv)) { + mFailed = true; + } + QuitPumpingEvents(); + return NS_OK; +} + +int +main(int32_t argc, char *argv[]) +{ + ScopedXPCOM xpcom("SocketTransport"); + if (xpcom.failed()) { + fail("Unable to initalize XPCOM."); + return -1; + } + + // + // Server side. + // + nsCOMPtr server = do_CreateInstance("@mozilla.org/network/server-socket;1"); + if (!server) { + fail("Failed to create server socket."); + return -1; + } + + nsresult rv = server->Init(-1, true, -1); + if (NS_FAILED(rv)) { + fail("Failed to initialize server."); + return -1; + } + + int32_t serverPort; + rv = server->GetPort(&serverPort); + if (NS_FAILED(rv)) { + fail("Unable to get server port."); + return -1; + } + + // Listening. + nsRefPtr serverListener = new ServerListener(); + rv = server->AsyncListen(serverListener); + if (NS_FAILED(rv)) { + fail("Server fail to start listening."); + return -1; + } + + // + // Client side + // + uint32_t bindingPort = 20000; + nsCOMPtr sts = + do_GetService("@mozilla.org/network/socket-transport-service;1", &rv); + if (NS_FAILED(rv)) { + fail("Unable to get socket transport service."); + return -1; + } + + for (int32_t tried = 0; tried < 100; tried++) { + nsCOMPtr client; + rv = sts->CreateTransport(nullptr, 0, NS_LITERAL_CSTRING("127.0.0.1"), + serverPort, nullptr, getter_AddRefs(client)); + if (NS_FAILED(rv)) { + fail("Unable to create transport."); + return -1; + } + + // Bind to a port. It's possible that we are binding to a port that is + // currently in use. If we failed to bind, we try next port. + NetAddr bindingAddr; + bindingAddr.inet.family = AF_INET; + bindingAddr.inet.ip = 0; + bindingAddr.inet.port = PR_htons(bindingPort); + rv = client->Bind(&bindingAddr); + if (NS_FAILED(rv)) { + fail("Unable to bind a port."); + return -1; + } + + // Open IO streams, to make client SocketTransport connect to server. + nsRefPtr clientCallback = new ClientInputCallback(); + nsCOMPtr inputStream; + rv = client->OpenInputStream(nsITransport::OPEN_UNBUFFERED, + 0, 0, getter_AddRefs(inputStream)); + if (NS_FAILED(rv)) { + fail("Failed to open an input stream."); + return -1; + } + nsCOMPtr asyncInputStream = do_QueryInterface(inputStream); + rv = asyncInputStream->AsyncWait(clientCallback, 0, 0, nullptr); + + // Wait for server's response or callback of input stream. + PumpEvents(); + if (clientCallback->mFailed) { + // if client received error, we likely have bound a port that is in use. + // we can try another port. + bindingPort++; + } else { + // We are unlocked by server side, leave the loop and check result. + break; + } + } + + if (serverListener->mFailed) { + fail("Server failure."); + return -1; + } + if (serverListener->mClientPort != bindingPort) { + fail("Port that server got doesn't match what we are expecting."); + return -1; + } + passed("Port matched"); + return 0; +} diff --git a/netwerk/test/moz.build b/netwerk/test/moz.build index 75e4ced440d7..9d95514b369e 100644 --- a/netwerk/test/moz.build +++ b/netwerk/test/moz.build @@ -47,6 +47,7 @@ SimplePrograms([ #] CppUnitTests([ + 'TestBind', 'TestCookie', 'TestSTSParser', 'TestUDPSocket', From eec11c26a07144bee3e56ea85986fee61c7a46dc Mon Sep 17 00:00:00 2001 From: Tom Schuster Date: Tue, 7 Oct 2014 11:29:02 +0200 Subject: [PATCH 10/84] Bug 1071177 - Introduce JSIDVariant type for CPOWs. r=billm --- js/ipc/JavaScriptBase.h | 32 +++++------ js/ipc/JavaScriptLogging.h | 25 +++++++++ js/ipc/JavaScriptShared.cpp | 35 ++++++++++++ js/ipc/JavaScriptShared.h | 3 + js/ipc/JavaScriptTypes.ipdlh | 6 ++ js/ipc/PJavaScript.ipdl | 16 +++--- js/ipc/WrapperAnswer.cpp | 106 +++++++++++++++++------------------ js/ipc/WrapperAnswer.h | 16 +++--- js/ipc/WrapperOwner.cpp | 55 +++++++++--------- js/ipc/WrapperOwner.h | 16 +++--- 10 files changed, 190 insertions(+), 120 deletions(-) diff --git a/js/ipc/JavaScriptBase.h b/js/ipc/JavaScriptBase.h index 6754d5bb088e..cc91cd91ddc8 100644 --- a/js/ipc/JavaScriptBase.h +++ b/js/ipc/JavaScriptBase.h @@ -38,42 +38,42 @@ class JavaScriptBase : public WrapperOwner, public WrapperAnswer, public Base bool AnswerPreventExtensions(const uint64_t &objId, ReturnStatus *rs) { return Answer::AnswerPreventExtensions(ObjectId::deserialize(objId), rs); } - bool AnswerGetPropertyDescriptor(const uint64_t &objId, const nsString &id, + bool AnswerGetPropertyDescriptor(const uint64_t &objId, const JSIDVariant &id, ReturnStatus *rs, PPropertyDescriptor *out) { return Answer::AnswerGetPropertyDescriptor(ObjectId::deserialize(objId), id, rs, out); } bool AnswerGetOwnPropertyDescriptor(const uint64_t &objId, - const nsString &id, + const JSIDVariant &id, ReturnStatus *rs, PPropertyDescriptor *out) { return Answer::AnswerGetOwnPropertyDescriptor(ObjectId::deserialize(objId), id, rs, out); } - bool AnswerDefineProperty(const uint64_t &objId, const nsString &id, + bool AnswerDefineProperty(const uint64_t &objId, const JSIDVariant &id, const PPropertyDescriptor &flags, ReturnStatus *rs) { return Answer::AnswerDefineProperty(ObjectId::deserialize(objId), id, flags, rs); } - bool AnswerDelete(const uint64_t &objId, const nsString &id, + bool AnswerDelete(const uint64_t &objId, const JSIDVariant &id, ReturnStatus *rs, bool *success) { return Answer::AnswerDelete(ObjectId::deserialize(objId), id, rs, success); } - bool AnswerHas(const uint64_t &objId, const nsString &id, + bool AnswerHas(const uint64_t &objId, const JSIDVariant &id, ReturnStatus *rs, bool *bp) { return Answer::AnswerHas(ObjectId::deserialize(objId), id, rs, bp); } - bool AnswerHasOwn(const uint64_t &objId, const nsString &id, + bool AnswerHasOwn(const uint64_t &objId, const JSIDVariant &id, ReturnStatus *rs, bool *bp) { return Answer::AnswerHasOwn(ObjectId::deserialize(objId), id, rs, bp); } bool AnswerGet(const uint64_t &objId, const ObjectVariant &receiverVar, - const nsString &id, + const JSIDVariant &id, ReturnStatus *rs, JSVariant *result) { return Answer::AnswerGet(ObjectId::deserialize(objId), receiverVar, id, rs, result); } bool AnswerSet(const uint64_t &objId, const ObjectVariant &receiverVar, - const nsString &id, const bool &strict, + const JSIDVariant &id, const bool &strict, const JSVariant &value, ReturnStatus *rs, JSVariant *result) { return Answer::AnswerSet(ObjectId::deserialize(objId), receiverVar, id, strict, value, rs, result); } @@ -134,42 +134,42 @@ class JavaScriptBase : public WrapperOwner, public WrapperAnswer, public Base bool CallPreventExtensions(const ObjectId &objId, ReturnStatus *rs) { return Base::CallPreventExtensions(objId.serialize(), rs); } - bool CallGetPropertyDescriptor(const ObjectId &objId, const nsString &id, + bool CallGetPropertyDescriptor(const ObjectId &objId, const JSIDVariant &id, ReturnStatus *rs, PPropertyDescriptor *out) { return Base::CallGetPropertyDescriptor(objId.serialize(), id, rs, out); } bool CallGetOwnPropertyDescriptor(const ObjectId &objId, - const nsString &id, + const JSIDVariant &id, ReturnStatus *rs, PPropertyDescriptor *out) { return Base::CallGetOwnPropertyDescriptor(objId.serialize(), id, rs, out); } - bool CallDefineProperty(const ObjectId &objId, const nsString &id, + bool CallDefineProperty(const ObjectId &objId, const JSIDVariant &id, const PPropertyDescriptor &flags, ReturnStatus *rs) { return Base::CallDefineProperty(objId.serialize(), id, flags, rs); } - bool CallDelete(const ObjectId &objId, const nsString &id, + bool CallDelete(const ObjectId &objId, const JSIDVariant &id, ReturnStatus *rs, bool *success) { return Base::CallDelete(objId.serialize(), id, rs, success); } - bool CallHas(const ObjectId &objId, const nsString &id, + bool CallHas(const ObjectId &objId, const JSIDVariant &id, ReturnStatus *rs, bool *bp) { return Base::CallHas(objId.serialize(), id, rs, bp); } - bool CallHasOwn(const ObjectId &objId, const nsString &id, + bool CallHasOwn(const ObjectId &objId, const JSIDVariant &id, ReturnStatus *rs, bool *bp) { return Base::CallHasOwn(objId.serialize(), id, rs, bp); } bool CallGet(const ObjectId &objId, const ObjectVariant &receiverVar, - const nsString &id, + const JSIDVariant &id, ReturnStatus *rs, JSVariant *result) { return Base::CallGet(objId.serialize(), receiverVar, id, rs, result); } bool CallSet(const ObjectId &objId, const ObjectVariant &receiverVar, - const nsString &id, const bool &strict, + const JSIDVariant &id, const bool &strict, const JSVariant &value, ReturnStatus *rs, JSVariant *result) { return Base::CallSet(objId.serialize(), receiverVar, id, strict, value, rs, result); } diff --git a/js/ipc/JavaScriptLogging.h b/js/ipc/JavaScriptLogging.h index eeb47a1a9d33..fe34812d3db8 100644 --- a/js/ipc/JavaScriptLogging.h +++ b/js/ipc/JavaScriptLogging.h @@ -49,6 +49,12 @@ struct OutVariant explicit OutVariant(const JSVariant &variant) : variant(variant) {} }; +struct Identifier +{ + JSIDVariant variant; + explicit Identifier(const JSIDVariant &variant) : variant(variant) {} +}; + class Logging { public: @@ -184,6 +190,25 @@ class Logging } } + void format(const Identifier &id, nsCString &out) { + switch (id.variant.type()) { + case JSIDVariant::TnsString: { + nsAutoCString tmp; + format(id.variant.get_nsString(), tmp); + out = nsPrintfCString("\"%s\"", tmp.get()); + break; + } + case JSIDVariant::Tint32_t: { + out = nsPrintfCString("%d", id.variant.get_int32_t()); + break; + } + default: { + out = "Unknown"; + break; + } + } + } + private: JavaScriptShared *shared; JSContext *cx; diff --git a/js/ipc/JavaScriptShared.cpp b/js/ipc/JavaScriptShared.cpp index 882be465929d..41bf4e436362 100644 --- a/js/ipc/JavaScriptShared.cpp +++ b/js/ipc/JavaScriptShared.cpp @@ -348,10 +348,45 @@ JavaScriptShared::fromVariant(JSContext *cx, const JSVariant &from, MutableHandl } default: + MOZ_CRASH("NYI"); return false; } } +bool +JavaScriptShared::toJSIDVariant(JSContext *cx, HandleId from, JSIDVariant *to) +{ + if (JSID_IS_STRING(from)) { + nsAutoJSString autoStr; + if (!autoStr.init(cx, JSID_TO_STRING(from))) + return false; + *to = autoStr; + return true; + } + if (JSID_IS_INT(from)) { + *to = JSID_TO_INT(from); + return true; + } + MOZ_CRASH("NYI"); + return false; +} + +bool +JavaScriptShared::fromJSIDVariant(JSContext *cx, const JSIDVariant &from, MutableHandleId to) +{ + switch (from.type()) { + case JSIDVariant::TnsString: + return convertGeckoStringToId(cx, from.get_nsString(), to); + + case JSIDVariant::Tint32_t: + to.set(INT_TO_JSID(from.get_int32_t())); + return true; + + default: + return false; + } +} + /* static */ void JavaScriptShared::ConvertID(const nsID &from, JSIID *to) { diff --git a/js/ipc/JavaScriptShared.h b/js/ipc/JavaScriptShared.h index 3c0cd766105f..ca8674478d34 100644 --- a/js/ipc/JavaScriptShared.h +++ b/js/ipc/JavaScriptShared.h @@ -158,6 +158,9 @@ class JavaScriptShared bool toVariant(JSContext *cx, JS::HandleValue from, JSVariant *to); bool fromVariant(JSContext *cx, const JSVariant &from, JS::MutableHandleValue to); + bool toJSIDVariant(JSContext *cx, JS::HandleId from, JSIDVariant *to); + bool fromJSIDVariant(JSContext *cx, const JSIDVariant &from, JS::MutableHandleId to); + bool fromDescriptor(JSContext *cx, JS::Handle desc, PPropertyDescriptor *out); bool toDescriptor(JSContext *cx, const PPropertyDescriptor &in, diff --git a/js/ipc/JavaScriptTypes.ipdlh b/js/ipc/JavaScriptTypes.ipdlh index 07b359f29c14..cea0280a25eb 100644 --- a/js/ipc/JavaScriptTypes.ipdlh +++ b/js/ipc/JavaScriptTypes.ipdlh @@ -57,6 +57,12 @@ union JSVariant JSIID; /* XPC nsIID */ }; +union JSIDVariant +{ + nsString; + int32_t; +}; + struct ReturnSuccess { }; diff --git a/js/ipc/PJavaScript.ipdl b/js/ipc/PJavaScript.ipdl index 6efb0a8b06a4..f4c29e074577 100644 --- a/js/ipc/PJavaScript.ipdl +++ b/js/ipc/PJavaScript.ipdl @@ -25,15 +25,15 @@ both: // These roughly map to the ProxyHandler hooks that CPOWs need. rpc PreventExtensions(uint64_t objId) returns (ReturnStatus rs); - rpc GetPropertyDescriptor(uint64_t objId, nsString id) returns (ReturnStatus rs, PPropertyDescriptor result); - rpc GetOwnPropertyDescriptor(uint64_t objId, nsString id) returns (ReturnStatus rs, PPropertyDescriptor result); - rpc DefineProperty(uint64_t objId, nsString id, PPropertyDescriptor descriptor) returns (ReturnStatus rs); - rpc Delete(uint64_t objId, nsString id) returns (ReturnStatus rs, bool successful); + rpc GetPropertyDescriptor(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, PPropertyDescriptor result); + rpc GetOwnPropertyDescriptor(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, PPropertyDescriptor result); + rpc DefineProperty(uint64_t objId, JSIDVariant id, PPropertyDescriptor descriptor) returns (ReturnStatus rs); + rpc Delete(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, bool successful); - rpc Has(uint64_t objId, nsString id) returns (ReturnStatus rs, bool has); - rpc HasOwn(uint64_t objId, nsString id) returns (ReturnStatus rs, bool has); - rpc Get(uint64_t objId, ObjectVariant receiver, nsString id) returns (ReturnStatus rs, JSVariant result); - rpc Set(uint64_t objId, ObjectVariant receiver, nsString id, bool strict, JSVariant value) returns (ReturnStatus rs, JSVariant result); + rpc Has(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, bool has); + rpc HasOwn(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, bool has); + rpc Get(uint64_t objId, ObjectVariant receiver, JSIDVariant id) returns (ReturnStatus rs, JSVariant result); + rpc Set(uint64_t objId, ObjectVariant receiver, JSIDVariant id, bool strict, JSVariant value) returns (ReturnStatus rs, JSVariant result); rpc IsExtensible(uint64_t objId) returns (ReturnStatus rs, bool result); rpc CallOrConstruct(uint64_t objId, JSParam[] argv, bool construct) returns (ReturnStatus rs, JSVariant result, JSParam[] outparams); diff --git a/js/ipc/WrapperAnswer.cpp b/js/ipc/WrapperAnswer.cpp index 5fb3e45040d1..9fb1fa3bbbc3 100644 --- a/js/ipc/WrapperAnswer.cpp +++ b/js/ipc/WrapperAnswer.cpp @@ -87,8 +87,8 @@ EmptyDesc(PPropertyDescriptor *desc) } bool -WrapperAnswer::AnswerGetPropertyDescriptor(const ObjectId &objId, const nsString &id, - ReturnStatus *rs, PPropertyDescriptor *out) +WrapperAnswer::AnswerGetPropertyDescriptor(const ObjectId &objId, const JSIDVariant &idVar, + ReturnStatus *rs, PPropertyDescriptor *out) { AutoSafeJSContext cx; JSAutoRequest request(cx); @@ -101,14 +101,14 @@ WrapperAnswer::AnswerGetPropertyDescriptor(const ObjectId &objId, const nsString JSAutoCompartment comp(cx, obj); - LOG("%s.getPropertyDescriptor(%s)", ReceiverObj(objId), id); + LOG("%s.getPropertyDescriptor(%s)", ReceiverObj(objId), Identifier(idVar)); - RootedId internedId(cx); - if (!convertGeckoStringToId(cx, id, &internedId)) + RootedId id(cx); + if (!fromJSIDVariant(cx, idVar, &id)) return fail(cx, rs); Rooted desc(cx); - if (!JS_GetPropertyDescriptorById(cx, obj, internedId, &desc)) + if (!JS_GetPropertyDescriptorById(cx, obj, id, &desc)) return fail(cx, rs); if (!desc.object()) @@ -121,8 +121,8 @@ WrapperAnswer::AnswerGetPropertyDescriptor(const ObjectId &objId, const nsString } bool -WrapperAnswer::AnswerGetOwnPropertyDescriptor(const ObjectId &objId, const nsString &id, - ReturnStatus *rs, PPropertyDescriptor *out) +WrapperAnswer::AnswerGetOwnPropertyDescriptor(const ObjectId &objId, const JSIDVariant &idVar, + ReturnStatus *rs, PPropertyDescriptor *out) { AutoSafeJSContext cx; JSAutoRequest request(cx); @@ -135,14 +135,14 @@ WrapperAnswer::AnswerGetOwnPropertyDescriptor(const ObjectId &objId, const nsStr JSAutoCompartment comp(cx, obj); - LOG("%s.getOwnPropertyDescriptor(%s)", ReceiverObj(objId), id); + LOG("%s.getOwnPropertyDescriptor(%s)", ReceiverObj(objId), Identifier(idVar)); - RootedId internedId(cx); - if (!convertGeckoStringToId(cx, id, &internedId)) + RootedId id(cx); + if (!fromJSIDVariant(cx, idVar, &id)) return fail(cx, rs); Rooted desc(cx); - if (!JS_GetPropertyDescriptorById(cx, obj, internedId, &desc)) + if (!JS_GetPropertyDescriptorById(cx, obj, id, &desc)) return fail(cx, rs); if (desc.object() != obj) @@ -155,8 +155,8 @@ WrapperAnswer::AnswerGetOwnPropertyDescriptor(const ObjectId &objId, const nsStr } bool -WrapperAnswer::AnswerDefineProperty(const ObjectId &objId, const nsString &id, - const PPropertyDescriptor &descriptor, ReturnStatus *rs) +WrapperAnswer::AnswerDefineProperty(const ObjectId &objId, const JSIDVariant &idVar, + const PPropertyDescriptor &descriptor, ReturnStatus *rs) { AutoSafeJSContext cx; JSAutoRequest request(cx); @@ -167,23 +167,23 @@ WrapperAnswer::AnswerDefineProperty(const ObjectId &objId, const nsString &id, JSAutoCompartment comp(cx, obj); - LOG("define %s[%s]", ReceiverObj(objId), id); + LOG("define %s[%s]", ReceiverObj(objId), Identifier(idVar)); - RootedId internedId(cx); - if (!convertGeckoStringToId(cx, id, &internedId)) + RootedId id(cx); + if (!fromJSIDVariant(cx, idVar, &id)) return fail(cx, rs); Rooted desc(cx); if (!toDescriptor(cx, descriptor, &desc)) return fail(cx, rs); - if (!js::CheckDefineProperty(cx, obj, internedId, desc.value(), desc.attributes(), + if (!js::CheckDefineProperty(cx, obj, id, desc.value(), desc.attributes(), desc.getter(), desc.setter())) { return fail(cx, rs); } - if (!JS_DefinePropertyById(cx, obj, internedId, desc.value(), desc.attributes(), + if (!JS_DefinePropertyById(cx, obj, id, desc.value(), desc.attributes(), desc.getter(), desc.setter())) { return fail(cx, rs); @@ -193,8 +193,8 @@ WrapperAnswer::AnswerDefineProperty(const ObjectId &objId, const nsString &id, } bool -WrapperAnswer::AnswerDelete(const ObjectId &objId, const nsString &id, ReturnStatus *rs, - bool *success) +WrapperAnswer::AnswerDelete(const ObjectId &objId, const JSIDVariant &idVar, ReturnStatus *rs, + bool *success) { AutoSafeJSContext cx; JSAutoRequest request(cx); @@ -207,20 +207,20 @@ WrapperAnswer::AnswerDelete(const ObjectId &objId, const nsString &id, ReturnSta JSAutoCompartment comp(cx, obj); - LOG("delete %s[%s]", ReceiverObj(objId), id); + LOG("delete %s[%s]", ReceiverObj(objId), Identifier(idVar)); - RootedId internedId(cx); - if (!convertGeckoStringToId(cx, id, &internedId)) + RootedId id(cx); + if (!fromJSIDVariant(cx, idVar, &id)) return fail(cx, rs); - if (!JS_DeletePropertyById2(cx, obj, internedId, success)) + if (!JS_DeletePropertyById2(cx, obj, id, success)) return fail(cx, rs); return ok(rs); } bool -WrapperAnswer::AnswerHas(const ObjectId &objId, const nsString &id, ReturnStatus *rs, bool *bp) +WrapperAnswer::AnswerHas(const ObjectId &objId, const JSIDVariant &idVar, ReturnStatus *rs, bool *bp) { AutoSafeJSContext cx; JSAutoRequest request(cx); @@ -233,14 +233,14 @@ WrapperAnswer::AnswerHas(const ObjectId &objId, const nsString &id, ReturnStatus JSAutoCompartment comp(cx, obj); - LOG("%s.has(%s)", ReceiverObj(objId), id); + LOG("%s.has(%s)", ReceiverObj(objId), Identifier(idVar)); - RootedId internedId(cx); - if (!convertGeckoStringToId(cx, id, &internedId)) + RootedId id(cx); + if (!fromJSIDVariant(cx, idVar, &id)) return fail(cx, rs); bool found; - if (!JS_HasPropertyById(cx, obj, internedId, &found)) + if (!JS_HasPropertyById(cx, obj, id, &found)) return fail(cx, rs); *bp = !!found; @@ -248,7 +248,8 @@ WrapperAnswer::AnswerHas(const ObjectId &objId, const nsString &id, ReturnStatus } bool -WrapperAnswer::AnswerHasOwn(const ObjectId &objId, const nsString &id, ReturnStatus *rs, bool *bp) +WrapperAnswer::AnswerHasOwn(const ObjectId &objId, const JSIDVariant &idVar, ReturnStatus *rs, + bool *bp) { AutoSafeJSContext cx; JSAutoRequest request(cx); @@ -261,14 +262,14 @@ WrapperAnswer::AnswerHasOwn(const ObjectId &objId, const nsString &id, ReturnSta JSAutoCompartment comp(cx, obj); - LOG("%s.hasOwn(%s)", ReceiverObj(objId), id); + LOG("%s.hasOwn(%s)", ReceiverObj(objId), Identifier(idVar)); - RootedId internedId(cx); - if (!convertGeckoStringToId(cx, id, &internedId)) + RootedId id(cx); + if (!fromJSIDVariant(cx, idVar, &id)) return fail(cx, rs); Rooted desc(cx); - if (!JS_GetPropertyDescriptorById(cx, obj, internedId, &desc)) + if (!JS_GetPropertyDescriptorById(cx, obj, id, &desc)) return fail(cx, rs); *bp = (desc.object() == obj); @@ -276,8 +277,8 @@ WrapperAnswer::AnswerHasOwn(const ObjectId &objId, const nsString &id, ReturnSta } bool -WrapperAnswer::AnswerGet(const ObjectId &objId, const ObjectVariant &receiverVar, const nsString &id, - ReturnStatus *rs, JSVariant *result) +WrapperAnswer::AnswerGet(const ObjectId &objId, const ObjectVariant &receiverVar, + const JSIDVariant &idVar, ReturnStatus *rs, JSVariant *result) { AutoSafeJSContext cx; JSAutoRequest request(cx); @@ -296,26 +297,26 @@ WrapperAnswer::AnswerGet(const ObjectId &objId, const ObjectVariant &receiverVar if (!receiver) return fail(cx, rs); - RootedId internedId(cx); - if (!convertGeckoStringToId(cx, id, &internedId)) + RootedId id(cx); + if (!fromJSIDVariant(cx, idVar, &id)) return fail(cx, rs); JS::RootedValue val(cx); - if (!JS_ForwardGetPropertyTo(cx, obj, internedId, receiver, &val)) + if (!JS_ForwardGetPropertyTo(cx, obj, id, receiver, &val)) return fail(cx, rs); if (!toVariant(cx, val, result)) return fail(cx, rs); - LOG("get %s.%s = %s", ReceiverObj(objId), id, OutVariant(*result)); + LOG("get %s.%s = %s", ReceiverObj(objId), Identifier(idVar), OutVariant(*result)); return ok(rs); } bool -WrapperAnswer::AnswerSet(const ObjectId &objId, const ObjectVariant &receiverVar, const nsString &id, - const bool &strict, const JSVariant &value, ReturnStatus *rs, - JSVariant *result) +WrapperAnswer::AnswerSet(const ObjectId &objId, const ObjectVariant &receiverVar, + const JSIDVariant &idVar, const bool &strict, const JSVariant &value, + ReturnStatus *rs, JSVariant *result) { AutoSafeJSContext cx; JSAutoRequest request(cx); @@ -334,10 +335,10 @@ WrapperAnswer::AnswerSet(const ObjectId &objId, const ObjectVariant &receiverVar if (!receiver) return fail(cx, rs); - LOG("set %s[%s] = %s", ReceiverObj(objId), id, InVariant(value)); + LOG("set %s[%s] = %s", ReceiverObj(objId), Identifier(idVar), InVariant(value)); - RootedId internedId(cx); - if (!convertGeckoStringToId(cx, id, &internedId)) + RootedId id(cx); + if (!fromJSIDVariant(cx, idVar, &id)) return fail(cx, rs); MOZ_ASSERT(obj == receiver); @@ -346,7 +347,7 @@ WrapperAnswer::AnswerSet(const ObjectId &objId, const ObjectVariant &receiverVar if (!fromVariant(cx, value, &val)) return fail(cx, rs); - if (!JS_SetPropertyById(cx, obj, internedId, val)) + if (!JS_SetPropertyById(cx, obj, id, val)) return fail(cx, rs); if (!toVariant(cx, val, result)) @@ -512,7 +513,7 @@ WrapperAnswer::AnswerHasInstance(const ObjectId &objId, const JSVariant &vVar, R bool WrapperAnswer::AnswerObjectClassIs(const ObjectId &objId, const uint32_t &classValue, - bool *result) + bool *result) { AutoSafeJSContext cx; JSAutoRequest request(cx); @@ -579,7 +580,7 @@ WrapperAnswer::AnswerRegExpToShared(const ObjectId &objId, ReturnStatus *rs, bool WrapperAnswer::AnswerGetPropertyNames(const ObjectId &objId, const uint32_t &flags, - ReturnStatus *rs, nsTArray *names) + ReturnStatus *rs, nsTArray *names) { AutoSafeJSContext cx; JSAutoRequest request(cx); @@ -609,7 +610,7 @@ WrapperAnswer::AnswerGetPropertyNames(const ObjectId &objId, const uint32_t &fla bool WrapperAnswer::AnswerInstanceOf(const ObjectId &objId, const JSIID &iid, ReturnStatus *rs, - bool *instanceof) + bool *instanceof) { AutoSafeJSContext cx; JSAutoRequest request(cx); @@ -636,8 +637,7 @@ WrapperAnswer::AnswerInstanceOf(const ObjectId &objId, const JSIID &iid, ReturnS bool WrapperAnswer::AnswerDOMInstanceOf(const ObjectId &objId, const int &prototypeID, - const int &depth, - ReturnStatus *rs, bool *instanceof) + const int &depth, ReturnStatus *rs, bool *instanceof) { AutoSafeJSContext cx; JSAutoRequest request(cx); diff --git a/js/ipc/WrapperAnswer.h b/js/ipc/WrapperAnswer.h index 9bc998c078d6..330c5d662d17 100644 --- a/js/ipc/WrapperAnswer.h +++ b/js/ipc/WrapperAnswer.h @@ -19,28 +19,28 @@ class WrapperAnswer : public virtual JavaScriptShared explicit WrapperAnswer(JSRuntime *rt) : JavaScriptShared(rt) {} bool AnswerPreventExtensions(const ObjectId &objId, ReturnStatus *rs); - bool AnswerGetPropertyDescriptor(const ObjectId &objId, const nsString &id, + bool AnswerGetPropertyDescriptor(const ObjectId &objId, const JSIDVariant &id, ReturnStatus *rs, PPropertyDescriptor *out); bool AnswerGetOwnPropertyDescriptor(const ObjectId &objId, - const nsString &id, + const JSIDVariant &id, ReturnStatus *rs, PPropertyDescriptor *out); - bool AnswerDefineProperty(const ObjectId &objId, const nsString &id, + bool AnswerDefineProperty(const ObjectId &objId, const JSIDVariant &id, const PPropertyDescriptor &flags, ReturnStatus *rs); - bool AnswerDelete(const ObjectId &objId, const nsString &id, + bool AnswerDelete(const ObjectId &objId, const JSIDVariant &id, ReturnStatus *rs, bool *success); - bool AnswerHas(const ObjectId &objId, const nsString &id, + bool AnswerHas(const ObjectId &objId, const JSIDVariant &id, ReturnStatus *rs, bool *bp); - bool AnswerHasOwn(const ObjectId &objId, const nsString &id, + bool AnswerHasOwn(const ObjectId &objId, const JSIDVariant &id, ReturnStatus *rs, bool *bp); bool AnswerGet(const ObjectId &objId, const ObjectVariant &receiverVar, - const nsString &id, + const JSIDVariant &id, ReturnStatus *rs, JSVariant *result); bool AnswerSet(const ObjectId &objId, const ObjectVariant &receiverVar, - const nsString &id, const bool &strict, + const JSIDVariant &id, const bool &strict, const JSVariant &value, ReturnStatus *rs, JSVariant *result); bool AnswerIsExtensible(const ObjectId &objId, ReturnStatus *rs, diff --git a/js/ipc/WrapperOwner.cpp b/js/ipc/WrapperOwner.cpp index 906f7a55a9da..33e48cc89ea0 100644 --- a/js/ipc/WrapperOwner.cpp +++ b/js/ipc/WrapperOwner.cpp @@ -145,13 +145,13 @@ WrapperOwner::getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId { ObjectId objId = idOf(proxy); - nsString idstr; - if (!convertIdToGeckoString(cx, id, &idstr)) + JSIDVariant idVar; + if (!toJSIDVariant(cx, id, &idVar)) return false; ReturnStatus status; PPropertyDescriptor result; - if (!CallGetPropertyDescriptor(objId, idstr, &status, &result)) + if (!CallGetPropertyDescriptor(objId, idVar, &status, &result)) return ipcfail(cx); LOG_STACK(); @@ -175,13 +175,13 @@ WrapperOwner::getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, Handle { ObjectId objId = idOf(proxy); - nsString idstr; - if (!convertIdToGeckoString(cx, id, &idstr)) + JSIDVariant idVar; + if (!toJSIDVariant(cx, id, &idVar)) return false; ReturnStatus status; PPropertyDescriptor result; - if (!CallGetOwnPropertyDescriptor(objId, idstr, &status, &result)) + if (!CallGetOwnPropertyDescriptor(objId, idVar, &status, &result)) return ipcfail(cx); LOG_STACK(); @@ -205,8 +205,8 @@ WrapperOwner::defineProperty(JSContext *cx, HandleObject proxy, HandleId id, { ObjectId objId = idOf(proxy); - nsString idstr; - if (!convertIdToGeckoString(cx, id, &idstr)) + JSIDVariant idVar; + if (!toJSIDVariant(cx, id, &idVar)) return false; PPropertyDescriptor descriptor; @@ -214,7 +214,7 @@ WrapperOwner::defineProperty(JSContext *cx, HandleObject proxy, HandleId id, return false; ReturnStatus status; - if (!CallDefineProperty(objId, idstr, descriptor, &status)) + if (!CallDefineProperty(objId, idVar, descriptor, &status)) return ipcfail(cx); LOG_STACK(); @@ -246,12 +246,12 @@ WrapperOwner::delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) { ObjectId objId = idOf(proxy); - nsString idstr; - if (!convertIdToGeckoString(cx, id, &idstr)) + JSIDVariant idVar; + if (!toJSIDVariant(cx, id, &idVar)) return false; ReturnStatus status; - if (!CallDelete(objId, idstr, &status, bp)) + if (!CallDelete(objId, idVar, &status, bp)) return ipcfail(cx); LOG_STACK(); @@ -282,12 +282,12 @@ WrapperOwner::has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) { ObjectId objId = idOf(proxy); - nsString idstr; - if (!convertIdToGeckoString(cx, id, &idstr)) + JSIDVariant idVar; + if (!toJSIDVariant(cx, id, &idVar)) return false; ReturnStatus status; - if (!CallHas(objId, idstr, &status, bp)) + if (!CallHas(objId, idVar, &status, bp)) return ipcfail(cx); LOG_STACK(); @@ -306,12 +306,12 @@ WrapperOwner::hasOwn(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) { ObjectId objId = idOf(proxy); - nsString idstr; - if (!convertIdToGeckoString(cx, id, &idstr)) + JSIDVariant idVar; + if (!toJSIDVariant(cx, id, &idVar)) return false; ReturnStatus status; - if (!CallHasOwn(objId, idstr, &status, bp)) + if (!CallHasOwn(objId, idVar, &status, bp)) return ipcfail(cx); LOG_STACK(); @@ -382,7 +382,7 @@ WrapperOwner::toString(JSContext *cx, HandleObject cpow, JS::CallArgs &args) bool WrapperOwner::get(JSContext *cx, HandleObject proxy, HandleObject receiver, - HandleId id, MutableHandleValue vp) + HandleId id, MutableHandleValue vp) { ObjectId objId = idOf(proxy); @@ -390,13 +390,13 @@ WrapperOwner::get(JSContext *cx, HandleObject proxy, HandleObject receiver, if (!toObjectVariant(cx, receiver, &receiverVar)) return false; - nsString idstr; - if (!convertIdToGeckoString(cx, id, &idstr)) + JSIDVariant idVar; + if (!toJSIDVariant(cx, id, &idVar)) return false; JSVariant val; ReturnStatus status; - if (!CallGet(objId, receiverVar, idstr, &status, &val)) + if (!CallGet(objId, receiverVar, idVar, &status, &val)) return ipcfail(cx); LOG_STACK(); @@ -407,7 +407,8 @@ WrapperOwner::get(JSContext *cx, HandleObject proxy, HandleObject receiver, if (!fromVariant(cx, val, vp)) return false; - if (idstr.EqualsLiteral("toString")) { + if (idVar.type() == JSIDVariant::TnsString && + idVar.get_nsString().EqualsLiteral("toString")) { RootedFunction toString(cx, JS_NewFunction(cx, CPOWToString, 0, 0, proxy, "toString")); if (!toString) return false; @@ -432,7 +433,7 @@ CPOWProxyHandler::set(JSContext *cx, JS::HandleObject proxy, JS::HandleObject re bool WrapperOwner::set(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver, - JS::HandleId id, bool strict, JS::MutableHandleValue vp) + JS::HandleId id, bool strict, JS::MutableHandleValue vp) { ObjectId objId = idOf(proxy); @@ -440,8 +441,8 @@ WrapperOwner::set(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiv if (!toObjectVariant(cx, receiver, &receiverVar)) return false; - nsString idstr; - if (!convertIdToGeckoString(cx, id, &idstr)) + JSIDVariant idVar; + if (!toJSIDVariant(cx, id, &idVar)) return false; JSVariant val; @@ -450,7 +451,7 @@ WrapperOwner::set(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiv ReturnStatus status; JSVariant result; - if (!CallSet(objId, receiverVar, idstr, strict, val, &status, &result)) + if (!CallSet(objId, receiverVar, idVar, strict, val, &status, &result)) return ipcfail(cx); LOG_STACK(); diff --git a/js/ipc/WrapperOwner.h b/js/ipc/WrapperOwner.h index 98e55355d02c..5e6060f7e63f 100644 --- a/js/ipc/WrapperOwner.h +++ b/js/ipc/WrapperOwner.h @@ -108,28 +108,28 @@ class WrapperOwner : public virtual JavaScriptShared public: virtual bool SendDropObject(const ObjectId &objId) = 0; virtual bool CallPreventExtensions(const ObjectId &objId, ReturnStatus *rs) = 0; - virtual bool CallGetPropertyDescriptor(const ObjectId &objId, const nsString &id, + virtual bool CallGetPropertyDescriptor(const ObjectId &objId, const JSIDVariant &id, ReturnStatus *rs, PPropertyDescriptor *out) = 0; virtual bool CallGetOwnPropertyDescriptor(const ObjectId &objId, - const nsString &id, + const JSIDVariant &id, ReturnStatus *rs, PPropertyDescriptor *out) = 0; - virtual bool CallDefineProperty(const ObjectId &objId, const nsString &id, + virtual bool CallDefineProperty(const ObjectId &objId, const JSIDVariant &id, const PPropertyDescriptor &flags, ReturnStatus *rs) = 0; - virtual bool CallDelete(const ObjectId &objId, const nsString &id, + virtual bool CallDelete(const ObjectId &objId, const JSIDVariant &id, ReturnStatus *rs, bool *success) = 0; - virtual bool CallHas(const ObjectId &objId, const nsString &id, + virtual bool CallHas(const ObjectId &objId, const JSIDVariant &id, ReturnStatus *rs, bool *bp) = 0; - virtual bool CallHasOwn(const ObjectId &objId, const nsString &id, + virtual bool CallHasOwn(const ObjectId &objId, const JSIDVariant &id, ReturnStatus *rs, bool *bp) = 0; virtual bool CallGet(const ObjectId &objId, const ObjectVariant &receiverVar, - const nsString &id, + const JSIDVariant &id, ReturnStatus *rs, JSVariant *result) = 0; virtual bool CallSet(const ObjectId &objId, const ObjectVariant &receiverVar, - const nsString &id, const bool &strict, + const JSIDVariant &id, const bool &strict, const JSVariant &value, ReturnStatus *rs, JSVariant *result) = 0; virtual bool CallIsExtensible(const ObjectId &objId, ReturnStatus *rs, From 07191c41f8c2eff625235bd6e6bf200d6a9e26fd Mon Sep 17 00:00:00 2001 From: Tom Schuster Date: Tue, 7 Oct 2014 11:29:03 +0200 Subject: [PATCH 11/84] Bug 1071177 - Add support for well-known and registered symbols as CPOW jsids. r=billm,jorendorff --- js/ipc/JavaScriptLogging.h | 4 +++ js/ipc/JavaScriptShared.cpp | 64 +++++++++++++++++++++++++++++++++++- js/ipc/JavaScriptShared.h | 3 ++ js/ipc/JavaScriptTypes.ipdlh | 17 ++++++++++ 4 files changed, 87 insertions(+), 1 deletion(-) diff --git a/js/ipc/JavaScriptLogging.h b/js/ipc/JavaScriptLogging.h index fe34812d3db8..79b66f71eae0 100644 --- a/js/ipc/JavaScriptLogging.h +++ b/js/ipc/JavaScriptLogging.h @@ -192,6 +192,10 @@ class Logging void format(const Identifier &id, nsCString &out) { switch (id.variant.type()) { + case JSIDVariant::TSymbolVariant: { + out = ""; + break; + } case JSIDVariant::TnsString: { nsAutoCString tmp; format(id.variant.get_nsString(), tmp); diff --git a/js/ipc/JavaScriptShared.cpp b/js/ipc/JavaScriptShared.cpp index 41bf4e436362..39cfb50c055d 100644 --- a/js/ipc/JavaScriptShared.cpp +++ b/js/ipc/JavaScriptShared.cpp @@ -367,7 +367,14 @@ JavaScriptShared::toJSIDVariant(JSContext *cx, HandleId from, JSIDVariant *to) *to = JSID_TO_INT(from); return true; } - MOZ_CRASH("NYI"); + if (JSID_IS_SYMBOL(from)) { + SymbolVariant symVar; + if (!toSymbolVariant(cx, JSID_TO_SYMBOL(from), &symVar)) + return false; + *to = symVar; + return true; + } + MOZ_ASSERT(false); return false; } @@ -375,6 +382,14 @@ bool JavaScriptShared::fromJSIDVariant(JSContext *cx, const JSIDVariant &from, MutableHandleId to) { switch (from.type()) { + case JSIDVariant::TSymbolVariant: { + Symbol *sym = fromSymbolVariant(cx, from.get_SymbolVariant()); + if (!sym) + return false; + to.set(SYMBOL_TO_JSID(sym)); + return true; + } + case JSIDVariant::TnsString: return convertGeckoStringToId(cx, from.get_nsString(), to); @@ -387,6 +402,53 @@ JavaScriptShared::fromJSIDVariant(JSContext *cx, const JSIDVariant &from, Mutabl } } +bool +JavaScriptShared::toSymbolVariant(JSContext *cx, JS::Symbol *symArg, SymbolVariant *symVarp) +{ + RootedSymbol sym(cx, symArg); + MOZ_ASSERT(sym); + + SymbolCode code = GetSymbolCode(sym); + if (static_cast(code) < WellKnownSymbolLimit) { + *symVarp = WellKnownSymbol(static_cast(code)); + return true; + } + if (code == SymbolCode::InSymbolRegistry) { + nsAutoJSString autoStr; + if (!autoStr.init(cx, GetSymbolDescription(sym))) + return false; + *symVarp = RegisteredSymbol(autoStr); + return true; + } + MOZ_CRASH("unique symbols not yet implemented"); + return false; +} + +JS::Symbol * +JavaScriptShared::fromSymbolVariant(JSContext *cx, SymbolVariant symVar) +{ + switch (symVar.type()) { + case SymbolVariant::TWellKnownSymbol: { + uint32_t which = symVar.get_WellKnownSymbol().which(); + if (which < WellKnownSymbolLimit) + return GetWellKnownSymbol(cx, static_cast(which)); + MOZ_ASSERT(false, "bad child data"); + return nullptr; + } + + case SymbolVariant::TRegisteredSymbol: { + nsString key = symVar.get_RegisteredSymbol().key(); + RootedString str(cx, JS_NewUCStringCopyN(cx, key.get(), key.Length())); + if (!str) + return nullptr; + return GetSymbolFor(cx, str); + } + + default: + return nullptr; + } +} + /* static */ void JavaScriptShared::ConvertID(const nsID &from, JSIID *to) { diff --git a/js/ipc/JavaScriptShared.h b/js/ipc/JavaScriptShared.h index ca8674478d34..7b182cd026b1 100644 --- a/js/ipc/JavaScriptShared.h +++ b/js/ipc/JavaScriptShared.h @@ -161,6 +161,9 @@ class JavaScriptShared bool toJSIDVariant(JSContext *cx, JS::HandleId from, JSIDVariant *to); bool fromJSIDVariant(JSContext *cx, const JSIDVariant &from, JS::MutableHandleId to); + bool toSymbolVariant(JSContext *cx, JS::Symbol *sym, SymbolVariant *symVarp); + JS::Symbol *fromSymbolVariant(JSContext *cx, SymbolVariant symVar); + bool fromDescriptor(JSContext *cx, JS::Handle desc, PPropertyDescriptor *out); bool toDescriptor(JSContext *cx, const PPropertyDescriptor &in, diff --git a/js/ipc/JavaScriptTypes.ipdlh b/js/ipc/JavaScriptTypes.ipdlh index cea0280a25eb..e2e8722a52c7 100644 --- a/js/ipc/JavaScriptTypes.ipdlh +++ b/js/ipc/JavaScriptTypes.ipdlh @@ -43,6 +43,22 @@ union ObjectVariant RemoteObject; }; +struct WellKnownSymbol +{ + uint32_t which; +}; + +struct RegisteredSymbol +{ + nsString key; +}; + +union SymbolVariant +{ + WellKnownSymbol; + RegisteredSymbol; +}; + struct UndefinedVariant {}; struct NullVariant {}; @@ -59,6 +75,7 @@ union JSVariant union JSIDVariant { + SymbolVariant; nsString; int32_t; }; From 0bf1b2a134d9cc61f9cb21f330f78d15110a4857 Mon Sep 17 00:00:00 2001 From: Tom Schuster Date: Tue, 7 Oct 2014 11:29:03 +0200 Subject: [PATCH 12/84] Bug 1071177 - Add support for symbols as a value type. r=billm --- js/ipc/JavaScriptLogging.h | 4 ++++ js/ipc/JavaScriptShared.cpp | 20 ++++++++++++++++++++ js/ipc/JavaScriptTypes.ipdlh | 1 + 3 files changed, 25 insertions(+) diff --git a/js/ipc/JavaScriptLogging.h b/js/ipc/JavaScriptLogging.h index 79b66f71eae0..1ba2036b21b8 100644 --- a/js/ipc/JavaScriptLogging.h +++ b/js/ipc/JavaScriptLogging.h @@ -171,6 +171,10 @@ class Logging formatObject(incoming, false, ObjectId::deserialize(ovar.get_RemoteObject().serializedId()), out); break; } + case JSVariant::TSymbolVariant: { + out = ""; + break; + } case JSVariant::Tdouble: { out = nsPrintfCString("%.0f", value.get_double()); break; diff --git a/js/ipc/JavaScriptShared.cpp b/js/ipc/JavaScriptShared.cpp index 39cfb50c055d..cff04a719612 100644 --- a/js/ipc/JavaScriptShared.cpp +++ b/js/ipc/JavaScriptShared.cpp @@ -267,6 +267,17 @@ JavaScriptShared::toVariant(JSContext *cx, JS::HandleValue from, JSVariant *to) return true; } + case JSTYPE_SYMBOL: + { + RootedSymbol sym(cx, from.toSymbol()); + + SymbolVariant symVar; + if (!toSymbolVariant(cx, sym, &symVar)) + return false; + *to = symVar; + return true; + } + case JSTYPE_STRING: { nsAutoJSString autoStr; @@ -314,6 +325,15 @@ JavaScriptShared::fromVariant(JSContext *cx, const JSVariant &from, MutableHandl return true; } + case JSVariant::TSymbolVariant: + { + Symbol *sym = fromSymbolVariant(cx, from.get_SymbolVariant()); + if (!sym) + return false; + to.setSymbol(sym); + return true; + } + case JSVariant::Tdouble: to.set(JS_NumberValue(from.get_double())); return true; diff --git a/js/ipc/JavaScriptTypes.ipdlh b/js/ipc/JavaScriptTypes.ipdlh index e2e8722a52c7..53b2cf65a24c 100644 --- a/js/ipc/JavaScriptTypes.ipdlh +++ b/js/ipc/JavaScriptTypes.ipdlh @@ -67,6 +67,7 @@ union JSVariant UndefinedVariant; NullVariant; ObjectVariant; + SymbolVariant; nsString; /* StringValue(x) */ double; /* NumberValue(x) */ bool; /* BooleanValue(x) */ From 156c81f370c846a1618ebfe84d69df66d6c409e3 Mon Sep 17 00:00:00 2001 From: Tom Schuster Date: Tue, 7 Oct 2014 11:29:03 +0200 Subject: [PATCH 13/84] Bug 1071177 - Test --- content/base/test/chrome/cpows_child.js | 15 +++++++++++++++ content/base/test/chrome/cpows_parent.xul | 8 ++++++++ 2 files changed, 23 insertions(+) diff --git a/content/base/test/chrome/cpows_child.js b/content/base/test/chrome/cpows_child.js index 3617a69410ea..8dc79bd497a2 100644 --- a/content/base/test/chrome/cpows_child.js +++ b/content/base/test/chrome/cpows_child.js @@ -115,6 +115,21 @@ function xray_test() sendSyncMessage("cpows:xray_test", {}, {element: element}); } +function symbol_test() +{ + let iterator = Symbol.iterator; + let named = Symbol.for("cpow-test"); + // let unique = Symbol(); + + let object = { + [iterator]: iterator, + [named]: named, + // [unique]: unique, + // "unique": unique + }; + sendSyncMessage("cpows:symbol_test", {}, object); +} + // Parent->Child references should go X->parent.privilegedJunkScope->child.privilegedJunkScope->Y // Child->Parent references should go X->child.privilegedJunkScope->parent.unprivilegedJunkScope->Y function compartment_test() diff --git a/content/base/test/chrome/cpows_parent.xul b/content/base/test/chrome/cpows_parent.xul index 6c11ca5721aa..74c5437c297b 100644 --- a/content/base/test/chrome/cpows_parent.xul +++ b/content/base/test/chrome/cpows_parent.xul @@ -205,6 +205,13 @@ is(element.foo, undefined, "DOM element does not expose content properties"); } + function recvSymbolTest(message) { + let object = message.objects; + is(object[Symbol.iterator], Symbol.iterator, "Should use Symbol.iterator"); + is(Symbol.keyFor(object[Symbol.for("cpow-test")]), "cpow-test", "Symbols aren't registered correctly"); + // is(object.unique, object[object.unique], "Unique symbols as ids and values don't seem to work"); + } + let systemGlobal = this; function recvCompartmentTest(message) { let getUnprivilegedObject = message.objects.getUnprivilegedObject; @@ -300,6 +307,7 @@ mm.addMessageListener("cpows:dom_test", recvDomTest); mm.addMessageListener("cpows:dom_test_after_gc", recvDomTestAfterGC); mm.addMessageListener("cpows:xray_test", recvXrayTest); + mm.addMessageListener("cpows:symbol_test", recvSymbolTest); mm.addMessageListener("cpows:compartment_test", recvCompartmentTest); mm.addMessageListener("cpows:regexp_test", recvRegExpTest); mm.addMessageListener("cpows:lifetime_test_1", recvLifetimeTest1); From ea79d5919e2a39d482ae37466b8a89857637c1e6 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Tue, 7 Oct 2014 19:01:46 +0900 Subject: [PATCH 14/84] Bug 960871 part.1 Rename WidgetTextEvent::theText to WidgetTextEvent::mData r=smaug --- dom/base/CompositionStringSynthesizer.cpp | 2 +- dom/events/TextComposition.cpp | 12 ++++++------ dom/ipc/TabParent.cpp | 4 ++-- editor/libeditor/nsPlaintextEditor.cpp | 2 +- widget/TextEvents.h | 2 +- widget/android/nsWindow.cpp | 18 +++++++++--------- widget/cocoa/TextInputHandler.mm | 4 ++-- widget/gtk/nsGtkIMModule.cpp | 2 +- widget/gtk/nsWindow.cpp | 2 +- widget/nsGUIEventIPC.h | 4 ++-- widget/windows/nsIMM32Handler.cpp | 2 +- widget/windows/nsTextStore.cpp | 8 ++++---- widget/xpwidgets/PuppetWidget.cpp | 2 +- 13 files changed, 32 insertions(+), 32 deletions(-) diff --git a/dom/base/CompositionStringSynthesizer.cpp b/dom/base/CompositionStringSynthesizer.cpp index 728e45bfc5a4..0da6d20bbdb5 100644 --- a/dom/base/CompositionStringSynthesizer.cpp +++ b/dom/base/CompositionStringSynthesizer.cpp @@ -137,7 +137,7 @@ CompositionStringSynthesizer::DispatchEvent(bool* aDefaultPrevented) WidgetTextEvent textEvent(true, NS_TEXT_TEXT, widget); textEvent.time = PR_IntervalNow(); - textEvent.theText = mString; + textEvent.mData = mString; if (!mClauses->IsEmpty()) { textEvent.mRanges = mClauses; } diff --git a/dom/events/TextComposition.cpp b/dom/events/TextComposition.cpp index 5651f521c7b5..2ca2fcefda5b 100644 --- a/dom/events/TextComposition.cpp +++ b/dom/events/TextComposition.cpp @@ -67,7 +67,7 @@ TextComposition::MaybeDispatchCompositionUpdate(const WidgetTextEvent* aEvent) return false; } - if (mLastData == aEvent->theText) { + if (mLastData == aEvent->mData) { return true; } @@ -76,7 +76,7 @@ TextComposition::MaybeDispatchCompositionUpdate(const WidgetTextEvent* aEvent) aEvent->widget); compositionUpdate.time = aEvent->time; compositionUpdate.timeStamp = aEvent->timeStamp; - compositionUpdate.data = aEvent->theText; + compositionUpdate.data = aEvent->mData; compositionUpdate.mFlags.mIsSynthesizedForTests = aEvent->mFlags.mIsSynthesizedForTests; @@ -149,7 +149,7 @@ TextComposition::DispatchEvent(WidgetGUIEvent* aEvent, committingData = &aEvent->AsCompositionEvent()->data; break; case NS_TEXT_TEXT: - committingData = &aEvent->AsTextEvent()->theText; + committingData = &aEvent->AsTextEvent()->mData; break; default: NS_WARNING("Unexpected event comes during committing or " @@ -287,7 +287,7 @@ TextComposition::RequestToCommit(nsIWidget* aWidget, bool aDiscard) bool changingData = lastData != commitData; WidgetTextEvent textEvent(true, NS_TEXT_TEXT, widget); - textEvent.theText = commitData; + textEvent.mData = commitData; textEvent.mFlags.mIsSynthesizedForTests = true; MaybeDispatchCompositionUpdate(&textEvent); @@ -346,7 +346,7 @@ TextComposition::EditorWillHandleTextEvent(const WidgetTextEvent* aTextEvent) mRanges = aTextEvent->mRanges; mIsEditorHandlingEvent = true; - MOZ_ASSERT(mLastData == aTextEvent->theText, + MOZ_ASSERT(mLastData == aTextEvent->mData, "The text of a text event must be same as previous data attribute value " "of the latest compositionupdate event"); } @@ -455,7 +455,7 @@ TextComposition::CompositionEventDispatcher::Run() } case NS_TEXT_TEXT: { WidgetTextEvent textEvent(true, NS_TEXT_TEXT, widget); - textEvent.theText = mData; + textEvent.mData = mData; textEvent.mFlags.mIsSynthesizedForTests = mTextComposition->IsSynthesizedForTests(); IMEStateManager::DispatchCompositionEvent(mEventTarget, presContext, diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index 724fa612203e..b6bdfc37fe1d 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -1588,7 +1588,7 @@ TabParent::SendTextEvent(WidgetTextEvent& event) return false; } if (mIMECompositionEnding) { - mIMECompositionText = event.theText; + mIMECompositionText = event.mData; return true; } @@ -1598,7 +1598,7 @@ TabParent::SendTextEvent(WidgetTextEvent& event) mIMECompositionStart = std::min(mIMESelectionAnchor, mIMESelectionFocus); } mIMESelectionAnchor = mIMESelectionFocus = - mIMECompositionStart + event.theText.Length(); + mIMECompositionStart + event.mData.Length(); event.mSeqno = ++mIMESeqno; return PBrowserParent::SendTextEvent(event); diff --git a/editor/libeditor/nsPlaintextEditor.cpp b/editor/libeditor/nsPlaintextEditor.cpp index 97bbb1a9193d..62469f59d20b 100644 --- a/editor/libeditor/nsPlaintextEditor.cpp +++ b/editor/libeditor/nsPlaintextEditor.cpp @@ -879,7 +879,7 @@ nsPlaintextEditor::UpdateIMEComposition(nsIDOMEvent* aDOMTextEvent) { nsAutoPlaceHolderBatch batch(this, nsGkAtoms::IMETxnName); - rv = InsertText(widgetTextEvent->theText); + rv = InsertText(widgetTextEvent->mData); if (caretP) { caretP->SetSelection(selection); diff --git a/widget/TextEvents.h b/widget/TextEvents.h index 3bf14367e873..f80ca6811801 100644 --- a/widget/TextEvents.h +++ b/widget/TextEvents.h @@ -242,7 +242,7 @@ public: } // The composition string or the commit string. - nsString theText; + nsString mData; // Indicates whether the event signifies printable text. // XXX This is not a standard, and most platforms don't set this properly. // So, perhaps, we can get rid of this. diff --git a/widget/android/nsWindow.cpp b/widget/android/nsWindow.cpp index 7be17db0152f..bd32b5367e11 100644 --- a/widget/android/nsWindow.cpp +++ b/widget/android/nsWindow.cpp @@ -685,7 +685,7 @@ nsWindow::DispatchEvent(WidgetGUIEvent* aEvent) break; case NS_TEXT_TEXT: MOZ_ASSERT(mIMEComposing); - mIMEComposingText = aEvent->AsTextEvent()->theText; + mIMEComposingText = aEvent->AsTextEvent()->mData; break; } return status; @@ -1709,7 +1709,7 @@ nsWindow::RemoveIMEComposition() WidgetTextEvent textEvent(true, NS_TEXT_TEXT, this); InitEvent(textEvent, nullptr); - textEvent.theText = mIMEComposingText; + textEvent.mData = mIMEComposingText; DispatchEvent(&textEvent); WidgetCompositionEvent event(true, NS_COMPOSITION_END, this); @@ -1847,14 +1847,14 @@ nsWindow::OnIMEEvent(AndroidGeckoEvent *ae) { WidgetTextEvent event(true, NS_TEXT_TEXT, this); InitEvent(event, nullptr); - event.theText = ae->Characters(); + event.mData = ae->Characters(); if (ae->Action() == AndroidGeckoEvent::IME_COMPOSE_TEXT) { // Because we're leaving the composition open, we need to // include proper text ranges to make the editor happy. TextRange range; range.mStartOffset = 0; - range.mEndOffset = event.theText.Length(); + range.mEndOffset = event.mData.Length(); range.mRangeType = NS_TEXTRANGE_RAWINPUT; event.mRanges = new TextRangeArray(); event.mRanges->AppendElement(range); @@ -1986,7 +1986,7 @@ nsWindow::OnIMEEvent(AndroidGeckoEvent *ae) InitEvent(queryEvent, nullptr); DispatchEvent(&queryEvent); MOZ_ASSERT(queryEvent.mSucceeded && !queryEvent.mWasAsync); - event.theText = queryEvent.mReply.mString; + event.mData = queryEvent.mReply.mString; mIMEComposingStart = queryEvent.mReply.mOffset; } @@ -2001,14 +2001,14 @@ nsWindow::OnIMEEvent(AndroidGeckoEvent *ae) } else { // If the new composition matches the existing composition, // reuse the old composition. - event.theText = mIMEComposingText; + event.mData = mIMEComposingText; } #ifdef DEBUG_ANDROID_IME - const NS_ConvertUTF16toUTF8 theText8(event.theText); - const char* text = theText8.get(); + const NS_ConvertUTF16toUTF8 data(event.mData); + const char* text = data.get(); ALOGIME("IME: IME_SET_TEXT: text=\"%s\", length=%u, range=%u", - text, event.theText.Length(), event.mRanges->Length()); + text, event.mData.Length(), event.mRanges->Length()); #endif // DEBUG_ANDROID_IME DispatchEvent(&event); diff --git a/widget/cocoa/TextInputHandler.mm b/widget/cocoa/TextInputHandler.mm index bb7b295e2fac..009df5a3b376 100644 --- a/widget/cocoa/TextInputHandler.mm +++ b/widget/cocoa/TextInputHandler.mm @@ -2718,11 +2718,11 @@ IMEInputHandler::DispatchTextEvent(const nsString& aText, WidgetTextEvent textEvent(true, NS_TEXT_TEXT, mWidget); textEvent.time = PR_IntervalNow(); - textEvent.theText = aText; + textEvent.mData = aText; if (!aDoCommit) { textEvent.mRanges = CreateTextRangeArray(aAttrString, aSelectedRange); } - mLastDispatchedCompositionString = textEvent.theText; + mLastDispatchedCompositionString = textEvent.mData; return DispatchEvent(textEvent); } diff --git a/widget/gtk/nsGtkIMModule.cpp b/widget/gtk/nsGtkIMModule.cpp index 3334e9380f3e..d50eb0d7efb6 100644 --- a/widget/gtk/nsGtkIMModule.cpp +++ b/widget/gtk/nsGtkIMModule.cpp @@ -1111,7 +1111,7 @@ nsGtkIMModule::DispatchTextEvent(const nsAString &aCompositionString, uint32_t targetOffset = mCompositionStart; - textEvent.theText = mDispatchedCompositionString = aCompositionString; + textEvent.mData = mDispatchedCompositionString = aCompositionString; if (!aIsCommit) { // NOTE: SetTextRangeList() assumes that mDispatchedCompositionString diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp index 96a6c063ba12..9c978c6d83b2 100644 --- a/widget/gtk/nsWindow.cpp +++ b/widget/gtk/nsWindow.cpp @@ -3050,7 +3050,7 @@ nsWindow::OnKeyPressEvent(GdkEventKey *aEvent) textString[0] = H_SURROGATE(event.charCode); textString[1] = L_SURROGATE(event.charCode); textString[2] = 0; - textEvent.theText = textString; + textEvent.mData = textString; textEvent.time = event.time; DispatchEvent(&textEvent, status); } diff --git a/widget/nsGUIEventIPC.h b/widget/nsGUIEventIPC.h index 3231a38ff0dd..7311cc0de6cf 100644 --- a/widget/nsGUIEventIPC.h +++ b/widget/nsGUIEventIPC.h @@ -450,7 +450,7 @@ struct ParamTraits { WriteParam(aMsg, static_cast(aParam)); WriteParam(aMsg, aParam.mSeqno); - WriteParam(aMsg, aParam.theText); + WriteParam(aMsg, aParam.mData); WriteParam(aMsg, aParam.isChar); bool hasRanges = !!aParam.mRanges; WriteParam(aMsg, hasRanges); @@ -465,7 +465,7 @@ struct ParamTraits if (!ReadParam(aMsg, aIter, static_cast(aResult)) || !ReadParam(aMsg, aIter, &aResult->mSeqno) || - !ReadParam(aMsg, aIter, &aResult->theText) || + !ReadParam(aMsg, aIter, &aResult->mData) || !ReadParam(aMsg, aIter, &aResult->isChar) || !ReadParam(aMsg, aIter, &hasRanges)) { return false; diff --git a/widget/windows/nsIMM32Handler.cpp b/widget/windows/nsIMM32Handler.cpp index ca4b8001262a..8c6b094062c3 100644 --- a/widget/windows/nsIMM32Handler.cpp +++ b/widget/windows/nsIMM32Handler.cpp @@ -1598,7 +1598,7 @@ nsIMM32Handler::DispatchTextEvent(nsWindow* aWindow, event.mRanges = CreateTextRangeArray(); } - event.theText = mLastDispatchedCompositionString = mCompositionString; + event.mData = mLastDispatchedCompositionString = mCompositionString; aWindow->DispatchWindowEvent(&event); diff --git a/widget/windows/nsTextStore.cpp b/widget/windows/nsTextStore.cpp index 7edf0e34fec3..7747386100a2 100644 --- a/widget/windows/nsTextStore.cpp +++ b/widget/windows/nsTextStore.cpp @@ -1652,11 +1652,11 @@ nsTextStore::FlushPendingActions() "dispatching text event...", this)); WidgetTextEvent textEvent(true, NS_TEXT_TEXT, mWidget); mWidget->InitEvent(textEvent); - textEvent.theText = action.mData; + textEvent.mData = action.mData; if (action.mRanges->IsEmpty()) { TextRange wholeRange; wholeRange.mStartOffset = 0; - wholeRange.mEndOffset = textEvent.theText.Length(); + wholeRange.mEndOffset = textEvent.mData.Length(); wholeRange.mRangeType = NS_TEXTRANGE_RAWINPUT; action.mRanges->AppendElement(wholeRange); } @@ -1679,7 +1679,7 @@ nsTextStore::FlushPendingActions() "dispatching text event...", this)); WidgetTextEvent textEvent(true, NS_TEXT_TEXT, mWidget); mWidget->InitEvent(textEvent); - textEvent.theText = action.mData; + textEvent.mData = action.mData; mWidget->DispatchWindowEvent(&textEvent); if (!mWidget || mWidget->Destroyed()) { break; @@ -1690,7 +1690,7 @@ nsTextStore::FlushPendingActions() "dispatching compositionend event...", this)); WidgetCompositionEvent compositionEnd(true, NS_COMPOSITION_END, mWidget); - compositionEnd.data = textEvent.theText; + compositionEnd.data = textEvent.mData; mWidget->InitEvent(compositionEnd); mWidget->DispatchWindowEvent(&compositionEnd); if (!mWidget || mWidget->Destroyed()) { diff --git a/widget/xpwidgets/PuppetWidget.cpp b/widget/xpwidgets/PuppetWidget.cpp index 412579ee6ac5..4912351a9063 100644 --- a/widget/xpwidgets/PuppetWidget.cpp +++ b/widget/xpwidgets/PuppetWidget.cpp @@ -388,7 +388,7 @@ PuppetWidget::IMEEndComposition(bool aCancel) // SendEndIMEComposition is always called since ResetInputState // should always be called even if we aren't composing something. if (!mTabChild || - !mTabChild->SendEndIMEComposition(aCancel, &textEvent.theText)) { + !mTabChild->SendEndIMEComposition(aCancel, &textEvent.mData)) { return NS_ERROR_FAILURE; } From aafe327f6d119ec85ef8e9119b001802292ab7eb Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Tue, 7 Oct 2014 19:01:46 +0900 Subject: [PATCH 15/84] Bug 960871 part.2 Rename WidgetCompositionEvent::data to WidgetCompositionEvent::mData r=smaug --- dom/base/nsDOMWindowUtils.cpp | 2 +- dom/events/CompositionEvent.cpp | 3 ++- dom/events/EventStateManager.cpp | 2 +- dom/events/TextComposition.cpp | 12 ++++++------ widget/TextEvents.h | 4 ++-- widget/android/nsWindow.cpp | 2 +- widget/cocoa/TextInputHandler.mm | 4 ++-- widget/gtk/nsGtkIMModule.cpp | 2 +- widget/nsGUIEventIPC.h | 4 ++-- widget/windows/nsIMM32Handler.cpp | 2 +- widget/windows/nsTextStore.cpp | 2 +- 11 files changed, 20 insertions(+), 19 deletions(-) diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index 3988ceb280e8..cdd8d706111d 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -2132,7 +2132,7 @@ nsDOMWindowUtils::SendCompositionEvent(const nsAString& aType, WidgetCompositionEvent compositionEvent(true, msg, widget); InitEvent(compositionEvent); if (msg != NS_COMPOSITION_START) { - compositionEvent.data = aData; + compositionEvent.mData = aData; } compositionEvent.mFlags.mIsSynthesizedForTests = true; diff --git a/dom/events/CompositionEvent.cpp b/dom/events/CompositionEvent.cpp index 68e2dca6269b..496352a773d1 100644 --- a/dom/events/CompositionEvent.cpp +++ b/dom/events/CompositionEvent.cpp @@ -32,7 +32,8 @@ CompositionEvent::CompositionEvent(EventTarget* aOwner, mEvent->mFlags.mCancelable = false; } - mData = mEvent->AsCompositionEvent()->data; + // XXX Do we really need to duplicate the data value? + mData = mEvent->AsCompositionEvent()->mData; // TODO: Native event should have locale information. } diff --git a/dom/events/EventStateManager.cpp b/dom/events/EventStateManager.cpp index dc5e5b98d7be..96aae5aac7ac 100644 --- a/dom/events/EventStateManager.cpp +++ b/dom/events/EventStateManager.cpp @@ -817,7 +817,7 @@ EventStateManager::PreHandleEvent(nsPresContext* aPresContext, compositionEvent->widget); DoQuerySelectedText(&selectedText); NS_ASSERTION(selectedText.mSucceeded, "Failed to get selected text"); - compositionEvent->data = selectedText.mReply.mString; + compositionEvent->mData = selectedText.mReply.mString; } // through to compositionend handling case NS_COMPOSITION_END: diff --git a/dom/events/TextComposition.cpp b/dom/events/TextComposition.cpp index 2ca2fcefda5b..77914aab6d9f 100644 --- a/dom/events/TextComposition.cpp +++ b/dom/events/TextComposition.cpp @@ -76,12 +76,12 @@ TextComposition::MaybeDispatchCompositionUpdate(const WidgetTextEvent* aEvent) aEvent->widget); compositionUpdate.time = aEvent->time; compositionUpdate.timeStamp = aEvent->timeStamp; - compositionUpdate.data = aEvent->mData; + compositionUpdate.mData = aEvent->mData; compositionUpdate.mFlags.mIsSynthesizedForTests = aEvent->mFlags.mIsSynthesizedForTests; nsEventStatus status = nsEventStatus_eConsumeNoDefault; - mLastData = compositionUpdate.data; + mLastData = compositionUpdate.mData; EventDispatcher::Dispatch(mNode, mPresContext, &compositionUpdate, nullptr, &status, nullptr); return !Destroyed(); @@ -146,7 +146,7 @@ TextComposition::DispatchEvent(WidgetGUIEvent* aEvent, nsString* committingData = nullptr; switch (aEvent->message) { case NS_COMPOSITION_END: - committingData = &aEvent->AsCompositionEvent()->data; + committingData = &aEvent->AsCompositionEvent()->mData; break; case NS_TEXT_TEXT: committingData = &aEvent->AsTextEvent()->mData; @@ -304,7 +304,7 @@ TextComposition::RequestToCommit(nsIWidget* aWidget, bool aDiscard) if (!Destroyed() && !widget->Destroyed()) { nsEventStatus status = nsEventStatus_eIgnore; WidgetCompositionEvent endEvent(true, NS_COMPOSITION_END, widget); - endEvent.data = commitData; + endEvent.mData = commitData; endEvent.mFlags.mIsSynthesizedForTests = true; widget->DispatchEvent(&endEvent, status); } @@ -435,7 +435,7 @@ TextComposition::CompositionEventDispatcher::Run() ContentEventHandler handler(presContext); handler.OnQuerySelectedText(&selectedText); NS_ASSERTION(selectedText.mSucceeded, "Failed to get selected text"); - compStart.data = selectedText.mReply.mString; + compStart.mData = selectedText.mReply.mString; compStart.mFlags.mIsSynthesizedForTests = mTextComposition->IsSynthesizedForTests(); IMEStateManager::DispatchCompositionEvent(mEventTarget, presContext, @@ -445,7 +445,7 @@ TextComposition::CompositionEventDispatcher::Run() } case NS_COMPOSITION_END: { WidgetCompositionEvent compEvent(true, mEventMessage, widget); - compEvent.data = mData; + compEvent.mData = mData; compEvent.mFlags.mIsSynthesizedForTests = mTextComposition->IsSynthesizedForTests(); IMEStateManager::DispatchCompositionEvent(mEventTarget, presContext, diff --git a/widget/TextEvents.h b/widget/TextEvents.h index f80ca6811801..80758fc7822e 100644 --- a/widget/TextEvents.h +++ b/widget/TextEvents.h @@ -326,14 +326,14 @@ public: // The composition string or the commit string. If the instance is a // compositionstart event, this is initialized with selected text by // TextComposition automatically. - nsString data; + nsString mData; void AssignCompositionEventData(const WidgetCompositionEvent& aEvent, bool aCopyTargets) { AssignGUIEventData(aEvent, aCopyTargets); - data = aEvent.data; + mData = aEvent.mData; } }; diff --git a/widget/android/nsWindow.cpp b/widget/android/nsWindow.cpp index bd32b5367e11..a840ac8f9aea 100644 --- a/widget/android/nsWindow.cpp +++ b/widget/android/nsWindow.cpp @@ -1868,7 +1868,7 @@ nsWindow::OnIMEEvent(AndroidGeckoEvent *ae) { WidgetCompositionEvent event(true, NS_COMPOSITION_END, this); InitEvent(event, nullptr); - event.data = ae->Characters(); + event.mData = ae->Characters(); DispatchEvent(&event); } diff --git a/widget/cocoa/TextInputHandler.mm b/widget/cocoa/TextInputHandler.mm index 009df5a3b376..3b73000f700f 100644 --- a/widget/cocoa/TextInputHandler.mm +++ b/widget/cocoa/TextInputHandler.mm @@ -2820,7 +2820,7 @@ IMEInputHandler::InsertTextAsCommittingComposition( WidgetCompositionEvent compEnd(true, NS_COMPOSITION_END, mWidget); InitCompositionEvent(compEnd); - compEnd.data = mLastDispatchedCompositionString; + compEnd.mData = mLastDispatchedCompositionString; DispatchEvent(compEnd); if (Destroyed()) { PR_LOG(gLog, PR_LOG_ALWAYS, @@ -2929,7 +2929,7 @@ IMEInputHandler::SetMarkedText(NSAttributedString* aAttrString, if (doCommit) { WidgetCompositionEvent compEnd(true, NS_COMPOSITION_END, mWidget); InitCompositionEvent(compEnd); - compEnd.data = mLastDispatchedCompositionString; + compEnd.mData = mLastDispatchedCompositionString; DispatchEvent(compEnd); if (Destroyed()) { PR_LOG(gLog, PR_LOG_ALWAYS, diff --git a/widget/gtk/nsGtkIMModule.cpp b/widget/gtk/nsGtkIMModule.cpp index d50eb0d7efb6..e13abf916e65 100644 --- a/widget/gtk/nsGtkIMModule.cpp +++ b/widget/gtk/nsGtkIMModule.cpp @@ -1048,7 +1048,7 @@ nsGtkIMModule::DispatchCompositionEnd() WidgetCompositionEvent compEvent(true, NS_COMPOSITION_END, mLastFocusedWindow); InitEvent(compEvent); - compEvent.data = mDispatchedCompositionString; + compEvent.mData = mDispatchedCompositionString; nsEventStatus status; nsCOMPtr kungFuDeathGrip = mLastFocusedWindow; mLastFocusedWindow->DispatchEvent(&compEvent, status); diff --git a/widget/nsGUIEventIPC.h b/widget/nsGUIEventIPC.h index 7311cc0de6cf..bb3b7e8bf4a5 100644 --- a/widget/nsGUIEventIPC.h +++ b/widget/nsGUIEventIPC.h @@ -495,7 +495,7 @@ struct ParamTraits { WriteParam(aMsg, static_cast(aParam)); WriteParam(aMsg, aParam.mSeqno); - WriteParam(aMsg, aParam.data); + WriteParam(aMsg, aParam.mData); } static bool Read(const Message* aMsg, void** aIter, paramType* aResult) @@ -503,7 +503,7 @@ struct ParamTraits return ReadParam(aMsg, aIter, static_cast(aResult)) && ReadParam(aMsg, aIter, &aResult->mSeqno) && - ReadParam(aMsg, aIter, &aResult->data); + ReadParam(aMsg, aIter, &aResult->mData); } }; diff --git a/widget/windows/nsIMM32Handler.cpp b/widget/windows/nsIMM32Handler.cpp index 8c6b094062c3..c39e76e80605 100644 --- a/widget/windows/nsIMM32Handler.cpp +++ b/widget/windows/nsIMM32Handler.cpp @@ -1227,7 +1227,7 @@ nsIMM32Handler::HandleEndComposition(nsWindow* aWindow) aWindow->InitEvent(event, &point); // The last dispatched composition string must be the committed string. - event.data = mLastDispatchedCompositionString; + event.mData = mLastDispatchedCompositionString; aWindow->DispatchWindowEvent(&event); mIsComposing = false; mComposingWindow = nullptr; diff --git a/widget/windows/nsTextStore.cpp b/widget/windows/nsTextStore.cpp index 7747386100a2..97c4c53daf67 100644 --- a/widget/windows/nsTextStore.cpp +++ b/widget/windows/nsTextStore.cpp @@ -1690,7 +1690,7 @@ nsTextStore::FlushPendingActions() "dispatching compositionend event...", this)); WidgetCompositionEvent compositionEnd(true, NS_COMPOSITION_END, mWidget); - compositionEnd.data = textEvent.mData; + compositionEnd.mData = textEvent.mData; mWidget->InitEvent(compositionEnd); mWidget->DispatchWindowEvent(&compositionEnd); if (!mWidget || mWidget->Destroyed()) { From c3e6df2ad330e54ebb439ddbdf4010434081301b Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Tue, 7 Oct 2014 19:01:47 +0900 Subject: [PATCH 16/84] Bug 960871 part.3 Remove WidgetTextEvent::isChar since it's always false on all platforms r=smaug --- dom/events/UIEvent.cpp | 6 +----- widget/TextEvents.h | 8 -------- widget/nsGUIEventIPC.h | 2 -- 3 files changed, 1 insertion(+), 15 deletions(-) diff --git a/dom/events/UIEvent.cpp b/dom/events/UIEvent.cpp index 3ea084d21d86..a0637afa5777 100644 --- a/dom/events/UIEvent.cpp +++ b/dom/events/UIEvent.cpp @@ -344,11 +344,7 @@ bool UIEvent::IsChar() const { WidgetKeyboardEvent* keyEvent = mEvent->AsKeyboardEvent(); - if (keyEvent) { - return keyEvent->isChar; - } - WidgetTextEvent* textEvent = mEvent->AsTextEvent(); - return textEvent ? textEvent->isChar : false; + return keyEvent ? keyEvent->isChar : false; } NS_IMETHODIMP diff --git a/widget/TextEvents.h b/widget/TextEvents.h index 80758fc7822e..f7907fb140e9 100644 --- a/widget/TextEvents.h +++ b/widget/TextEvents.h @@ -213,7 +213,6 @@ private: WidgetTextEvent() : mSeqno(kLatestSeqno) - , isChar(false) { } @@ -226,7 +225,6 @@ public: WidgetTextEvent(bool aIsTrusted, uint32_t aMessage, nsIWidget* aWidget) : WidgetGUIEvent(aIsTrusted, aMessage, aWidget, eTextEventClass) , mSeqno(kLatestSeqno) - , isChar(false) { } @@ -243,10 +241,6 @@ public: // The composition string or the commit string. nsString mData; - // Indicates whether the event signifies printable text. - // XXX This is not a standard, and most platforms don't set this properly. - // So, perhaps, we can get rid of this. - bool isChar; nsRefPtr mRanges; @@ -254,8 +248,6 @@ public: { AssignGUIEventData(aEvent, aCopyTargets); - isChar = aEvent.isChar; - // Currently, we don't need to copy the other members because they are // for internal use only (not available from JS). } diff --git a/widget/nsGUIEventIPC.h b/widget/nsGUIEventIPC.h index bb3b7e8bf4a5..b5f0fb680c76 100644 --- a/widget/nsGUIEventIPC.h +++ b/widget/nsGUIEventIPC.h @@ -451,7 +451,6 @@ struct ParamTraits WriteParam(aMsg, static_cast(aParam)); WriteParam(aMsg, aParam.mSeqno); WriteParam(aMsg, aParam.mData); - WriteParam(aMsg, aParam.isChar); bool hasRanges = !!aParam.mRanges; WriteParam(aMsg, hasRanges); if (hasRanges) { @@ -466,7 +465,6 @@ struct ParamTraits static_cast(aResult)) || !ReadParam(aMsg, aIter, &aResult->mSeqno) || !ReadParam(aMsg, aIter, &aResult->mData) || - !ReadParam(aMsg, aIter, &aResult->isChar) || !ReadParam(aMsg, aIter, &hasRanges)) { return false; } From 09a5b86212ad371a561bcefe7214abf05bf9bf1c Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Tue, 7 Oct 2014 19:01:47 +0900 Subject: [PATCH 17/84] Bug 960871 part.4 Rename NS_TEXT_TEXT to NS_COMPOSITION_CHANGE and fix comments which mention text events r=smaug --- dom/base/CompositionStringSynthesizer.cpp | 2 +- dom/base/nsDOMWindowUtils.cpp | 2 +- dom/events/EventNameList.h | 6 +++- dom/events/EventStateManager.cpp | 2 +- dom/events/IMEStateManager.cpp | 4 +-- dom/events/IMEStateManager.h | 16 ++++----- dom/events/TextComposition.cpp | 34 +++++++++---------- dom/events/TextComposition.h | 23 ++++++------- dom/ipc/TabParent.cpp | 4 +-- editor/libeditor/nsEditor.cpp | 12 +++---- editor/libeditor/nsEditor.h | 5 ++- editor/libeditor/nsEditorEventListener.cpp | 2 +- editor/libeditor/nsPlaintextEditor.cpp | 4 +-- widget/BasicEvents.h | 13 +++++--- widget/android/nsWindow.cpp | 10 +++--- widget/cocoa/TextInputHandler.h | 2 +- widget/cocoa/TextInputHandler.mm | 6 ++-- widget/gtk/nsGtkIMModule.cpp | 12 ++++--- widget/gtk/nsGtkIMModule.h | 7 ++-- widget/gtk/nsWindow.cpp | 7 ++-- widget/shared/WidgetEventImpl.cpp | 2 +- widget/tests/TestWinTSF.cpp | 2 +- widget/windows/nsIMM32Handler.cpp | 38 ++++++++++++---------- widget/windows/nsTextStore.cpp | 18 +++++----- widget/windows/nsTextStore.h | 12 +++---- widget/xpwidgets/PuppetWidget.cpp | 2 +- 26 files changed, 128 insertions(+), 119 deletions(-) diff --git a/dom/base/CompositionStringSynthesizer.cpp b/dom/base/CompositionStringSynthesizer.cpp index 0da6d20bbdb5..931fbe513422 100644 --- a/dom/base/CompositionStringSynthesizer.cpp +++ b/dom/base/CompositionStringSynthesizer.cpp @@ -135,7 +135,7 @@ CompositionStringSynthesizer::DispatchEvent(bool* aDefaultPrevented) mClauses->AppendElement(mCaret); } - WidgetTextEvent textEvent(true, NS_TEXT_TEXT, widget); + WidgetTextEvent textEvent(true, NS_COMPOSITION_CHANGE, widget); textEvent.time = PR_IntervalNow(); textEvent.mData = mString; if (!mClauses->IsEmpty()) { diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index cdd8d706111d..8bb074063ac5 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -2118,7 +2118,7 @@ nsDOMWindowUtils::SendCompositionEvent(const nsAString& aType, msg = NS_COMPOSITION_END; } else if (aType.EqualsLiteral("compositionupdate")) { // Now we don't support manually dispatching composition update with this - // API. compositionupdate is dispatched when text event modifies + // API. A compositionupdate is dispatched when a DOM text event modifies // composition string automatically. For backward compatibility, this // shouldn't return error in this case. NS_WARNING("Don't call nsIDOMWindowUtils.sendCompositionEvent() for " diff --git a/dom/events/EventNameList.h b/dom/events/EventNameList.h index 607ce7b3246a..3ca264c01b9b 100644 --- a/dom/events/EventNameList.h +++ b/dom/events/EventNameList.h @@ -651,8 +651,12 @@ NON_IDL_EVENT(speakerforcedchange, eBasicEventClass) // Events that only have on* attributes on XUL elements + + // "text" event is legacy event for modifying composition string in nsEditor. + // This shouldn't be used by web/xul apps. "compositionupdate" should be + // used instead. NON_IDL_EVENT(text, - NS_TEXT_TEXT, + NS_COMPOSITION_CHANGE, EventNameType_XUL, eTextEventClass) NON_IDL_EVENT(compositionstart, diff --git a/dom/events/EventStateManager.cpp b/dom/events/EventStateManager.cpp index 96aae5aac7ac..40df138ca874 100644 --- a/dom/events/EventStateManager.cpp +++ b/dom/events/EventStateManager.cpp @@ -796,7 +796,7 @@ EventStateManager::PreHandleEvent(nsPresContext* aPresContext, DoContentCommandScrollEvent(aEvent->AsContentCommandEvent()); } break; - case NS_TEXT_TEXT: + case NS_COMPOSITION_CHANGE: { WidgetTextEvent *textEvent = aEvent->AsTextEvent(); if (IsTargetCrossProcess(textEvent)) { diff --git a/dom/events/IMEStateManager.cpp b/dom/events/IMEStateManager.cpp index 1f99df00bac1..362d22c81038 100644 --- a/dom/events/IMEStateManager.cpp +++ b/dom/events/IMEStateManager.cpp @@ -153,8 +153,8 @@ GetEventMessageName(uint32_t aMessage) return "NS_COMPOSITION_END"; case NS_COMPOSITION_UPDATE: return "NS_COMPOSITION_UPDATE"; - case NS_TEXT_TEXT: - return "NS_TEXT_TEXT"; + case NS_COMPOSITION_CHANGE: + return "NS_COMPOSITION_CHANGE"; default: return "unacceptable event message"; } diff --git a/dom/events/IMEStateManager.h b/dom/events/IMEStateManager.h index 0a1b3fd0e71d..312c27371a64 100644 --- a/dom/events/IMEStateManager.h +++ b/dom/events/IMEStateManager.h @@ -92,11 +92,10 @@ public: nsIContent* aContent); /** - * All DOM composition events and DOM text events must be dispatched via - * DispatchCompositionEvent() for storing the composition target - * and ensuring a set of composition events must be fired the stored target. - * If the stored composition event target is destroying, this removes the - * stored composition automatically. + * All composition events must be dispatched via DispatchCompositionEvent() + * for storing the composition target and ensuring a set of composition + * events must be fired the stored target. If the stored composition event + * target is destroying, this removes the stored composition automatically. */ static void DispatchCompositionEvent(nsINode* aEventTargetNode, nsPresContext* aPresContext, @@ -106,8 +105,8 @@ public: bool aIsSynthesized = false); /** - * This is called when PresShell ignores composition event or text event due - * to not safe to dispatch events. + * This is called when PresShell ignores a composition event due to not safe + * to dispatch events. */ static void OnCompositionEventDiscarded(WidgetEvent* aEvent); @@ -120,8 +119,7 @@ public: /** * Returns TextComposition instance for the event. * - * @param aEvent Should be a composition event or a text event which is - * being dispatched. + * @param aEvent Should be a composition event which is being dispatched. */ static already_AddRefed GetTextCompositionFor(WidgetGUIEvent* aEvent); diff --git a/dom/events/TextComposition.cpp b/dom/events/TextComposition.cpp index 77914aab6d9f..ec5b1e5b1ae7 100644 --- a/dom/events/TextComposition.cpp +++ b/dom/events/TextComposition.cpp @@ -148,7 +148,7 @@ TextComposition::DispatchEvent(WidgetGUIEvent* aEvent, case NS_COMPOSITION_END: committingData = &aEvent->AsCompositionEvent()->mData; break; - case NS_TEXT_TEXT: + case NS_COMPOSITION_CHANGE: committingData = &aEvent->AsTextEvent()->mData; break; default: @@ -166,7 +166,7 @@ TextComposition::DispatchEvent(WidgetGUIEvent* aEvent, } } - if (aEvent->message == NS_TEXT_TEXT) { + if (aEvent->message == NS_COMPOSITION_CHANGE) { if (!MaybeDispatchCompositionUpdate(aEvent->AsTextEvent())) { return; } @@ -179,9 +179,9 @@ TextComposition::DispatchEvent(WidgetGUIEvent* aEvent, return; } - // Emulate editor behavior of text event handler if no editor handles - // composition/text events. - if (aEvent->message == NS_TEXT_TEXT && !HasEditor()) { + // Emulate editor behavior of compositionchange event (DOM text event) handler + // if no editor handles composition events. + if (aEvent->message == NS_COMPOSITION_CHANGE && !HasEditor()) { EditorWillHandleTextEvent(aEvent->AsTextEvent()); EditorDidHandleTextEvent(); } @@ -204,7 +204,7 @@ TextComposition::NotityUpdateComposition(WidgetGUIEvent* aEvent) // When compositon start, notify the rect of first offset character. // When not compositon start, notify the rect of selected composition - // string if text event. + // string if compositionchange event. if (aEvent->message == NS_COMPOSITION_START) { nsCOMPtr widget = mPresContext->GetRootWidget(); // Update composition start offset @@ -286,15 +286,15 @@ TextComposition::RequestToCommit(nsIWidget* aWidget, bool aDiscard) nsAutoString commitData(aDiscard ? EmptyString() : lastData); bool changingData = lastData != commitData; - WidgetTextEvent textEvent(true, NS_TEXT_TEXT, widget); + WidgetTextEvent textEvent(true, NS_COMPOSITION_CHANGE, widget); textEvent.mData = commitData; textEvent.mFlags.mIsSynthesizedForTests = true; MaybeDispatchCompositionUpdate(&textEvent); // If changing the data or committing string isn't empty, we need to - // dispatch text event for setting the composition string without - // IME selection. + // dispatch compositionchange event for setting the composition string + // without IME selection. if (!Destroyed() && !widget->Destroyed() && (changingData || !commitData.IsEmpty())) { nsEventStatus status = nsEventStatus_eIgnore; @@ -321,11 +321,11 @@ TextComposition::RequestToCommit(nsIWidget* aWidget, bool aDiscard) // Otherwise, synthesize the commit in content. nsAutoString data(aDiscard ? EmptyString() : lastData); // If the last composition string and new data are different, we need to - // dispatch text event for removing IME selection. However, if the commit - // string is empty string and it's not changed from the last data, we don't - // need to dispatch text event. + // dispatch compositionchange event for removing IME selection. However, if + // the commit string is empty string and it's not changed from the last data, + // we don't need to dispatch compositionchange event. if (lastData != data || !data.IsEmpty()) { - DispatchCompositionEventRunnable(NS_TEXT_TEXT, data, true); + DispatchCompositionEventRunnable(NS_COMPOSITION_CHANGE, data, true); } DispatchCompositionEventRunnable(NS_COMPOSITION_END, data, true); @@ -347,8 +347,8 @@ TextComposition::EditorWillHandleTextEvent(const WidgetTextEvent* aTextEvent) mIsEditorHandlingEvent = true; MOZ_ASSERT(mLastData == aTextEvent->mData, - "The text of a text event must be same as previous data attribute value " - "of the latest compositionupdate event"); + "The text of a compositionchange event must be same as previous data " + "attribute value of the latest compositionupdate event"); } void @@ -453,8 +453,8 @@ TextComposition::CompositionEventDispatcher::Run() mIsSynthesizedEvent); break; } - case NS_TEXT_TEXT: { - WidgetTextEvent textEvent(true, NS_TEXT_TEXT, widget); + case NS_COMPOSITION_CHANGE: { + WidgetTextEvent textEvent(true, NS_COMPOSITION_CHANGE, widget); textEvent.mData = mData; textEvent.mFlags.mIsSynthesizedForTests = mTextComposition->IsSynthesizedForTests(); diff --git a/dom/events/TextComposition.h b/dom/events/TextComposition.h index db0d847ffe65..1c9c3f825d49 100644 --- a/dom/events/TextComposition.h +++ b/dom/events/TextComposition.h @@ -52,7 +52,7 @@ public: // I.e., this value must be same as the composition string on the focused // editor. This value is modified at a call of EditorDidHandleTextEvent(). // Note that mString and mLastData are different between dispatcing - // compositionupdate and text event handled by focused editor. + // compositionupdate and compositionchange event handled by focused editor. const nsString& String() const { return mString; } // Returns the clauses and/or caret range of the composition string. // This is modified at a call of EditorWillHandleTextEvent(). @@ -233,13 +233,13 @@ private: /** * EditorWillHandleTextEvent() must be called before the focused editor - * handles the text event. + * handles the compositionchange event. */ void EditorWillHandleTextEvent(const WidgetTextEvent* aTextEvent); /** * EditorDidHandleTextEvent() must be called after the focused editor handles - * a text event. + * a compositionchange event. */ void EditorDidHandleTextEvent(); @@ -271,8 +271,8 @@ private: /** * OnCompositionEventDiscarded() is called when PresShell discards - * compositionupdate, compositionend or text event due to not safe to - * dispatch event. + * compositionupdate, compositionend or compositionchange event due to not + * safe to dispatch event. */ void OnCompositionEventDiscarded(const WidgetGUIEvent* aEvent); @@ -306,17 +306,14 @@ private: }; /** - * DispatchCompositionEventRunnable() dispatches a composition or text event - * to the content. Be aware, if you use this method, nsPresShellEventCB - * isn't used. That means that nsIFrame::HandleEvent() is never called. + * DispatchCompositionEventRunnable() dispatches a composition event to the + * content. Be aware, if you use this method, nsPresShellEventCB isn't used. + * That means that nsIFrame::HandleEvent() is never called. * WARNING: The instance which is managed by IMEStateManager may be * destroyed by this method call. * - * @param aEventMessage Must be one of composition event or text event. - * @param aData Used for data value if aEventMessage is - * NS_COMPOSITION_END. - * Used for theText value if aEventMessage is - * NS_TEXT_TEXT. + * @param aEventMessage Must be one of composition events. + * @param aData Used for mData value. * @param aIsSynthesizingCommit true if this is called for synthesizing * commit or cancel composition. Otherwise, * false. diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index b6bdfc37fe1d..b73538a49707 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -1575,8 +1575,8 @@ TabParent::SendCompositionEvent(WidgetCompositionEvent& event) /** * During REQUEST_TO_COMMIT_COMPOSITION or REQUEST_TO_CANCEL_COMPOSITION, - * widget usually sends a NS_TEXT_TEXT event to finalize or clear the - * composition, respectively + * widget usually sends a NS_COMPOSITION_CHANGE event to finalize or + * clear the composition, respectively * * Because the event will not reach content in time, we intercept it * here and pass the text as the EndIMEComposition return value diff --git a/editor/libeditor/nsEditor.cpp b/editor/libeditor/nsEditor.cpp index 0228dcffc3b7..cdb6e934eef6 100644 --- a/editor/libeditor/nsEditor.cpp +++ b/editor/libeditor/nsEditor.cpp @@ -973,7 +973,7 @@ nsEditor::EndPlaceHolderTransaction() // For now just removing the assert. } // notify editor observers of action but if composing, it's done by - // text event handler. + // compositionchange event handler. if (!mComposition) { NotifyEditorObservers(eNotifyEditorObserversOfEnd); } @@ -5097,9 +5097,9 @@ nsEditor::IsAcceptableInputEvent(nsIDOMEvent* aEvent) } } - // If composition event or text event isn't dispatched via widget, - // we need to ignore them since they cannot be managed by TextComposition. - // E.g., the event was created by chrome JS. + // If a composition event isn't dispatched via widget, we need to ignore them + // since they cannot be managed by TextComposition. E.g., the event was + // created by chrome JS. // Note that if we allow to handle such events, editor may be confused by // strange event order. bool needsWidget = false; @@ -5109,8 +5109,8 @@ nsEditor::IsAcceptableInputEvent(nsIDOMEvent* aEvent) // If events are not created with proper event interface, their message // are initialized with NS_USER_DEFINED_EVENT. Let's ignore such event. return false; - case NS_TEXT_TEXT: - // Don't allow text events whose internal event are not + case NS_COMPOSITION_CHANGE: + // Don't allow compositionchange events whose internal event are not // WidgetTextEvent. widgetGUIEvent = aEvent->GetInternalNSEvent()->AsTextEvent(); needsWidget = true; diff --git a/editor/libeditor/nsEditor.h b/editor/libeditor/nsEditor.h index 9d95d9c98a35..5da57f57961d 100644 --- a/editor/libeditor/nsEditor.h +++ b/editor/libeditor/nsEditor.h @@ -417,9 +417,8 @@ protected: } /** - * EnsureComposition() should be composition event handlers or text event - * handler. This tries to get the composition for the event and set it to - * mComposition. + * EnsureComposition() should be called by composition event handlers. This + * tries to get the composition for the event and set it to mComposition. */ void EnsureComposition(mozilla::WidgetGUIEvent* aEvent); diff --git a/editor/libeditor/nsEditorEventListener.cpp b/editor/libeditor/nsEditorEventListener.cpp index 7a81a89b92fe..78d2a4e7951d 100644 --- a/editor/libeditor/nsEditorEventListener.cpp +++ b/editor/libeditor/nsEditorEventListener.cpp @@ -456,7 +456,7 @@ nsEditorEventListener::HandleEvent(nsIDOMEvent* aEvent) case NS_BLUR_CONTENT: return Blur(aEvent); // text - case NS_TEXT_TEXT: + case NS_COMPOSITION_CHANGE: return HandleText(aEvent); // compositionstart case NS_COMPOSITION_START: diff --git a/editor/libeditor/nsPlaintextEditor.cpp b/editor/libeditor/nsPlaintextEditor.cpp index 62469f59d20b..c6c64973eebc 100644 --- a/editor/libeditor/nsPlaintextEditor.cpp +++ b/editor/libeditor/nsPlaintextEditor.cpp @@ -861,8 +861,8 @@ nsPlaintextEditor::UpdateIMEComposition(nsIDOMEvent* aDOMTextEvent) // NOTE: TextComposition should receive selection change notification before // TextEventHandlingMarker notifies TextComposition of the end of - // handling TextEvent because TextComposition may need to ignore - // selection changes caused by composition. Therefore, + // handling compositionchange event because TextComposition may need to + // ignore selection changes caused by composition. Therefore, // TextEventHandlingMarker must be destroyed after a call of // NotifiyEditorObservers(eNotifyEditorObserversOfEnd) or // NotifiyEditorObservers(eNotifyEditorObserversOfCancel) which notifies diff --git a/widget/BasicEvents.h b/widget/BasicEvents.h index 873882bccdaf..c380d87b2885 100644 --- a/widget/BasicEvents.h +++ b/widget/BasicEvents.h @@ -172,11 +172,16 @@ #define NS_COMPOSITION_EVENT_START 2200 #define NS_COMPOSITION_START (NS_COMPOSITION_EVENT_START) #define NS_COMPOSITION_END (NS_COMPOSITION_EVENT_START + 1) +// NS_COMPOSITION_UPDATE is the message for DOM compositionupdate event. +// This event should NOT be dispatched from widget since it will be dispatched +// by mozilla::TextComposition automatically if NS_COMPOSITION_CHANGE event +// will change composition string. #define NS_COMPOSITION_UPDATE (NS_COMPOSITION_EVENT_START + 2) - -// text events -#define NS_TEXT_START 2400 -#define NS_TEXT_TEXT (NS_TEXT_START) +// NS_COMPOSITION_CHANGE is the message for representing a change of +// composition string. This should be dispatched from widget even if +// composition string isn't changed but the ranges are changed. This causes +// a DOM "text" event which is a non-standard DOM event. +#define NS_COMPOSITION_CHANGE (NS_COMPOSITION_EVENT_START + 3) // UI events #define NS_UI_EVENT_START 2500 diff --git a/widget/android/nsWindow.cpp b/widget/android/nsWindow.cpp index a840ac8f9aea..31f745347a9d 100644 --- a/widget/android/nsWindow.cpp +++ b/widget/android/nsWindow.cpp @@ -683,7 +683,7 @@ nsWindow::DispatchEvent(WidgetGUIEvent* aEvent) mIMEComposingStart = -1; mIMEComposingText.Truncate(); break; - case NS_TEXT_TEXT: + case NS_COMPOSITION_CHANGE: MOZ_ASSERT(mIMEComposing); mIMEComposingText = aEvent->AsTextEvent()->mData; break; @@ -1707,7 +1707,7 @@ nsWindow::RemoveIMEComposition() AutoIMEMask selMask(mIMEMaskSelectionUpdate); AutoIMEMask textMask(mIMEMaskTextUpdate); - WidgetTextEvent textEvent(true, NS_TEXT_TEXT, this); + WidgetTextEvent textEvent(true, NS_COMPOSITION_CHANGE, this); InitEvent(textEvent, nullptr); textEvent.mData = mIMEComposingText; DispatchEvent(&textEvent); @@ -1845,7 +1845,7 @@ nsWindow::OnIMEEvent(AndroidGeckoEvent *ae) } { - WidgetTextEvent event(true, NS_TEXT_TEXT, this); + WidgetTextEvent event(true, NS_COMPOSITION_CHANGE, this); InitEvent(event, nullptr); event.mData = ae->Characters(); @@ -1955,7 +1955,7 @@ nsWindow::OnIMEEvent(AndroidGeckoEvent *ae) AutoIMEMask selMask(mIMEMaskSelectionUpdate); AutoIMEMask textMask(mIMEMaskTextUpdate); - WidgetTextEvent event(true, NS_TEXT_TEXT, this); + WidgetTextEvent event(true, NS_COMPOSITION_CHANGE, this); InitEvent(event, nullptr); event.mRanges = new TextRangeArray(); @@ -2086,7 +2086,7 @@ nsWindow::NotifyIME(const IMENotification& aIMENotification) if (mIMEComposing) { nsRefPtr kungFuDeathGrip(this); - WidgetTextEvent textEvent(true, NS_TEXT_TEXT, this); + WidgetTextEvent textEvent(true, NS_COMPOSITION_CHANGE, this); InitEvent(textEvent, nullptr); DispatchEvent(&textEvent); diff --git a/widget/cocoa/TextInputHandler.h b/widget/cocoa/TextInputHandler.h index 7cb6e4a40472..94963ed1ae8e 100644 --- a/widget/cocoa/TextInputHandler.h +++ b/widget/cocoa/TextInputHandler.h @@ -846,7 +846,7 @@ public: void OnSelectionChange() { mSelectedRange.location = NSNotFound; } /** - * DispatchTextEvent() dispatches a text event on mWidget. + * DispatchTextEvent() dispatches a compositionchange event on mWidget. * * @param aText User text input. * @param aAttrString An NSAttributedString instance which indicates diff --git a/widget/cocoa/TextInputHandler.mm b/widget/cocoa/TextInputHandler.mm index 3b73000f700f..46f77c51ecec 100644 --- a/widget/cocoa/TextInputHandler.mm +++ b/widget/cocoa/TextInputHandler.mm @@ -2716,7 +2716,7 @@ IMEInputHandler::DispatchTextEvent(const nsString& aText, nsRefPtr kungFuDeathGrip(this); - WidgetTextEvent textEvent(true, NS_TEXT_TEXT, mWidget); + WidgetTextEvent textEvent(true, NS_COMPOSITION_CHANGE, mWidget); textEvent.time = PR_IntervalNow(); textEvent.mData = aText; if (!aDoCommit) { @@ -2812,7 +2812,7 @@ IMEInputHandler::InsertTextAsCommittingComposition( if (Destroyed()) { PR_LOG(gLog, PR_LOG_ALWAYS, ("%p IMEInputHandler::InsertTextAsCommittingComposition, " - "destroyed by text event", this)); + "destroyed by compositionchange event", this)); return; } @@ -2922,7 +2922,7 @@ IMEInputHandler::SetMarkedText(NSAttributedString* aAttrString, if (Destroyed()) { PR_LOG(gLog, PR_LOG_ALWAYS, ("%p IMEInputHandler::SetMarkedText, " - "destroyed by text event", this)); + "destroyed by compositionchange event", this)); return; } diff --git a/widget/gtk/nsGtkIMModule.cpp b/widget/gtk/nsGtkIMModule.cpp index e13abf916e65..c82238a17fd1 100644 --- a/widget/gtk/nsGtkIMModule.cpp +++ b/widget/gtk/nsGtkIMModule.cpp @@ -439,7 +439,7 @@ nsGtkIMModule::EndIMEComposition(nsWindow* aCaller) // forcibly. Therefore, TextComposition will recompute commit string for // the request even if native IME will cause unexpected commit string. // So, we don't need to emulate commit or cancel composition with - // proper composition events and a text event. + // proper composition events. // XXX ResetIME() might not enough for finishing compositoin on some // environments. We should emulate focus change too because some IMEs // may commit or cancel composition at blur. @@ -1092,10 +1092,11 @@ nsGtkIMModule::DispatchTextEvent(const nsAString &aCompositionString, nsEventStatus status; nsRefPtr lastFocusedWindow = mLastFocusedWindow; - // Store the selected string which will be removed by following text event. + // Store the selected string which will be removed by following + // compositionchange event. if (mCompositionState == eCompositionState_CompositionStartDispatched) { // XXX We should assume, for now, any web applications don't change - // selection at handling this text event. + // selection at handling this compositionchange event. WidgetQueryContentEvent querySelectedTextEvent(true, NS_QUERY_SELECTED_TEXT, mLastFocusedWindow); @@ -1106,7 +1107,7 @@ nsGtkIMModule::DispatchTextEvent(const nsAString &aCompositionString, } } - WidgetTextEvent textEvent(true, NS_TEXT_TEXT, mLastFocusedWindow); + WidgetTextEvent textEvent(true, NS_COMPOSITION_CHANGE, mLastFocusedWindow); InitEvent(textEvent); uint32_t targetOffset = mCompositionStart; @@ -1128,7 +1129,8 @@ nsGtkIMModule::DispatchTextEvent(const nsAString &aCompositionString, if (lastFocusedWindow->IsDestroyed() || lastFocusedWindow != mLastFocusedWindow) { PR_LOG(gGtkIMLog, PR_LOG_ALWAYS, - (" NOTE, the focused widget was destroyed/changed by text event")); + (" NOTE, the focused widget was destroyed/changed by " + "compositionchange event")); return false; } diff --git a/widget/gtk/nsGtkIMModule.h b/widget/gtk/nsGtkIMModule.h index dd4a00e20997..3965e69196dc 100644 --- a/widget/gtk/nsGtkIMModule.h +++ b/widget/gtk/nsGtkIMModule.h @@ -134,7 +134,7 @@ protected: nsString mDispatchedCompositionString; // mSelectedString is the selected string which was removed by first - // text event. + // compositionchange event. nsString mSelectedString; // OnKeyEvent() temporarily sets mProcessingKeyEvent to the given native @@ -304,8 +304,9 @@ protected: bool DispatchCompositionStart(); bool DispatchCompositionEnd(); - // Dispatches a text event. If aIsCommit is TRUE, dispatches a committed - // text event. Otherwise, dispatches a composing text event. + // Dispatches a compositionchange event. If aIsCommit is TRUE, dispatches + // a committed compositionchange event. Otherwise, dispatches a composing + // compositionchange event. bool DispatchTextEvent(const nsAString& aCompositionString, bool aIsCommit); diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp index 9c978c6d83b2..08a8551dc98d 100644 --- a/widget/gtk/nsWindow.cpp +++ b/widget/gtk/nsWindow.cpp @@ -3040,12 +3040,13 @@ nsWindow::OnKeyPressEvent(GdkEventKey *aEvent) } else { // If the character code is in the BMP, send the key press event. - // Otherwise, send a text event with the equivalent UTF-16 string. + // Otherwise, send a compositionchange event with the equivalent UTF-16 + // string. if (IS_IN_BMP(event.charCode)) { DispatchEvent(&event, status); } else { - WidgetTextEvent textEvent(true, NS_TEXT_TEXT, this); + WidgetTextEvent textEvent(true, NS_COMPOSITION_CHANGE, this); char16_t textString[3]; textString[0] = H_SURROGATE(event.charCode); textString[1] = L_SURROGATE(event.charCode); @@ -5997,7 +5998,7 @@ nsWindow::GetIMEUpdatePreference() nsIMEUpdatePreference::NOTIFY_SELECTION_CHANGE); // We shouldn't notify IME of selection change caused by changes of // composition string. Therefore, we don't need to be notified selection - // changes which are caused by text events handled. + // changes which are caused by compositionchange events handled. updatePreference.DontNotifyChangesCausedByComposition(); return updatePreference; } diff --git a/widget/shared/WidgetEventImpl.cpp b/widget/shared/WidgetEventImpl.cpp index 0639205670d7..a963a8783118 100644 --- a/widget/shared/WidgetEventImpl.cpp +++ b/widget/shared/WidgetEventImpl.cpp @@ -132,10 +132,10 @@ bool WidgetEvent::HasIMEEventMessage() const { switch (message) { - case NS_TEXT_TEXT: case NS_COMPOSITION_START: case NS_COMPOSITION_END: case NS_COMPOSITION_UPDATE: + case NS_COMPOSITION_CHANGE: return true; default: return false; diff --git a/widget/tests/TestWinTSF.cpp b/widget/tests/TestWinTSF.cpp index db0701127a53..c80357975eaa 100644 --- a/widget/tests/TestWinTSF.cpp +++ b/widget/tests/TestWinTSF.cpp @@ -1965,7 +1965,7 @@ TestApp::TestText(void) * Bug in NS_QUERY_TEXT_CONTENT handler * nsTextStore::SetText not calling SetSelection or InsertTextAtSelection * Bug in SetSelection or InsertTextAtSelection - * NS_SELECTION_SET bug or NS_COMPOSITION_* / NS_TEXT_TEXT bug + * NS_SELECTION_SET bug or NS_COMPOSITION_* / NS_COMPOSITION_CHANGE bug */ if (!mMgr->GetFocusedStore()) { diff --git a/widget/windows/nsIMM32Handler.cpp b/widget/windows/nsIMM32Handler.cpp index c39e76e80605..ba409d641f14 100644 --- a/widget/windows/nsIMM32Handler.cpp +++ b/widget/windows/nsIMM32Handler.cpp @@ -152,7 +152,7 @@ nsIMM32Handler::GetIMEUpdatePreference() ((lParam) & (GCS_COMPSTR | GCS_COMPATTR | GCS_COMPCLAUSE | GCS_CURSORPOS)) #define IS_COMMITTING_LPARAM(lParam) ((lParam) & GCS_RESULTSTR) // Some IMEs (e.g., the standard IME for Korean) don't have caret position, -// then, we should not set caret position to text event. +// then, we should not set caret position to compositionchange event. #define NO_IME_CARET -1 nsIMM32Handler::nsIMM32Handler() : @@ -483,10 +483,10 @@ nsIMM32Handler::OnIMEEndComposition(nsWindow* aWindow, // Otherwise, e.g., ChangJie doesn't post WM_IME_COMPOSITION before // WM_IME_ENDCOMPOSITION when composition string becomes empty. - // Then, we should dispatch a compositionupdate event, a text event and - // a compositionend event. - // XXX Shouldn't we dispatch the text event with actual or latest composition - // string? + // Then, we should dispatch a compositionupdate event, a compositionchange + // event and a compositionend event. + // XXX Shouldn't we dispatch the compositionchange event with actual or + // latest composition string? PR_LOG(gIMM32Log, PR_LOG_ALWAYS, ("IMM32: OnIMEEndComposition, mCompositionString=\"%s\"%s", NS_ConvertUTF16toUTF8(mCompositionString).get(), @@ -512,10 +512,10 @@ nsIMM32Handler::OnIMEChar(nsWindow* aWindow, ("IMM32: OnIMEChar, hWnd=%08x, char=%08x\n", aWindow->GetWindowHandle(), wParam)); - // We don't need to fire any text events from here. This method will be - // called when the composition string of the current IME is not drawn by us - // and some characters are committed. In that case, the committed string was - // processed in nsWindow::OnIMEComposition already. + // We don't need to fire any compositionchange events from here. This method + // will be called when the composition string of the current IME is not drawn + // by us and some characters are committed. In that case, the committed + // string was processed in nsWindow::OnIMEComposition already. // We need to consume the message so that Windows don't send two WM_CHAR msgs aResult.mConsumed = true; @@ -1059,15 +1059,16 @@ nsIMM32Handler::HandleComposition(nsWindow* aWindow, // IME may send WM_IME_COMPOSITION without composing lParam values // when composition string becomes empty (e.g., using Backspace key). - // If composition string is empty, we should dispatch a text event with - // empty string. + // If composition string is empty, we should dispatch a compositionchange + // event with empty string. if (mCompositionString.IsEmpty()) { DispatchTextEvent(aWindow, aIMEContext, false); return ShouldDrawCompositionStringOurselves(); } // Otherwise, we cannot trust the lParam value. We might need to - // dispatch text event with the latest composition string information. + // dispatch compositionchange event with the latest composition string + // information. } // See https://bugzilla.mozilla.org/show_bug.cgi?id=296339 @@ -1199,7 +1200,7 @@ nsIMM32Handler::HandleComposition(nsWindow* aWindow, mCursorPosition)); //-------------------------------------------------------- - // 5. Send the text event + // 5. Send the compositionchange event //-------------------------------------------------------- DispatchTextEvent(aWindow, aIMEContext); @@ -1578,8 +1579,8 @@ nsIMM32Handler::DispatchTextEvent(nsWindow* aWindow, aCheckAttr ? "TRUE": "FALSE")); // If we don't need to draw composition string ourselves and this is not - // commit event (i.e., under composing), we don't need to fire text event - // during composing. + // commit event (i.e., under composing), we don't need to fire + // compositionchange event during composing. if (aCheckAttr && !ShouldDrawCompositionStringOurselves()) { // But we need to adjust composition window pos and native caret pos, here. SetIMERelatedWindowsPos(aWindow, aIMEContext); @@ -1590,7 +1591,7 @@ nsIMM32Handler::DispatchTextEvent(nsWindow* aWindow, nsIntPoint point(0, 0); - WidgetTextEvent event(true, NS_TEXT_TEXT, aWindow); + WidgetTextEvent event(true, NS_COMPOSITION_CHANGE, aWindow); aWindow->InitEvent(event, &point); @@ -1603,7 +1604,7 @@ nsIMM32Handler::DispatchTextEvent(nsWindow* aWindow, aWindow->DispatchWindowEvent(&event); // Calling SetIMERelatedWindowsPos will be failure on e10s at this point. - // text event will notify NOTIFY_IME_OF_COMPOSITION_UPDATE, then + // compositionchange event will notify NOTIFY_IME_OF_COMPOSITION_UPDATE, then // it will call SetIMERelatedWindowsPos. } @@ -1615,7 +1616,8 @@ nsIMM32Handler::CreateTextRangeArray() // string and attributes) are empty. So, if you want to remove following // assertion, be careful. NS_ASSERTION(ShouldDrawCompositionStringOurselves(), - "CreateTextRangeArray is called when we don't need to fire text event"); + "CreateTextRangeArray is called when we don't need to fire " + "compositionchange event"); nsRefPtr textRangeArray = new TextRangeArray(); diff --git a/widget/windows/nsTextStore.cpp b/widget/windows/nsTextStore.cpp index 97c4c53daf67..da766fe4089f 100644 --- a/widget/windows/nsTextStore.cpp +++ b/widget/windows/nsTextStore.cpp @@ -1649,8 +1649,8 @@ nsTextStore::FlushPendingActions() PR_LOG(sTextStoreLog, PR_LOG_DEBUG, ("TSF: 0x%p nsTextStore::FlushPendingActions(), " - "dispatching text event...", this)); - WidgetTextEvent textEvent(true, NS_TEXT_TEXT, mWidget); + "dispatching compositionchange event...", this)); + WidgetTextEvent textEvent(true, NS_COMPOSITION_CHANGE, mWidget); mWidget->InitEvent(textEvent); textEvent.mData = action.mData; if (action.mRanges->IsEmpty()) { @@ -1676,8 +1676,8 @@ nsTextStore::FlushPendingActions() PR_LOG(sTextStoreLog, PR_LOG_DEBUG, ("TSF: 0x%p nsTextStore::FlushPendingActions(), " - "dispatching text event...", this)); - WidgetTextEvent textEvent(true, NS_TEXT_TEXT, mWidget); + "dispatching compositionchange event...", this)); + WidgetTextEvent textEvent(true, NS_COMPOSITION_CHANGE, mWidget); mWidget->InitEvent(textEvent); textEvent.mData = action.mData; mWidget->DispatchWindowEvent(&textEvent); @@ -2269,7 +2269,7 @@ nsTextStore::RecordCompositionUpdateAction() // the attribute, we have to find out all the ranges that have distinct // attribute values. Then we query for what the value represents through // the display attribute manager and translate that to TextRange to be - // sent in NS_TEXT_TEXT + // sent in NS_COMPOSITION_CHANGE nsRefPtr attrPropetry; HRESULT hr = mContext->GetProperty(GUID_PROP_ATTRIBUTE, @@ -2318,7 +2318,7 @@ nsTextStore::RecordCompositionUpdateAction() TextRange newRange; // No matter if we have display attribute info or not, - // we always pass in at least one range to NS_TEXT_TEXT + // we always pass in at least one range to NS_COMPOSITION_CHANGE newRange.mStartOffset = 0; newRange.mEndOffset = action->mData.Length(); newRange.mRangeType = NS_TEXTRANGE_RAWINPUT; @@ -4875,9 +4875,9 @@ nsTextStore::Content::ReplaceTextWith(LONG aStart, LONG aLength, if (mComposition.IsComposing()) { // Emulate text insertion during compositions, because during a // composition, editor expects the whole composition string to - // be sent in NS_TEXT_TEXT, not just the inserted part. - // The actual NS_TEXT_TEXT will be sent in SetSelection or - // OnUpdateComposition. + // be sent in NS_COMPOSITION_CHANGE, not just the inserted part. + // The actual NS_COMPOSITION_CHANGE will be sent in SetSelection + // or OnUpdateComposition. MOZ_ASSERT(aStart >= mComposition.mStart); MOZ_ASSERT(aStart + aLength <= mComposition.EndOffset()); mComposition.mString.Replace( diff --git a/widget/windows/nsTextStore.h b/widget/windows/nsTextStore.h index 627ca026c72f..511818f03c14 100644 --- a/widget/windows/nsTextStore.h +++ b/widget/windows/nsTextStore.h @@ -251,10 +251,10 @@ protected: void DidLockGranted(); bool GetScreenExtInternal(RECT &aScreenExt); - // If aDispatchTextEvent is true, this method will dispatch text event if - // this is called during IME composing. aDispatchTextEvent should be true - // only when this is called from SetSelection. Because otherwise, the text - // event should not be sent from here. + // If aDispatchTextEvent is true, this method will dispatch compositionchange + // event if this is called during IME composing. aDispatchTextEvent should + // be true only when this is called from SetSelection. Because otherwise, + // the compositionchange event should not be sent from here. HRESULT SetSelectionInternal(const TS_SELECTION_ACP*, bool aDispatchTextEvent = false); bool InsertTextAtSelectionInternal(const nsAString &aInsertStr, @@ -322,8 +322,8 @@ protected: // Current copy of the active composition string. Only mString is // changed during a InsertTextAtSelection call if we have a composition. // mString acts as a buffer until OnUpdateComposition is called - // and mString is flushed to editor through NS_TEXT_TEXT. This - // way all changes are updated in batches to avoid + // and mString is flushed to editor through NS_COMPOSITION_CHANGE. + // This way all changes are updated in batches to avoid // inconsistencies/artifacts. nsString mString; diff --git a/widget/xpwidgets/PuppetWidget.cpp b/widget/xpwidgets/PuppetWidget.cpp index 4912351a9063..0bed153a792d 100644 --- a/widget/xpwidgets/PuppetWidget.cpp +++ b/widget/xpwidgets/PuppetWidget.cpp @@ -382,7 +382,7 @@ PuppetWidget::IMEEndComposition(bool aCancel) #endif nsEventStatus status; - WidgetTextEvent textEvent(true, NS_TEXT_TEXT, this); + WidgetTextEvent textEvent(true, NS_COMPOSITION_CHANGE, this); InitEvent(textEvent, nullptr); textEvent.mSeqno = mIMELastReceivedSeqno; // SendEndIMEComposition is always called since ResetInputState From 19d03b41aa4e60b1c87d92a142c0bf70d4951d96 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Tue, 7 Oct 2014 19:01:47 +0900 Subject: [PATCH 18/84] Bug 960871 part.5 Copy mRanges and related methods from WidgetTextEvent to WidgetCompositionEvent r=smaug --- widget/TextEvents.h | 20 ++++++++++++++++++++ widget/nsGUIEventIPC.h | 27 +++++++++++++++++++++++---- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/widget/TextEvents.h b/widget/TextEvents.h index f7907fb140e9..81645e7aa1af 100644 --- a/widget/TextEvents.h +++ b/widget/TextEvents.h @@ -320,12 +320,32 @@ public: // TextComposition automatically. nsString mData; + nsRefPtr mRanges; + void AssignCompositionEventData(const WidgetCompositionEvent& aEvent, bool aCopyTargets) { AssignGUIEventData(aEvent, aCopyTargets); mData = aEvent.mData; + + // Currently, we don't need to copy the other members because they are + // for internal use only (not available from JS). + } + + bool IsComposing() const + { + return mRanges && mRanges->IsComposing(); + } + + uint32_t TargetClauseOffset() const + { + return mRanges ? mRanges->TargetClauseOffset() : 0; + } + + uint32_t RangeCount() const + { + return mRanges ? mRanges->Length() : 0; } }; diff --git a/widget/nsGUIEventIPC.h b/widget/nsGUIEventIPC.h index b5f0fb680c76..5635f663ecac 100644 --- a/widget/nsGUIEventIPC.h +++ b/widget/nsGUIEventIPC.h @@ -494,14 +494,33 @@ struct ParamTraits WriteParam(aMsg, static_cast(aParam)); WriteParam(aMsg, aParam.mSeqno); WriteParam(aMsg, aParam.mData); + bool hasRanges = !!aParam.mRanges; + WriteParam(aMsg, hasRanges); + if (hasRanges) { + WriteParam(aMsg, *aParam.mRanges.get()); + } } static bool Read(const Message* aMsg, void** aIter, paramType* aResult) { - return ReadParam(aMsg, aIter, - static_cast(aResult)) && - ReadParam(aMsg, aIter, &aResult->mSeqno) && - ReadParam(aMsg, aIter, &aResult->mData); + bool hasRanges; + if (!ReadParam(aMsg, aIter, + static_cast(aResult)) || + !ReadParam(aMsg, aIter, &aResult->mSeqno) || + !ReadParam(aMsg, aIter, &aResult->mData) || + !ReadParam(aMsg, aIter, &hasRanges)) { + return false; + } + + if (!hasRanges) { + aResult->mRanges = nullptr; + } else { + aResult->mRanges = new mozilla::TextRangeArray(); + if (!ReadParam(aMsg, aIter, aResult->mRanges.get())) { + return false; + } + } + return true; } }; From 9011740f123d5c4d505bedcdb87b2b8c6788181f Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Tue, 7 Oct 2014 19:01:48 +0900 Subject: [PATCH 19/84] Bug 960871 part.6 Use WidgetCompositionEvent for NS_COMPOSITION_CHANGE instead of WidgetTextEvent r=smaug --- dom/base/CompositionStringSynthesizer.cpp | 2 +- dom/events/EventDispatcher.cpp | 12 ++++----- dom/events/EventNameList.h | 2 +- dom/events/EventStateManager.cpp | 2 +- dom/events/IMEStateManager.cpp | 31 +++++------------------ dom/events/TextComposition.cpp | 30 +++++++++++----------- dom/events/TextComposition.h | 6 ++--- dom/ipc/PBrowser.ipdl | 3 +-- dom/ipc/TabChild.cpp | 4 +-- dom/ipc/TabChild.h | 2 +- dom/ipc/TabParent.cpp | 2 +- dom/ipc/TabParent.h | 2 +- editor/libeditor/nsEditor.cpp | 7 +---- editor/libeditor/nsPlaintextEditor.cpp | 6 +++-- layout/base/nsPresShell.cpp | 6 ++--- widget/android/nsWindow.cpp | 10 ++++---- widget/cocoa/TextInputHandler.mm | 2 +- widget/gtk/nsGtkIMModule.cpp | 3 ++- widget/gtk/nsWindow.cpp | 2 +- widget/windows/nsIMM32Handler.cpp | 2 +- widget/windows/nsTextStore.cpp | 4 +-- widget/xpwidgets/PuppetWidget.cpp | 2 +- 22 files changed, 58 insertions(+), 84 deletions(-) diff --git a/dom/base/CompositionStringSynthesizer.cpp b/dom/base/CompositionStringSynthesizer.cpp index 931fbe513422..83b26d7033fd 100644 --- a/dom/base/CompositionStringSynthesizer.cpp +++ b/dom/base/CompositionStringSynthesizer.cpp @@ -135,7 +135,7 @@ CompositionStringSynthesizer::DispatchEvent(bool* aDefaultPrevented) mClauses->AppendElement(mCaret); } - WidgetTextEvent textEvent(true, NS_COMPOSITION_CHANGE, widget); + WidgetCompositionEvent textEvent(true, NS_COMPOSITION_CHANGE, widget); textEvent.time = PR_IntervalNow(); textEvent.mData = mString; if (!mClauses->IsEmpty()) { diff --git a/dom/events/EventDispatcher.cpp b/dom/events/EventDispatcher.cpp index 16ec46a3d53f..873c54246349 100644 --- a/dom/events/EventDispatcher.cpp +++ b/dom/events/EventDispatcher.cpp @@ -702,6 +702,7 @@ EventDispatcher::CreateEvent(EventTarget* aOwner, return NS_NewDOMKeyboardEvent(aDOMEvent, aOwner, aPresContext, aEvent->AsKeyboardEvent()); case eCompositionEventClass: + case eTextEventClass: return NS_NewDOMCompositionEvent(aDOMEvent, aOwner, aPresContext, aEvent->AsCompositionEvent()); case eMouseEventClass: @@ -722,9 +723,6 @@ EventDispatcher::CreateEvent(EventTarget* aOwner, case eDragEventClass: return NS_NewDOMDragEvent(aDOMEvent, aOwner, aPresContext, aEvent->AsDragEvent()); - case eTextEventClass: - return NS_NewDOMUIEvent(aDOMEvent, aOwner, aPresContext, - aEvent->AsTextEvent()); case eClipboardEventClass: return NS_NewDOMClipboardEvent(aDOMEvent, aOwner, aPresContext, aEvent->AsClipboardEvent()); @@ -772,14 +770,14 @@ EventDispatcher::CreateEvent(EventTarget* aOwner, if (aEventType.LowerCaseEqualsLiteral("keyboardevent") || aEventType.LowerCaseEqualsLiteral("keyevents")) return NS_NewDOMKeyboardEvent(aDOMEvent, aOwner, aPresContext, nullptr); - if (aEventType.LowerCaseEqualsLiteral("compositionevent")) + if (aEventType.LowerCaseEqualsLiteral("compositionevent") || + aEventType.LowerCaseEqualsLiteral("textevent") || + aEventType.LowerCaseEqualsLiteral("textevents")) { return NS_NewDOMCompositionEvent(aDOMEvent, aOwner, aPresContext, nullptr); + } if (aEventType.LowerCaseEqualsLiteral("mutationevent") || aEventType.LowerCaseEqualsLiteral("mutationevents")) return NS_NewDOMMutationEvent(aDOMEvent, aOwner, aPresContext, nullptr); - if (aEventType.LowerCaseEqualsLiteral("textevent") || - aEventType.LowerCaseEqualsLiteral("textevents")) - return NS_NewDOMUIEvent(aDOMEvent, aOwner, aPresContext, nullptr); if (aEventType.LowerCaseEqualsLiteral("deviceorientationevent")) { DeviceOrientationEventInit init; nsRefPtr event = diff --git a/dom/events/EventNameList.h b/dom/events/EventNameList.h index 3ca264c01b9b..4864ab98cba0 100644 --- a/dom/events/EventNameList.h +++ b/dom/events/EventNameList.h @@ -658,7 +658,7 @@ NON_IDL_EVENT(speakerforcedchange, NON_IDL_EVENT(text, NS_COMPOSITION_CHANGE, EventNameType_XUL, - eTextEventClass) + eCompositionEventClass) NON_IDL_EVENT(compositionstart, NS_COMPOSITION_START, EventNameType_XUL, diff --git a/dom/events/EventStateManager.cpp b/dom/events/EventStateManager.cpp index 40df138ca874..a22c76318555 100644 --- a/dom/events/EventStateManager.cpp +++ b/dom/events/EventStateManager.cpp @@ -798,7 +798,7 @@ EventStateManager::PreHandleEvent(nsPresContext* aPresContext, break; case NS_COMPOSITION_CHANGE: { - WidgetTextEvent *textEvent = aEvent->AsTextEvent(); + WidgetCompositionEvent* textEvent = aEvent->AsCompositionEvent(); if (IsTargetCrossProcess(textEvent)) { // Will not be handled locally, remote the event if (GetCrossProcessTarget()->SendTextEvent(*textEvent)) { diff --git a/dom/events/IMEStateManager.cpp b/dom/events/IMEStateManager.cpp index 362d22c81038..d766d0dca95c 100644 --- a/dom/events/IMEStateManager.cpp +++ b/dom/events/IMEStateManager.cpp @@ -130,19 +130,6 @@ GetIMEStateSetOpenName(IMEState::Open aOpen) } } -static const char* -GetEventClassIDName(EventClassID aEventClassID) -{ - switch (aEventClassID) { - case eCompositionEventClass: - return "eCompositionEventClass"; - case eTextEventClass: - return "eTextEventClass"; - default: - return "unacceptable event struct type"; - } -} - static const char* GetEventMessageName(uint32_t aMessage) { @@ -892,18 +879,16 @@ IMEStateManager::DispatchCompositionEvent(nsINode* aEventTargetNode, { PR_LOG(sISMLog, PR_LOG_ALWAYS, ("ISM: IMEStateManager::DispatchCompositionEvent(aNode=0x%p, " - "aPresContext=0x%p, aEvent={ mClass=%s, message=%s, " + "aPresContext=0x%p, aEvent={ message=%s, " "mFlags={ mIsTrusted=%s, mPropagationStopped=%s } }, " "aIsSynthesized=%s)", aEventTargetNode, aPresContext, - GetEventClassIDName(aEvent->mClass), GetEventMessageName(aEvent->message), GetBoolName(aEvent->mFlags.mIsTrusted), GetBoolName(aEvent->mFlags.mPropagationStopped), GetBoolName(aIsSynthesized))); - MOZ_ASSERT(aEvent->mClass == eCompositionEventClass || - aEvent->mClass == eTextEventClass); + MOZ_ASSERT(aEvent->mClass == eCompositionEventClass); if (!aEvent->mFlags.mIsTrusted || aEvent->mFlags.mPropagationStopped) { return; } @@ -975,14 +960,12 @@ IMEStateManager::OnCompositionEventDiscarded(WidgetEvent* aEvent) // commit or cancel composition. PR_LOG(sISMLog, PR_LOG_ALWAYS, - ("ISM: IMEStateManager::OnCompositionEventDiscarded(aEvent={ mClass=%s, " + ("ISM: IMEStateManager::OnCompositionEventDiscarded(aEvent={ " "message=%s, mFlags={ mIsTrusted=%s } })", - GetEventClassIDName(aEvent->mClass), GetEventMessageName(aEvent->message), GetBoolName(aEvent->mFlags.mIsTrusted))); - MOZ_ASSERT(aEvent->mClass == eCompositionEventClass || - aEvent->mClass == eTextEventClass); + MOZ_ASSERT(aEvent->mClass == eCompositionEventClass); if (!aEvent->mFlags.mIsTrusted) { return; } @@ -1233,10 +1216,8 @@ IMEStateManager::GetTextCompositionFor(nsIWidget* aWidget) already_AddRefed IMEStateManager::GetTextCompositionFor(WidgetGUIEvent* aEvent) { - MOZ_ASSERT(aEvent->AsCompositionEvent() || aEvent->AsTextEvent() || - aEvent->AsKeyboardEvent(), - "aEvent has to be WidgetCompositionEvent, WidgetTextEvent or " - "WidgetKeyboardEvent"); + MOZ_ASSERT(aEvent->AsCompositionEvent() || aEvent->AsKeyboardEvent(), + "aEvent has to be WidgetCompositionEvent or WidgetKeyboardEvent"); return GetTextCompositionFor(aEvent->widget); } diff --git a/dom/events/TextComposition.cpp b/dom/events/TextComposition.cpp index ec5b1e5b1ae7..6af20f6c4144 100644 --- a/dom/events/TextComposition.cpp +++ b/dom/events/TextComposition.cpp @@ -61,7 +61,8 @@ TextComposition::MatchesNativeContext(nsIWidget* aWidget) const } bool -TextComposition::MaybeDispatchCompositionUpdate(const WidgetTextEvent* aEvent) +TextComposition::MaybeDispatchCompositionUpdate( + const WidgetCompositionEvent* aEvent) { if (Destroyed()) { return false; @@ -95,8 +96,7 @@ TextComposition::OnCompositionEventDiscarded(const WidgetGUIEvent* aEvent) MOZ_ASSERT(aEvent->mFlags.mIsTrusted, "Shouldn't be called with untrusted event"); - MOZ_ASSERT(aEvent->mClass == eCompositionEventClass || - aEvent->mClass == eTextEventClass); + MOZ_ASSERT(aEvent->mClass == eCompositionEventClass); // XXX If composition events are discarded, should we dispatch them with // runnable event? However, even if we do so, it might make native IME @@ -146,10 +146,8 @@ TextComposition::DispatchEvent(WidgetGUIEvent* aEvent, nsString* committingData = nullptr; switch (aEvent->message) { case NS_COMPOSITION_END: - committingData = &aEvent->AsCompositionEvent()->mData; - break; case NS_COMPOSITION_CHANGE: - committingData = &aEvent->AsTextEvent()->mData; + committingData = &aEvent->AsCompositionEvent()->mData; break; default: NS_WARNING("Unexpected event comes during committing or " @@ -167,7 +165,7 @@ TextComposition::DispatchEvent(WidgetGUIEvent* aEvent, } if (aEvent->message == NS_COMPOSITION_CHANGE) { - if (!MaybeDispatchCompositionUpdate(aEvent->AsTextEvent())) { + if (!MaybeDispatchCompositionUpdate(aEvent->AsCompositionEvent())) { return; } } @@ -182,7 +180,7 @@ TextComposition::DispatchEvent(WidgetGUIEvent* aEvent, // Emulate editor behavior of compositionchange event (DOM text event) handler // if no editor handles composition events. if (aEvent->message == NS_COMPOSITION_CHANGE && !HasEditor()) { - EditorWillHandleTextEvent(aEvent->AsTextEvent()); + EditorWillHandleTextEvent(aEvent->AsCompositionEvent()); EditorDidHandleTextEvent(); } @@ -220,11 +218,12 @@ TextComposition::NotityUpdateComposition(WidgetGUIEvent* aEvent) mCompositionStartOffset = 0; } mCompositionTargetOffset = mCompositionStartOffset; - } else if (aEvent->mClass != eTextEventClass) { - return; - } else { + } else if (aEvent->message == NS_COMPOSITION_CHANGE) { mCompositionTargetOffset = - mCompositionStartOffset + aEvent->AsTextEvent()->TargetClauseOffset(); + mCompositionStartOffset + + aEvent->AsCompositionEvent()->TargetClauseOffset(); + } else { + return; } NotifyIME(NOTIFY_IME_OF_COMPOSITION_UPDATE); @@ -286,7 +285,7 @@ TextComposition::RequestToCommit(nsIWidget* aWidget, bool aDiscard) nsAutoString commitData(aDiscard ? EmptyString() : lastData); bool changingData = lastData != commitData; - WidgetTextEvent textEvent(true, NS_COMPOSITION_CHANGE, widget); + WidgetCompositionEvent textEvent(true, NS_COMPOSITION_CHANGE, widget); textEvent.mData = commitData; textEvent.mFlags.mIsSynthesizedForTests = true; @@ -340,7 +339,8 @@ TextComposition::NotifyIME(IMEMessage aMessage) } void -TextComposition::EditorWillHandleTextEvent(const WidgetTextEvent* aTextEvent) +TextComposition::EditorWillHandleTextEvent( + const WidgetCompositionEvent* aTextEvent) { mIsComposing = aTextEvent->IsComposing(); mRanges = aTextEvent->mRanges; @@ -454,7 +454,7 @@ TextComposition::CompositionEventDispatcher::Run() break; } case NS_COMPOSITION_CHANGE: { - WidgetTextEvent textEvent(true, NS_COMPOSITION_CHANGE, widget); + WidgetCompositionEvent textEvent(true, NS_COMPOSITION_CHANGE, widget); textEvent.mData = mData; textEvent.mFlags.mIsSynthesizedForTests = mTextComposition->IsSynthesizedForTests(); diff --git a/dom/events/TextComposition.h b/dom/events/TextComposition.h index 1c9c3f825d49..4c8ff8cb240d 100644 --- a/dom/events/TextComposition.h +++ b/dom/events/TextComposition.h @@ -132,7 +132,7 @@ public: { public: TextEventHandlingMarker(TextComposition* aComposition, - const WidgetTextEvent* aTextEvent) + const WidgetCompositionEvent* aTextEvent) : mComposition(aComposition) { mComposition->EditorWillHandleTextEvent(aTextEvent); @@ -235,7 +235,7 @@ private: * EditorWillHandleTextEvent() must be called before the focused editor * handles the compositionchange event. */ - void EditorWillHandleTextEvent(const WidgetTextEvent* aTextEvent); + void EditorWillHandleTextEvent(const WidgetCompositionEvent* aTextEvent); /** * EditorDidHandleTextEvent() must be called after the focused editor handles @@ -258,7 +258,7 @@ private: * @return Returns false if dispatching the compositionupdate event caused * destroying this composition. */ - bool MaybeDispatchCompositionUpdate(const WidgetTextEvent* aEvent); + bool MaybeDispatchCompositionUpdate(const WidgetCompositionEvent* aEvent); /** * If IME has already dispatched compositionend event but it was discarded diff --git a/dom/ipc/PBrowser.ipdl b/dom/ipc/PBrowser.ipdl index 22691ead7465..976d89209846 100644 --- a/dom/ipc/PBrowser.ipdl +++ b/dom/ipc/PBrowser.ipdl @@ -44,7 +44,6 @@ using class mozilla::WidgetMouseEvent from "ipc/nsGUIEventIPC.h"; using class mozilla::WidgetWheelEvent from "ipc/nsGUIEventIPC.h"; using struct nsRect from "nsRect.h"; using class mozilla::WidgetSelectionEvent from "ipc/nsGUIEventIPC.h"; -using class mozilla::WidgetTextEvent from "ipc/nsGUIEventIPC.h"; using class mozilla::WidgetTouchEvent from "ipc/nsGUIEventIPC.h"; using struct mozilla::dom::RemoteDOMEvent from "mozilla/dom/TabMessageUtils.h"; using mozilla::dom::ScreenOrientation from "mozilla/dom/ScreenOrientation.h"; @@ -479,7 +478,7 @@ child: CompositionEvent(WidgetCompositionEvent event); - TextEvent(WidgetTextEvent event); + TextEvent(WidgetCompositionEvent event); SelectionEvent(WidgetSelectionEvent event); diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index 102333e89a94..3def67b24d89 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -2389,9 +2389,9 @@ TabChild::RecvCompositionEvent(const WidgetCompositionEvent& event) } bool -TabChild::RecvTextEvent(const WidgetTextEvent& event) +TabChild::RecvTextEvent(const WidgetCompositionEvent& event) { - WidgetTextEvent localEvent(event); + WidgetCompositionEvent localEvent(event); localEvent.widget = mWidget; DispatchWidgetEvent(localEvent); return true; diff --git a/dom/ipc/TabChild.h b/dom/ipc/TabChild.h index 2442882eb8c6..2e2003e11d2b 100644 --- a/dom/ipc/TabChild.h +++ b/dom/ipc/TabChild.h @@ -360,7 +360,7 @@ public: const int32_t& aModifiers, const bool& aPreventDefault) MOZ_OVERRIDE; virtual bool RecvCompositionEvent(const mozilla::WidgetCompositionEvent& event) MOZ_OVERRIDE; - virtual bool RecvTextEvent(const mozilla::WidgetTextEvent& event) MOZ_OVERRIDE; + virtual bool RecvTextEvent(const mozilla::WidgetCompositionEvent& event) MOZ_OVERRIDE; virtual bool RecvSelectionEvent(const mozilla::WidgetSelectionEvent& event) MOZ_OVERRIDE; virtual bool RecvActivateFrameEvent(const nsString& aType, const bool& capture) MOZ_OVERRIDE; virtual bool RecvLoadRemoteScript(const nsString& aURL, diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index b73538a49707..3796d39b760e 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -1582,7 +1582,7 @@ TabParent::SendCompositionEvent(WidgetCompositionEvent& event) * here and pass the text as the EndIMEComposition return value */ bool -TabParent::SendTextEvent(WidgetTextEvent& event) +TabParent::SendTextEvent(WidgetCompositionEvent& event) { if (mIsDestroyed) { return false; diff --git a/dom/ipc/TabParent.h b/dom/ipc/TabParent.h index 33fcb6b4a40e..409a515a8899 100644 --- a/dom/ipc/TabParent.h +++ b/dom/ipc/TabParent.h @@ -318,7 +318,7 @@ public: static TabParent *GetIMETabParent() { return mIMETabParent; } bool HandleQueryContentEvent(mozilla::WidgetQueryContentEvent& aEvent); bool SendCompositionEvent(mozilla::WidgetCompositionEvent& event); - bool SendTextEvent(mozilla::WidgetTextEvent& event); + bool SendTextEvent(mozilla::WidgetCompositionEvent& event); bool SendSelectionEvent(mozilla::WidgetSelectionEvent& event); static TabParent* GetFrom(nsFrameLoader* aFrameLoader); diff --git a/editor/libeditor/nsEditor.cpp b/editor/libeditor/nsEditor.cpp index cdb6e934eef6..13ebc2a2ae6b 100644 --- a/editor/libeditor/nsEditor.cpp +++ b/editor/libeditor/nsEditor.cpp @@ -5109,15 +5109,10 @@ nsEditor::IsAcceptableInputEvent(nsIDOMEvent* aEvent) // If events are not created with proper event interface, their message // are initialized with NS_USER_DEFINED_EVENT. Let's ignore such event. return false; - case NS_COMPOSITION_CHANGE: - // Don't allow compositionchange events whose internal event are not - // WidgetTextEvent. - widgetGUIEvent = aEvent->GetInternalNSEvent()->AsTextEvent(); - needsWidget = true; - break; case NS_COMPOSITION_START: case NS_COMPOSITION_END: case NS_COMPOSITION_UPDATE: + case NS_COMPOSITION_CHANGE: // Don't allow composition events whose internal event are not // WidgetCompositionEvent. widgetGUIEvent = aEvent->GetInternalNSEvent()->AsCompositionEvent(); diff --git a/editor/libeditor/nsPlaintextEditor.cpp b/editor/libeditor/nsPlaintextEditor.cpp index c6c64973eebc..80f7290ba8af 100644 --- a/editor/libeditor/nsPlaintextEditor.cpp +++ b/editor/libeditor/nsPlaintextEditor.cpp @@ -846,9 +846,11 @@ nsPlaintextEditor::UpdateIMEComposition(nsIDOMEvent* aDOMTextEvent) { NS_ABORT_IF_FALSE(aDOMTextEvent, "aDOMTextEvent must not be nullptr"); - WidgetTextEvent* widgetTextEvent = - aDOMTextEvent->GetInternalNSEvent()->AsTextEvent(); + WidgetCompositionEvent* widgetTextEvent = + aDOMTextEvent->GetInternalNSEvent()->AsCompositionEvent(); NS_ENSURE_TRUE(widgetTextEvent, NS_ERROR_INVALID_ARG); + MOZ_ASSERT(compChangeEvent->message == NS_COMPOSITION_CHANGE, + "The internal event should be NS_COMPOSITION_CHANGE"); EnsureComposition(widgetTextEvent); diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index b780580cb9f8..d920bd51cae9 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -6942,8 +6942,7 @@ PresShell::HandleEvent(nsIFrame* aFrame, if (!nsContentUtils::IsSafeToRunScript() && aEvent->IsAllowedToDispatchDOMEvent()) { - if (aEvent->mClass == eCompositionEventClass || - aEvent->mClass == eTextEventClass) { + if (aEvent->mClass == eCompositionEventClass) { IMEStateManager::OnCompositionEventDiscarded(aEvent); } #ifdef DEBUG @@ -7859,8 +7858,7 @@ PresShell::HandleEventInternal(WidgetEvent* aEvent, nsEventStatus* aStatus) } } if (eventTarget) { - if (aEvent->mClass == eCompositionEventClass || - aEvent->mClass == eTextEventClass) { + if (aEvent->mClass == eCompositionEventClass) { IMEStateManager::DispatchCompositionEvent(eventTarget, mPresContext, aEvent, aStatus, eventCBPtr); } else { diff --git a/widget/android/nsWindow.cpp b/widget/android/nsWindow.cpp index 31f745347a9d..1a855fce3182 100644 --- a/widget/android/nsWindow.cpp +++ b/widget/android/nsWindow.cpp @@ -685,7 +685,7 @@ nsWindow::DispatchEvent(WidgetGUIEvent* aEvent) break; case NS_COMPOSITION_CHANGE: MOZ_ASSERT(mIMEComposing); - mIMEComposingText = aEvent->AsTextEvent()->mData; + mIMEComposingText = aEvent->AsCompositionEvent()->mData; break; } return status; @@ -1707,7 +1707,7 @@ nsWindow::RemoveIMEComposition() AutoIMEMask selMask(mIMEMaskSelectionUpdate); AutoIMEMask textMask(mIMEMaskTextUpdate); - WidgetTextEvent textEvent(true, NS_COMPOSITION_CHANGE, this); + WidgetCompositionEvent textEvent(true, NS_COMPOSITION_CHANGE, this); InitEvent(textEvent, nullptr); textEvent.mData = mIMEComposingText; DispatchEvent(&textEvent); @@ -1845,7 +1845,7 @@ nsWindow::OnIMEEvent(AndroidGeckoEvent *ae) } { - WidgetTextEvent event(true, NS_COMPOSITION_CHANGE, this); + WidgetCompositionEvent event(true, NS_COMPOSITION_CHANGE, this); InitEvent(event, nullptr); event.mData = ae->Characters(); @@ -1955,7 +1955,7 @@ nsWindow::OnIMEEvent(AndroidGeckoEvent *ae) AutoIMEMask selMask(mIMEMaskSelectionUpdate); AutoIMEMask textMask(mIMEMaskTextUpdate); - WidgetTextEvent event(true, NS_COMPOSITION_CHANGE, this); + WidgetCompositionEvent event(true, NS_COMPOSITION_CHANGE, this); InitEvent(event, nullptr); event.mRanges = new TextRangeArray(); @@ -2086,7 +2086,7 @@ nsWindow::NotifyIME(const IMENotification& aIMENotification) if (mIMEComposing) { nsRefPtr kungFuDeathGrip(this); - WidgetTextEvent textEvent(true, NS_COMPOSITION_CHANGE, this); + WidgetCompositionEvent textEvent(true, NS_COMPOSITION_CHANGE, this); InitEvent(textEvent, nullptr); DispatchEvent(&textEvent); diff --git a/widget/cocoa/TextInputHandler.mm b/widget/cocoa/TextInputHandler.mm index 46f77c51ecec..d2397057edda 100644 --- a/widget/cocoa/TextInputHandler.mm +++ b/widget/cocoa/TextInputHandler.mm @@ -2716,7 +2716,7 @@ IMEInputHandler::DispatchTextEvent(const nsString& aText, nsRefPtr kungFuDeathGrip(this); - WidgetTextEvent textEvent(true, NS_COMPOSITION_CHANGE, mWidget); + WidgetCompositionEvent textEvent(true, NS_COMPOSITION_CHANGE, mWidget); textEvent.time = PR_IntervalNow(); textEvent.mData = aText; if (!aDoCommit) { diff --git a/widget/gtk/nsGtkIMModule.cpp b/widget/gtk/nsGtkIMModule.cpp index c82238a17fd1..237c6a654ce8 100644 --- a/widget/gtk/nsGtkIMModule.cpp +++ b/widget/gtk/nsGtkIMModule.cpp @@ -1107,7 +1107,8 @@ nsGtkIMModule::DispatchTextEvent(const nsAString &aCompositionString, } } - WidgetTextEvent textEvent(true, NS_COMPOSITION_CHANGE, mLastFocusedWindow); + WidgetCompositionEvent textEvent(true, NS_COMPOSITION_CHANGE, + mLastFocusedWindow); InitEvent(textEvent); uint32_t targetOffset = mCompositionStart; diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp index 08a8551dc98d..25dc55282816 100644 --- a/widget/gtk/nsWindow.cpp +++ b/widget/gtk/nsWindow.cpp @@ -3046,7 +3046,7 @@ nsWindow::OnKeyPressEvent(GdkEventKey *aEvent) DispatchEvent(&event, status); } else { - WidgetTextEvent textEvent(true, NS_COMPOSITION_CHANGE, this); + WidgetCompositionEvent textEvent(true, NS_COMPOSITION_CHANGE, this); char16_t textString[3]; textString[0] = H_SURROGATE(event.charCode); textString[1] = L_SURROGATE(event.charCode); diff --git a/widget/windows/nsIMM32Handler.cpp b/widget/windows/nsIMM32Handler.cpp index ba409d641f14..e2110137b30d 100644 --- a/widget/windows/nsIMM32Handler.cpp +++ b/widget/windows/nsIMM32Handler.cpp @@ -1591,7 +1591,7 @@ nsIMM32Handler::DispatchTextEvent(nsWindow* aWindow, nsIntPoint point(0, 0); - WidgetTextEvent event(true, NS_COMPOSITION_CHANGE, aWindow); + WidgetCompositionEvent event(true, NS_COMPOSITION_CHANGE, aWindow); aWindow->InitEvent(event, &point); diff --git a/widget/windows/nsTextStore.cpp b/widget/windows/nsTextStore.cpp index da766fe4089f..edcc776ed931 100644 --- a/widget/windows/nsTextStore.cpp +++ b/widget/windows/nsTextStore.cpp @@ -1650,7 +1650,7 @@ nsTextStore::FlushPendingActions() PR_LOG(sTextStoreLog, PR_LOG_DEBUG, ("TSF: 0x%p nsTextStore::FlushPendingActions(), " "dispatching compositionchange event...", this)); - WidgetTextEvent textEvent(true, NS_COMPOSITION_CHANGE, mWidget); + WidgetCompositionEvent textEvent(true, NS_COMPOSITION_CHANGE, mWidget); mWidget->InitEvent(textEvent); textEvent.mData = action.mData; if (action.mRanges->IsEmpty()) { @@ -1677,7 +1677,7 @@ nsTextStore::FlushPendingActions() PR_LOG(sTextStoreLog, PR_LOG_DEBUG, ("TSF: 0x%p nsTextStore::FlushPendingActions(), " "dispatching compositionchange event...", this)); - WidgetTextEvent textEvent(true, NS_COMPOSITION_CHANGE, mWidget); + WidgetCompositionEvent textEvent(true, NS_COMPOSITION_CHANGE, mWidget); mWidget->InitEvent(textEvent); textEvent.mData = action.mData; mWidget->DispatchWindowEvent(&textEvent); diff --git a/widget/xpwidgets/PuppetWidget.cpp b/widget/xpwidgets/PuppetWidget.cpp index 0bed153a792d..371ba9efecc4 100644 --- a/widget/xpwidgets/PuppetWidget.cpp +++ b/widget/xpwidgets/PuppetWidget.cpp @@ -382,7 +382,7 @@ PuppetWidget::IMEEndComposition(bool aCancel) #endif nsEventStatus status; - WidgetTextEvent textEvent(true, NS_COMPOSITION_CHANGE, this); + WidgetCompositionEvent textEvent(true, NS_COMPOSITION_CHANGE, this); InitEvent(textEvent, nullptr); textEvent.mSeqno = mIMELastReceivedSeqno; // SendEndIMEComposition is always called since ResetInputState From d08404080c1194d5cfbd849639cfc4c9b0d9d530 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Tue, 7 Oct 2014 19:01:48 +0900 Subject: [PATCH 20/84] Bug 960871 part.7 Get rid of WidgetTextEvent r=smaug --- dom/events/EventDispatcher.cpp | 1 - dom/interfaces/events/nsIDOMEvent.idl | 5 -- widget/EventClassList.h | 1 - widget/TextEvents.h | 74 --------------------------- widget/nsGUIEventIPC.h | 43 ---------------- widget/xpwidgets/PuppetWidget.cpp | 3 -- 6 files changed, 127 deletions(-) diff --git a/dom/events/EventDispatcher.cpp b/dom/events/EventDispatcher.cpp index 873c54246349..1388fa29bc9c 100644 --- a/dom/events/EventDispatcher.cpp +++ b/dom/events/EventDispatcher.cpp @@ -702,7 +702,6 @@ EventDispatcher::CreateEvent(EventTarget* aOwner, return NS_NewDOMKeyboardEvent(aDOMEvent, aOwner, aPresContext, aEvent->AsKeyboardEvent()); case eCompositionEventClass: - case eTextEventClass: return NS_NewDOMCompositionEvent(aDOMEvent, aOwner, aPresContext, aEvent->AsCompositionEvent()); case eMouseEventClass: diff --git a/dom/interfaces/events/nsIDOMEvent.idl b/dom/interfaces/events/nsIDOMEvent.idl index f808bc95b3a9..7904bfe42031 100644 --- a/dom/interfaces/events/nsIDOMEvent.idl +++ b/dom/interfaces/events/nsIDOMEvent.idl @@ -288,11 +288,6 @@ NS_NewDOMDeviceMotionEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, mozilla::WidgetEvent* aEvent); nsresult -NS_NewDOMTextEvent(nsIDOMEvent** aResult, - mozilla::dom::EventTarget* aOwner, - nsPresContext* aPresContext, - mozilla::WidgetTextEvent* aEvent); -nsresult NS_NewDOMBeforeUnloadEvent(nsIDOMEvent** aResult, mozilla::dom::EventTarget* aOwner, nsPresContext* aPresContext, diff --git a/widget/EventClassList.h b/widget/EventClassList.h index 3ed982479f90..e6a160fab86d 100644 --- a/widget/EventClassList.h +++ b/widget/EventClassList.h @@ -22,7 +22,6 @@ NS_EVENT_CLASS(Internal, UIEvent) // TextEvents.h NS_EVENT_CLASS(Widget, KeyboardEvent) -NS_EVENT_CLASS(Widget, TextEvent) NS_EVENT_CLASS(Widget, CompositionEvent) NS_EVENT_CLASS(Widget, QueryContentEvent) NS_EVENT_CLASS(Widget, SelectionEvent) diff --git a/widget/TextEvents.h b/widget/TextEvents.h index 81645e7aa1af..9d5bdc06238e 100644 --- a/widget/TextEvents.h +++ b/widget/TextEvents.h @@ -194,80 +194,6 @@ public: } }; -/****************************************************************************** - * mozilla::WidgetTextEvent - * - * XXX WidgetTextEvent is fired with compositionupdate event almost every time. - * This wastes performance and the cost of mantaining each platform's - * implementation. Therefore, we should merge WidgetTextEvent and - * WidgetCompositionEvent. Then, DOM compositionupdate should be fired - * from TextComposition automatically. - ******************************************************************************/ - -class WidgetTextEvent : public WidgetGUIEvent -{ -private: - friend class dom::PBrowserParent; - friend class dom::PBrowserChild; - friend class plugins::PPluginInstanceChild; - - WidgetTextEvent() - : mSeqno(kLatestSeqno) - { - } - -public: - uint32_t mSeqno; - -public: - virtual WidgetTextEvent* AsTextEvent() MOZ_OVERRIDE { return this; } - - WidgetTextEvent(bool aIsTrusted, uint32_t aMessage, nsIWidget* aWidget) - : WidgetGUIEvent(aIsTrusted, aMessage, aWidget, eTextEventClass) - , mSeqno(kLatestSeqno) - { - } - - virtual WidgetEvent* Duplicate() const MOZ_OVERRIDE - { - MOZ_ASSERT(mClass == eTextEventClass, - "Duplicate() must be overridden by sub class"); - // Not copying widget, it is a weak reference. - WidgetTextEvent* result = new WidgetTextEvent(false, message, nullptr); - result->AssignTextEventData(*this, true); - result->mFlags = mFlags; - return result; - } - - // The composition string or the commit string. - nsString mData; - - nsRefPtr mRanges; - - void AssignTextEventData(const WidgetTextEvent& aEvent, bool aCopyTargets) - { - AssignGUIEventData(aEvent, aCopyTargets); - - // Currently, we don't need to copy the other members because they are - // for internal use only (not available from JS). - } - - bool IsComposing() const - { - return mRanges && mRanges->IsComposing(); - } - - uint32_t TargetClauseOffset() const - { - return mRanges ? mRanges->TargetClauseOffset() : 0; - } - - uint32_t RangeCount() const - { - return mRanges ? mRanges->Length() : 0; - } -}; - /****************************************************************************** * mozilla::WidgetCompositionEvent ******************************************************************************/ diff --git a/widget/nsGUIEventIPC.h b/widget/nsGUIEventIPC.h index 5635f663ecac..cb639b526385 100644 --- a/widget/nsGUIEventIPC.h +++ b/widget/nsGUIEventIPC.h @@ -441,49 +441,6 @@ struct ParamTraits } }; -template<> -struct ParamTraits -{ - typedef mozilla::WidgetTextEvent paramType; - - static void Write(Message* aMsg, const paramType& aParam) - { - WriteParam(aMsg, static_cast(aParam)); - WriteParam(aMsg, aParam.mSeqno); - WriteParam(aMsg, aParam.mData); - bool hasRanges = !!aParam.mRanges; - WriteParam(aMsg, hasRanges); - if (hasRanges) { - WriteParam(aMsg, *aParam.mRanges.get()); - } - } - - static bool Read(const Message* aMsg, void** aIter, paramType* aResult) - { - bool hasRanges; - if (!ReadParam(aMsg, aIter, - static_cast(aResult)) || - !ReadParam(aMsg, aIter, &aResult->mSeqno) || - !ReadParam(aMsg, aIter, &aResult->mData) || - !ReadParam(aMsg, aIter, &hasRanges)) { - return false; - } - - if (!hasRanges) { - aResult->mRanges = nullptr; - } else { - aResult->mRanges = new mozilla::TextRangeArray(); - if (!aResult->mRanges) { - return false; - } - if (!ReadParam(aMsg, aIter, aResult->mRanges.get())) { - return false; - } - } - return true; - } -}; - template<> struct ParamTraits { diff --git a/widget/xpwidgets/PuppetWidget.cpp b/widget/xpwidgets/PuppetWidget.cpp index 371ba9efecc4..109380e32023 100644 --- a/widget/xpwidgets/PuppetWidget.cpp +++ b/widget/xpwidgets/PuppetWidget.cpp @@ -291,9 +291,6 @@ PuppetWidget::DispatchEvent(WidgetGUIEvent* event, nsEventStatus& aStatus) case eCompositionEventClass: seqno = event->AsCompositionEvent()->mSeqno; break; - case eTextEventClass: - seqno = event->AsTextEvent()->mSeqno; - break; case eSelectionEventClass: seqno = event->AsSelectionEvent()->mSeqno; break; From 6072e74d014a4ff32aa2b0e00f1c53f7c866989b Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Tue, 7 Oct 2014 19:01:49 +0900 Subject: [PATCH 21/84] Bug 960871 part.8 Rename variable names of NS_COMPOSITION_CHANGE event r=smaug --- dom/base/CompositionStringSynthesizer.cpp | 12 ++++----- dom/events/EventStateManager.cpp | 6 ++--- dom/events/TextComposition.cpp | 31 ++++++++--------------- dom/events/TextComposition.h | 10 +++++--- editor/libeditor/nsPlaintextEditor.cpp | 12 ++++----- widget/android/nsWindow.cpp | 30 ++++++++++++---------- widget/cocoa/TextInputHandler.mm | 16 +++++++----- widget/gtk/nsGtkIMModule.cpp | 15 ++++++----- widget/gtk/nsWindow.cpp | 9 ++++--- widget/windows/nsTextStore.cpp | 24 ++++++++++-------- widget/xpwidgets/PuppetWidget.cpp | 20 ++++++++------- 11 files changed, 94 insertions(+), 91 deletions(-) diff --git a/dom/base/CompositionStringSynthesizer.cpp b/dom/base/CompositionStringSynthesizer.cpp index 83b26d7033fd..1c57ffab843e 100644 --- a/dom/base/CompositionStringSynthesizer.cpp +++ b/dom/base/CompositionStringSynthesizer.cpp @@ -135,18 +135,18 @@ CompositionStringSynthesizer::DispatchEvent(bool* aDefaultPrevented) mClauses->AppendElement(mCaret); } - WidgetCompositionEvent textEvent(true, NS_COMPOSITION_CHANGE, widget); - textEvent.time = PR_IntervalNow(); - textEvent.mData = mString; + WidgetCompositionEvent compChangeEvent(true, NS_COMPOSITION_CHANGE, widget); + compChangeEvent.time = PR_IntervalNow(); + compChangeEvent.mData = mString; if (!mClauses->IsEmpty()) { - textEvent.mRanges = mClauses; + compChangeEvent.mRanges = mClauses; } // XXX How should we set false for this on b2g? - textEvent.mFlags.mIsSynthesizedForTests = true; + compChangeEvent.mFlags.mIsSynthesizedForTests = true; nsEventStatus status = nsEventStatus_eIgnore; - nsresult rv = widget->DispatchEvent(&textEvent, status); + nsresult rv = widget->DispatchEvent(&compChangeEvent, status); *aDefaultPrevented = (status == nsEventStatus_eConsumeNoDefault); ClearInternal(); diff --git a/dom/events/EventStateManager.cpp b/dom/events/EventStateManager.cpp index a22c76318555..a24a4b15e5d8 100644 --- a/dom/events/EventStateManager.cpp +++ b/dom/events/EventStateManager.cpp @@ -798,10 +798,10 @@ EventStateManager::PreHandleEvent(nsPresContext* aPresContext, break; case NS_COMPOSITION_CHANGE: { - WidgetCompositionEvent* textEvent = aEvent->AsCompositionEvent(); - if (IsTargetCrossProcess(textEvent)) { + WidgetCompositionEvent* compositionEvent = aEvent->AsCompositionEvent(); + if (IsTargetCrossProcess(compositionEvent)) { // Will not be handled locally, remote the event - if (GetCrossProcessTarget()->SendTextEvent(*textEvent)) { + if (GetCrossProcessTarget()->SendTextEvent(*compositionEvent)) { // Cancel local dispatching aEvent->mFlags.mPropagationStopped = true; } diff --git a/dom/events/TextComposition.cpp b/dom/events/TextComposition.cpp index 6af20f6c4144..18073480819c 100644 --- a/dom/events/TextComposition.cpp +++ b/dom/events/TextComposition.cpp @@ -285,11 +285,11 @@ TextComposition::RequestToCommit(nsIWidget* aWidget, bool aDiscard) nsAutoString commitData(aDiscard ? EmptyString() : lastData); bool changingData = lastData != commitData; - WidgetCompositionEvent textEvent(true, NS_COMPOSITION_CHANGE, widget); - textEvent.mData = commitData; - textEvent.mFlags.mIsSynthesizedForTests = true; + WidgetCompositionEvent changeEvent(true, NS_COMPOSITION_CHANGE, widget); + changeEvent.mData = commitData; + changeEvent.mFlags.mIsSynthesizedForTests = true; - MaybeDispatchCompositionUpdate(&textEvent); + MaybeDispatchCompositionUpdate(&changeEvent); // If changing the data or committing string isn't empty, we need to // dispatch compositionchange event for setting the composition string @@ -297,7 +297,7 @@ TextComposition::RequestToCommit(nsIWidget* aWidget, bool aDiscard) if (!Destroyed() && !widget->Destroyed() && (changingData || !commitData.IsEmpty())) { nsEventStatus status = nsEventStatus_eIgnore; - widget->DispatchEvent(&textEvent, status); + widget->DispatchEvent(&changeEvent, status); } if (!Destroyed() && !widget->Destroyed()) { @@ -340,13 +340,13 @@ TextComposition::NotifyIME(IMEMessage aMessage) void TextComposition::EditorWillHandleTextEvent( - const WidgetCompositionEvent* aTextEvent) + const WidgetCompositionEvent* aCompositionChangeEvent) { - mIsComposing = aTextEvent->IsComposing(); - mRanges = aTextEvent->mRanges; + mIsComposing = aCompositionChangeEvent->IsComposing(); + mRanges = aCompositionChangeEvent->mRanges; mIsEditorHandlingEvent = true; - MOZ_ASSERT(mLastData == aTextEvent->mData, + MOZ_ASSERT(mLastData == aCompositionChangeEvent->mData, "The text of a compositionchange event must be same as previous data " "attribute value of the latest compositionupdate event"); } @@ -443,7 +443,8 @@ TextComposition::CompositionEventDispatcher::Run() mIsSynthesizedEvent); break; } - case NS_COMPOSITION_END: { + case NS_COMPOSITION_END: + case NS_COMPOSITION_CHANGE: { WidgetCompositionEvent compEvent(true, mEventMessage, widget); compEvent.mData = mData; compEvent.mFlags.mIsSynthesizedForTests = @@ -453,16 +454,6 @@ TextComposition::CompositionEventDispatcher::Run() mIsSynthesizedEvent); break; } - case NS_COMPOSITION_CHANGE: { - WidgetCompositionEvent textEvent(true, NS_COMPOSITION_CHANGE, widget); - textEvent.mData = mData; - textEvent.mFlags.mIsSynthesizedForTests = - mTextComposition->IsSynthesizedForTests(); - IMEStateManager::DispatchCompositionEvent(mEventTarget, presContext, - &textEvent, &status, nullptr, - mIsSynthesizedEvent); - break; - } default: MOZ_CRASH("Unsupported event"); } diff --git a/dom/events/TextComposition.h b/dom/events/TextComposition.h index 4c8ff8cb240d..9ac2d9303205 100644 --- a/dom/events/TextComposition.h +++ b/dom/events/TextComposition.h @@ -131,11 +131,12 @@ public: class MOZ_STACK_CLASS TextEventHandlingMarker { public: - TextEventHandlingMarker(TextComposition* aComposition, - const WidgetCompositionEvent* aTextEvent) + TextEventHandlingMarker( + TextComposition* aComposition, + const WidgetCompositionEvent* aCompositionChangeEvent) : mComposition(aComposition) { - mComposition->EditorWillHandleTextEvent(aTextEvent); + mComposition->EditorWillHandleTextEvent(aCompositionChangeEvent); } ~TextEventHandlingMarker() @@ -235,7 +236,8 @@ private: * EditorWillHandleTextEvent() must be called before the focused editor * handles the compositionchange event. */ - void EditorWillHandleTextEvent(const WidgetCompositionEvent* aTextEvent); + void EditorWillHandleTextEvent( + const WidgetCompositionEvent* aCompositionChangeEvent); /** * EditorDidHandleTextEvent() must be called after the focused editor handles diff --git a/editor/libeditor/nsPlaintextEditor.cpp b/editor/libeditor/nsPlaintextEditor.cpp index 80f7290ba8af..27a35c0c0898 100644 --- a/editor/libeditor/nsPlaintextEditor.cpp +++ b/editor/libeditor/nsPlaintextEditor.cpp @@ -846,13 +846,13 @@ nsPlaintextEditor::UpdateIMEComposition(nsIDOMEvent* aDOMTextEvent) { NS_ABORT_IF_FALSE(aDOMTextEvent, "aDOMTextEvent must not be nullptr"); - WidgetCompositionEvent* widgetTextEvent = + WidgetCompositionEvent* compositionChangeEvent = aDOMTextEvent->GetInternalNSEvent()->AsCompositionEvent(); - NS_ENSURE_TRUE(widgetTextEvent, NS_ERROR_INVALID_ARG); - MOZ_ASSERT(compChangeEvent->message == NS_COMPOSITION_CHANGE, + NS_ENSURE_TRUE(compositionChangeEvent, NS_ERROR_INVALID_ARG); + MOZ_ASSERT(compositionChangeEvent->message == NS_COMPOSITION_CHANGE, "The internal event should be NS_COMPOSITION_CHANGE"); - EnsureComposition(widgetTextEvent); + EnsureComposition(compositionChangeEvent); nsCOMPtr ps = GetPresShell(); NS_ENSURE_TRUE(ps, NS_ERROR_NOT_INITIALIZED); @@ -872,7 +872,7 @@ nsPlaintextEditor::UpdateIMEComposition(nsIDOMEvent* aDOMTextEvent) MOZ_ASSERT(!mPlaceHolderBatch, "UpdateIMEComposition() must be called without place holder batch"); TextComposition::TextEventHandlingMarker - textEventHandlingMarker(mComposition, widgetTextEvent); + textEventHandlingMarker(mComposition, compositionChangeEvent); NotifyEditorObservers(eNotifyEditorObserversOfBefore); @@ -881,7 +881,7 @@ nsPlaintextEditor::UpdateIMEComposition(nsIDOMEvent* aDOMTextEvent) { nsAutoPlaceHolderBatch batch(this, nsGkAtoms::IMETxnName); - rv = InsertText(widgetTextEvent->mData); + rv = InsertText(compositionChangeEvent->mData); if (caretP) { caretP->SetSelection(selection); diff --git a/widget/android/nsWindow.cpp b/widget/android/nsWindow.cpp index 1a855fce3182..cb9443e48807 100644 --- a/widget/android/nsWindow.cpp +++ b/widget/android/nsWindow.cpp @@ -1707,14 +1707,15 @@ nsWindow::RemoveIMEComposition() AutoIMEMask selMask(mIMEMaskSelectionUpdate); AutoIMEMask textMask(mIMEMaskTextUpdate); - WidgetCompositionEvent textEvent(true, NS_COMPOSITION_CHANGE, this); - InitEvent(textEvent, nullptr); - textEvent.mData = mIMEComposingText; - DispatchEvent(&textEvent); + WidgetCompositionEvent compositionChangeEvent(true, NS_COMPOSITION_CHANGE, + this); + InitEvent(compositionChangeEvent, nullptr); + compositionChangeEvent.mData = mIMEComposingText; + DispatchEvent(&compositionChangeEvent); - WidgetCompositionEvent event(true, NS_COMPOSITION_END, this); - InitEvent(event, nullptr); - DispatchEvent(&event); + WidgetCompositionEvent compEndEvent(true, NS_COMPOSITION_END, this); + InitEvent(compEndEvent, nullptr); + DispatchEvent(&compEndEvent); } void @@ -2086,14 +2087,15 @@ nsWindow::NotifyIME(const IMENotification& aIMENotification) if (mIMEComposing) { nsRefPtr kungFuDeathGrip(this); - WidgetCompositionEvent textEvent(true, NS_COMPOSITION_CHANGE, this); - InitEvent(textEvent, nullptr); - DispatchEvent(&textEvent); + WidgetCompositionEvent compositionChangeEvent( + true, NS_COMPOSITION_CHANGE, this); + InitEvent(compositionChangeEvent, nullptr); + DispatchEvent(&compositionChangeEvent); - WidgetCompositionEvent compEvent(true, NS_COMPOSITION_END, - this); - InitEvent(compEvent, nullptr); - DispatchEvent(&compEvent); + WidgetCompositionEvent compositionEndEvent( + true, NS_COMPOSITION_END, this); + InitEvent(compositionEndEvent, nullptr); + DispatchEvent(&compositionEndEvent); } mozilla::widget::android::GeckoAppShell::NotifyIME(REQUEST_TO_CANCEL_COMPOSITION); diff --git a/widget/cocoa/TextInputHandler.mm b/widget/cocoa/TextInputHandler.mm index d2397057edda..4d4a35bb35f7 100644 --- a/widget/cocoa/TextInputHandler.mm +++ b/widget/cocoa/TextInputHandler.mm @@ -2140,7 +2140,7 @@ TextInputHandler::InsertText(NSAttributedString* aAttrString, NS_ENSURE_TRUE_VOID(SetSelection(*aReplacementRange)); } - // Dispatch keypress event with char instead of textEvent + // Dispatch keypress event with char instead of compositionchange event WidgetKeyboardEvent keypressEvent(true, NS_KEY_PRESS, mWidget); keypressEvent.isChar = IsPrintableChar(str.CharAt(0)); @@ -2716,14 +2716,16 @@ IMEInputHandler::DispatchTextEvent(const nsString& aText, nsRefPtr kungFuDeathGrip(this); - WidgetCompositionEvent textEvent(true, NS_COMPOSITION_CHANGE, mWidget); - textEvent.time = PR_IntervalNow(); - textEvent.mData = aText; + WidgetCompositionEvent compositionChangeEvent(true, NS_COMPOSITION_CHANGE, + mWidget); + compositionChangeEvent.time = PR_IntervalNow(); + compositionChangeEvent.mData = aText; if (!aDoCommit) { - textEvent.mRanges = CreateTextRangeArray(aAttrString, aSelectedRange); + compositionChangeEvent.mRanges = + CreateTextRangeArray(aAttrString, aSelectedRange); } - mLastDispatchedCompositionString = textEvent.mData; - return DispatchEvent(textEvent); + mLastDispatchedCompositionString = compositionChangeEvent.mData; + return DispatchEvent(compositionChangeEvent); } void diff --git a/widget/gtk/nsGtkIMModule.cpp b/widget/gtk/nsGtkIMModule.cpp index 237c6a654ce8..164400923f5f 100644 --- a/widget/gtk/nsGtkIMModule.cpp +++ b/widget/gtk/nsGtkIMModule.cpp @@ -1107,26 +1107,27 @@ nsGtkIMModule::DispatchTextEvent(const nsAString &aCompositionString, } } - WidgetCompositionEvent textEvent(true, NS_COMPOSITION_CHANGE, - mLastFocusedWindow); - InitEvent(textEvent); + WidgetCompositionEvent compositionChangeEvent(true, NS_COMPOSITION_CHANGE, + mLastFocusedWindow); + InitEvent(compositionChangeEvent); uint32_t targetOffset = mCompositionStart; - textEvent.mData = mDispatchedCompositionString = aCompositionString; + compositionChangeEvent.mData = + mDispatchedCompositionString = aCompositionString; if (!aIsCommit) { // NOTE: SetTextRangeList() assumes that mDispatchedCompositionString // has been updated already. - textEvent.mRanges = CreateTextRangeArray(); - targetOffset += textEvent.mRanges->TargetClauseOffset(); + compositionChangeEvent.mRanges = CreateTextRangeArray(); + targetOffset += compositionChangeEvent.mRanges->TargetClauseOffset(); } mCompositionState = aIsCommit ? eCompositionState_CommitTextEventDispatched : eCompositionState_TextEventDispatched; - mLastFocusedWindow->DispatchEvent(&textEvent, status); + mLastFocusedWindow->DispatchEvent(&compositionChangeEvent, status); if (lastFocusedWindow->IsDestroyed() || lastFocusedWindow != mLastFocusedWindow) { PR_LOG(gGtkIMLog, PR_LOG_ALWAYS, diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp index 25dc55282816..2734f844b8f7 100644 --- a/widget/gtk/nsWindow.cpp +++ b/widget/gtk/nsWindow.cpp @@ -3046,14 +3046,15 @@ nsWindow::OnKeyPressEvent(GdkEventKey *aEvent) DispatchEvent(&event, status); } else { - WidgetCompositionEvent textEvent(true, NS_COMPOSITION_CHANGE, this); + WidgetCompositionEvent compositionChangeEvent( + true, NS_COMPOSITION_CHANGE, this); char16_t textString[3]; textString[0] = H_SURROGATE(event.charCode); textString[1] = L_SURROGATE(event.charCode); textString[2] = 0; - textEvent.mData = textString; - textEvent.time = event.time; - DispatchEvent(&textEvent, status); + compositionChangeEvent.mData = textString; + compositionChangeEvent.time = event.time; + DispatchEvent(&compositionChangeEvent, status); } } diff --git a/widget/windows/nsTextStore.cpp b/widget/windows/nsTextStore.cpp index edcc776ed931..11a2ac7de0a0 100644 --- a/widget/windows/nsTextStore.cpp +++ b/widget/windows/nsTextStore.cpp @@ -1650,18 +1650,19 @@ nsTextStore::FlushPendingActions() PR_LOG(sTextStoreLog, PR_LOG_DEBUG, ("TSF: 0x%p nsTextStore::FlushPendingActions(), " "dispatching compositionchange event...", this)); - WidgetCompositionEvent textEvent(true, NS_COMPOSITION_CHANGE, mWidget); - mWidget->InitEvent(textEvent); - textEvent.mData = action.mData; + WidgetCompositionEvent compositionChange(true, NS_COMPOSITION_CHANGE, + mWidget); + mWidget->InitEvent(compositionChange); + compositionChange.mData = action.mData; if (action.mRanges->IsEmpty()) { TextRange wholeRange; wholeRange.mStartOffset = 0; - wholeRange.mEndOffset = textEvent.mData.Length(); + wholeRange.mEndOffset = compositionChange.mData.Length(); wholeRange.mRangeType = NS_TEXTRANGE_RAWINPUT; action.mRanges->AppendElement(wholeRange); } - textEvent.mRanges = action.mRanges; - mWidget->DispatchWindowEvent(&textEvent); + compositionChange.mRanges = action.mRanges; + mWidget->DispatchWindowEvent(&compositionChange); // Be aware, the mWidget might already have been destroyed. break; } @@ -1677,10 +1678,11 @@ nsTextStore::FlushPendingActions() PR_LOG(sTextStoreLog, PR_LOG_DEBUG, ("TSF: 0x%p nsTextStore::FlushPendingActions(), " "dispatching compositionchange event...", this)); - WidgetCompositionEvent textEvent(true, NS_COMPOSITION_CHANGE, mWidget); - mWidget->InitEvent(textEvent); - textEvent.mData = action.mData; - mWidget->DispatchWindowEvent(&textEvent); + WidgetCompositionEvent compositionChange(true, NS_COMPOSITION_CHANGE, + mWidget); + mWidget->InitEvent(compositionChange); + compositionChange.mData = action.mData; + mWidget->DispatchWindowEvent(&compositionChange); if (!mWidget || mWidget->Destroyed()) { break; } @@ -1690,7 +1692,7 @@ nsTextStore::FlushPendingActions() "dispatching compositionend event...", this)); WidgetCompositionEvent compositionEnd(true, NS_COMPOSITION_END, mWidget); - compositionEnd.mData = textEvent.mData; + compositionEnd.mData = compositionChange.mData; mWidget->InitEvent(compositionEnd); mWidget->DispatchWindowEvent(&compositionEnd); if (!mWidget || mWidget->Destroyed()) { diff --git a/widget/xpwidgets/PuppetWidget.cpp b/widget/xpwidgets/PuppetWidget.cpp index 109380e32023..4eebf1ab26ef 100644 --- a/widget/xpwidgets/PuppetWidget.cpp +++ b/widget/xpwidgets/PuppetWidget.cpp @@ -379,25 +379,27 @@ PuppetWidget::IMEEndComposition(bool aCancel) #endif nsEventStatus status; - WidgetCompositionEvent textEvent(true, NS_COMPOSITION_CHANGE, this); - InitEvent(textEvent, nullptr); - textEvent.mSeqno = mIMELastReceivedSeqno; + WidgetCompositionEvent compositionChangeEvent(true, NS_COMPOSITION_CHANGE, + this); + InitEvent(compositionChangeEvent, nullptr); + compositionChangeEvent.mSeqno = mIMELastReceivedSeqno; // SendEndIMEComposition is always called since ResetInputState // should always be called even if we aren't composing something. if (!mTabChild || - !mTabChild->SendEndIMEComposition(aCancel, &textEvent.mData)) { + !mTabChild->SendEndIMEComposition(aCancel, + &compositionChangeEvent.mData)) { return NS_ERROR_FAILURE; } if (!mIMEComposing) return NS_OK; - DispatchEvent(&textEvent, status); + DispatchEvent(&compositionChangeEvent, status); - WidgetCompositionEvent compEvent(true, NS_COMPOSITION_END, this); - InitEvent(compEvent, nullptr); - compEvent.mSeqno = mIMELastReceivedSeqno; - DispatchEvent(&compEvent, status); + WidgetCompositionEvent compositionEndEvent(true, NS_COMPOSITION_END, this); + InitEvent(compositionEndEvent, nullptr); + compositionEndEvent.mSeqno = mIMELastReceivedSeqno; + DispatchEvent(&compositionEndEvent, status); return NS_OK; } From d028544b2b405d7a9224d84da4510744902f75d3 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Tue, 7 Oct 2014 19:01:49 +0900 Subject: [PATCH 22/84] Bug 960871 part.9 Rename methods and classes which handled WidgetTextEvent r=smaug --- dom/events/TextComposition.cpp | 13 ++++----- dom/events/TextComposition.h | 40 ++++++++++++++------------ editor/libeditor/nsPlaintextEditor.cpp | 14 ++++----- widget/cocoa/TextInputHandler.h | 11 +++---- widget/cocoa/TextInputHandler.mm | 14 ++++----- widget/gtk/nsGtkIMModule.cpp | 19 ++++++------ widget/gtk/nsGtkIMModule.h | 21 +++++++------- widget/windows/nsIMM32Handler.cpp | 18 ++++++------ widget/windows/nsIMM32Handler.h | 5 ++-- widget/windows/nsTextStore.cpp | 10 +++---- widget/windows/nsTextStore.h | 11 +++---- 11 files changed, 92 insertions(+), 84 deletions(-) diff --git a/dom/events/TextComposition.cpp b/dom/events/TextComposition.cpp index 18073480819c..c8132e10c5da 100644 --- a/dom/events/TextComposition.cpp +++ b/dom/events/TextComposition.cpp @@ -180,8 +180,8 @@ TextComposition::DispatchEvent(WidgetGUIEvent* aEvent, // Emulate editor behavior of compositionchange event (DOM text event) handler // if no editor handles composition events. if (aEvent->message == NS_COMPOSITION_CHANGE && !HasEditor()) { - EditorWillHandleTextEvent(aEvent->AsCompositionEvent()); - EditorDidHandleTextEvent(); + EditorWillHandleCompositionChangeEvent(aEvent->AsCompositionEvent()); + EditorDidHandleCompositionChangeEvent(); } #ifdef DEBUG @@ -264,9 +264,8 @@ TextComposition::RequestToCommit(nsIWidget* aWidget, bool aDiscard) mIsRequestingCommit = true; } if (!mIsSynthesizedForTests) { - // FYI: CompositionEvent and TextEvent caused by a call of NotifyIME() - // may be discarded by PresShell if it's not safe to dispatch the - // event. + // FYI: CompositionEvents caused by a call of NotifyIME() may be + // discarded by PresShell if it's not safe to dispatch the event. nsresult rv = aWidget->NotifyIME(IMENotification(aDiscard ? REQUEST_TO_CANCEL_COMPOSITION : @@ -339,7 +338,7 @@ TextComposition::NotifyIME(IMEMessage aMessage) } void -TextComposition::EditorWillHandleTextEvent( +TextComposition::EditorWillHandleCompositionChangeEvent( const WidgetCompositionEvent* aCompositionChangeEvent) { mIsComposing = aCompositionChangeEvent->IsComposing(); @@ -352,7 +351,7 @@ TextComposition::EditorWillHandleTextEvent( } void -TextComposition::EditorDidHandleTextEvent() +TextComposition::EditorDidHandleCompositionChangeEvent() { mString = mLastData; mIsEditorHandlingEvent = false; diff --git a/dom/events/TextComposition.h b/dom/events/TextComposition.h index 9ac2d9303205..ff406c14e445 100644 --- a/dom/events/TextComposition.h +++ b/dom/events/TextComposition.h @@ -50,12 +50,13 @@ public: const nsString& LastData() const { return mLastData; } // The composition string which is already handled by the focused editor. // I.e., this value must be same as the composition string on the focused - // editor. This value is modified at a call of EditorDidHandleTextEvent(). + // editor. This value is modified at a call of + // EditorDidHandleCompositionChangeEvent(). // Note that mString and mLastData are different between dispatcing // compositionupdate and compositionchange event handled by focused editor. const nsString& String() const { return mString; } // Returns the clauses and/or caret range of the composition string. - // This is modified at a call of EditorWillHandleTextEvent(). + // This is modified at a call of EditorWillHandleCompositionChangeEvent(). // This may return null if there is no clauses and caret. // XXX We should return |const TextRangeArray*| here, but it causes compile // error due to inaccessible Release() method. @@ -124,30 +125,33 @@ public: void EndHandlingComposition(nsIEditor* aEditor); /** - * TextEventHandlingMarker class should be created at starting to handle text - * event in focused editor. This calls EditorWillHandleTextEvent() and - * EditorDidHandleTextEvent() automatically. + * CompositionChangeEventHandlingMarker class should be created at starting + * to handle text event in focused editor. This calls + * EditorWillHandleCompositionChangeEvent() and + * EditorDidHandleCompositionChangeEvent() automatically. */ - class MOZ_STACK_CLASS TextEventHandlingMarker + class MOZ_STACK_CLASS CompositionChangeEventHandlingMarker { public: - TextEventHandlingMarker( + CompositionChangeEventHandlingMarker( TextComposition* aComposition, const WidgetCompositionEvent* aCompositionChangeEvent) : mComposition(aComposition) { - mComposition->EditorWillHandleTextEvent(aCompositionChangeEvent); + mComposition->EditorWillHandleCompositionChangeEvent( + aCompositionChangeEvent); } - ~TextEventHandlingMarker() + ~CompositionChangeEventHandlingMarker() { - mComposition->EditorDidHandleTextEvent(); + mComposition->EditorDidHandleCompositionChangeEvent(); } private: nsRefPtr mComposition; - TextEventHandlingMarker(); - TextEventHandlingMarker(const TextEventHandlingMarker& aOther); + CompositionChangeEventHandlingMarker(); + CompositionChangeEventHandlingMarker( + const CompositionChangeEventHandlingMarker& aOther); }; private: @@ -233,17 +237,17 @@ private: bool HasEditor() const; /** - * EditorWillHandleTextEvent() must be called before the focused editor - * handles the compositionchange event. + * EditorWillHandleCompositionChangeEvent() must be called before the focused + * editor handles the compositionchange event. */ - void EditorWillHandleTextEvent( + void EditorWillHandleCompositionChangeEvent( const WidgetCompositionEvent* aCompositionChangeEvent); /** - * EditorDidHandleTextEvent() must be called after the focused editor handles - * a compositionchange event. + * EditorDidHandleCompositionChangeEvent() must be called after the focused + * editor handles a compositionchange event. */ - void EditorDidHandleTextEvent(); + void EditorDidHandleCompositionChangeEvent(); /** * DispatchEvent() dispatches the aEvent to the mContent synchronously. diff --git a/editor/libeditor/nsPlaintextEditor.cpp b/editor/libeditor/nsPlaintextEditor.cpp index 27a35c0c0898..fe3284b91189 100644 --- a/editor/libeditor/nsPlaintextEditor.cpp +++ b/editor/libeditor/nsPlaintextEditor.cpp @@ -862,17 +862,17 @@ nsPlaintextEditor::UpdateIMEComposition(nsIDOMEvent* aDOMTextEvent) NS_ENSURE_SUCCESS(rv, rv); // NOTE: TextComposition should receive selection change notification before - // TextEventHandlingMarker notifies TextComposition of the end of - // handling compositionchange event because TextComposition may need to - // ignore selection changes caused by composition. Therefore, - // TextEventHandlingMarker must be destroyed after a call of - // NotifiyEditorObservers(eNotifyEditorObserversOfEnd) or + // CompositionChangeEventHandlingMarker notifies TextComposition of the + // end of handling compositionchange event because TextComposition may + // need to ignore selection changes caused by composition. Therefore, + // CompositionChangeEventHandlingMarker must be destroyed after a call + // of NotifiyEditorObservers(eNotifyEditorObserversOfEnd) or // NotifiyEditorObservers(eNotifyEditorObserversOfCancel) which notifies // TextComposition of a selection change. MOZ_ASSERT(!mPlaceHolderBatch, "UpdateIMEComposition() must be called without place holder batch"); - TextComposition::TextEventHandlingMarker - textEventHandlingMarker(mComposition, compositionChangeEvent); + TextComposition::CompositionChangeEventHandlingMarker + compositionChangeEventHandlingMarker(mComposition, compositionChangeEvent); NotifyEditorObservers(eNotifyEditorObserversOfBefore); diff --git a/widget/cocoa/TextInputHandler.h b/widget/cocoa/TextInputHandler.h index 94963ed1ae8e..68eb2a83b1d1 100644 --- a/widget/cocoa/TextInputHandler.h +++ b/widget/cocoa/TextInputHandler.h @@ -846,7 +846,8 @@ public: void OnSelectionChange() { mSelectedRange.location = NSNotFound; } /** - * DispatchTextEvent() dispatches a compositionchange event on mWidget. + * DispatchCompositionChangeEvent() dispatches a compositionchange event on + * mWidget. * * @param aText User text input. * @param aAttrString An NSAttributedString instance which indicates @@ -855,10 +856,10 @@ public: * @param aDoCommit TRUE if the composition string should be * committed. Otherwise, FALSE. */ - bool DispatchTextEvent(const nsString& aText, - NSAttributedString* aAttrString, - NSRange& aSelectedRange, - bool aDoCommit); + bool DispatchCompositionChangeEvent(const nsString& aText, + NSAttributedString* aAttrString, + NSRange& aSelectedRange, + bool aDoCommit); /** * SetMarkedText() is a handler of setMarkedText of NSTextInput. diff --git a/widget/cocoa/TextInputHandler.mm b/widget/cocoa/TextInputHandler.mm index 4d4a35bb35f7..54882c442e15 100644 --- a/widget/cocoa/TextInputHandler.mm +++ b/widget/cocoa/TextInputHandler.mm @@ -2697,13 +2697,13 @@ IMEInputHandler::CreateTextRangeArray(NSAttributedString *aAttrString, } bool -IMEInputHandler::DispatchTextEvent(const nsString& aText, - NSAttributedString* aAttrString, - NSRange& aSelectedRange, - bool aDoCommit) +IMEInputHandler::DispatchCompositionChangeEvent(const nsString& aText, + NSAttributedString* aAttrString, + NSRange& aSelectedRange, + bool aDoCommit) { PR_LOG(gLog, PR_LOG_ALWAYS, - ("%p IMEInputHandler::DispatchTextEvent, " + ("%p IMEInputHandler::DispatchCompositionChangeEvent, " "aText=\"%s\", aAttrString=\"%s\", " "aSelectedRange={ location=%llu, length=%llu }, " "aDoCommit=%s, Destroyed()=%s", @@ -2810,7 +2810,7 @@ IMEInputHandler::InsertTextAsCommittingComposition( } NSRange range = NSMakeRange(0, str.Length()); - DispatchTextEvent(str, aAttrString, range, true); + DispatchCompositionChangeEvent(str, aAttrString, range, true); if (Destroyed()) { PR_LOG(gLog, PR_LOG_ALWAYS, ("%p IMEInputHandler::InsertTextAsCommittingComposition, " @@ -2920,7 +2920,7 @@ IMEInputHandler::SetMarkedText(NSAttributedString* aAttrString, OnUpdateIMEComposition([aAttrString string]); bool doCommit = str.IsEmpty(); - DispatchTextEvent(str, aAttrString, aSelectedRange, doCommit); + DispatchCompositionChangeEvent(str, aAttrString, aSelectedRange, doCommit); if (Destroyed()) { PR_LOG(gLog, PR_LOG_ALWAYS, ("%p IMEInputHandler::SetMarkedText, " diff --git a/widget/gtk/nsGtkIMModule.cpp b/widget/gtk/nsGtkIMModule.cpp index 164400923f5f..0588da1ae53a 100644 --- a/widget/gtk/nsGtkIMModule.cpp +++ b/widget/gtk/nsGtkIMModule.cpp @@ -775,7 +775,7 @@ nsGtkIMModule::OnChangeCompositionNative(GtkIMContext *aContext) } // Be aware, widget can be gone - DispatchTextEvent(compositionString, false); + DispatchCompositionChangeEvent(compositionString, false); } /* static */ @@ -921,7 +921,7 @@ nsGtkIMModule::CommitCompositionBy(const nsAString& aString) this, NS_ConvertUTF16toUTF8(aString).get(), NS_ConvertUTF16toUTF8(mDispatchedCompositionString).get())); - if (!DispatchTextEvent(aString, true)) { + if (!DispatchCompositionChangeEvent(aString, true)) { return false; } // We should dispatch the compositionend event here because some IMEs @@ -1067,11 +1067,12 @@ nsGtkIMModule::DispatchCompositionEnd() } bool -nsGtkIMModule::DispatchTextEvent(const nsAString &aCompositionString, - bool aIsCommit) +nsGtkIMModule::DispatchCompositionChangeEvent( + const nsAString &aCompositionString, + bool aIsCommit) { PR_LOG(gGtkIMLog, PR_LOG_ALWAYS, - ("GtkIMModule(%p): DispatchTextEvent, aIsCommit=%s", + ("GtkIMModule(%p): DispatchCompositionChangeEvent, aIsCommit=%s", this, aIsCommit ? "TRUE" : "FALSE")); if (!mLastFocusedWindow) { @@ -1124,8 +1125,8 @@ nsGtkIMModule::DispatchTextEvent(const nsAString &aCompositionString, } mCompositionState = aIsCommit ? - eCompositionState_CommitTextEventDispatched : - eCompositionState_TextEventDispatched; + eCompositionState_CommitCompositionChangeEventDispatched : + eCompositionState_CompositionChangeEventDispatched; mLastFocusedWindow->DispatchEvent(&compositionChangeEvent, status); if (lastFocusedWindow->IsDestroyed() || @@ -1448,7 +1449,7 @@ nsGtkIMModule::DeleteText(const int32_t aOffset, const uint32_t aNChars) if (wasComposing) { selOffset = mCompositionStart; if (editorHadCompositionString && - !DispatchTextEvent(mSelectedString, false)) { + !DispatchCompositionChangeEvent(mSelectedString, false)) { PR_LOG(gGtkIMLog, PR_LOG_ALWAYS, (" FAILED, quitting from DeletText")); return NS_ERROR_FAILURE; @@ -1575,7 +1576,7 @@ nsGtkIMModule::DeleteText(const int32_t aOffset, const uint32_t aNChars) nsAutoString compositionString; GetCompositionString(compositionString); - if (!DispatchTextEvent(compositionString, true)) { + if (!DispatchCompositionChangeEvent(compositionString, true)) { PR_LOG(gGtkIMLog, PR_LOG_ALWAYS, (" FAILED, restoring composition string")); return NS_ERROR_FAILURE; diff --git a/widget/gtk/nsGtkIMModule.h b/widget/gtk/nsGtkIMModule.h index 3965e69196dc..c0e6dcc19594 100644 --- a/widget/gtk/nsGtkIMModule.h +++ b/widget/gtk/nsGtkIMModule.h @@ -148,8 +148,8 @@ protected: enum eCompositionState { eCompositionState_NotComposing, eCompositionState_CompositionStartDispatched, - eCompositionState_TextEventDispatched, - eCompositionState_CommitTextEventDispatched + eCompositionState_CompositionChangeEventDispatched, + eCompositionState_CommitCompositionChangeEventDispatched }; eCompositionState mCompositionState; @@ -160,7 +160,8 @@ protected: bool EditorHasCompositionString() { - return (mCompositionState == eCompositionState_TextEventDispatched); + return (mCompositionState == + eCompositionState_CompositionChangeEventDispatched); } #ifdef PR_LOGGING @@ -171,10 +172,10 @@ protected: return "NotComposing"; case eCompositionState_CompositionStartDispatched: return "CompositionStartDispatched"; - case eCompositionState_TextEventDispatched: - return "TextEventDispatched"; - case eCompositionState_CommitTextEventDispatched: - return "CommitTextEventDispatched"; + case eCompositionState_CompositionChangeEventDispatched: + return "CompositionChangeEventDispatched"; + case eCompositionState_CommitCompositionChangeEventDispatched: + return "CommitCompositionChangeEventDispatched"; default: return "InvaildState"; } @@ -294,7 +295,7 @@ protected: * - CommitCompositionBy * - DispatchCompositionStart * - DispatchCompositionEnd - * - DispatchTextEvent + * - DispatchCompositionChangeEvent */ // Commits the current composition by the aString. @@ -307,8 +308,8 @@ protected: // Dispatches a compositionchange event. If aIsCommit is TRUE, dispatches // a committed compositionchange event. Otherwise, dispatches a composing // compositionchange event. - bool DispatchTextEvent(const nsAString& aCompositionString, - bool aIsCommit); + bool DispatchCompositionChangeEvent(const nsAString& aCompositionString, + bool aIsCommit); }; diff --git a/widget/windows/nsIMM32Handler.cpp b/widget/windows/nsIMM32Handler.cpp index e2110137b30d..a74f41d315e8 100644 --- a/widget/windows/nsIMM32Handler.cpp +++ b/widget/windows/nsIMM32Handler.cpp @@ -495,7 +495,7 @@ nsIMM32Handler::OnIMEEndComposition(nsWindow* aWindow, mCompositionString.Truncate(); nsIMEContext IMEContext(aWindow->GetWindowHandle()); - DispatchTextEvent(aWindow, IMEContext, false); + DispatchCompositionChangeEvent(aWindow, IMEContext, false); HandleEndComposition(aWindow); @@ -1020,7 +1020,7 @@ nsIMM32Handler::HandleComposition(nsWindow* aWindow, PR_LOG(gIMM32Log, PR_LOG_ALWAYS, ("IMM32: HandleComposition, GCS_RESULTSTR\n")); - DispatchTextEvent(aWindow, aIMEContext, false); + DispatchCompositionChangeEvent(aWindow, aIMEContext, false); HandleEndComposition(aWindow); if (!IS_COMPOSING_LPARAM(lParam)) { @@ -1062,7 +1062,7 @@ nsIMM32Handler::HandleComposition(nsWindow* aWindow, // If composition string is empty, we should dispatch a compositionchange // event with empty string. if (mCompositionString.IsEmpty()) { - DispatchTextEvent(aWindow, aIMEContext, false); + DispatchCompositionChangeEvent(aWindow, aIMEContext, false); return ShouldDrawCompositionStringOurselves(); } @@ -1202,7 +1202,7 @@ nsIMM32Handler::HandleComposition(nsWindow* aWindow, //-------------------------------------------------------- // 5. Send the compositionchange event //-------------------------------------------------------- - DispatchTextEvent(aWindow, aIMEContext); + DispatchCompositionChangeEvent(aWindow, aIMEContext); return ShouldDrawCompositionStringOurselves(); } @@ -1516,7 +1516,7 @@ nsIMM32Handler::CommitCompositionOnPreviousWindow(nsWindow* aWindow) nsIMEContext IMEContext(mComposingWindow->GetWindowHandle()); NS_ASSERTION(IMEContext.IsValid(), "IME context must be valid"); - DispatchTextEvent(mComposingWindow, IMEContext, false); + DispatchCompositionChangeEvent(mComposingWindow, IMEContext, false); HandleEndComposition(mComposingWindow); return true; } @@ -1569,13 +1569,13 @@ GetRangeTypeName(uint32_t aRangeType) #endif void -nsIMM32Handler::DispatchTextEvent(nsWindow* aWindow, - const nsIMEContext &aIMEContext, - bool aCheckAttr) +nsIMM32Handler::DispatchCompositionChangeEvent(nsWindow* aWindow, + const nsIMEContext &aIMEContext, + bool aCheckAttr) { NS_ASSERTION(mIsComposing, "conflict state"); PR_LOG(gIMM32Log, PR_LOG_ALWAYS, - ("IMM32: DispatchTextEvent, aCheckAttr=%s\n", + ("IMM32: DispatchCompositionChangeEvent, aCheckAttr=%s\n", aCheckAttr ? "TRUE": "FALSE")); // If we don't need to draw composition string ourselves and this is not diff --git a/widget/windows/nsIMM32Handler.h b/widget/windows/nsIMM32Handler.h index b3a054d44c04..75c476966e54 100644 --- a/widget/windows/nsIMM32Handler.h +++ b/widget/windows/nsIMM32Handler.h @@ -290,8 +290,9 @@ protected: * in the composition string, you need to subtract mCompositionStart from it. */ bool GetTargetClauseRange(uint32_t *aOffset, uint32_t *aLength = nullptr); - void DispatchTextEvent(nsWindow* aWindow, const nsIMEContext &aIMEContext, - bool aCheckAttr = true); + void DispatchCompositionChangeEvent(nsWindow* aWindow, + const nsIMEContext &aIMEContext, + bool aCheckAttr = true); already_AddRefed CreateTextRangeArray(); nsresult EnsureClauseArray(int32_t aCount); diff --git a/widget/windows/nsTextStore.cpp b/widget/windows/nsTextStore.cpp index 11a2ac7de0a0..aa4006242bfe 100644 --- a/widget/windows/nsTextStore.cpp +++ b/widget/windows/nsTextStore.cpp @@ -2441,16 +2441,16 @@ nsTextStore::RecordCompositionUpdateAction() HRESULT nsTextStore::SetSelectionInternal(const TS_SELECTION_ACP* pSelection, - bool aDispatchTextEvent) + bool aDispatchCompositionChangeEvent) { PR_LOG(sTextStoreLog, PR_LOG_DEBUG, ("TSF: 0x%p nsTextStore::SetSelectionInternal(pSelection={ " "acpStart=%ld, acpEnd=%ld, style={ ase=%s, fInterimChar=%s} }, " - "aDispatchTextEvent=%s), mComposition.IsComposing()=%s", + "aDispatchCompositionChangeEvent=%s), mComposition.IsComposing()=%s", this, pSelection->acpStart, pSelection->acpEnd, GetActiveSelEndName(pSelection->style.ase), GetBoolName(pSelection->style.fInterimChar), - GetBoolName(aDispatchTextEvent), + GetBoolName(aDispatchCompositionChangeEvent), GetBoolName(mComposition.IsComposing()))); MOZ_ASSERT(IsReadWriteLocked()); @@ -2464,7 +2464,7 @@ nsTextStore::SetSelectionInternal(const TS_SELECTION_ACP* pSelection, } if (mComposition.IsComposing()) { - if (aDispatchTextEvent) { + if (aDispatchCompositionChangeEvent) { HRESULT hr = RestartCompositionIfNecessary(); if (FAILED(hr)) { PR_LOG(sTextStoreLog, PR_LOG_ERROR, @@ -2482,7 +2482,7 @@ nsTextStore::SetSelectionInternal(const TS_SELECTION_ACP* pSelection, } // Emulate selection during compositions currentSel.SetSelection(*pSelection); - if (aDispatchTextEvent) { + if (aDispatchCompositionChangeEvent) { HRESULT hr = RecordCompositionUpdateAction(); if (FAILED(hr)) { PR_LOG(sTextStoreLog, PR_LOG_ERROR, diff --git a/widget/windows/nsTextStore.h b/widget/windows/nsTextStore.h index 511818f03c14..85169478ed4b 100644 --- a/widget/windows/nsTextStore.h +++ b/widget/windows/nsTextStore.h @@ -251,12 +251,13 @@ protected: void DidLockGranted(); bool GetScreenExtInternal(RECT &aScreenExt); - // If aDispatchTextEvent is true, this method will dispatch compositionchange - // event if this is called during IME composing. aDispatchTextEvent should - // be true only when this is called from SetSelection. Because otherwise, - // the compositionchange event should not be sent from here. + // If aDispatchCompositionChangeEvent is true, this method will dispatch + // compositionchange event if this is called during IME composing. + // aDispatchCompositionChangeEvent should be true only when this is called + // from SetSelection. Because otherwise, the compositionchange event should + // not be sent from here. HRESULT SetSelectionInternal(const TS_SELECTION_ACP*, - bool aDispatchTextEvent = false); + bool aDispatchCompositionChangeEvent = false); bool InsertTextAtSelectionInternal(const nsAString &aInsertStr, TS_TEXTCHANGE* aTextChange); void CommitCompositionInternal(bool); From 2be456d529e91c5b5c25cf6369b4db961a67da81 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Tue, 7 Oct 2014 19:01:49 +0900 Subject: [PATCH 23/84] Bug 960871 part.10 Some methods which took both WidgetCompositionEvent and WidgetTextEvent should take only WidgetCompositionEvent r=smaug --- dom/events/IMEStateManager.cpp | 72 +++++++++++++++++----------------- dom/events/IMEStateManager.h | 20 +++++----- dom/events/TextComposition.cpp | 68 ++++++++++++++++---------------- dom/events/TextComposition.h | 24 ++++++------ layout/base/nsPresShell.cpp | 6 ++- 5 files changed, 99 insertions(+), 91 deletions(-) diff --git a/dom/events/IMEStateManager.cpp b/dom/events/IMEStateManager.cpp index d766d0dca95c..7c47231e0252 100644 --- a/dom/events/IMEStateManager.cpp +++ b/dom/events/IMEStateManager.cpp @@ -870,38 +870,37 @@ IMEStateManager::EnsureTextCompositionArray() // static void -IMEStateManager::DispatchCompositionEvent(nsINode* aEventTargetNode, - nsPresContext* aPresContext, - WidgetEvent* aEvent, - nsEventStatus* aStatus, - EventDispatchingCallback* aCallBack, - bool aIsSynthesized) +IMEStateManager::DispatchCompositionEvent( + nsINode* aEventTargetNode, + nsPresContext* aPresContext, + WidgetCompositionEvent* aCompositionEvent, + nsEventStatus* aStatus, + EventDispatchingCallback* aCallBack, + bool aIsSynthesized) { PR_LOG(sISMLog, PR_LOG_ALWAYS, ("ISM: IMEStateManager::DispatchCompositionEvent(aNode=0x%p, " - "aPresContext=0x%p, aEvent={ message=%s, " + "aPresContext=0x%p, aCompositionEvent={ message=%s, " "mFlags={ mIsTrusted=%s, mPropagationStopped=%s } }, " "aIsSynthesized=%s)", aEventTargetNode, aPresContext, - GetEventMessageName(aEvent->message), - GetBoolName(aEvent->mFlags.mIsTrusted), - GetBoolName(aEvent->mFlags.mPropagationStopped), + GetEventMessageName(aCompositionEvent->message), + GetBoolName(aCompositionEvent->mFlags.mIsTrusted), + GetBoolName(aCompositionEvent->mFlags.mPropagationStopped), GetBoolName(aIsSynthesized))); - MOZ_ASSERT(aEvent->mClass == eCompositionEventClass); - if (!aEvent->mFlags.mIsTrusted || aEvent->mFlags.mPropagationStopped) { + if (!aCompositionEvent->mFlags.mIsTrusted || + aCompositionEvent->mFlags.mPropagationStopped) { return; } - MOZ_ASSERT(aEvent->message != NS_COMPOSITION_UPDATE, + MOZ_ASSERT(aCompositionEvent->message != NS_COMPOSITION_UPDATE, "compositionupdate event shouldn't be dispatched manually"); EnsureTextCompositionArray(); - WidgetGUIEvent* GUIEvent = aEvent->AsGUIEvent(); - nsRefPtr composition = - sTextCompositions->GetCompositionFor(GUIEvent->widget); + sTextCompositions->GetCompositionFor(aCompositionEvent->widget); if (!composition) { // If synthesized event comes after delayed native composition events // for request of commit or cancel, we should ignore it. @@ -911,18 +910,20 @@ IMEStateManager::DispatchCompositionEvent(nsINode* aEventTargetNode, PR_LOG(sISMLog, PR_LOG_DEBUG, ("ISM: IMEStateManager::DispatchCompositionEvent(), " "adding new TextComposition to the array")); - MOZ_ASSERT(GUIEvent->message == NS_COMPOSITION_START); - composition = new TextComposition(aPresContext, aEventTargetNode, GUIEvent); + MOZ_ASSERT(aCompositionEvent->message == NS_COMPOSITION_START); + composition = + new TextComposition(aPresContext, aEventTargetNode, aCompositionEvent); sTextCompositions->AppendElement(composition); } #ifdef DEBUG else { - MOZ_ASSERT(GUIEvent->message != NS_COMPOSITION_START); + MOZ_ASSERT(aCompositionEvent->message != NS_COMPOSITION_START); } #endif // #ifdef DEBUG // Dispatch the event on composing target. - composition->DispatchEvent(GUIEvent, aStatus, aCallBack, aIsSynthesized); + composition->DispatchCompositionEvent(aCompositionEvent, aStatus, aCallBack, + aIsSynthesized); // WARNING: the |composition| might have been destroyed already. @@ -938,9 +939,9 @@ IMEStateManager::DispatchCompositionEvent(nsINode* aEventTargetNode, // destroy the TextComposition with synthesized compositionend event. if ((!aIsSynthesized || composition->WasNativeCompositionEndEventDiscarded()) && - aEvent->message == NS_COMPOSITION_END) { + aCompositionEvent->message == NS_COMPOSITION_END) { TextCompositionArray::index_type i = - sTextCompositions->IndexOf(GUIEvent->widget); + sTextCompositions->IndexOf(aCompositionEvent->widget); if (i != TextCompositionArray::NoIndex) { PR_LOG(sISMLog, PR_LOG_DEBUG, ("ISM: IMEStateManager::DispatchCompositionEvent(), " @@ -954,32 +955,31 @@ IMEStateManager::DispatchCompositionEvent(nsINode* aEventTargetNode, // static void -IMEStateManager::OnCompositionEventDiscarded(WidgetEvent* aEvent) +IMEStateManager::OnCompositionEventDiscarded( + const WidgetCompositionEvent* aCompositionEvent) { // Note that this method is never called for synthesized events for emulating // commit or cancel composition. PR_LOG(sISMLog, PR_LOG_ALWAYS, - ("ISM: IMEStateManager::OnCompositionEventDiscarded(aEvent={ " + ("ISM: IMEStateManager::OnCompositionEventDiscarded(aCompositionEvent={ " "message=%s, mFlags={ mIsTrusted=%s } })", - GetEventMessageName(aEvent->message), - GetBoolName(aEvent->mFlags.mIsTrusted))); + GetEventMessageName(aCompositionEvent->message), + GetBoolName(aCompositionEvent->mFlags.mIsTrusted))); - MOZ_ASSERT(aEvent->mClass == eCompositionEventClass); - if (!aEvent->mFlags.mIsTrusted) { + if (!aCompositionEvent->mFlags.mIsTrusted) { return; } // Ignore compositionstart for now because sTextCompositions may not have // been created yet. - if (aEvent->message == NS_COMPOSITION_START) { + if (aCompositionEvent->message == NS_COMPOSITION_START) { return; } - WidgetGUIEvent* GUIEvent = aEvent->AsGUIEvent(); nsRefPtr composition = - sTextCompositions->GetCompositionFor(GUIEvent->widget); - composition->OnCompositionEventDiscarded(GUIEvent); + sTextCompositions->GetCompositionFor(aCompositionEvent->widget); + composition->OnCompositionEventDiscarded(aCompositionEvent); } // static @@ -1214,11 +1214,11 @@ IMEStateManager::GetTextCompositionFor(nsIWidget* aWidget) // static already_AddRefed -IMEStateManager::GetTextCompositionFor(WidgetGUIEvent* aEvent) +IMEStateManager::GetTextCompositionFor(WidgetGUIEvent* aGUIEvent) { - MOZ_ASSERT(aEvent->AsCompositionEvent() || aEvent->AsKeyboardEvent(), - "aEvent has to be WidgetCompositionEvent or WidgetKeyboardEvent"); - return GetTextCompositionFor(aEvent->widget); + MOZ_ASSERT(aGUIEvent->AsCompositionEvent() || aGUIEvent->AsKeyboardEvent(), + "aGUIEvent has to be WidgetCompositionEvent or WidgetKeyboardEvent"); + return GetTextCompositionFor(aGUIEvent->widget); } } // namespace mozilla diff --git a/dom/events/IMEStateManager.h b/dom/events/IMEStateManager.h index 312c27371a64..665edcc2d0f1 100644 --- a/dom/events/IMEStateManager.h +++ b/dom/events/IMEStateManager.h @@ -97,18 +97,20 @@ public: * events must be fired the stored target. If the stored composition event * target is destroying, this removes the stored composition automatically. */ - static void DispatchCompositionEvent(nsINode* aEventTargetNode, - nsPresContext* aPresContext, - WidgetEvent* aEvent, - nsEventStatus* aStatus, - EventDispatchingCallback* aCallBack, - bool aIsSynthesized = false); + static void DispatchCompositionEvent( + nsINode* aEventTargetNode, + nsPresContext* aPresContext, + WidgetCompositionEvent* aCompositionEvent, + nsEventStatus* aStatus, + EventDispatchingCallback* aCallBack, + bool aIsSynthesized = false); /** * This is called when PresShell ignores a composition event due to not safe * to dispatch events. */ - static void OnCompositionEventDiscarded(WidgetEvent* aEvent); + static void OnCompositionEventDiscarded( + const WidgetCompositionEvent* aCompositionEvent); /** * Get TextComposition from widget. @@ -119,10 +121,10 @@ public: /** * Returns TextComposition instance for the event. * - * @param aEvent Should be a composition event which is being dispatched. + * @param aGUIEvent Should be a composition event which is being dispatched. */ static already_AddRefed - GetTextCompositionFor(WidgetGUIEvent* aEvent); + GetTextCompositionFor(WidgetGUIEvent* aGUIEvent); /** * Send a notification to IME. It depends on the IME or platform spec what diff --git a/dom/events/TextComposition.cpp b/dom/events/TextComposition.cpp index c8132e10c5da..e9e2a0c84b48 100644 --- a/dom/events/TextComposition.cpp +++ b/dom/events/TextComposition.cpp @@ -29,13 +29,14 @@ namespace mozilla { TextComposition::TextComposition(nsPresContext* aPresContext, nsINode* aNode, - WidgetGUIEvent* aEvent) + WidgetCompositionEvent* aCompositionEvent) : mPresContext(aPresContext) , mNode(aNode) - , mNativeContext(aEvent->widget->GetInputContext().mNativeIMEContext) + , mNativeContext( + aCompositionEvent->widget->GetInputContext().mNativeIMEContext) , mCompositionStartOffset(0) , mCompositionTargetOffset(0) - , mIsSynthesizedForTests(aEvent->mFlags.mIsSynthesizedForTests) + , mIsSynthesizedForTests(aCompositionEvent->mFlags.mIsSynthesizedForTests) , mIsComposing(false) , mIsEditorHandlingEvent(false) , mIsRequestingCommit(false) @@ -62,24 +63,24 @@ TextComposition::MatchesNativeContext(nsIWidget* aWidget) const bool TextComposition::MaybeDispatchCompositionUpdate( - const WidgetCompositionEvent* aEvent) + const WidgetCompositionEvent* aCompositionEvent) { if (Destroyed()) { return false; } - if (mLastData == aEvent->mData) { + if (mLastData == aCompositionEvent->mData) { return true; } - WidgetCompositionEvent compositionUpdate(aEvent->mFlags.mIsTrusted, + WidgetCompositionEvent compositionUpdate(aCompositionEvent->mFlags.mIsTrusted, NS_COMPOSITION_UPDATE, - aEvent->widget); - compositionUpdate.time = aEvent->time; - compositionUpdate.timeStamp = aEvent->timeStamp; - compositionUpdate.mData = aEvent->mData; + aCompositionEvent->widget); + compositionUpdate.time = aCompositionEvent->time; + compositionUpdate.timeStamp = aCompositionEvent->timeStamp; + compositionUpdate.mData = aCompositionEvent->mData; compositionUpdate.mFlags.mIsSynthesizedForTests = - aEvent->mFlags.mIsSynthesizedForTests; + aCompositionEvent->mFlags.mIsSynthesizedForTests; nsEventStatus status = nsEventStatus_eConsumeNoDefault; mLastData = compositionUpdate.mData; @@ -89,20 +90,20 @@ TextComposition::MaybeDispatchCompositionUpdate( } void -TextComposition::OnCompositionEventDiscarded(const WidgetGUIEvent* aEvent) +TextComposition::OnCompositionEventDiscarded( + const WidgetCompositionEvent* aCompositionEvent) { // Note that this method is never called for synthesized events for emulating // commit or cancel composition. - MOZ_ASSERT(aEvent->mFlags.mIsTrusted, + MOZ_ASSERT(aCompositionEvent->mFlags.mIsTrusted, "Shouldn't be called with untrusted event"); - MOZ_ASSERT(aEvent->mClass == eCompositionEventClass); // XXX If composition events are discarded, should we dispatch them with // runnable event? However, even if we do so, it might make native IME // confused due to async modification. Especially when native IME is // TSF. - if (aEvent->message != NS_COMPOSITION_END) { + if (aCompositionEvent->message != NS_COMPOSITION_END) { return; } @@ -110,10 +111,11 @@ TextComposition::OnCompositionEventDiscarded(const WidgetGUIEvent* aEvent) } void -TextComposition::DispatchEvent(WidgetGUIEvent* aEvent, - nsEventStatus* aStatus, - EventDispatchingCallback* aCallBack, - bool aIsSynthesized) +TextComposition::DispatchCompositionEvent( + WidgetCompositionEvent* aCompositionEvent, + nsEventStatus* aStatus, + EventDispatchingCallback* aCallBack, + bool aIsSynthesized) { if (Destroyed()) { *aStatus = nsEventStatus_eConsumeNoDefault; @@ -144,10 +146,10 @@ TextComposition::DispatchEvent(WidgetGUIEvent* aEvent, // 2. non-empty string is committed at requesting cancel. if (!aIsSynthesized && (mIsRequestingCommit || mIsRequestingCancel)) { nsString* committingData = nullptr; - switch (aEvent->message) { + switch (aCompositionEvent->message) { case NS_COMPOSITION_END: case NS_COMPOSITION_CHANGE: - committingData = &aEvent->AsCompositionEvent()->mData; + committingData = &aCompositionEvent->mData; break; default: NS_WARNING("Unexpected event comes during committing or " @@ -164,14 +166,14 @@ TextComposition::DispatchEvent(WidgetGUIEvent* aEvent, } } - if (aEvent->message == NS_COMPOSITION_CHANGE) { - if (!MaybeDispatchCompositionUpdate(aEvent->AsCompositionEvent())) { + if (aCompositionEvent->message == NS_COMPOSITION_CHANGE) { + if (!MaybeDispatchCompositionUpdate(aCompositionEvent)) { return; } } EventDispatcher::Dispatch(mNode, mPresContext, - aEvent, nullptr, aStatus, aCallBack); + aCompositionEvent, nullptr, aStatus, aCallBack); if (NS_WARN_IF(Destroyed())) { return; @@ -179,31 +181,32 @@ TextComposition::DispatchEvent(WidgetGUIEvent* aEvent, // Emulate editor behavior of compositionchange event (DOM text event) handler // if no editor handles composition events. - if (aEvent->message == NS_COMPOSITION_CHANGE && !HasEditor()) { - EditorWillHandleCompositionChangeEvent(aEvent->AsCompositionEvent()); + if (aCompositionEvent->message == NS_COMPOSITION_CHANGE && !HasEditor()) { + EditorWillHandleCompositionChangeEvent(aCompositionEvent); EditorDidHandleCompositionChangeEvent(); } #ifdef DEBUG - else if (aEvent->message == NS_COMPOSITION_END) { + else if (aCompositionEvent->message == NS_COMPOSITION_END) { MOZ_ASSERT(!mIsComposing, "Why is the editor still composing?"); MOZ_ASSERT(!HasEditor(), "Why does the editor still keep to hold this?"); } #endif // #ifdef DEBUG // Notify composition update to widget if possible - NotityUpdateComposition(aEvent); + NotityUpdateComposition(aCompositionEvent); } void -TextComposition::NotityUpdateComposition(WidgetGUIEvent* aEvent) +TextComposition::NotityUpdateComposition( + const WidgetCompositionEvent* aCompositionEvent) { nsEventStatus status; // When compositon start, notify the rect of first offset character. // When not compositon start, notify the rect of selected composition // string if compositionchange event. - if (aEvent->message == NS_COMPOSITION_START) { + if (aCompositionEvent->message == NS_COMPOSITION_START) { nsCOMPtr widget = mPresContext->GetRootWidget(); // Update composition start offset WidgetQueryContentEvent selectedTextEvent(true, @@ -218,10 +221,9 @@ TextComposition::NotityUpdateComposition(WidgetGUIEvent* aEvent) mCompositionStartOffset = 0; } mCompositionTargetOffset = mCompositionStartOffset; - } else if (aEvent->message == NS_COMPOSITION_CHANGE) { + } else if (aCompositionEvent->message == NS_COMPOSITION_CHANGE) { mCompositionTargetOffset = - mCompositionStartOffset + - aEvent->AsCompositionEvent()->TargetClauseOffset(); + mCompositionStartOffset + aCompositionEvent->TargetClauseOffset(); } else { return; } diff --git a/dom/events/TextComposition.h b/dom/events/TextComposition.h index ff406c14e445..a9efc9c20875 100644 --- a/dom/events/TextComposition.h +++ b/dom/events/TextComposition.h @@ -40,7 +40,7 @@ class TextComposition MOZ_FINAL public: TextComposition(nsPresContext* aPresContext, nsINode* aNode, - WidgetGUIEvent* aEvent); + WidgetCompositionEvent* aCompositionEvent); bool Destroyed() const { return !mPresContext; } nsPresContext* GetPresContext() const { return mPresContext; } @@ -250,21 +250,22 @@ private: void EditorDidHandleCompositionChangeEvent(); /** - * DispatchEvent() dispatches the aEvent to the mContent synchronously. - * The caller must ensure that it's safe to dispatch the event. + * DispatchCompositionEvent() dispatches the aCompositionEvent to the mContent + * synchronously. The caller must ensure that it's safe to dispatch the event. */ - void DispatchEvent(WidgetGUIEvent* aEvent, - nsEventStatus* aStatus, - EventDispatchingCallback* aCallBack, - bool aIsSynthesized); + void DispatchCompositionEvent(WidgetCompositionEvent* aCompositionEvent, + nsEventStatus* aStatus, + EventDispatchingCallback* aCallBack, + bool aIsSynthesized); /** * MaybeDispatchCompositionUpdate() may dispatch a compositionupdate event - * if aEvent changes composition string. + * if aCompositionEvent changes composition string. * @return Returns false if dispatching the compositionupdate event caused * destroying this composition. */ - bool MaybeDispatchCompositionUpdate(const WidgetCompositionEvent* aEvent); + bool MaybeDispatchCompositionUpdate( + const WidgetCompositionEvent* aCompositionEvent); /** * If IME has already dispatched compositionend event but it was discarded @@ -280,12 +281,13 @@ private: * compositionupdate, compositionend or compositionchange event due to not * safe to dispatch event. */ - void OnCompositionEventDiscarded(const WidgetGUIEvent* aEvent); + void OnCompositionEventDiscarded( + const WidgetCompositionEvent* aCompositionEvent); /** * Calculate composition offset then notify composition update to widget */ - void NotityUpdateComposition(WidgetGUIEvent* aEvent); + void NotityUpdateComposition(const WidgetCompositionEvent* aCompositionEvent); /** * CompositionEventDispatcher dispatches the specified composition (or text) diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index d920bd51cae9..2ca41c4571a3 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -6943,7 +6943,8 @@ PresShell::HandleEvent(nsIFrame* aFrame, if (!nsContentUtils::IsSafeToRunScript() && aEvent->IsAllowedToDispatchDOMEvent()) { if (aEvent->mClass == eCompositionEventClass) { - IMEStateManager::OnCompositionEventDiscarded(aEvent); + IMEStateManager::OnCompositionEventDiscarded( + aEvent->AsCompositionEvent()); } #ifdef DEBUG if (aEvent->IsIMERelatedEvent()) { @@ -7860,7 +7861,8 @@ PresShell::HandleEventInternal(WidgetEvent* aEvent, nsEventStatus* aStatus) if (eventTarget) { if (aEvent->mClass == eCompositionEventClass) { IMEStateManager::DispatchCompositionEvent(eventTarget, - mPresContext, aEvent, aStatus, eventCBPtr); + mPresContext, aEvent->AsCompositionEvent(), aStatus, + eventCBPtr); } else { EventDispatcher::Dispatch(eventTarget, mPresContext, aEvent, nullptr, aStatus, eventCBPtr); From 17d8fb7e4a103ec1de19b055c4f91f624f95b379 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Tue, 7 Oct 2014 19:01:50 +0900 Subject: [PATCH 24/84] Bug 960871 part.11 Rename EventUtils.synthesizeText() to EventUtils.synthesizeCompositionChange() r=smaug --- editor/libeditor/tests/test_bug1026397.html | 4 +- editor/libeditor/tests/test_bug697842.html | 8 +- editor/libeditor/tests/test_bug795785.html | 4 +- ...t_contenteditable_text_input_handling.html | 4 +- layout/base/tests/bug613807-1.html | 8 +- .../Harness_sanity/test_sanityEventUtils.html | 6 +- .../mochitest/tests/SimpleTest/EventUtils.js | 15 +- .../file_autocomplete_with_composition.js | 58 +++--- .../content/tests/chrome/findbar_window.xul | 4 +- widget/tests/test_assign_event_data.html | 16 +- widget/tests/test_imestate.html | 4 +- .../test_input_events_on_deactive_window.xul | 4 +- .../window_composition_text_querycontent.xul | 192 +++++++++--------- 13 files changed, 164 insertions(+), 163 deletions(-) diff --git a/editor/libeditor/tests/test_bug1026397.html b/editor/libeditor/tests/test_bug1026397.html index 35261128844e..e48d8d01e04e 100644 --- a/editor/libeditor/tests/test_bug1026397.html +++ b/editor/libeditor/tests/test_bug1026397.html @@ -47,7 +47,7 @@ function runTests() } synthesizeComposition({ type: "compositionstart" }); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": aInsertString, "clauses": @@ -60,7 +60,7 @@ function runTests() is(input.value, aExpectedValueDuringComposition, "The value of input whose maxlength is " + maxLengthStr + " should be " + aExpectedValueDuringComposition + " during composition" + aAdditionalExplanation); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": aInsertString, "clauses": diff --git a/editor/libeditor/tests/test_bug697842.html b/editor/libeditor/tests/test_bug697842.html index ac1ee8f59e6e..d814a5c5764d 100644 --- a/editor/libeditor/tests/test_bug697842.html +++ b/editor/libeditor/tests/test_bug697842.html @@ -53,7 +53,7 @@ function runTests() // input first character composingString = "\u306B"; - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": composingString, "clauses": @@ -66,7 +66,7 @@ function runTests() // input second character composingString = "\u306B\u3085"; - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": composingString, "clauses": @@ -78,7 +78,7 @@ function runTests() }); // convert them - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": composingString, "clauses": @@ -91,7 +91,7 @@ function runTests() }); // commit - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": composingString, "clauses": diff --git a/editor/libeditor/tests/test_bug795785.html b/editor/libeditor/tests/test_bug795785.html index 1b311a8b09e4..443e06392111 100644 --- a/editor/libeditor/tests/test_bug795785.html +++ b/editor/libeditor/tests/test_bug795785.html @@ -122,7 +122,7 @@ function doCompositionTest(aElement, aElementDescription, aCallback) "\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3092\u3088\u308a" + "\u77ed\u6642\u9593\u3067\u7c21\u5358\u306b\u4f5c\u6210\u3067" + "\u304d\u307e\u3059\u3002"; - synthesizeText({ + synthesizeCompositionChange({ composition: { string: str, clauses: [ @@ -134,7 +134,7 @@ function doCompositionTest(aElement, aElementDescription, aCallback) hitEventLoop(function () { isnot(aElement.scrollTop, 0, aElementDescription + " was not scrolled by composition"); - synthesizeText({ + synthesizeCompositionChange({ composition: { string: "", clauses: [ { length: 0, attr: 0 } ] }, caret: { start: 0, length: 0 } }); diff --git a/editor/libeditor/tests/test_contenteditable_text_input_handling.html b/editor/libeditor/tests/test_contenteditable_text_input_handling.html index 31c9054bbe94..06db744de266 100644 --- a/editor/libeditor/tests/test_contenteditable_text_input_handling.html +++ b/editor/libeditor/tests/test_contenteditable_text_input_handling.html @@ -222,7 +222,7 @@ function runTests() // start composition synthesizeComposition({ type: "compositionstart" }); // input first character - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3089", "clauses": @@ -257,7 +257,7 @@ function runTests() is(querySelectedText.text, "", "query selected text event returns wrong selected text" + when); // commit composition - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3089", "clauses": diff --git a/layout/base/tests/bug613807-1.html b/layout/base/tests/bug613807-1.html index 08f516f890be..6b89013f3afb 100644 --- a/layout/base/tests/bug613807-1.html +++ b/layout/base/tests/bug613807-1.html @@ -50,7 +50,7 @@ synthesizeComposition({ type: "compositionstart" }); // input raw characters - synthesizeText( + synthesizeCompositionChange( { composition: { string: "\u306D", clauses: [ @@ -59,7 +59,7 @@ }, caret: { start: 1, length: 0 } }); - synthesizeText( + synthesizeCompositionChange( { composition: { string: "\u306D\u3053", clauses: [ @@ -70,7 +70,7 @@ }); // convert - synthesizeText( + synthesizeCompositionChange( { composition: { string: "\u732B", clauses: [ @@ -81,7 +81,7 @@ }); // commit - synthesizeText( + synthesizeCompositionChange( { composition: { string: "\u732B", clauses: [ diff --git a/testing/mochitest/tests/Harness_sanity/test_sanityEventUtils.html b/testing/mochitest/tests/Harness_sanity/test_sanityEventUtils.html index 76e32d9d774a..e3643d395897 100644 --- a/testing/mochitest/tests/Harness_sanity/test_sanityEventUtils.html +++ b/testing/mochitest/tests/Harness_sanity/test_sanityEventUtils.html @@ -128,7 +128,7 @@ function starttest() { check = false; window.addEventListener("text", function() { check = true; }, false); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "a", "clauses": @@ -139,9 +139,9 @@ function starttest() { "caret": { "start": 1, "length": 0 } } ); - is(check, true, "synthesizeText should dispatch text event"); + is(check, true, "synthesizeCompositionChange should cause dispatching a DOM text event"); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "a", "clauses": diff --git a/testing/mochitest/tests/SimpleTest/EventUtils.js b/testing/mochitest/tests/SimpleTest/EventUtils.js index 6412cd6d10a5..4028bbae2fcd 100644 --- a/testing/mochitest/tests/SimpleTest/EventUtils.js +++ b/testing/mochitest/tests/SimpleTest/EventUtils.js @@ -889,13 +889,14 @@ function synthesizeComposition(aEvent, aWindow) aEvent.locale ? aEvent.locale : ""); } /** - * Synthesize a text event. + * Synthesize a compositionchange event which causes a DOM text event and + * compositionupdate event if it's necessary. * - * @param aEvent The text event's information, this has |composition| - * and |caret| members. |composition| has |string| and - * |clauses| members. |clauses| must be array object. Each - * object has |length| and |attr|. And |caret| has |start| and - * |length|. See the following tree image. + * @param aEvent The compositionchange event's information, this has + * |composition| and |caret| members. |composition| has + * |string| and |clauses| members. |clauses| must be array + * object. Each object has |length| and |attr|. And |caret| + * has |start| and |length|. See the following tree image. * * aEvent * +-- composition @@ -928,7 +929,7 @@ function synthesizeComposition(aEvent, aWindow) * * @param aWindow Optional (If null, current |window| will be used) */ -function synthesizeText(aEvent, aWindow) +function synthesizeCompositionChange(aEvent, aWindow) { var utils = _getDOMWindowUtils(aWindow); if (!utils) { diff --git a/toolkit/content/tests/chrome/file_autocomplete_with_composition.js b/toolkit/content/tests/chrome/file_autocomplete_with_composition.js index d8e67ebe719e..f91b4aae4c19 100644 --- a/toolkit/content/tests/chrome/file_autocomplete_with_composition.js +++ b/toolkit/content/tests/chrome/file_autocomplete_with_composition.js @@ -88,7 +88,7 @@ nsDoTestsForAutoCompleteWithComposition.prototype = { execute: function (aWindow) { synthesizeKey("m", { type: "keydown", shiftKey: true }, aWindow); synthesizeComposition({ type: "compositionstart" }, aWindow); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "M", "clauses": @@ -103,7 +103,7 @@ nsDoTestsForAutoCompleteWithComposition.prototype = { { description: "modifying composition string shouldn't open the popup", completeDefaultIndex: false, execute: function (aWindow) { - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "Mo", "clauses": @@ -118,7 +118,7 @@ nsDoTestsForAutoCompleteWithComposition.prototype = { { description: "compositionend should open the popup", completeDefaultIndex: false, execute: function (aWindow) { - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "Mo", "clauses": @@ -139,7 +139,7 @@ nsDoTestsForAutoCompleteWithComposition.prototype = { execute: function (aWindow) { synthesizeKey("z", { type: "keydown" }, aWindow); synthesizeComposition({ type: "compositionstart" }, aWindow); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "z", "clauses": @@ -154,7 +154,7 @@ nsDoTestsForAutoCompleteWithComposition.prototype = { { description: "modifying composition string shouldn't reopen the popup", completeDefaultIndex: false, execute: function (aWindow) { - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "zi", "clauses": @@ -169,7 +169,7 @@ nsDoTestsForAutoCompleteWithComposition.prototype = { { description: "compositionend should research the result and open the popup", completeDefaultIndex: false, execute: function (aWindow) { - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "zi", "clauses": @@ -189,7 +189,7 @@ nsDoTestsForAutoCompleteWithComposition.prototype = { execute: function (aWindow) { synthesizeKey("l", { type: "keydown" }, aWindow); synthesizeComposition({ type: "compositionstart" }, aWindow); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "l", "clauses": @@ -204,7 +204,7 @@ nsDoTestsForAutoCompleteWithComposition.prototype = { { description: "modifying composition string shouldn't reopen the popup", completeDefaultIndex: false, execute: function (aWindow) { - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "ll", "clauses": @@ -219,7 +219,7 @@ nsDoTestsForAutoCompleteWithComposition.prototype = { { description: "modifying composition string to empty string shouldn't reopen the popup", completeDefaultIndex: false, execute: function (aWindow) { - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "", "clauses": @@ -234,7 +234,7 @@ nsDoTestsForAutoCompleteWithComposition.prototype = { { description: "cancled compositionend should reopen the popup", completeDefaultIndex: false, execute: function (aWindow) { - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "", "clauses": @@ -257,7 +257,7 @@ nsDoTestsForAutoCompleteWithComposition.prototype = { synthesizeKey("VK_LEFT", { shiftKey: true }, aWindow); synthesizeKey("z", { type: "keydown" }, aWindow); synthesizeComposition({ type: "compositionstart" }, aWindow); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "z", "clauses": @@ -272,7 +272,7 @@ nsDoTestsForAutoCompleteWithComposition.prototype = { { description: "modifying composition string shouldn't reopen the popup", completeDefaultIndex: false, execute: function (aWindow) { - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "zi", "clauses": @@ -287,7 +287,7 @@ nsDoTestsForAutoCompleteWithComposition.prototype = { { description: "modifying composition string to empty string shouldn't reopen the popup", completeDefaultIndex: false, execute: function (aWindow) { - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "", "clauses": @@ -302,7 +302,7 @@ nsDoTestsForAutoCompleteWithComposition.prototype = { { description: "canceled compositionend should seach the result with the latest value", completeDefaultIndex: false, execute: function (aWindow) { - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "", "clauses": @@ -330,7 +330,7 @@ nsDoTestsForAutoCompleteWithComposition.prototype = { execute: function (aWindow) { synthesizeKey("m", { type: "keydown", shiftKey: true }, aWindow); synthesizeComposition({ type: "compositionstart" }, aWindow); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "M", "clauses": @@ -345,7 +345,7 @@ nsDoTestsForAutoCompleteWithComposition.prototype = { { description: "modifying composition string shouldn't open the popup", completeDefaultIndex: false, execute: function (aWindow) { - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "Mo", "clauses": @@ -360,7 +360,7 @@ nsDoTestsForAutoCompleteWithComposition.prototype = { { description: "modifying composition string to empty string shouldn't open the popup", completeDefaultIndex: false, execute: function (aWindow) { - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "", "clauses": @@ -375,7 +375,7 @@ nsDoTestsForAutoCompleteWithComposition.prototype = { { description: "canceled compositionend shouldn't open the popup if it was closed", completeDefaultIndex: false, execute: function (aWindow) { - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "", "clauses": @@ -403,7 +403,7 @@ nsDoTestsForAutoCompleteWithComposition.prototype = { execute: function (aWindow) { synthesizeKey("m", { type: "keydown", shiftKey: true }, aWindow); synthesizeComposition({ type: "compositionstart" }, aWindow); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "M", "clauses": @@ -418,7 +418,7 @@ nsDoTestsForAutoCompleteWithComposition.prototype = { { description: "modifying composition string shouldn't open the popup", completeDefaultIndex: false, execute: function (aWindow) { - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "Mo", "clauses": @@ -433,7 +433,7 @@ nsDoTestsForAutoCompleteWithComposition.prototype = { { description: "modifying composition string to empty string shouldn't open the popup", completeDefaultIndex: false, execute: function (aWindow) { - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "", "clauses": @@ -448,7 +448,7 @@ nsDoTestsForAutoCompleteWithComposition.prototype = { { description: "canceled compositionend should open the popup if it was opened", completeDefaultIndex: false, execute: function (aWindow) { - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "", "clauses": @@ -479,7 +479,7 @@ nsDoTestsForAutoCompleteWithComposition.prototype = { execute: function (aWindow) { synthesizeKey("z", { type: "keydown", shiftKey: true }, aWindow); synthesizeComposition({ type: "compositionstart" }, aWindow); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "z", "clauses": @@ -494,7 +494,7 @@ nsDoTestsForAutoCompleteWithComposition.prototype = { { description: "modifying composition string shouldn't open the popup", completeDefaultIndex: false, execute: function (aWindow) { - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "zi", "clauses": @@ -509,7 +509,7 @@ nsDoTestsForAutoCompleteWithComposition.prototype = { { description: "modifying composition string to empty string shouldn't open the popup", completeDefaultIndex: false, execute: function (aWindow) { - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "", "clauses": @@ -524,7 +524,7 @@ nsDoTestsForAutoCompleteWithComposition.prototype = { { description: "canceled compositionend shouldn't open the popup if the popup was closed", completeDefaultIndex: false, execute: function (aWindow) { - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "", "clauses": @@ -552,7 +552,7 @@ nsDoTestsForAutoCompleteWithComposition.prototype = { execute: function (aWindow) { synthesizeKey("m", { type: "keydown", shiftKey: true }, aWindow); synthesizeComposition({ type: "compositionstart" }, aWindow); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "M", "clauses": @@ -567,7 +567,7 @@ nsDoTestsForAutoCompleteWithComposition.prototype = { { description: "modifying composition string shouldn't open the popup (completeDefaultIndex is true)", completeDefaultIndex: true, execute: function (aWindow) { - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "Mo", "clauses": @@ -582,7 +582,7 @@ nsDoTestsForAutoCompleteWithComposition.prototype = { { description: "compositionend should open the popup (completeDefaultIndex is true)", completeDefaultIndex: true, execute: function (aWindow) { - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "Mo", "clauses": diff --git a/toolkit/content/tests/chrome/findbar_window.xul b/toolkit/content/tests/chrome/findbar_window.xul index fb9d37dcb468..a144d0afaccd 100644 --- a/toolkit/content/tests/chrome/findbar_window.xul +++ b/toolkit/content/tests/chrome/findbar_window.xul @@ -245,7 +245,7 @@ var searchStr = "text"; synthesizeComposition({ type: "compositionstart" }); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": searchStr, "clauses": @@ -259,7 +259,7 @@ ok(gBrowser.contentWindow.getSelection().toString().toLowerCase() != searchStr, "testNormalFindWithComposition: text shouldn't be found during composition"); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": searchStr, "clauses": diff --git a/widget/tests/test_assign_event_data.html b/widget/tests/test_assign_event_data.html index d723be5ffa91..9275f2cab0d1 100644 --- a/widget/tests/test_assign_event_data.html +++ b/widget/tests/test_assign_event_data.html @@ -176,7 +176,7 @@ const kTests = [ document.getElementById(this.targetID).focus(); synthesizeKey("a", { type: "keydown" }); synthesizeComposition({ type: "compositionstart" }); - synthesizeText({ "composition": + synthesizeCompositionChange({ "composition": { "string": "\u306D", "clauses": [ @@ -186,7 +186,7 @@ const kTests = [ "caret": { "start": 1, "length": 0 } }); synthesizeKey("a", { type: "keyup" }); - synthesizeText({ "composition": + synthesizeCompositionChange({ "composition": { "string": "\u306D", "clauses": [ @@ -208,7 +208,7 @@ const kTests = [ document.getElementById(this.targetID).value = ""; document.getElementById(this.targetID).focus(); synthesizeComposition({ type: "compositionstart" }); - synthesizeText({ "composition": + synthesizeCompositionChange({ "composition": { "string": "\u306D", "clauses": [ @@ -218,7 +218,7 @@ const kTests = [ "caret": { "start": 1, "length": 0 } }); synthesizeKey("VK_RETURN", { type: "keydown" }); - synthesizeText({ "composition": + synthesizeCompositionChange({ "composition": { "string": "\u306D", "clauses": [ @@ -288,7 +288,7 @@ const kTests = [ document.getElementById(this.targetID).value = ""; document.getElementById(this.targetID).focus(); synthesizeComposition({ type: "compositionstart" }); - synthesizeText({ "composition": + synthesizeCompositionChange({ "composition": { "string": "\u306D", "clauses": [ @@ -310,7 +310,7 @@ const kTests = [ document.getElementById(this.targetID).value = ""; document.getElementById(this.targetID).focus(); synthesizeComposition({ type: "compositionstart" }); - synthesizeText({ "composition": + synthesizeCompositionChange({ "composition": { "string": "\u30E9\u30FC\u30E1\u30F3", "clauses": [ @@ -345,7 +345,7 @@ const kTests = [ document.getElementById(this.targetID).value = ""; document.getElementById(this.targetID).focus(); synthesizeComposition({ type: "compositionstart" }); - synthesizeText({ "composition": + synthesizeCompositionChange({ "composition": { "string": "\u30E9\u30FC\u30E1\u30F3", "clauses": [ @@ -363,7 +363,7 @@ const kTests = [ { description: "InternalEditorInputEvent (input at committing)", targetID: "input-text", eventType: "input", dispatchEvent: function () { - synthesizeText({ "composition": + synthesizeCompositionChange({ "composition": { "string": "\u30E9\u30FC\u30E1\u30F3", "clauses": [ diff --git a/widget/tests/test_imestate.html b/widget/tests/test_imestate.html index cdb63e92bbfd..a6f29a828e77 100644 --- a/widget/tests/test_imestate.html +++ b/widget/tests/test_imestate.html @@ -1236,7 +1236,7 @@ function runEditorFlagChangeTests() synthesizeComposition({ type: "compositionstart" }); // input characters - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3078\u3093\u3057\u3093", "clauses": @@ -1266,7 +1266,7 @@ function runEditorFlagChangeTests() description + "#3 IME isn't enabled on HTML editor"); // cancel the composition - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "", "clauses": diff --git a/widget/tests/test_input_events_on_deactive_window.xul b/widget/tests/test_input_events_on_deactive_window.xul index d7e3f4c7812b..7d38ff94fe9d 100644 --- a/widget/tests/test_input_events_on_deactive_window.xul +++ b/widget/tests/test_input_events_on_deactive_window.xul @@ -159,7 +159,7 @@ function startTests() checkCompositionEvents(true, false, false, false, "compositionstart"); clear(); // input first character - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3089", "clauses": @@ -195,7 +195,7 @@ function startTests() "query selected text event returns wrong selected text"); clear(); // commit composition - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3089", "clauses": diff --git a/widget/tests/window_composition_text_querycontent.xul b/widget/tests/window_composition_text_querycontent.xul index 3dbbaa7ba567..d6e09592c51a 100644 --- a/widget/tests/window_composition_text_querycontent.xul +++ b/widget/tests/window_composition_text_querycontent.xul @@ -194,7 +194,7 @@ function runUndoRedoTest() synthesizeComposition({ type: "compositionstart" }); // input raw characters - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u306D", "clauses": @@ -205,7 +205,7 @@ function runUndoRedoTest() "caret": { "start": 1, "length": 0 } }); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u306D\u3053", "clauses": @@ -217,7 +217,7 @@ function runUndoRedoTest() }); // convert - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u732B", "clauses": @@ -230,7 +230,7 @@ function runUndoRedoTest() }); // commit - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u732B", "clauses": @@ -248,7 +248,7 @@ function runUndoRedoTest() synthesizeComposition({ type: "compositionstart" }); // input raw characters - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u307E", "clauses": @@ -260,7 +260,7 @@ function runUndoRedoTest() }); // cancel the composition - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "", "clauses": @@ -278,7 +278,7 @@ function runUndoRedoTest() synthesizeComposition({ type: "compositionstart" }); // input raw characters - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3080", "clauses": @@ -289,7 +289,7 @@ function runUndoRedoTest() "caret": { "start": 1, "length": 0 } }); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3080\u3059", "clauses": @@ -300,7 +300,7 @@ function runUndoRedoTest() "caret": { "start": 2, "length": 0 } }); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3080\u3059\u3081", "clauses": @@ -312,7 +312,7 @@ function runUndoRedoTest() }); // convert - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u5A18", "clauses": @@ -325,7 +325,7 @@ function runUndoRedoTest() }); // commit - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u5A18", "clauses": @@ -376,7 +376,7 @@ function runUndoRedoTest() synthesizeComposition({ type: "compositionstart" }); // input raw characters - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3088", "clauses": @@ -387,7 +387,7 @@ function runUndoRedoTest() "caret": { "start": 1, "length": 0 } }); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3088\u3046", "clauses": @@ -398,7 +398,7 @@ function runUndoRedoTest() "caret": { "start": 2, "length": 0 } }); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3088\u3046\u304b", "clauses": @@ -409,7 +409,7 @@ function runUndoRedoTest() "caret": { "start": 3, "length": 0 } }); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3088\u3046\u304b\u3044", "clauses": @@ -421,7 +421,7 @@ function runUndoRedoTest() }); // convert - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u5996\u602a", "clauses": @@ -433,7 +433,7 @@ function runUndoRedoTest() }); // commit - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u5996\u602a", "clauses": @@ -631,7 +631,7 @@ function runCompositionTest() synthesizeComposition({ type: "compositionstart" }); // input first character - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3089", "clauses": @@ -655,7 +655,7 @@ function runCompositionTest() caretRects[1] = caretRect; // input second character - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3089\u30FC", "clauses": @@ -688,7 +688,7 @@ function runCompositionTest() "runCompositionTest: caret width is wrong (#1-2)"); // input third character - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3089\u30FC\u3081", "clauses": @@ -721,7 +721,7 @@ function runCompositionTest() "runCompositionTest: caret height is wrong (#1-3)"); // moves the caret left - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3089\u30FC\u3081", "clauses": @@ -755,7 +755,7 @@ function runCompositionTest() "runCompositionTest: caret rects are different (#1-3-1, height)"); // moves the caret left - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3089\u30FC\u3081", "clauses": @@ -788,7 +788,7 @@ function runCompositionTest() is(caretRect.height, caretRects[1].height, "runCompositionTest: caret rects are different (#1-3-2, height)"); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3089\u30FC\u3081\u3093", "clauses": @@ -806,7 +806,7 @@ function runCompositionTest() // backspace - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3089\u30FC\u3081", "clauses": @@ -823,7 +823,7 @@ function runCompositionTest() } // re-input - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3089\u30FC\u3081\u3093", "clauses": @@ -839,7 +839,7 @@ function runCompositionTest() return; } - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3089\u30FC\u3081\u3093\u3055", "clauses": @@ -855,7 +855,7 @@ function runCompositionTest() return; } - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3089\u30FC\u3081\u3093\u3055\u3044", "clauses": @@ -871,7 +871,7 @@ function runCompositionTest() return; } - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3089\u30FC\u3081\u3093\u3055\u3044\u3053", "clauses": @@ -887,7 +887,7 @@ function runCompositionTest() return; } - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3089\u30FC\u3081\u3093\u3055\u3044\u3053\u3046", "clauses": @@ -905,7 +905,7 @@ function runCompositionTest() } // convert - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u30E9\u30FC\u30E1\u30F3\u6700\u9AD8", "clauses": @@ -926,7 +926,7 @@ function runCompositionTest() } // change the selected clause - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u30E9\u30FC\u30E1\u30F3\u6700\u9AD8", "clauses": @@ -947,7 +947,7 @@ function runCompositionTest() } // reset clauses - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u30E9\u30FC\u30E1\u30F3\u3055\u884C\u3053\u3046", "clauses": @@ -978,7 +978,7 @@ function runCompositionTest() } // commit the composition string - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u30E9\u30FC\u30E1\u30F3\u3055\u884C\u3053\u3046", "clauses": @@ -1015,7 +1015,7 @@ function runCompositionTest() synthesizeComposition({ type: "compositionstart" }); // input characters - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3057", "clauses": @@ -1032,7 +1032,7 @@ function runCompositionTest() return; } - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3058", "clauses": @@ -1049,7 +1049,7 @@ function runCompositionTest() return; } - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3058\u3087", "clauses": @@ -1066,7 +1066,7 @@ function runCompositionTest() return; } - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3058\u3087\u3046", "clauses": @@ -1084,7 +1084,7 @@ function runCompositionTest() } // commit the composition string - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3058\u3087\u3046", "clauses": @@ -1114,7 +1114,7 @@ function runCompositionTest() // start composition with selection synthesizeComposition({ type: "compositionstart" }); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u304A", "clauses": @@ -1132,7 +1132,7 @@ function runCompositionTest() } // remove the composition string - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "", "clauses": @@ -1150,7 +1150,7 @@ function runCompositionTest() } // re-input the composition string - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3046", "clauses": @@ -1168,7 +1168,7 @@ function runCompositionTest() } // cancel the composition - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "", "clauses": @@ -1192,7 +1192,7 @@ function runCompositionTest() // its candidate window. synthesizeComposition({ type: "compositionstart" }); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "", "clauses": @@ -1209,7 +1209,7 @@ function runCompositionTest() return; } - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "", "clauses": @@ -1226,7 +1226,7 @@ function runCompositionTest() return; } - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u6700", "clauses": @@ -1254,7 +1254,7 @@ function runCompositionTest() // testing the canceling case synthesizeComposition({ type: "compositionstart" }); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "", "clauses": @@ -1271,7 +1271,7 @@ function runCompositionTest() return; } - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "", "clauses": @@ -1301,7 +1301,7 @@ function runCompositionTest() synthesizeComposition({ type: "compositionstart" }); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "", "clauses": @@ -1318,7 +1318,7 @@ function runCompositionTest() return; } - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u9AD8", "clauses": @@ -1354,7 +1354,7 @@ function runCompositionTest() // twice at canceling composition. synthesizeComposition({ type: "compositionstart" }); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u6700", "clauses": @@ -1371,7 +1371,7 @@ function runCompositionTest() return; } - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "", "clauses": @@ -1388,7 +1388,7 @@ function runCompositionTest() return; } - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "", "clauses": @@ -1544,7 +1544,7 @@ function runCompositionEventTest() initResults(); synthesizeComposition({ type: "compositionstart" }); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3089", "clauses": @@ -1595,7 +1595,7 @@ function runCompositionEventTest() is(inputEventData["input"], "\u3089", kDescription + "value of input element wasn't modified (input) #1"); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3089\u30FC", "clauses": @@ -1639,7 +1639,7 @@ function runCompositionEventTest() kDescription + "value of input element wasn't modified (input) #2"); // text event shouldn't cause composition update, e.g., at committing. - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3089\u30FC", "clauses": @@ -1691,7 +1691,7 @@ function runCompositionEventTest() synthesizeComposition({ type: "compositionstart" }); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3089", "clauses": @@ -1702,7 +1702,7 @@ function runCompositionEventTest() "caret": { "start": 1, "length": 0 } }); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3089", "clauses": @@ -1771,7 +1771,7 @@ function runCompositionEventTest() synthesizeComposition({ type: "compositionstart" }); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u306D", "clauses": @@ -1782,7 +1782,7 @@ function runCompositionEventTest() "caret": { "start": 1, "length": 0 } }); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u306D", "clauses": @@ -1853,7 +1853,7 @@ function runCompositionEventTest() synthesizeComposition({ type: "compositionstart" }); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u306E", "clauses": @@ -1864,7 +1864,7 @@ function runCompositionEventTest() "caret": { "start": 1, "length": 0 } }); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u306E", "clauses": @@ -2238,7 +2238,7 @@ function runForceCommitTest() events = []; synthesizeComposition({ type: "compositionstart" }); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u306E", "clauses": @@ -2291,7 +2291,7 @@ function runForceCommitTest() synthesizeComposition({ type: "compositionstart" }); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u306E", "clauses": @@ -2336,7 +2336,7 @@ function runForceCommitTest() synthesizeComposition({ type: "compositionstart" }); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u306E", "clauses": @@ -2378,7 +2378,7 @@ function runForceCommitTest() synthesizeComposition({ type: "compositionstart" }); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u306E", "clauses": @@ -2424,7 +2424,7 @@ function runForceCommitTest() synthesizeComposition({ type: "compositionstart" }); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u306E", "clauses": @@ -2470,7 +2470,7 @@ function runForceCommitTest() synthesizeComposition({ type: "compositionstart" }); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u306E", "clauses": @@ -2517,7 +2517,7 @@ function runForceCommitTest() synthesizeComposition({ type: "compositionstart" }); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u306E", "clauses": @@ -2563,7 +2563,7 @@ function runForceCommitTest() synthesizeComposition({ type: "compositionstart" }, iframe2.contentWindow); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u306E", "clauses": @@ -2607,7 +2607,7 @@ function runForceCommitTest() synthesizeComposition({ type: "compositionstart" }, iframe2.contentWindow); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u306E", "clauses": @@ -2656,7 +2656,7 @@ function runForceCommitTest() synthesizeComposition({ type: "compositionstart" }, iframe2.contentWindow); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u306E", "clauses": @@ -2759,7 +2759,7 @@ function runIsComposingTest() synthesizeComposition({ type: "compositionstart" }); expectedIsComposing = true; description = "events after dispatching compositionstart"; - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3042", "clauses": @@ -2776,7 +2776,7 @@ function runIsComposingTest() description = "events for committing composition string"; synthesizeKey("VK_RETURN", { type: "keydown" }); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3042", "clauses": @@ -2820,7 +2820,7 @@ function runRemoveContentTest(aCallback) synthesizeComposition({ type: "compositionstart" }); - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u306E", "clauses": @@ -2919,7 +2919,7 @@ function runTestOnAnotherContext(aPanelOrFrame, aFocusedEditor, aTestName) synthesizeComposition({ type: "compositionstart" }); // input characters - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3078\u3093\u3057\u3093", "clauses": @@ -2936,7 +2936,7 @@ function runTestOnAnotherContext(aPanelOrFrame, aFocusedEditor, aTestName) } // convert them #1 - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u8FD4\u4FE1", "clauses": @@ -2954,7 +2954,7 @@ function runTestOnAnotherContext(aPanelOrFrame, aFocusedEditor, aTestName) } // convert them #2 - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u5909\u8EAB", "clauses": @@ -2972,7 +2972,7 @@ function runTestOnAnotherContext(aPanelOrFrame, aFocusedEditor, aTestName) } // commit them - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u5909\u8EAB", "clauses": @@ -3072,7 +3072,7 @@ function runMaxLengthTest() synthesizeComposition({ type: "compositionstart" }); // input first character - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3089", "clauses": @@ -3089,7 +3089,7 @@ function runMaxLengthTest() } // input second character - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3089\u30FC", "clauses": @@ -3106,7 +3106,7 @@ function runMaxLengthTest() } // input third character - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3089\u30FC\u3081", "clauses": @@ -3123,7 +3123,7 @@ function runMaxLengthTest() } // input fourth character - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3089\u30FC\u3081\u3093", "clauses": @@ -3141,7 +3141,7 @@ function runMaxLengthTest() // backspace - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3089\u30FC\u3081", "clauses": @@ -3158,7 +3158,7 @@ function runMaxLengthTest() } // re-input - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3089\u30FC\u3081\u3093", "clauses": @@ -3174,7 +3174,7 @@ function runMaxLengthTest() return; } - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3089\u30FC\u3081\u3093\u3055", "clauses": @@ -3190,7 +3190,7 @@ function runMaxLengthTest() return; } - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3089\u30FC\u3081\u3093\u3055\u3044", "clauses": @@ -3206,7 +3206,7 @@ function runMaxLengthTest() return; } - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3089\u30FC\u3081\u3093\u3055\u3044\u3053", "clauses": @@ -3223,7 +3223,7 @@ function runMaxLengthTest() return; } - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3089\u30FC\u3081\u3093\u3055\u3044\u3053\u3046", "clauses": @@ -3241,7 +3241,7 @@ function runMaxLengthTest() } // convert - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u30E9\u30FC\u30E1\u30F3\u6700\u9AD8", "clauses": @@ -3261,7 +3261,7 @@ function runMaxLengthTest() } // commit the composition string - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u30E9\u30FC\u30E1\u30F3\u6700\u9AD8", "clauses": @@ -3284,7 +3284,7 @@ function runMaxLengthTest() synthesizeComposition({ type: "compositionstart" }); // input characters - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3057", "clauses": @@ -3301,7 +3301,7 @@ function runMaxLengthTest() } // commit the composition string - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u3058", "clauses": @@ -3358,7 +3358,7 @@ function runMaxLengthTest() synthesizeComposition({ type: "compositionstart" }); // input characters - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u9B54", "clauses": @@ -3375,7 +3375,7 @@ function runMaxLengthTest() } // commit the composition string - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u9B54", "clauses": @@ -3399,7 +3399,7 @@ function runMaxLengthTest() synthesizeComposition({ type: "compositionstart" }); // input characters - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u9B54\u6CD5", "clauses": @@ -3416,7 +3416,7 @@ function runMaxLengthTest() } // commit the composition string - synthesizeText( + synthesizeCompositionChange( { "composition": { "string": "\u9B54\u6CD5", "clauses": From 9763dfc421dce67b0ddc30a2516943075652b287 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Tue, 7 Oct 2014 19:01:50 +0900 Subject: [PATCH 25/84] Bug 960871 part.12 Get rid of TextEvent() of PBrowser r=smaug --- dom/events/EventStateManager.cpp | 13 +------------ dom/ipc/PBrowser.ipdl | 2 -- dom/ipc/TabChild.cpp | 9 --------- dom/ipc/TabChild.h | 1 - dom/ipc/TabParent.cpp | 12 +++++++----- dom/ipc/TabParent.h | 3 ++- 6 files changed, 10 insertions(+), 30 deletions(-) diff --git a/dom/events/EventStateManager.cpp b/dom/events/EventStateManager.cpp index a24a4b15e5d8..785ade495ea1 100644 --- a/dom/events/EventStateManager.cpp +++ b/dom/events/EventStateManager.cpp @@ -796,18 +796,6 @@ EventStateManager::PreHandleEvent(nsPresContext* aPresContext, DoContentCommandScrollEvent(aEvent->AsContentCommandEvent()); } break; - case NS_COMPOSITION_CHANGE: - { - WidgetCompositionEvent* compositionEvent = aEvent->AsCompositionEvent(); - if (IsTargetCrossProcess(compositionEvent)) { - // Will not be handled locally, remote the event - if (GetCrossProcessTarget()->SendTextEvent(*compositionEvent)) { - // Cancel local dispatching - aEvent->mFlags.mPropagationStopped = true; - } - } - } - break; case NS_COMPOSITION_START: if (aEvent->mFlags.mIsTrusted) { // If the event is trusted event, set the selected text to data of @@ -821,6 +809,7 @@ EventStateManager::PreHandleEvent(nsPresContext* aPresContext, } // through to compositionend handling case NS_COMPOSITION_END: + case NS_COMPOSITION_CHANGE: { WidgetCompositionEvent* compositionEvent = aEvent->AsCompositionEvent(); if (IsTargetCrossProcess(compositionEvent)) { diff --git a/dom/ipc/PBrowser.ipdl b/dom/ipc/PBrowser.ipdl index 976d89209846..954c311f7f79 100644 --- a/dom/ipc/PBrowser.ipdl +++ b/dom/ipc/PBrowser.ipdl @@ -478,8 +478,6 @@ child: CompositionEvent(WidgetCompositionEvent event); - TextEvent(WidgetCompositionEvent event); - SelectionEvent(WidgetSelectionEvent event); /** diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index 3def67b24d89..28bbb8a68174 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -2388,15 +2388,6 @@ TabChild::RecvCompositionEvent(const WidgetCompositionEvent& event) return true; } -bool -TabChild::RecvTextEvent(const WidgetCompositionEvent& event) -{ - WidgetCompositionEvent localEvent(event); - localEvent.widget = mWidget; - DispatchWidgetEvent(localEvent); - return true; -} - bool TabChild::RecvSelectionEvent(const WidgetSelectionEvent& event) { diff --git a/dom/ipc/TabChild.h b/dom/ipc/TabChild.h index 2e2003e11d2b..7c5340490684 100644 --- a/dom/ipc/TabChild.h +++ b/dom/ipc/TabChild.h @@ -360,7 +360,6 @@ public: const int32_t& aModifiers, const bool& aPreventDefault) MOZ_OVERRIDE; virtual bool RecvCompositionEvent(const mozilla::WidgetCompositionEvent& event) MOZ_OVERRIDE; - virtual bool RecvTextEvent(const mozilla::WidgetCompositionEvent& event) MOZ_OVERRIDE; virtual bool RecvSelectionEvent(const mozilla::WidgetSelectionEvent& event) MOZ_OVERRIDE; virtual bool RecvActivateFrameEvent(const nsString& aType, const bool& capture) MOZ_OVERRIDE; virtual bool RecvLoadRemoteScript(const nsString& aURL, diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index 3796d39b760e..ee225d49cad9 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -1565,6 +1565,11 @@ TabParent::SendCompositionEvent(WidgetCompositionEvent& event) if (mIsDestroyed) { return false; } + + if (event.message == NS_COMPOSITION_CHANGE) { + return SendCompositionChangeEvent(event); + } + mIMEComposing = event.message != NS_COMPOSITION_END; mIMECompositionStart = std::min(mIMESelectionAnchor, mIMESelectionFocus); if (mIMECompositionEnding) @@ -1582,11 +1587,8 @@ TabParent::SendCompositionEvent(WidgetCompositionEvent& event) * here and pass the text as the EndIMEComposition return value */ bool -TabParent::SendTextEvent(WidgetCompositionEvent& event) +TabParent::SendCompositionChangeEvent(WidgetCompositionEvent& event) { - if (mIsDestroyed) { - return false; - } if (mIMECompositionEnding) { mIMECompositionText = event.mData; return true; @@ -1601,7 +1603,7 @@ TabParent::SendTextEvent(WidgetCompositionEvent& event) mIMECompositionStart + event.mData.Length(); event.mSeqno = ++mIMESeqno; - return PBrowserParent::SendTextEvent(event); + return PBrowserParent::SendCompositionEvent(event); } bool diff --git a/dom/ipc/TabParent.h b/dom/ipc/TabParent.h index 409a515a8899..c13d450647f1 100644 --- a/dom/ipc/TabParent.h +++ b/dom/ipc/TabParent.h @@ -318,7 +318,6 @@ public: static TabParent *GetIMETabParent() { return mIMETabParent; } bool HandleQueryContentEvent(mozilla::WidgetQueryContentEvent& aEvent); bool SendCompositionEvent(mozilla::WidgetCompositionEvent& event); - bool SendTextEvent(mozilla::WidgetCompositionEvent& event); bool SendSelectionEvent(mozilla::WidgetSelectionEvent& event); static TabParent* GetFrom(nsFrameLoader* aFrameLoader); @@ -364,6 +363,8 @@ protected: virtual bool RecvRemotePaintIsReady() MOZ_OVERRIDE; + bool SendCompositionChangeEvent(mozilla::WidgetCompositionEvent& event); + // IME static TabParent *mIMETabParent; nsString mIMECacheText; From 2dbcab7289223b67c2406a0773cc9431eb53ca76 Mon Sep 17 00:00:00 2001 From: "Carsten \"Tomcat\" Book" Date: Tue, 7 Oct 2014 12:52:49 +0200 Subject: [PATCH 26/84] Backed out changeset 124b04c01c71 (bug 1077926) --- security/pkix/test/gtest/pkixbuild_tests.cpp | 36 +++++++---- .../test/gtest/pkixcert_extension_tests.cpp | 8 +-- .../pkixocsp_VerifyEncodedOCSPResponse.cpp | 60 +++++++++--------- security/pkix/test/lib/pkixtestnss.cpp | 63 +++---------------- security/pkix/test/lib/pkixtestutil.cpp | 34 +++++++--- security/pkix/test/lib/pkixtestutil.h | 15 +++-- 6 files changed, 100 insertions(+), 116 deletions(-) diff --git a/security/pkix/test/gtest/pkixbuild_tests.cpp b/security/pkix/test/gtest/pkixbuild_tests.cpp index 07582f74807d..3c14ca13e31e 100644 --- a/security/pkix/test/gtest/pkixbuild_tests.cpp +++ b/security/pkix/test/gtest/pkixbuild_tests.cpp @@ -40,6 +40,8 @@ static ByteString CreateCert(const char* issuerCN, const char* subjectCN, EndEntityOrCA endEntityOrCA, + /*optional*/ TestKeyPair* issuerKey, + /*out*/ ScopedTestKeyPair& subjectKey, /*out*/ ScopedCERTCertificate* subjectCert = nullptr) { static long serialNumberValue = 0; @@ -58,12 +60,13 @@ CreateCert(const char* issuerCN, EXPECT_FALSE(ENCODING_FAILED(extensions[0])); } - ScopedTestKeyPair reusedKey(CloneReusedKeyPair()); ByteString certDER(CreateEncodedCertificate( - v3, sha256WithRSAEncryption, serialNumber, issuerDER, - oneDayBeforeNow, oneDayAfterNow, subjectDER, - *reusedKey, extensions, *reusedKey, - SignatureAlgorithm::rsa_pkcs1_with_sha256)); + v3, sha256WithRSAEncryption, + serialNumber, issuerDER, + oneDayBeforeNow, oneDayAfterNow, + subjectDER, extensions, issuerKey, + SignatureAlgorithm::rsa_pkcs1_with_sha256, + subjectKey)); EXPECT_FALSE(ENCODING_FAILED(certDER)); if (subjectCert) { SECItem certDERItem = { @@ -97,7 +100,7 @@ public: for (size_t i = 0; i < MOZILLA_PKIX_ARRAY_LENGTH(names); ++i) { const char* issuerName = i == 0 ? names[0] : names[i-1]; (void) CreateCert(issuerName, names[i], EndEntityOrCA::MustBeCA, - &certChainTail[i]); + leafCAKey.get(), leafCAKey, &certChainTail[i]); } return true; @@ -189,6 +192,7 @@ private: ScopedCERTCertificate certChainTail[7]; public: + ScopedTestKeyPair leafCAKey; CERTCertificate* GetLeafCACert() const { return certChainTail[MOZILLA_PKIX_ARRAY_LENGTH(certChainTail) - 1].get(); @@ -234,9 +238,11 @@ TEST_F(pkixbuild, MaxAcceptableCertChainLength) } { + ScopedTestKeyPair unusedKeyPair; ScopedCERTCertificate cert; ByteString certDER(CreateCert("CA7", "Direct End-Entity", - EndEntityOrCA::MustBeEndEntity)); + EndEntityOrCA::MustBeEndEntity, + trustDomain.leafCAKey.get(), unusedKeyPair)); ASSERT_FALSE(ENCODING_FAILED(certDER)); Input certDERInput; ASSERT_EQ(Success, certDERInput.Init(certDER.data(), certDER.length())); @@ -253,6 +259,7 @@ TEST_F(pkixbuild, MaxAcceptableCertChainLength) TEST_F(pkixbuild, BeyondMaxAcceptableCertChainLength) { static char const* const caCertName = "CA Too Far"; + ScopedTestKeyPair caKeyPair; // We need a CERTCertificate for caCert so that the trustdomain's FindIssuer // method can find it through the NSS cert DB. @@ -260,6 +267,7 @@ TEST_F(pkixbuild, BeyondMaxAcceptableCertChainLength) { ByteString certDER(CreateCert("CA7", caCertName, EndEntityOrCA::MustBeCA, + trustDomain.leafCAKey.get(), caKeyPair, &caCert)); ASSERT_FALSE(ENCODING_FAILED(certDER)); Input certDERInput; @@ -274,8 +282,10 @@ TEST_F(pkixbuild, BeyondMaxAcceptableCertChainLength) } { + ScopedTestKeyPair unusedKeyPair; ByteString certDER(CreateCert(caCertName, "End-Entity Too Far", - EndEntityOrCA::MustBeEndEntity)); + EndEntityOrCA::MustBeEndEntity, + caKeyPair.get(), unusedKeyPair)); ASSERT_FALSE(ENCODING_FAILED(certDER)); Input certDERInput; ASSERT_EQ(Success, certDERInput.Init(certDER.data(), certDER.length())); @@ -373,8 +383,9 @@ private: TEST_F(pkixbuild, NoRevocationCheckingForExpiredCert) { const char* rootCN = "Root CA"; + ScopedTestKeyPair rootKey; ByteString rootDER(CreateCert(rootCN, rootCN, EndEntityOrCA::MustBeCA, - nullptr)); + nullptr, rootKey, nullptr)); EXPECT_FALSE(ENCODING_FAILED(rootDER)); ExpiredCertTrustDomain expiredCertTrustDomain(rootDER); @@ -382,14 +393,15 @@ TEST_F(pkixbuild, NoRevocationCheckingForExpiredCert) EXPECT_FALSE(ENCODING_FAILED(serialNumber)); ByteString issuerDER(CNToDERName(rootCN)); ByteString subjectDER(CNToDERName("Expired End-Entity Cert")); - ScopedTestKeyPair reusedKey(CloneReusedKeyPair()); + ScopedTestKeyPair unusedSubjectKey; ByteString certDER(CreateEncodedCertificate( v3, sha256WithRSAEncryption, serialNumber, issuerDER, oneDayBeforeNow - Time::ONE_DAY_IN_SECONDS, oneDayBeforeNow, - subjectDER, *reusedKey, nullptr, *reusedKey, - SignatureAlgorithm::rsa_pkcs1_with_sha256)); + subjectDER, nullptr, rootKey.get(), + SignatureAlgorithm::rsa_pkcs1_with_sha256, + unusedSubjectKey)); EXPECT_FALSE(ENCODING_FAILED(certDER)); Input cert; diff --git a/security/pkix/test/gtest/pkixcert_extension_tests.cpp b/security/pkix/test/gtest/pkixcert_extension_tests.cpp index d988e1045448..371928e1379c 100644 --- a/security/pkix/test/gtest/pkixcert_extension_tests.cpp +++ b/security/pkix/test/gtest/pkixcert_extension_tests.cpp @@ -43,13 +43,13 @@ CreateCert(const char* subjectCN, EXPECT_FALSE(ENCODING_FAILED(issuerDER)); ByteString subjectDER(CNToDERName(subjectCN)); EXPECT_FALSE(ENCODING_FAILED(subjectDER)); - subjectKey = CloneReusedKeyPair(); return CreateEncodedCertificate(v3, sha256WithRSAEncryption, serialNumber, issuerDER, oneDayBeforeNow, oneDayAfterNow, - subjectDER, *subjectKey, extensions, - *subjectKey, - SignatureAlgorithm::rsa_pkcs1_with_sha256); + subjectDER, extensions, + nullptr, + SignatureAlgorithm::rsa_pkcs1_with_sha256, + subjectKey); } // Creates a self-signed certificate with the given extension. diff --git a/security/pkix/test/gtest/pkixocsp_VerifyEncodedOCSPResponse.cpp b/security/pkix/test/gtest/pkixocsp_VerifyEncodedOCSPResponse.cpp index 962c30d75e5f..27ccf630bb75 100644 --- a/security/pkix/test/gtest/pkixocsp_VerifyEncodedOCSPResponse.cpp +++ b/security/pkix/test/gtest/pkixocsp_VerifyEncodedOCSPResponse.cpp @@ -392,12 +392,12 @@ protected: : ByteString(), ByteString() }; - ScopedTestKeyPair signerKeyPair(GenerateKeyPair()); + ScopedTestKeyPair signerKeyPair; ByteString signerDER(CreateEncodedCertificate( ++rootIssuedCount, rootName, oneDayBeforeNow, oneDayAfterNow, certSubjectName, - *signerKeyPair, signerEKUDER ? extensions : nullptr, - *rootKeyPair)); + signerEKUDER ? extensions : nullptr, + rootKeyPair.get(), signerKeyPair)); EXPECT_FALSE(ENCODING_FAILED(signerDER)); if (signerDEROut) { *signerDEROut = signerDER; @@ -421,9 +421,9 @@ protected: time_t notBefore, time_t notAfter, const char* subject, - const TestKeyPair& subjectKeyPair, /*optional*/ const ByteString* extensions, - const TestKeyPair& signerKeyPair) + /*optional*/ TestKeyPair* signerKeyPair, + /*out*/ ScopedTestKeyPair& keyPair) { ByteString serialNumberDER(CreateEncodedSerialNumber(serialNumber)); if (ENCODING_FAILED(serialNumberDER)) { @@ -441,9 +441,10 @@ protected: v3, sha256WithRSAEncryption, serialNumberDER, issuerDER, notBefore, - notAfter, subjectDER, subjectKeyPair, - extensions, signerKeyPair, - SignatureAlgorithm::rsa_pkcs1_with_sha256); + notAfter, subjectDER, extensions, + signerKeyPair, + SignatureAlgorithm::rsa_pkcs1_with_sha256, + keyPair); } static const Input OCSPSigningEKUDER; @@ -539,13 +540,13 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, good_expired) ByteString() }; - ScopedTestKeyPair signerKeyPair(GenerateKeyPair()); + ScopedTestKeyPair signerKeyPair; ByteString signerDER(CreateEncodedCertificate( ++rootIssuedCount, rootName, now - (10 * Time::ONE_DAY_IN_SECONDS), now - (2 * Time::ONE_DAY_IN_SECONDS), - signerName, *signerKeyPair, extensions, - *rootKeyPair)); + signerName, extensions, rootKeyPair.get(), + signerKeyPair)); ASSERT_FALSE(ENCODING_FAILED(signerDER)); ByteString certs[] = { signerDER, ByteString() }; @@ -574,13 +575,13 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, good_future) ByteString() }; - ScopedTestKeyPair signerKeyPair(GenerateKeyPair()); + ScopedTestKeyPair signerKeyPair; ByteString signerDER(CreateEncodedCertificate( ++rootIssuedCount, rootName, now + (2 * Time::ONE_DAY_IN_SECONDS), now + (10 * Time::ONE_DAY_IN_SECONDS), - signerName, *signerKeyPair, extensions, - *rootKeyPair)); + signerName, extensions, rootKeyPair.get(), + signerKeyPair)); ASSERT_FALSE(ENCODING_FAILED(signerDER)); ByteString certs[] = { signerDER, ByteString() }; @@ -676,11 +677,11 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, good_unknown_issuer) ExtensionCriticality::NotCritical), ByteString() }; - ScopedTestKeyPair signerKeyPair(GenerateKeyPair()); + ScopedTestKeyPair signerKeyPair; ByteString signerDER(CreateEncodedCertificate( 1, subCAName, oneDayBeforeNow, oneDayAfterNow, - signerName, *signerKeyPair, extensions, - *unknownKeyPair)); + signerName, extensions, unknownKeyPair.get(), + signerKeyPair)); ASSERT_FALSE(ENCODING_FAILED(signerDER)); // OCSP response signed by that delegated responder @@ -715,12 +716,12 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, CreateEncodedBasicConstraints(true, 0, ExtensionCriticality::NotCritical), ByteString() }; - ScopedTestKeyPair subCAKeyPair(GenerateKeyPair()); + ScopedTestKeyPair subCAKeyPair; ByteString subCADER(CreateEncodedCertificate( ++rootIssuedCount, rootName, oneDayBeforeNow, oneDayAfterNow, - subCAName, *subCAKeyPair, subCAExtensions, - *rootKeyPair)); + subCAName, subCAExtensions, rootKeyPair.get(), + subCAKeyPair)); ASSERT_FALSE(ENCODING_FAILED(subCADER)); // Delegated responder cert signed by that sub-CA @@ -729,11 +730,11 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, ExtensionCriticality::NotCritical), ByteString(), }; - ScopedTestKeyPair signerKeyPair(GenerateKeyPair()); + ScopedTestKeyPair signerKeyPair; ByteString signerDER(CreateEncodedCertificate( 1, subCAName, oneDayBeforeNow, oneDayAfterNow, - signerName, *signerKeyPair, extensions, - *subCAKeyPair)); + signerName, extensions, subCAKeyPair.get(), + signerKeyPair)); ASSERT_FALSE(ENCODING_FAILED(signerDER)); // OCSP response signed by the delegated responder issued by the sub-CA @@ -769,11 +770,12 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, CreateEncodedBasicConstraints(true, 0, ExtensionCriticality::NotCritical), ByteString() }; - ScopedTestKeyPair subCAKeyPair(GenerateKeyPair()); + ScopedTestKeyPair subCAKeyPair; ByteString subCADER(CreateEncodedCertificate(++rootIssuedCount, rootName, oneDayBeforeNow, oneDayAfterNow, - subCAName, *subCAKeyPair, - subCAExtensions, *rootKeyPair)); + subCAName, subCAExtensions, + rootKeyPair.get(), + subCAKeyPair)); ASSERT_FALSE(ENCODING_FAILED(subCADER)); // Delegated responder cert signed by that sub-CA @@ -782,11 +784,11 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, ExtensionCriticality::NotCritical), ByteString() }; - ScopedTestKeyPair signerKeyPair(GenerateKeyPair()); + ScopedTestKeyPair signerKeyPair; ByteString signerDER(CreateEncodedCertificate( 1, subCAName, oneDayBeforeNow, oneDayAfterNow, - signerName, *signerKeyPair, extensions, - *subCAKeyPair)); + signerName, extensions, subCAKeyPair.get(), + signerKeyPair)); ASSERT_FALSE(ENCODING_FAILED(signerDER)); // OCSP response signed by the delegated responder issued by the sub-CA diff --git a/security/pkix/test/lib/pkixtestnss.cpp b/security/pkix/test/lib/pkixtestnss.cpp index 0648000a69be..2ba33b529982 100644 --- a/security/pkix/test/lib/pkixtestnss.cpp +++ b/security/pkix/test/lib/pkixtestnss.cpp @@ -31,7 +31,6 @@ #include "nss.h" #include "pk11pub.h" #include "pkix/pkixnss.h" -#include "prinit.h" #include "secerr.h" #include "secitem.h" @@ -52,28 +51,10 @@ SECITEM_FreeItem_true(SECItem* item) typedef mozilla::pkix::ScopedPtr ScopedSECItem; -TestKeyPair* GenerateKeyPairInner(); - -static ScopedTestKeyPair reusedKeyPair; - -PRStatus -init() -{ - if (NSS_NoDB_Init(nullptr) != SECSuccess) { - abort(); - } - - reusedKeyPair = GenerateKeyPairInner(); - assert(reusedKeyPair); - - return PR_SUCCESS; -} - Result InitNSSIfNeeded() { - static PRCallOnceType initCallOnce; - if (PR_CallOnce(&initCallOnce, init) != PR_SUCCESS) { + if (NSS_NoDB_Init(nullptr) != SECSuccess) { return MapPRErrorCodeToResult(PR_GetError()); } return Success; @@ -144,14 +125,16 @@ TestKeyPair* CreateTestKeyPair(const ByteString& spki, return new (std::nothrow) NSSTestKeyPair(spki, spk, privateKey); } -namespace { - TestKeyPair* -GenerateKeyPairInner() +GenerateKeyPair() { + if (InitNSSIfNeeded() != Success) { + return nullptr; + } + ScopedPtr slot(PK11_GetInternalSlot()); if (!slot) { - abort(); + return nullptr; } // Bug 1012786: PK11_GenerateKeyPair can fail if there is insufficient @@ -171,12 +154,12 @@ GenerateKeyPairInner() ScopedSECItem spkiDER(SECKEY_EncodeDERSubjectPublicKeyInfo(publicKey.get())); if (!spkiDER) { - break; + return nullptr; } ScopedPtr spki(SECKEY_CreateSubjectPublicKeyInfo(publicKey.get())); if (!spki) { - break; + return nullptr; } SECItem spkDER = spki->subjectPublicKey; DER_ConvertBitString(&spkDER); // bits to bytes @@ -201,35 +184,7 @@ GenerateKeyPairInner() } } - abort(); -#if defined(_MSC_VER) && (_MSC_VER < 1700) - // Older versions of MSVC don't know that abort() never returns, so silence - // its warning by adding a redundant and never-reached return. But, only do - // it for that ancient compiler, because some other compilers will rightly - // warn that the return statement is unreachable. return nullptr; -#endif -} - -} // unnamed namespace - -TestKeyPair* -GenerateKeyPair() -{ - if (InitNSSIfNeeded() != Success) { - abort(); - } - return GenerateKeyPairInner(); -} - -TestKeyPair* -CloneReusedKeyPair() -{ - if (InitNSSIfNeeded() != Success) { - abort(); - } - assert(reusedKeyPair); - return reusedKeyPair->Clone(); } ByteString diff --git a/security/pkix/test/lib/pkixtestutil.cpp b/security/pkix/test/lib/pkixtestutil.cpp index 3e0d09857be8..708d13720da7 100644 --- a/security/pkix/test/lib/pkixtestutil.cpp +++ b/security/pkix/test/lib/pkixtestutil.cpp @@ -341,13 +341,16 @@ YMDHMS(int16_t year, int16_t month, int16_t day, static ByteString SignedData(const ByteString& tbsData, - const TestKeyPair& keyPair, + /*optional*/ TestKeyPair* keyPair, SignatureAlgorithm signatureAlgorithm, bool corrupt, /*optional*/ const ByteString* certs) { ByteString signature; - if (keyPair.SignData(tbsData, signatureAlgorithm, signature) != Success) { - return ByteString(); + if (keyPair) { + if (keyPair->SignData(tbsData, signatureAlgorithm, signature) + != Success) { + return ByteString(); + } } ByteString signatureAlgorithmDER; @@ -462,21 +465,31 @@ CreateEncodedCertificate(long version, Input signature, const ByteString& issuerNameDER, time_t notBefore, time_t notAfter, const ByteString& subjectNameDER, - const TestKeyPair& subjectKeyPair, /*optional*/ const ByteString* extensions, - const TestKeyPair& issuerKeyPair, - SignatureAlgorithm signatureAlgorithm) + /*optional*/ TestKeyPair* issuerKeyPair, + SignatureAlgorithm signatureAlgorithm, + /*out*/ ScopedTestKeyPair& keyPairResult) { + // It may be the case that privateKeyResult references the same TestKeyPair + // as issuerKeyPair. Thus, we can't set keyPairResult until after we're done + // with issuerKeyPair. + ScopedTestKeyPair subjectKeyPair(GenerateKeyPair()); + if (!subjectKeyPair) { + return ByteString(); + } + ByteString tbsCertificate(TBSCertificate(version, serialNumber, signature, issuerNameDER, notBefore, notAfter, subjectNameDER, - subjectKeyPair.subjectPublicKeyInfo, + subjectKeyPair->subjectPublicKeyInfo, extensions)); if (ENCODING_FAILED(tbsCertificate)) { return ByteString(); } - ByteString result(SignedData(tbsCertificate, issuerKeyPair, + ByteString result(SignedData(tbsCertificate, + issuerKeyPair ? issuerKeyPair + : subjectKeyPair.get(), signatureAlgorithm, false, nullptr)); if (ENCODING_FAILED(result)) { return ByteString(); @@ -484,6 +497,8 @@ CreateEncodedCertificate(long version, Input signature, MaybeLogOutput(result, "cert"); + keyPairResult = subjectKeyPair.release(); + return result; } @@ -749,7 +764,8 @@ BasicOCSPResponse(OCSPResponseContext& context) return ByteString(); } - return SignedData(tbsResponseData, *context.signerKeyPair, + // TODO(bug 980538): certs + return SignedData(tbsResponseData, context.signerKeyPair.get(), SignatureAlgorithm::rsa_pkcs1_with_sha256, context.badSignature, context.certs); } diff --git a/security/pkix/test/lib/pkixtestutil.h b/security/pkix/test/lib/pkixtestutil.h index c4d3cdaa7806..411221c51ea5 100644 --- a/security/pkix/test/lib/pkixtestutil.h +++ b/security/pkix/test/lib/pkixtestutil.h @@ -111,11 +111,6 @@ protected: void operator=(const TestKeyPair&) /*= delete*/; }; -// If the objective of the test doesn't involve verifying that signature -// verification is done correctly then use the keypair returned from -// CloneReusedKeyPair to make the test run much faster. -TestKeyPair* CloneReusedKeyPair(); - TestKeyPair* GenerateKeyPair(); inline void DeleteTestKeyPair(TestKeyPair* keyPair) { delete keyPair; } typedef ScopedPtr ScopedTestKeyPair; @@ -151,15 +146,19 @@ enum Version { v1 = 0, v2 = 1, v3 = 2 }; // extensions must point to an array of ByteStrings, terminated with an empty // ByteString. (If the first item of the array is empty then an empty // Extensions sequence will be encoded.) +// +// If issuerPrivateKey is null, then the certificate will be self-signed. +// Parameter order is based on the order of the attributes of the certificate +// in RFC 5280. ByteString CreateEncodedCertificate(long version, Input signature, const ByteString& serialNumber, const ByteString& issuerNameDER, time_t notBefore, time_t notAfter, const ByteString& subjectNameDER, - const TestKeyPair& subjectKeyPair, /*optional*/ const ByteString* extensions, - const TestKeyPair& issuerKeyPair, - SignatureAlgorithm signatureAlgorithm); + /*optional*/ TestKeyPair* issuerKeyPair, + SignatureAlgorithm signatureAlgorithm, + /*out*/ ScopedTestKeyPair& keyPairResult); ByteString CreateEncodedSerialNumber(long value); From f3c6c6a49be62fd9ab3ef8d23210b0d6099d3781 Mon Sep 17 00:00:00 2001 From: "Carsten \"Tomcat\" Book" Date: Tue, 7 Oct 2014 12:53:03 +0200 Subject: [PATCH 27/84] Backed out changeset 16fe1b9eb9e6 (bug 1077887) --- security/pkix/include/pkix/Result.h | 8 ++++---- security/pkix/include/pkix/enumclass.h | 10 ++++------ 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/security/pkix/include/pkix/Result.h b/security/pkix/include/pkix/Result.h index ff76b5ab6715..e82e6428d341 100644 --- a/security/pkix/include/pkix/Result.h +++ b/security/pkix/include/pkix/Result.h @@ -149,10 +149,10 @@ const char* MapResultToName(Result result); // those comparisons clearer, especially because the shortened name often // results in less line wrapping. // -// If MOZILLA_PKIX_ENUM_CLASS doesn't expand to "enum class" then -// Result::Success will already be in scope, and compilation would fail if we -// were to try to define a variable named "Success" here. -#ifdef MOZILLA_PKIX_ENUM_CLASS_REALLY_IS_ENUM_CLASS +// Visual Studio before VS2013 does not support "enum class," so +// Result::Success will already be visible in this scope, and compilation will +// fail if we try to define a variable with that name here. +#if !defined(_MSC_VER) || (_MSC_VER >= 1700) static const Result Success = Result::Success; #endif diff --git a/security/pkix/include/pkix/enumclass.h b/security/pkix/include/pkix/enumclass.h index 40d5b840a016..e3dd58220d75 100644 --- a/security/pkix/include/pkix/enumclass.h +++ b/security/pkix/include/pkix/enumclass.h @@ -22,6 +22,10 @@ * limitations under the License. */ +// Work around missing std::bind, std::ref, std::cref in older compilers. This +// implementation isn't intended to be complete; rather, it is the minimal +// implementation needed to make our use of std::bind work. + #ifndef mozilla_pkix__enumclass_h #define mozilla_pkix__enumclass_h @@ -31,14 +35,8 @@ // enums results in C4480: nonstandard extension used: specifying underlying // type for enum. #define MOZILLA_PKIX_ENUM_CLASS __pragma(warning(suppress: 4480)) enum -#elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 407) -// GCC before version 4.7 may crash when compiling code that static_casts a -// value of scoped typed enum type. See -// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48106. -#define MOZILLA_PKIX_ENUM_CLASS enum #else #define MOZILLA_PKIX_ENUM_CLASS enum class -#define MOZILLA_PKIX_ENUM_CLASS_REALLY_IS_ENUM_CLASS #endif #endif // mozilla_pkix__enumclass_h From 811400331ca9ac2260ed61dd583c333a0b8a8cf0 Mon Sep 17 00:00:00 2001 From: "Carsten \"Tomcat\" Book" Date: Tue, 7 Oct 2014 12:53:42 +0200 Subject: [PATCH 28/84] Backed out changeset 76000f9f12da (bug 1077859) for causing frequent Mac OSX XPCshell test failures --- .../tests/unit/tlsserver/lib/OCSPCommon.cpp | 2 +- security/pkix/test/gtest/pkixbuild_tests.cpp | 22 +- .../test/gtest/pkixcert_extension_tests.cpp | 20 +- ...kixocsp_CreateEncodedOCSPRequest_tests.cpp | 2 +- .../pkixocsp_VerifyEncodedOCSPResponse.cpp | 38 ++-- security/pkix/test/lib/pkixtestnss.cpp | 4 +- security/pkix/test/lib/pkixtestutil.cpp | 212 +++++++++++------- security/pkix/test/lib/pkixtestutil.h | 4 +- 8 files changed, 185 insertions(+), 119 deletions(-) diff --git a/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp b/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp index 0c1c8a54c56c..e24957888a6e 100644 --- a/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp +++ b/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp @@ -199,7 +199,7 @@ GetOCSPResponseForType(OCSPResponseType aORT, CERTCertificate *aCert, } ByteString response(CreateEncodedOCSPResponse(context)); - if (ENCODING_FAILED(response)) { + if (response == ENCODING_FAILED) { PrintPRError("CreateEncodedOCSPResponse failed"); return nullptr; } diff --git a/security/pkix/test/gtest/pkixbuild_tests.cpp b/security/pkix/test/gtest/pkixbuild_tests.cpp index 3c14ca13e31e..a7ac7dd4e49a 100644 --- a/security/pkix/test/gtest/pkixbuild_tests.cpp +++ b/security/pkix/test/gtest/pkixbuild_tests.cpp @@ -47,17 +47,19 @@ CreateCert(const char* issuerCN, static long serialNumberValue = 0; ++serialNumberValue; ByteString serialNumber(CreateEncodedSerialNumber(serialNumberValue)); - EXPECT_FALSE(ENCODING_FAILED(serialNumber)); + EXPECT_NE(ENCODING_FAILED, serialNumber); ByteString issuerDER(CNToDERName(issuerCN)); + EXPECT_NE(ENCODING_FAILED, issuerDER); ByteString subjectDER(CNToDERName(subjectCN)); + EXPECT_NE(ENCODING_FAILED, subjectDER); ByteString extensions[2]; if (endEntityOrCA == EndEntityOrCA::MustBeCA) { extensions[0] = CreateEncodedBasicConstraints(true, nullptr, ExtensionCriticality::Critical); - EXPECT_FALSE(ENCODING_FAILED(extensions[0])); + EXPECT_NE(ENCODING_FAILED, extensions[0]); } ByteString certDER(CreateEncodedCertificate( @@ -67,7 +69,7 @@ CreateCert(const char* issuerCN, subjectDER, extensions, issuerKey, SignatureAlgorithm::rsa_pkcs1_with_sha256, subjectKey)); - EXPECT_FALSE(ENCODING_FAILED(certDER)); + EXPECT_NE(ENCODING_FAILED, certDER); if (subjectCert) { SECItem certDERItem = { siBuffer, @@ -243,7 +245,7 @@ TEST_F(pkixbuild, MaxAcceptableCertChainLength) ByteString certDER(CreateCert("CA7", "Direct End-Entity", EndEntityOrCA::MustBeEndEntity, trustDomain.leafCAKey.get(), unusedKeyPair)); - ASSERT_FALSE(ENCODING_FAILED(certDER)); + ASSERT_NE(ENCODING_FAILED, certDER); Input certDERInput; ASSERT_EQ(Success, certDERInput.Init(certDER.data(), certDER.length())); ASSERT_EQ(Success, @@ -269,7 +271,7 @@ TEST_F(pkixbuild, BeyondMaxAcceptableCertChainLength) ByteString certDER(CreateCert("CA7", caCertName, EndEntityOrCA::MustBeCA, trustDomain.leafCAKey.get(), caKeyPair, &caCert)); - ASSERT_FALSE(ENCODING_FAILED(certDER)); + ASSERT_NE(ENCODING_FAILED, certDER); Input certDERInput; ASSERT_EQ(Success, certDERInput.Init(certDER.data(), certDER.length())); ASSERT_EQ(Result::ERROR_UNKNOWN_ISSUER, @@ -286,7 +288,7 @@ TEST_F(pkixbuild, BeyondMaxAcceptableCertChainLength) ByteString certDER(CreateCert(caCertName, "End-Entity Too Far", EndEntityOrCA::MustBeEndEntity, caKeyPair.get(), unusedKeyPair)); - ASSERT_FALSE(ENCODING_FAILED(certDER)); + ASSERT_NE(ENCODING_FAILED, certDER); Input certDERInput; ASSERT_EQ(Success, certDERInput.Init(certDER.data(), certDER.length())); ASSERT_EQ(Result::ERROR_UNKNOWN_ISSUER, @@ -386,13 +388,15 @@ TEST_F(pkixbuild, NoRevocationCheckingForExpiredCert) ScopedTestKeyPair rootKey; ByteString rootDER(CreateCert(rootCN, rootCN, EndEntityOrCA::MustBeCA, nullptr, rootKey, nullptr)); - EXPECT_FALSE(ENCODING_FAILED(rootDER)); + EXPECT_NE(ENCODING_FAILED, rootDER); ExpiredCertTrustDomain expiredCertTrustDomain(rootDER); ByteString serialNumber(CreateEncodedSerialNumber(100)); - EXPECT_FALSE(ENCODING_FAILED(serialNumber)); + EXPECT_NE(ENCODING_FAILED, serialNumber); ByteString issuerDER(CNToDERName(rootCN)); + EXPECT_NE(ENCODING_FAILED, issuerDER); ByteString subjectDER(CNToDERName("Expired End-Entity Cert")); + EXPECT_NE(ENCODING_FAILED, subjectDER); ScopedTestKeyPair unusedSubjectKey; ByteString certDER(CreateEncodedCertificate( v3, sha256WithRSAEncryption, @@ -402,7 +406,7 @@ TEST_F(pkixbuild, NoRevocationCheckingForExpiredCert) subjectDER, nullptr, rootKey.get(), SignatureAlgorithm::rsa_pkcs1_with_sha256, unusedSubjectKey)); - EXPECT_FALSE(ENCODING_FAILED(certDER)); + EXPECT_NE(ENCODING_FAILED, certDER); Input cert; ASSERT_EQ(Success, cert.Init(certDER.data(), certDER.length())); diff --git a/security/pkix/test/gtest/pkixcert_extension_tests.cpp b/security/pkix/test/gtest/pkixcert_extension_tests.cpp index 371928e1379c..3a2d7d67e274 100644 --- a/security/pkix/test/gtest/pkixcert_extension_tests.cpp +++ b/security/pkix/test/gtest/pkixcert_extension_tests.cpp @@ -38,11 +38,11 @@ CreateCert(const char* subjectCN, static long serialNumberValue = 0; ++serialNumberValue; ByteString serialNumber(CreateEncodedSerialNumber(serialNumberValue)); - EXPECT_FALSE(ENCODING_FAILED(serialNumber)); + EXPECT_NE(ENCODING_FAILED, serialNumber); ByteString issuerDER(CNToDERName(subjectCN)); - EXPECT_FALSE(ENCODING_FAILED(issuerDER)); + EXPECT_NE(ENCODING_FAILED, issuerDER); ByteString subjectDER(CNToDERName(subjectCN)); - EXPECT_FALSE(ENCODING_FAILED(subjectDER)); + EXPECT_NE(ENCODING_FAILED, subjectDER); return CreateEncodedCertificate(v3, sha256WithRSAEncryption, serialNumber, issuerDER, oneDayBeforeNow, oneDayAfterNow, @@ -138,7 +138,7 @@ TEST_F(pkixcert_extension, UnknownCriticalExtension) const char* certCN = "Cert With Unknown Critical Extension"; ScopedTestKeyPair key; ByteString cert(CreateCert(certCN, unknownCriticalExtension, key)); - ASSERT_FALSE(ENCODING_FAILED(cert)); + ASSERT_NE(ENCODING_FAILED, cert); Input certInput; ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length())); ASSERT_EQ(Result::ERROR_UNKNOWN_CRITICAL_EXTENSION, @@ -168,7 +168,7 @@ TEST_F(pkixcert_extension, UnknownNonCriticalExtension) const char* certCN = "Cert With Unknown NonCritical Extension"; ScopedTestKeyPair key; ByteString cert(CreateCert(certCN, unknownNonCriticalExtension, key)); - ASSERT_FALSE(ENCODING_FAILED(cert)); + ASSERT_NE(ENCODING_FAILED, cert); Input certInput; ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length())); ASSERT_EQ(Success, @@ -199,7 +199,7 @@ TEST_F(pkixcert_extension, WrongOIDCriticalExtension) const char* certCN = "Cert With Critical Wrong OID Extension"; ScopedTestKeyPair key; ByteString cert(CreateCert(certCN, wrongOIDCriticalExtension, key)); - ASSERT_FALSE(ENCODING_FAILED(cert)); + ASSERT_NE(ENCODING_FAILED, cert); Input certInput; ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length())); ASSERT_EQ(Result::ERROR_UNKNOWN_CRITICAL_EXTENSION, @@ -232,7 +232,7 @@ TEST_F(pkixcert_extension, CriticalAIAExtension) const char* certCN = "Cert With Critical AIA Extension"; ScopedTestKeyPair key; ByteString cert(CreateCert(certCN, criticalAIAExtension, key)); - ASSERT_FALSE(ENCODING_FAILED(cert)); + ASSERT_NE(ENCODING_FAILED, cert); Input certInput; ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length())); ASSERT_EQ(Success, @@ -262,7 +262,7 @@ TEST_F(pkixcert_extension, UnknownCriticalCEExtension) const char* certCN = "Cert With Unknown Critical id-ce Extension"; ScopedTestKeyPair key; ByteString cert(CreateCert(certCN, unknownCriticalCEExtension, key)); - ASSERT_FALSE(ENCODING_FAILED(cert)); + ASSERT_NE(ENCODING_FAILED, cert); Input certInput; ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length())); ASSERT_EQ(Result::ERROR_UNKNOWN_CRITICAL_EXTENSION, @@ -292,7 +292,7 @@ TEST_F(pkixcert_extension, KnownCriticalCEExtension) const char* certCN = "Cert With Known Critical id-ce Extension"; ScopedTestKeyPair key; ByteString cert(CreateCert(certCN, criticalCEExtension, key)); - ASSERT_FALSE(ENCODING_FAILED(cert)); + ASSERT_NE(ENCODING_FAILED, cert); Input certInput; ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length())); ASSERT_EQ(Success, @@ -321,7 +321,7 @@ TEST_F(pkixcert_extension, DuplicateSubjectAltName) static const char* certCN = "Cert With Duplicate subjectAltName"; ScopedTestKeyPair key; ByteString cert(CreateCert(certCN, extensions, key)); - ASSERT_FALSE(ENCODING_FAILED(cert)); + ASSERT_NE(ENCODING_FAILED, cert); Input certInput; ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length())); ASSERT_EQ(Result::ERROR_EXTENSION_VALUE_INVALID, diff --git a/security/pkix/test/gtest/pkixocsp_CreateEncodedOCSPRequest_tests.cpp b/security/pkix/test/gtest/pkixocsp_CreateEncodedOCSPRequest_tests.cpp index f8d8560aae29..c8e93b6bb3ba 100644 --- a/security/pkix/test/gtest/pkixocsp_CreateEncodedOCSPRequest_tests.cpp +++ b/security/pkix/test/gtest/pkixocsp_CreateEncodedOCSPRequest_tests.cpp @@ -87,7 +87,7 @@ protected: /*out*/ ByteString& issuerSPKI) { issuerDER = CNToDERName(issuerASCII); - ASSERT_FALSE(ENCODING_FAILED(issuerDER)); + ASSERT_NE(ENCODING_FAILED, issuerDER); ScopedTestKeyPair keyPair(GenerateKeyPair()); ASSERT_TRUE(keyPair); diff --git a/security/pkix/test/gtest/pkixocsp_VerifyEncodedOCSPResponse.cpp b/security/pkix/test/gtest/pkixocsp_VerifyEncodedOCSPResponse.cpp index 27ccf630bb75..75320ecce931 100644 --- a/security/pkix/test/gtest/pkixocsp_VerifyEncodedOCSPResponse.cpp +++ b/security/pkix/test/gtest/pkixocsp_VerifyEncodedOCSPResponse.cpp @@ -110,7 +110,7 @@ public: void SetUp() { rootNameDER = CNToDERName(rootName); - if (ENCODING_FAILED(rootNameDER)) { + if (rootNameDER == ENCODING_FAILED) { abort(); } Input rootNameDERInput; @@ -120,7 +120,7 @@ public: } serialNumberDER = CreateEncodedSerialNumber(++rootIssuedCount); - if (ENCODING_FAILED(serialNumberDER)) { + if (serialNumberDER == ENCODING_FAILED) { abort(); } Input serialNumberDERInput; @@ -248,7 +248,7 @@ public: OCSPResponseContext context(certID, producedAt); if (signerName) { context.signerNameDER = CNToDERName(signerName); - EXPECT_FALSE(ENCODING_FAILED(context.signerNameDER)); + EXPECT_NE(ENCODING_FAILED, context.signerNameDER); } context.signerKeyPair = signerKeyPair.Clone(); EXPECT_TRUE(context.signerKeyPair); @@ -398,7 +398,7 @@ protected: oneDayBeforeNow, oneDayAfterNow, certSubjectName, signerEKUDER ? extensions : nullptr, rootKeyPair.get(), signerKeyPair)); - EXPECT_FALSE(ENCODING_FAILED(signerDER)); + EXPECT_NE(ENCODING_FAILED, signerDER); if (signerDEROut) { *signerDEROut = signerDER; } @@ -406,7 +406,7 @@ protected: ByteString signerNameDER; if (signerName) { signerNameDER = CNToDERName(signerName); - EXPECT_FALSE(ENCODING_FAILED(signerNameDER)); + EXPECT_NE(ENCODING_FAILED, signerNameDER); } ByteString certs[] = { signerDER, ByteString() }; return CreateEncodedOCSPSuccessfulResponse(certStatus, *endEntityCertID, @@ -426,16 +426,16 @@ protected: /*out*/ ScopedTestKeyPair& keyPair) { ByteString serialNumberDER(CreateEncodedSerialNumber(serialNumber)); - if (ENCODING_FAILED(serialNumberDER)) { - return ByteString(); + if (serialNumberDER == ENCODING_FAILED) { + return ENCODING_FAILED; } ByteString issuerDER(CNToDERName(issuer)); - if (ENCODING_FAILED(issuerDER)) { - return ByteString(); + if (issuerDER == ENCODING_FAILED) { + return ENCODING_FAILED; } ByteString subjectDER(CNToDERName(subject)); - if (ENCODING_FAILED(subjectDER)) { - return ByteString(); + if (subjectDER == ENCODING_FAILED) { + return ENCODING_FAILED; } return ::mozilla::pkix::test::CreateEncodedCertificate( v3, @@ -547,7 +547,7 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, good_expired) now - (2 * Time::ONE_DAY_IN_SECONDS), signerName, extensions, rootKeyPair.get(), signerKeyPair)); - ASSERT_FALSE(ENCODING_FAILED(signerDER)); + ASSERT_NE(ENCODING_FAILED, signerDER); ByteString certs[] = { signerDER, ByteString() }; ByteString responseString( @@ -582,7 +582,7 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, good_future) now + (10 * Time::ONE_DAY_IN_SECONDS), signerName, extensions, rootKeyPair.get(), signerKeyPair)); - ASSERT_FALSE(ENCODING_FAILED(signerDER)); + ASSERT_NE(ENCODING_FAILED, signerDER); ByteString certs[] = { signerDER, ByteString() }; ByteString responseString( @@ -682,7 +682,7 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, good_unknown_issuer) 1, subCAName, oneDayBeforeNow, oneDayAfterNow, signerName, extensions, unknownKeyPair.get(), signerKeyPair)); - ASSERT_FALSE(ENCODING_FAILED(signerDER)); + ASSERT_NE(ENCODING_FAILED, signerDER); // OCSP response signed by that delegated responder ByteString certs[] = { signerDER, ByteString() }; @@ -722,7 +722,7 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, oneDayBeforeNow, oneDayAfterNow, subCAName, subCAExtensions, rootKeyPair.get(), subCAKeyPair)); - ASSERT_FALSE(ENCODING_FAILED(subCADER)); + ASSERT_NE(ENCODING_FAILED, subCADER); // Delegated responder cert signed by that sub-CA const ByteString extensions[] = { @@ -735,7 +735,7 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, 1, subCAName, oneDayBeforeNow, oneDayAfterNow, signerName, extensions, subCAKeyPair.get(), signerKeyPair)); - ASSERT_FALSE(ENCODING_FAILED(signerDER)); + ASSERT_NE(ENCODING_FAILED, signerDER); // OCSP response signed by the delegated responder issued by the sub-CA // that is trying to impersonate the root. @@ -776,7 +776,7 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, subCAName, subCAExtensions, rootKeyPair.get(), subCAKeyPair)); - ASSERT_FALSE(ENCODING_FAILED(subCADER)); + ASSERT_NE(ENCODING_FAILED, subCADER); // Delegated responder cert signed by that sub-CA const ByteString extensions[] = { @@ -789,7 +789,7 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, 1, subCAName, oneDayBeforeNow, oneDayAfterNow, signerName, extensions, subCAKeyPair.get(), signerKeyPair)); - ASSERT_FALSE(ENCODING_FAILED(signerDER)); + ASSERT_NE(ENCODING_FAILED, signerDER); // OCSP response signed by the delegated responder issued by the sub-CA // that is trying to impersonate the root. @@ -821,7 +821,7 @@ public: CreateEncodedIndirectOCSPSuccessfulResponse( "OCSPGetCertTrustTest Signer", OCSPResponseContext::good, byKey, &OCSPSigningEKUDER, &signerCertDER); - if (ENCODING_FAILED(responseString)) { + if (responseString == ENCODING_FAILED) { abort(); } if (response.Init(responseString.data(), responseString.length()) diff --git a/security/pkix/test/lib/pkixtestnss.cpp b/security/pkix/test/lib/pkixtestnss.cpp index 2ba33b529982..41452a1c0256 100644 --- a/security/pkix/test/lib/pkixtestnss.cpp +++ b/security/pkix/test/lib/pkixtestnss.cpp @@ -191,14 +191,14 @@ ByteString SHA1(const ByteString& toHash) { if (InitNSSIfNeeded() != Success) { - return ByteString(); + return ENCODING_FAILED; } uint8_t digestBuf[SHA1_LENGTH]; SECStatus srv = PK11_HashBuf(SEC_OID_SHA1, digestBuf, toHash.data(), static_cast(toHash.length())); if (srv != SECSuccess) { - return ByteString(); + return ENCODING_FAILED; } return ByteString(digestBuf, sizeof(digestBuf)); } diff --git a/security/pkix/test/lib/pkixtestutil.cpp b/security/pkix/test/lib/pkixtestutil.cpp index 708d13720da7..7066e213e5ad 100644 --- a/security/pkix/test/lib/pkixtestutil.cpp +++ b/security/pkix/test/lib/pkixtestutil.cpp @@ -97,8 +97,11 @@ TamperOnce(/*in/out*/ ByteString& item, const ByteString& from, return Success; } +// An empty string returned from an encoding function signifies failure. +const ByteString ENCODING_FAILED; + // Given a tag and a value, generates a DER-encoded tag-length-value item. -ByteString +static ByteString TLV(uint8_t tag, const ByteString& value) { ByteString result; @@ -114,9 +117,8 @@ TLV(uint8_t tag, const ByteString& value) result.push_back(static_cast(value.length() / 256)); result.push_back(static_cast(value.length() % 256)); } else { - // It is MUCH more convenient for TLV to be infallible than for it to have - // "proper" error handling. - abort(); + assert(false); + return ENCODING_FAILED; } result.append(value); return result; @@ -153,8 +155,8 @@ static ByteString HashedOctetString(const ByteString& bytes) { ByteString digest(SHA1(bytes)); - if (ENCODING_FAILED(digest)) { - return ByteString(); + if (digest == ENCODING_FAILED) { + return ENCODING_FAILED; } return TLV(der::OCTET_STRING, digest); } @@ -188,9 +190,7 @@ Integer(long value) { if (value < 0 || value > 127) { // TODO: add encoding of larger values - // It is MUCH more convenient for Integer to be infallible than for it to - // have "proper" error handling. - abort(); + return ENCODING_FAILED; } ByteString encodedValue; @@ -225,7 +225,7 @@ TimeToEncodedTime(time_t time, TimeEncoding encoding) tm exploded; if (!gmtime_r(&time, &exploded)) { - return ByteString(); + return ENCODING_FAILED; } if (exploded.tm_sec >= 60) { @@ -237,7 +237,7 @@ TimeToEncodedTime(time_t time, TimeEncoding encoding) int year = exploded.tm_year + 1900; if (encoding == UTCTime && (year < 1950 || year >= 2050)) { - return ByteString(); + return ENCODING_FAILED; } ByteString value; @@ -281,7 +281,7 @@ TimeToTimeChoice(time_t time) { tm exploded; if (!gmtime_r(&time, &exploded)) { - return ByteString(); + return ENCODING_FAILED; } TimeEncoding encoding = (exploded.tm_year + 1900 >= 1950 && exploded.tm_year + 1900 < 2050) @@ -341,17 +341,14 @@ YMDHMS(int16_t year, int16_t month, int16_t day, static ByteString SignedData(const ByteString& tbsData, - /*optional*/ TestKeyPair* keyPair, + TestKeyPair& keyPair, SignatureAlgorithm signatureAlgorithm, bool corrupt, /*optional*/ const ByteString* certs) { ByteString signature; - if (keyPair) { - if (keyPair->SignData(tbsData, signatureAlgorithm, signature) - != Success) { - return ByteString(); - } - } + if (keyPair.SignData(tbsData, signatureAlgorithm, signature) != Success) { + return ENCODING_FAILED; + } ByteString signatureAlgorithmDER; switch (signatureAlgorithm) { @@ -360,14 +357,14 @@ SignedData(const ByteString& tbsData, sizeof(alg_sha256WithRSAEncryption)); break; default: - return ByteString(); + return ENCODING_FAILED; } // TODO: add ability to have signatures of bit length not divisible by 8, // resulting in unused bits in the bitstring encoding ByteString signatureNested(BitString(signature, corrupt)); - if (ENCODING_FAILED(signatureNested)) { - return ByteString(); + if (signatureNested == ENCODING_FAILED) { + return ENCODING_FAILED; } ByteString certsNested; @@ -378,8 +375,14 @@ SignedData(const ByteString& tbsData, ++certs; } ByteString certsSequence(TLV(der::SEQUENCE, certsSequenceValue)); + if (certsSequence == ENCODING_FAILED) { + return ENCODING_FAILED; + } certsNested = TLV(der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 0, certsSequence); + if (certsNested == ENCODING_FAILED) { + return ENCODING_FAILED; + } } ByteString value; @@ -408,11 +411,20 @@ Extension(Input extnID, ExtensionCriticality criticality, if (criticality == ExtensionCriticality::Critical) { ByteString critical(Boolean(true)); + if (critical == ENCODING_FAILED) { + return ENCODING_FAILED; + } encoded.append(critical); } ByteString extnValueSequence(TLV(der::SEQUENCE, extnValueBytes)); + if (extnValueBytes == ENCODING_FAILED) { + return ENCODING_FAILED; + } ByteString extnValue(TLV(der::OCTET_STRING, extnValueSequence)); + if (extnValue == ENCODING_FAILED) { + return ENCODING_FAILED; + } encoded.append(extnValue); return TLV(der::SEQUENCE, encoded); } @@ -475,7 +487,7 @@ CreateEncodedCertificate(long version, Input signature, // with issuerKeyPair. ScopedTestKeyPair subjectKeyPair(GenerateKeyPair()); if (!subjectKeyPair) { - return ByteString(); + return ENCODING_FAILED; } ByteString tbsCertificate(TBSCertificate(version, serialNumber, @@ -483,16 +495,16 @@ CreateEncodedCertificate(long version, Input signature, notAfter, subjectNameDER, subjectKeyPair->subjectPublicKeyInfo, extensions)); - if (ENCODING_FAILED(tbsCertificate)) { - return ByteString(); + if (tbsCertificate == ENCODING_FAILED) { + return ENCODING_FAILED; } ByteString result(SignedData(tbsCertificate, - issuerKeyPair ? issuerKeyPair - : subjectKeyPair.get(), + issuerKeyPair ? *issuerKeyPair + : *subjectKeyPair, signatureAlgorithm, false, nullptr)); - if (ENCODING_FAILED(result)) { - return ByteString(); + if (result == ENCODING_FAILED) { + return ENCODING_FAILED; } MaybeLogOutput(result, "cert"); @@ -528,8 +540,14 @@ TBSCertificate(long versionValue, if (versionValue != static_cast(der::Version::v1)) { ByteString versionInteger(Integer(versionValue)); + if (versionInteger == ENCODING_FAILED) { + return ENCODING_FAILED; + } ByteString version(TLV(der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 0, versionInteger)); + if (version == ENCODING_FAILED) { + return ENCODING_FAILED; + } value.append(version); } @@ -543,19 +561,19 @@ TBSCertificate(long versionValue, ByteString validity; { ByteString notBefore(TimeToTimeChoice(notBeforeTime)); - if (ENCODING_FAILED(notBefore)) { - return ByteString(); + if (notBefore == ENCODING_FAILED) { + return ENCODING_FAILED; } ByteString notAfter(TimeToTimeChoice(notAfterTime)); - if (ENCODING_FAILED(notAfter)) { - return ByteString(); + if (notAfter == ENCODING_FAILED) { + return ENCODING_FAILED; } ByteString validityValue; validityValue.append(notBefore); validityValue.append(notAfter); validity = TLV(der::SEQUENCE, validityValue); - if (ENCODING_FAILED(validity)) { - return ByteString(); + if (validity == ENCODING_FAILED) { + return ENCODING_FAILED; } } value.append(validity); @@ -571,13 +589,13 @@ TBSCertificate(long versionValue, ++extensions; } ByteString extensionsSequence(TLV(der::SEQUENCE, extensionsValue)); - if (ENCODING_FAILED(extensionsSequence)) { - return ByteString(); + if (extensionsSequence == ENCODING_FAILED) { + return ENCODING_FAILED; } ByteString extensionsWrapped( TLV(der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 3, extensionsSequence)); - if (ENCODING_FAILED(extensionsWrapped)) { - return ByteString(); + if (extensionsWrapped == ENCODING_FAILED) { + return ENCODING_FAILED; } value.append(extensionsWrapped); } @@ -626,7 +644,15 @@ CNToDERName(const char* cn) ava.append(tlv_id_at_commonName, sizeof(tlv_id_at_commonName)); ava.append(value); ava = TLV(der::SEQUENCE, ava); + if (ava == ENCODING_FAILED) { + return ENCODING_FAILED; + } + ByteString rdn(TLV(der::SET, ava)); + if (rdn == ENCODING_FAILED) { + return ENCODING_FAILED; + } + return TLV(der::SEQUENCE, rdn); } @@ -648,11 +674,17 @@ CreateEncodedBasicConstraints(bool isCA, if (isCA) { ByteString cA(Boolean(true)); + if (cA == ENCODING_FAILED) { + return ENCODING_FAILED; + } value.append(cA); } if (pathLenConstraintValue) { ByteString pathLenConstraint(Integer(*pathLenConstraintValue)); + if (pathLenConstraint == ENCODING_FAILED) { + return ENCODING_FAILED; + } value.append(pathLenConstraint); } @@ -686,7 +718,7 @@ CreateEncodedOCSPResponse(OCSPResponseContext& context) { if (!context.skipResponseBytes) { if (!context.signerKeyPair) { - return ByteString(); + return ENCODING_FAILED; } } @@ -706,22 +738,31 @@ CreateEncodedOCSPResponse(OCSPResponseContext& context) ByteString reponseStatusValue; reponseStatusValue.push_back(context.responseStatus); ByteString responseStatus(TLV(der::ENUMERATED, reponseStatusValue)); + if (responseStatus == ENCODING_FAILED) { + return ENCODING_FAILED; + } ByteString responseBytesNested; if (!context.skipResponseBytes) { ByteString responseBytes(ResponseBytes(context)); - if (ENCODING_FAILED(responseBytes)) { - return ByteString(); + if (responseBytes == ENCODING_FAILED) { + return ENCODING_FAILED; } responseBytesNested = TLV(der::CONSTRUCTED | der::CONTEXT_SPECIFIC, responseBytes); + if (responseBytesNested == ENCODING_FAILED) { + return ENCODING_FAILED; + } } ByteString value; value.append(responseStatus); value.append(responseBytesNested); ByteString result(TLV(der::SEQUENCE, value)); + if (result == ENCODING_FAILED) { + return ENCODING_FAILED; + } MaybeLogOutput(result, "ocsp"); @@ -739,10 +780,13 @@ ResponseBytes(OCSPResponseContext& context) 0x06, 0x09, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01 }; ByteString response(BasicOCSPResponse(context)); - if (ENCODING_FAILED(response)) { - return ByteString(); + if (response == ENCODING_FAILED) { + return ENCODING_FAILED; } ByteString responseNested = TLV(der::OCTET_STRING, response); + if (responseNested == ENCODING_FAILED) { + return ENCODING_FAILED; + } ByteString value; value.append(id_pkix_ocsp_basic_encoded, @@ -760,12 +804,12 @@ ByteString BasicOCSPResponse(OCSPResponseContext& context) { ByteString tbsResponseData(ResponseData(context)); - if (ENCODING_FAILED(tbsResponseData)) { - return ByteString(); + if (tbsResponseData == ENCODING_FAILED) { + return ENCODING_FAILED; } // TODO(bug 980538): certs - return SignedData(tbsResponseData, context.signerKeyPair.get(), + return SignedData(tbsResponseData, *context.signerKeyPair, SignatureAlgorithm::rsa_pkcs1_with_sha256, context.badSignature, context.certs); } @@ -782,9 +826,15 @@ OCSPExtension(OCSPResponseContext& context, OCSPResponseExtension& extension) encoded.append(extension.id); if (extension.critical) { ByteString critical(Boolean(true)); + if (critical == ENCODING_FAILED) { + return ENCODING_FAILED; + } encoded.append(critical); } ByteString value(TLV(der::OCTET_STRING, extension.value)); + if (value == ENCODING_FAILED) { + return ENCODING_FAILED; + } encoded.append(value); return TLV(der::SEQUENCE, encoded); } @@ -799,12 +849,15 @@ Extensions(OCSPResponseContext& context) for (OCSPResponseExtension* extension = context.extensions; extension; extension = extension->next) { ByteString extensionEncoded(OCSPExtension(context, *extension)); - if (ENCODING_FAILED(extensionEncoded)) { - return ByteString(); + if (extensionEncoded == ENCODING_FAILED) { + return ENCODING_FAILED; } value.append(extensionEncoded); } ByteString sequence(TLV(der::SEQUENCE, value)); + if (sequence == ENCODING_FAILED) { + return ENCODING_FAILED; + } return TLV(der::CONSTRUCTED | der::CONTEXT_SPECIFIC | 1, sequence); } @@ -818,18 +871,21 @@ ByteString ResponseData(OCSPResponseContext& context) { ByteString responderID(ResponderID(context)); - if (ENCODING_FAILED(responderID)) { - return ByteString(); + if (responderID == ENCODING_FAILED) { + return ENCODING_FAILED; } ByteString producedAtEncoded(TimeToGeneralizedTime(context.producedAt)); - if (ENCODING_FAILED(producedAtEncoded)) { - return ByteString(); + if (producedAtEncoded == ENCODING_FAILED) { + return ENCODING_FAILED; } ByteString response(SingleResponse(context)); - if (ENCODING_FAILED(response)) { - return ByteString(); + if (response == ENCODING_FAILED) { + return ENCODING_FAILED; } ByteString responses(TLV(der::SEQUENCE, response)); + if (responses == ENCODING_FAILED) { + return ENCODING_FAILED; + } ByteString responseExtensions; if (context.extensions || context.includeEmptyExtensions) { responseExtensions = Extensions(context); @@ -857,8 +913,8 @@ ResponderID(OCSPResponseContext& context) responderIDType = 1; // byName } else { contents = KeyHash(context.signerKeyPair->subjectPublicKey); - if (ENCODING_FAILED(contents)) { - return ByteString(); + if (contents == ENCODING_FAILED) { + return ENCODING_FAILED; } responderIDType = 2; // byKey } @@ -888,25 +944,28 @@ ByteString SingleResponse(OCSPResponseContext& context) { ByteString certID(CertID(context)); - if (ENCODING_FAILED(certID)) { - return ByteString(); + if (certID == ENCODING_FAILED) { + return ENCODING_FAILED; } ByteString certStatus(CertStatus(context)); - if (ENCODING_FAILED(certStatus)) { - return ByteString(); + if (certStatus == ENCODING_FAILED) { + return ENCODING_FAILED; } ByteString thisUpdateEncoded(TimeToGeneralizedTime(context.thisUpdate)); - if (ENCODING_FAILED(thisUpdateEncoded)) { - return ByteString(); + if (thisUpdateEncoded == ENCODING_FAILED) { + return ENCODING_FAILED; } ByteString nextUpdateEncodedNested; if (context.includeNextUpdate) { ByteString nextUpdateEncoded(TimeToGeneralizedTime(context.nextUpdate)); - if (ENCODING_FAILED(nextUpdateEncoded)) { - return ByteString(); + if (nextUpdateEncoded == ENCODING_FAILED) { + return ENCODING_FAILED; } nextUpdateEncodedNested = TLV(der::CONSTRUCTED | der::CONTEXT_SPECIFIC | 0, nextUpdateEncoded); + if (nextUpdateEncodedNested == ENCODING_FAILED) { + return ENCODING_FAILED; + } } ByteString value; @@ -928,8 +987,8 @@ CertID(OCSPResponseContext& context) ByteString issuerName(context.certID.issuer.UnsafeGetData(), context.certID.issuer.GetLength()); ByteString issuerNameHash(HashedOctetString(issuerName)); - if (ENCODING_FAILED(issuerNameHash)) { - return ByteString(); + if (issuerNameHash == ENCODING_FAILED) { + return ENCODING_FAILED; } ByteString issuerKeyHash; @@ -940,27 +999,30 @@ CertID(OCSPResponseContext& context) Reader input(context.certID.issuerSubjectPublicKeyInfo); Reader contents; if (der::ExpectTagAndGetValue(input, der::SEQUENCE, contents) != Success) { - return ByteString(); + return ENCODING_FAILED; } // Skip AlgorithmIdentifier if (der::ExpectTagAndSkipValue(contents, der::SEQUENCE) != Success) { - return ByteString(); + return ENCODING_FAILED; } Input subjectPublicKey; if (der::BitStringWithNoUnusedBits(contents, subjectPublicKey) != Success) { - return ByteString(); + return ENCODING_FAILED; } issuerKeyHash = KeyHash(ByteString(subjectPublicKey.UnsafeGetData(), subjectPublicKey.GetLength())); - if (ENCODING_FAILED(issuerKeyHash)) { - return ByteString(); + if (issuerKeyHash == ENCODING_FAILED) { + return ENCODING_FAILED; } } ByteString serialNumberValue(context.certID.serialNumber.UnsafeGetData(), context.certID.serialNumber.GetLength()); ByteString serialNumber(TLV(der::INTEGER, serialNumberValue)); + if (serialNumber == ENCODING_FAILED) { + return ENCODING_FAILED; + } // python DottedOIDToCode.py --alg id-sha1 1.3.14.3.2.26 static const uint8_t alg_id_sha1[] = { @@ -1000,8 +1062,8 @@ CertStatus(OCSPResponseContext& context) case 1: { ByteString revocationTime(TimeToGeneralizedTime(context.revocationTime)); - if (ENCODING_FAILED(revocationTime)) { - return ByteString(); + if (revocationTime == ENCODING_FAILED) { + return ENCODING_FAILED; } // TODO(bug 980536): add support for revocationReason return TLV(der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 1, revocationTime); @@ -1010,7 +1072,7 @@ CertStatus(OCSPResponseContext& context) assert(false); // fall through } - return ByteString(); + return ENCODING_FAILED; } } } } // namespace mozilla::pkix::test diff --git a/security/pkix/test/lib/pkixtestutil.h b/security/pkix/test/lib/pkixtestutil.h index 411221c51ea5..57cf057ac9cd 100644 --- a/security/pkix/test/lib/pkixtestutil.h +++ b/security/pkix/test/lib/pkixtestutil.h @@ -36,8 +36,7 @@ namespace mozilla { namespace pkix { namespace test { typedef std::basic_string ByteString; - -inline bool ENCODING_FAILED(const ByteString& bs) { return bs.empty(); } +extern const ByteString ENCODING_FAILED; // XXX: Ideally, we should define this instead: // @@ -80,6 +79,7 @@ extern const Input sha256WithRSAEncryption; mozilla::pkix::Time YMDHMS(int16_t year, int16_t month, int16_t day, int16_t hour, int16_t minutes, int16_t seconds); + ByteString CNToDERName(const char* cn); class TestKeyPair From d627ff5ba0372d24bf3edb3c5fd48571159ddb2d Mon Sep 17 00:00:00 2001 From: Ivan Jibaja Date: Fri, 25 Jul 2014 14:37:34 -0700 Subject: [PATCH 29/84] Bug 1044256 - SIMD backend: implement unary arithmetic operations; a=ijibaja,bbouvier; r=sunfish --- js/src/jit/IonTypes.h | 10 +++ js/src/jit/LIR-Common.h | 28 ++++++++ js/src/jit/LOpcodes.h | 2 + js/src/jit/Lowering.cpp | 22 ++++++ js/src/jit/Lowering.h | 1 + js/src/jit/MIR.h | 46 +++++++++++++ js/src/jit/MOpcodes.h | 1 + js/src/jit/ParallelSafetyAnalysis.cpp | 1 + js/src/jit/shared/Assembler-x86-shared.h | 48 +++++++++++++ js/src/jit/shared/BaseAssembler-x86-shared.h | 53 ++++++++++++++ .../jit/shared/CodeGenerator-x86-shared.cpp | 69 +++++++++++++++++++ js/src/jit/shared/CodeGenerator-x86-shared.h | 2 + js/src/jit/shared/MacroAssembler-x86-shared.h | 13 ++++ 13 files changed, 296 insertions(+) diff --git a/js/src/jit/IonTypes.h b/js/src/jit/IonTypes.h index 281845143842..5c35259e6ff8 100644 --- a/js/src/jit/IonTypes.h +++ b/js/src/jit/IonTypes.h @@ -284,6 +284,11 @@ class SimdConstant { cst.fillInt32x4(array[0], array[1], array[2], array[3]); return cst; } + static SimdConstant SplatX4(int32_t v) { + SimdConstant cst; + cst.fillInt32x4(v, v, v, v); + return cst; + } static SimdConstant CreateX4(float x, float y, float z, float w) { SimdConstant cst; cst.fillFloat32x4(x, y, z, w); @@ -294,6 +299,11 @@ class SimdConstant { cst.fillFloat32x4(array[0], array[1], array[2], array[3]); return cst; } + static SimdConstant SplatX4(float v) { + SimdConstant cst; + cst.fillFloat32x4(v, v, v, v); + return cst; + } uint32_t length() const { MOZ_ASSERT(defined()); diff --git a/js/src/jit/LIR-Common.h b/js/src/jit/LIR-Common.h index dadc3dd389f0..687ab64f72d5 100644 --- a/js/src/jit/LIR-Common.h +++ b/js/src/jit/LIR-Common.h @@ -310,6 +310,34 @@ class LSimdBinaryArithFx4 : public LSimdBinaryArith LSimdBinaryArithFx4() : LSimdBinaryArith() {} }; +// Unary SIMD arithmetic operation on a SIMD operand +class LSimdUnaryArith : public LInstructionHelper<1, 1, 0> +{ + public: + explicit LSimdUnaryArith(const LAllocation &in) { + setOperand(0, in); + } + MSimdUnaryArith::Operation operation() const { + return mir_->toSimdUnaryArith()->operation(); + } +}; + +// Unary SIMD arithmetic operation on a Int32x4 operand +class LSimdUnaryArithIx4 : public LSimdUnaryArith +{ + public: + LIR_HEADER(SimdUnaryArithIx4); + explicit LSimdUnaryArithIx4(const LAllocation &in) : LSimdUnaryArith(in) {} +}; + +// Unary SIMD arithmetic operation on a Float32x4 operand +class LSimdUnaryArithFx4 : public LSimdUnaryArith +{ + public: + LIR_HEADER(SimdUnaryArithFx4); + explicit LSimdUnaryArithFx4(const LAllocation &in) : LSimdUnaryArith(in) {} +}; + // Binary SIMD bitwise operation between two int32x4 or float32x4 operands class LSimdBinaryBitwiseX4 : public LInstructionHelper<1, 2, 0> { diff --git a/js/src/jit/LOpcodes.h b/js/src/jit/LOpcodes.h index 574e2d63ddba..60e31b5a390e 100644 --- a/js/src/jit/LOpcodes.h +++ b/js/src/jit/LOpcodes.h @@ -24,6 +24,8 @@ _(SimdInsertElementI) \ _(SimdInsertElementF) \ _(SimdSignMaskX4) \ + _(SimdUnaryArithIx4) \ + _(SimdUnaryArithFx4) \ _(SimdBinaryCompIx4) \ _(SimdBinaryCompFx4) \ _(SimdBinaryArithIx4) \ diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp index dbf5f1928740..f191fa4481f7 100644 --- a/js/src/jit/Lowering.cpp +++ b/js/src/jit/Lowering.cpp @@ -3801,6 +3801,28 @@ LIRGenerator::visitSimdSignMask(MSimdSignMask *ins) } } +bool +LIRGenerator::visitSimdUnaryArith(MSimdUnaryArith *ins) +{ + MOZ_ASSERT(IsSimdType(ins->type())); + + // Cannot be at start, as the ouput is used as a temporary to store values. + LUse in = use(ins->input()); + + if (ins->type() == MIRType_Int32x4) { + LSimdUnaryArithIx4 *lir = new(alloc()) LSimdUnaryArithIx4(in); + return define(lir, ins); + } + + if (ins->type() == MIRType_Float32x4) { + LSimdUnaryArithFx4 *lir = new(alloc()) LSimdUnaryArithFx4(in); + return define(lir, ins); + } + + MOZ_CRASH("Unknown SIMD kind for unary operation"); + return false; +} + bool LIRGenerator::visitSimdBinaryComp(MSimdBinaryComp *ins) { diff --git a/js/src/jit/Lowering.h b/js/src/jit/Lowering.h index 42a142e8e0f2..f1a347100798 100644 --- a/js/src/jit/Lowering.h +++ b/js/src/jit/Lowering.h @@ -271,6 +271,7 @@ class LIRGenerator : public LIRGeneratorSpecific bool visitSimdExtractElement(MSimdExtractElement *ins); bool visitSimdInsertElement(MSimdInsertElement *ins); bool visitSimdSignMask(MSimdSignMask *ins); + bool visitSimdUnaryArith(MSimdUnaryArith *ins); bool visitSimdBinaryComp(MSimdBinaryComp *ins); bool visitSimdBinaryArith(MSimdBinaryArith *ins); bool visitSimdBinaryBitwise(MSimdBinaryBitwise *ins); diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index 01f8fadd74d7..d969f1526674 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -1563,6 +1563,52 @@ class MSimdSignMask : public MUnaryInstruction ALLOW_CLONE(MSimdSignMask) }; +class MSimdUnaryArith : public MUnaryInstruction +{ + public: + enum Operation { + abs, + neg, + not_, + reciprocal, + reciprocalSqrt, + sqrt + }; + + private: + Operation operation_; + + MSimdUnaryArith(MDefinition *def, Operation op, MIRType type) + : MUnaryInstruction(def), operation_(op) + { + MOZ_ASSERT(IsSimdType(type)); + MOZ_ASSERT(def->type() == type); + MOZ_ASSERT_IF(type == MIRType_Int32x4, op == neg || op == not_); + setResultType(type); + setMovable(); + } + + public: + INSTRUCTION_HEADER(SimdUnaryArith); + static MSimdUnaryArith *NewAsmJS(TempAllocator &alloc, MDefinition *def, + Operation op, MIRType t) + { + return new(alloc) MSimdUnaryArith(def, op, t); + } + + Operation operation() const { return operation_; } + + AliasSet getAliasSet() const { + return AliasSet::None(); + } + + bool congruentTo(const MDefinition *ins) const { + return congruentIfOperandsEqual(ins) && ins->toSimdUnaryArith()->operation() == operation(); + } + + ALLOW_CLONE(MSimdUnaryArith); +}; + // Compares each value of a SIMD vector to each corresponding lane's value of // another SIMD vector, and returns a int32x4 vector containing the results of // the comparison: all bits are set to 1 if the comparison is true, 0 otherwise. diff --git a/js/src/jit/MOpcodes.h b/js/src/jit/MOpcodes.h index e1fd9fb196dc..f96509433c36 100644 --- a/js/src/jit/MOpcodes.h +++ b/js/src/jit/MOpcodes.h @@ -20,6 +20,7 @@ namespace jit { _(SimdExtractElement) \ _(SimdInsertElement) \ _(SimdSignMask) \ + _(SimdUnaryArith) \ _(SimdBinaryComp) \ _(SimdBinaryArith) \ _(SimdBinaryBitwise) \ diff --git a/js/src/jit/ParallelSafetyAnalysis.cpp b/js/src/jit/ParallelSafetyAnalysis.cpp index 5df70fd88ba3..2a7ef112c731 100644 --- a/js/src/jit/ParallelSafetyAnalysis.cpp +++ b/js/src/jit/ParallelSafetyAnalysis.cpp @@ -119,6 +119,7 @@ class ParallelSafetyVisitor : public MDefinitionVisitor SAFE_OP(SimdExtractElement) SAFE_OP(SimdInsertElement) SAFE_OP(SimdSignMask) + SAFE_OP(SimdUnaryArith) SAFE_OP(SimdBinaryComp) SAFE_OP(SimdBinaryArith) SAFE_OP(SimdBinaryBitwise) diff --git a/js/src/jit/shared/Assembler-x86-shared.h b/js/src/jit/shared/Assembler-x86-shared.h index fe4c145819ce..1ff589e26091 100644 --- a/js/src/jit/shared/Assembler-x86-shared.h +++ b/js/src/jit/shared/Assembler-x86-shared.h @@ -1600,6 +1600,54 @@ class AssemblerX86Shared : public AssemblerShared MOZ_CRASH("unexpected operand kind"); } } + void rcpps(const Operand &src, FloatRegister dest) { + MOZ_ASSERT(HasSSE2()); + switch (src.kind()) { + case Operand::FPREG: + masm.rcpps_rr(src.fpu(), dest.code()); + break; + case Operand::MEM_REG_DISP: + masm.rcpps_mr(src.disp(), src.base(), dest.code()); + break; + case Operand::MEM_ADDRESS32: + masm.rcpps_mr(src.address(), dest.code()); + break; + default: + MOZ_CRASH("unexpected operand kind"); + } + } + void sqrtps(const Operand &src, FloatRegister dest) { + MOZ_ASSERT(HasSSE2()); + switch (src.kind()) { + case Operand::FPREG: + masm.sqrtps_rr(src.fpu(), dest.code()); + break; + case Operand::MEM_REG_DISP: + masm.sqrtps_mr(src.disp(), src.base(), dest.code()); + break; + case Operand::MEM_ADDRESS32: + masm.sqrtps_mr(src.address(), dest.code()); + break; + default: + MOZ_CRASH("unexpected operand kind"); + } + } + void rsqrtps(const Operand &src, FloatRegister dest) { + MOZ_ASSERT(HasSSE2()); + switch (src.kind()) { + case Operand::FPREG: + masm.rsqrtps_rr(src.fpu(), dest.code()); + break; + case Operand::MEM_REG_DISP: + masm.rsqrtps_mr(src.disp(), src.base(), dest.code()); + break; + case Operand::MEM_ADDRESS32: + masm.rsqrtps_mr(src.address(), dest.code()); + break; + default: + MOZ_CRASH("unexpected operand kind"); + } + } void movd(Register src, FloatRegister dest) { MOZ_ASSERT(HasSSE2()); masm.movd_rr(src.code(), dest.code()); diff --git a/js/src/jit/shared/BaseAssembler-x86-shared.h b/js/src/jit/shared/BaseAssembler-x86-shared.h index 7fefdab1ffeb..ee82fcb02978 100644 --- a/js/src/jit/shared/BaseAssembler-x86-shared.h +++ b/js/src/jit/shared/BaseAssembler-x86-shared.h @@ -326,6 +326,9 @@ private: OP2_MAXPS_VpsWps = 0x5F, OP2_SQRTSD_VsdWsd = 0x51, OP2_SQRTSS_VssWss = 0x51, + OP2_SQRTPS_VpsWps = 0x51, + OP2_RSQRTPS_VpsWps = 0x52, + OP2_RCPPS_VpsWps = 0x53, OP2_ANDPD_VpdWpd = 0x54, OP2_ORPD_VpdWpd = 0x56, OP2_XORPD_VpdWpd = 0x57, @@ -2674,6 +2677,56 @@ public: m_formatter.immediate8(order); } + void rcpps_rr(XMMRegisterID src, XMMRegisterID dst){ + spew("rcpps %s, %s", + nameFPReg(src), nameFPReg(dst)); + m_formatter.twoByteOp(OP2_RCPPS_VpsWps, (RegisterID)dst, (RegisterID)src); + } + void rcpps_mr(int offset, RegisterID base, XMMRegisterID dst){ + spew("rcpps %s0x%x(%s), %s", + PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst)); + m_formatter.twoByteOp(OP2_RCPPS_VpsWps, (RegisterID)dst, base, offset); + } + void rcpps_mr(const void* address, XMMRegisterID dst){ + spew("rcpps %p, %s", + address, nameFPReg(dst)); + m_formatter.twoByteOp(OP2_RCPPS_VpsWps, (RegisterID)dst, address); + } + + void rsqrtps_rr(XMMRegisterID src, XMMRegisterID dst){ + spew("rsqrtps %s, %s", + nameFPReg(src), nameFPReg(dst)); + m_formatter.twoByteOp(OP2_RSQRTPS_VpsWps, (RegisterID)dst, (RegisterID)src); + } + void rsqrtps_mr(int offset, RegisterID base, XMMRegisterID dst){ + spew("rsqrtps %s0x%x(%s), %s", + PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst)); + m_formatter.twoByteOp(OP2_RSQRTPS_VpsWps, (RegisterID)dst, base, offset); + } + void rsqrtps_mr(const void* address, XMMRegisterID dst){ + spew("rsqrtps %p, %s", + address, nameFPReg(dst)); + m_formatter.twoByteOp(OP2_RSQRTPS_VpsWps, (RegisterID)dst, address); + } + + void sqrtps_rr(XMMRegisterID src, XMMRegisterID dst){ + spew("sqrtps %s, %s", + nameFPReg(src), nameFPReg(dst)); + m_formatter.twoByteOp(OP2_SQRTPS_VpsWps, (RegisterID)dst, (RegisterID)src); + } + + void sqrtps_mr(int offset, RegisterID base, XMMRegisterID dst){ + spew("sqrtps %s0x%x(%s), %s", + PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst)); + m_formatter.twoByteOp(OP2_SQRTPS_VpsWps, (RegisterID)dst, base, offset); + } + + void sqrtps_mr(const void* address, XMMRegisterID dst){ + spew("sqrtps %p, %s", + address, nameFPReg(dst)); + m_formatter.twoByteOp(OP2_SQRTPS_VpsWps, (RegisterID)dst, address); + } + void addsd_rr(XMMRegisterID src, XMMRegisterID dst) { spew("addsd %s, %s", diff --git a/js/src/jit/shared/CodeGenerator-x86-shared.cpp b/js/src/jit/shared/CodeGenerator-x86-shared.cpp index 4f456a6f87ea..df2f419f3d47 100644 --- a/js/src/jit/shared/CodeGenerator-x86-shared.cpp +++ b/js/src/jit/shared/CodeGenerator-x86-shared.cpp @@ -2525,6 +2525,75 @@ CodeGeneratorX86Shared::visitSimdBinaryArithFx4(LSimdBinaryArithFx4 *ins) MOZ_CRASH("unexpected SIMD op"); } +bool +CodeGeneratorX86Shared::visitSimdUnaryArithIx4(LSimdUnaryArithIx4 *ins) +{ + Operand in = ToOperand(ins->input()); + FloatRegister out = ToFloatRegister(ins->output()); + + static const SimdConstant allOnes = SimdConstant::CreateX4(-1, -1, -1, -1); + + switch (ins->operation()) { + case MSimdUnaryArith::neg: + masm.pxor(out, out); + masm.packedSubInt32(in, out); + return true; + case MSimdUnaryArith::not_: + masm.loadConstantInt32x4(allOnes, out); + masm.bitwiseXorX4(in, out); + return true; + case MSimdUnaryArith::abs: + case MSimdUnaryArith::reciprocal: + case MSimdUnaryArith::reciprocalSqrt: + case MSimdUnaryArith::sqrt: + break; + } + MOZ_CRASH("unexpected SIMD op"); +} + +bool +CodeGeneratorX86Shared::visitSimdUnaryArithFx4(LSimdUnaryArithFx4 *ins) +{ + Operand in = ToOperand(ins->input()); + FloatRegister out = ToFloatRegister(ins->output()); + + // All ones but the sign bit + float signMask = SpecificNaN(0, FloatingPoint::kSignificandBits); + static const SimdConstant signMasks = SimdConstant::SplatX4(signMask); + + // All ones including the sign bit + float ones = SpecificNaN(1, FloatingPoint::kSignificandBits); + static const SimdConstant allOnes = SimdConstant::SplatX4(ones); + + // All zeros but the sign bit + static const SimdConstant minusZero = SimdConstant::SplatX4(-0.f); + + switch (ins->operation()) { + case MSimdUnaryArith::abs: + masm.loadConstantFloat32x4(signMasks, out); + masm.bitwiseAndX4(in, out); + return true; + case MSimdUnaryArith::neg: + masm.loadConstantFloat32x4(minusZero, out); + masm.bitwiseXorX4(in, out); + return true; + case MSimdUnaryArith::not_: + masm.loadConstantFloat32x4(allOnes, out); + masm.bitwiseXorX4(in, out); + return true; + case MSimdUnaryArith::reciprocal: + masm.packedReciprocalFloat32x4(in, out); + return true; + case MSimdUnaryArith::reciprocalSqrt: + masm.packedReciprocalSqrtFloat32x4(in, out); + return true; + case MSimdUnaryArith::sqrt: + masm.packedSqrtFloat32x4(in, out); + return true; + } + MOZ_CRASH("unexpected SIMD op"); +} + bool CodeGeneratorX86Shared::visitSimdBinaryBitwiseX4(LSimdBinaryBitwiseX4 *ins) { diff --git a/js/src/jit/shared/CodeGenerator-x86-shared.h b/js/src/jit/shared/CodeGenerator-x86-shared.h index 6e7e4d010d2d..e216189c871d 100644 --- a/js/src/jit/shared/CodeGenerator-x86-shared.h +++ b/js/src/jit/shared/CodeGenerator-x86-shared.h @@ -219,6 +219,8 @@ class CodeGeneratorX86Shared : public CodeGeneratorShared bool visitSimdInsertElementI(LSimdInsertElementI *lir); bool visitSimdInsertElementF(LSimdInsertElementF *lir); bool visitSimdSignMaskX4(LSimdSignMaskX4 *ins); + bool visitSimdUnaryArithIx4(LSimdUnaryArithIx4 *lir); + bool visitSimdUnaryArithFx4(LSimdUnaryArithFx4 *lir); bool visitSimdBinaryCompIx4(LSimdBinaryCompIx4 *lir); bool visitSimdBinaryCompFx4(LSimdBinaryCompFx4 *lir); bool visitSimdBinaryArithIx4(LSimdBinaryArithIx4 *lir); diff --git a/js/src/jit/shared/MacroAssembler-x86-shared.h b/js/src/jit/shared/MacroAssembler-x86-shared.h index 9d700421e8fd..31b29c70fd1e 100644 --- a/js/src/jit/shared/MacroAssembler-x86-shared.h +++ b/js/src/jit/shared/MacroAssembler-x86-shared.h @@ -532,6 +532,19 @@ class MacroAssemblerX86Shared : public Assembler void packedSubInt32(const Operand &src, FloatRegister dest) { psubd(src, dest); } + void packedReciprocalFloat32x4(const Operand &src, FloatRegister dest) { + // This function is an approximation of the result, this might need + // fix up if the spec requires a given precision for this operation. + // TODO See also bug 1068028. + rcpps(src, dest); + } + void packedReciprocalSqrtFloat32x4(const Operand &src, FloatRegister dest) { + // TODO See comment above. See also bug 1068028. + rsqrtps(src, dest); + } + void packedSqrtFloat32x4(const Operand &src, FloatRegister dest) { + sqrtps(src, dest); + } void packedLeftShiftByScalar(FloatRegister src, FloatRegister dest) { pslld(src, dest); From 753461cce19e526bb8e2ac580213a8503765128c Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Tue, 7 Oct 2014 14:10:00 +0200 Subject: [PATCH 30/84] Bug 1044256: SIMD: Add support for unary operators in Odin; r=luke --- js/src/asmjs/AsmJSValidate.cpp | 36 ++++++++++++ js/src/builtin/SIMD.h | 8 ++- js/src/jit-test/tests/asm.js/testSIMD.js | 75 ++++++++++++++++++++++-- 3 files changed, 113 insertions(+), 6 deletions(-) diff --git a/js/src/asmjs/AsmJSValidate.cpp b/js/src/asmjs/AsmJSValidate.cpp index f096791194c4..a90623ecb1ff 100644 --- a/js/src/asmjs/AsmJSValidate.cpp +++ b/js/src/asmjs/AsmJSValidate.cpp @@ -2427,6 +2427,17 @@ class FunctionCompiler return ins; } + MDefinition *unarySimd(MDefinition *input, MSimdUnaryArith::Operation op, MIRType type) + { + if (inDeadCode()) + return nullptr; + + MOZ_ASSERT(IsSimdType(input->type()) && input->type() == type); + MInstruction *ins = MSimdUnaryArith::NewAsmJS(alloc(), input, op, type); + curBlock_->add(ins); + return ins; + } + MDefinition *binarySimd(MDefinition *lhs, MDefinition *rhs, MSimdBinaryArith::Operation op, MIRType type) { @@ -4853,6 +4864,18 @@ class CheckSimdVectorScalarArgs } // anonymous namespace +static inline bool +CheckSimdUnary(FunctionCompiler &f, ParseNode *call, Type retType, MSimdUnaryArith::Operation op, + MDefinition **def, Type *type) +{ + DefinitionVector defs; + if (!CheckSimdCallArgs(f, call, 1, CheckArgIsSubtypeOf(retType), &defs)) + return false; + *def = f.unarySimd(defs[0], op, retType.toMIRType()); + *type = retType; + return true; +} + template static inline bool CheckSimdBinary(FunctionCompiler &f, ParseNode *call, Type retType, OpEnum op, MDefinition **def, @@ -4985,6 +5008,19 @@ CheckSimdOperationCall(FunctionCompiler &f, ParseNode *call, const ModuleCompile case AsmJSSimdOperation_shiftRightLogical: return CheckSimdBinary(f, call, Type::Int32x4, MSimdShift::ursh, def, type); + case AsmJSSimdOperation_abs: + return CheckSimdUnary(f, call, retType, MSimdUnaryArith::abs, def, type); + case AsmJSSimdOperation_neg: + return CheckSimdUnary(f, call, retType, MSimdUnaryArith::neg, def, type); + case AsmJSSimdOperation_not: + return CheckSimdUnary(f, call, retType, MSimdUnaryArith::not_, def, type); + case AsmJSSimdOperation_sqrt: + return CheckSimdUnary(f, call, retType, MSimdUnaryArith::sqrt, def, type); + case AsmJSSimdOperation_reciprocal: + return CheckSimdUnary(f, call, retType, MSimdUnaryArith::reciprocal, def, type); + case AsmJSSimdOperation_reciprocalSqrt: + return CheckSimdUnary(f, call, retType, MSimdUnaryArith::reciprocalSqrt, def, type); + case AsmJSSimdOperation_splat: { DefinitionVector defs; Type formalType = retType.simdToCoercedScalarType(); diff --git a/js/src/builtin/SIMD.h b/js/src/builtin/SIMD.h index 6f777de5b575..5abbb1257488 100644 --- a/js/src/builtin/SIMD.h +++ b/js/src/builtin/SIMD.h @@ -120,6 +120,10 @@ _(shiftRight) \ _(shiftRightLogical) #define FOREACH_FLOAT32X4_SIMD_OP(_) \ + _(abs) \ + _(sqrt) \ + _(reciprocal) \ + _(reciprocalSqrt) \ _(fromInt32x4) \ _(fromInt32x4Bits) \ _(mul) \ @@ -143,7 +147,9 @@ _(withX) \ _(withY) \ _(withZ) \ - _(withW) + _(withW) \ + _(not) \ + _(neg) #define FORALL_SIMD_OP(_) \ FOREACH_INT32X4_SIMD_OP(_) \ FOREACH_FLOAT32X4_SIMD_OP(_) \ diff --git a/js/src/jit-test/tests/asm.js/testSIMD.js b/js/src/jit-test/tests/asm.js/testSIMD.js index 7389c92c8ac6..99b90b032d84 100644 --- a/js/src/jit-test/tests/asm.js/testSIMD.js +++ b/js/src/jit-test/tests/asm.js/testSIMD.js @@ -24,11 +24,14 @@ const INT32_MIN = INT32_MAX + 1 | 0; const assertEqFFI = {assertEq:assertEq}; -function assertEqX4(real, expected) { - assertEq(real.x, expected[0]); - assertEq(real.y, expected[1]); - assertEq(real.z, expected[2]); - assertEq(real.w, expected[3]); +function assertEqX4(real, expected, assertFunc) { + if (typeof assertFunc === 'undefined') + assertFunc = assertEq; + + assertFunc(real.x, expected[0]); + assertFunc(real.y, expected[1]); + assertFunc(real.z, expected[2]); + assertFunc(real.w, expected[3]); } function CheckI4(header, code, expected) { @@ -444,6 +447,68 @@ CheckF4(F32M, 'var x=f4(1,2,3,4); var y=f4(4,3,5,2); x=f4m(x,y)', [4,6,15,8]); CheckF4(F32M, 'var x=f4(13.37,2,3,4); var y=f4(4,3,5,2); x=f4m(x,y)', [Math.fround(13.37) * 4,6,15,8]); CheckF4(F32M, 'var x=f4(13.37,2,3,4); var y=f4(4,3,5,2); x=f4(f4m(x,y))', [Math.fround(13.37) * 4,6,15,8]); +// Unary arithmetic operators +function CheckUnaryF4(op, checkFunc, assertFunc) { + var _ = asmLink(asmCompile('glob', USE_ASM + F32 + 'var op=f4.' + op + '; function f(x){x=f4(x); return f4(op(x)); } return f'), this); + return function(input) { + var simd = SIMD.float32x4(input[0], input[1], input[2], input[3]); + + var exp = input.map(Math.fround).map(checkFunc).map(Math.fround); + var obs = _(simd); + assertEqX4(obs, exp, assertFunc); + } +} + +function CheckUnaryI4(op, checkFunc) { + var _ = asmLink(asmCompile('glob', USE_ASM + I32 + 'var op=i4.' + op + '; function f(x){x=i4(x); return i4(op(x)); } return f'), this); + return function(input) { + var simd = SIMD.int32x4(input[0], input[1], input[2], input[3]); + assertEqX4(_(simd), input.map(checkFunc).map(function(x) { return x | 0})); + } +} + +CheckUnaryI4('neg', function(x) { return -x })([1, -2, INT32_MIN, INT32_MAX]); +CheckUnaryI4('not', function(x) { return ~x })([1, -2, INT32_MIN, INT32_MAX]); + +var CheckAbs = CheckUnaryF4('abs', Math.abs); +CheckAbs([1, 42.42, 0.63, 13.37]); +CheckAbs([NaN, -Infinity, Infinity, 0]); + +var CheckNegF = CheckUnaryF4('neg', function(x) { return -x }); +CheckNegF([1, 42.42, 0.63, 13.37]); +CheckNegF([NaN, -Infinity, Infinity, 0]); + +var CheckNotF = CheckUnaryF4('not', (function() { + var f32 = new Float32Array(1); + var i32 = new Int32Array(f32.buffer); + return function(x) { + f32[0] = x; + i32[0] = ~i32[0]; + return f32[0]; + } +})()); +CheckNotF([1, 42.42, 0.63, 13.37]); +CheckNotF([NaN, -Infinity, Infinity, 0]); + +var CheckSqrt = CheckUnaryF4('sqrt', function(x) { return Math.sqrt(x); }); +CheckSqrt([1, 42.42, 0.63, 13.37]); +CheckSqrt([NaN, -Infinity, Infinity, 0]); + +// Reciprocal and reciprocalSqrt give approximate results +function assertNear(a, b) { + if (a !== a && b === b) + throw 'Observed NaN, expected ' + b; + if (Math.abs(a - b) > 1e-3) + throw 'More than 1e-3 between ' + a + ' and ' + b; +} +var CheckRecp = CheckUnaryF4('reciprocal', function(x) { return 1 / x; }, assertNear); +CheckRecp([1, 42.42, 0.63, 13.37]); +CheckRecp([NaN, -Infinity, Infinity, 0]); + +var CheckRecp = CheckUnaryF4('reciprocalSqrt', function(x) { return 1 / Math.sqrt(x); }, assertNear); +CheckRecp([1, 42.42, 0.63, 13.37]); +CheckRecp([NaN, -Infinity, Infinity, 0]); + // Min/Max assertAsmTypeFail('glob', USE_ASM + I32 + "var f4m=i4.min; function f() {} return f"); assertAsmTypeFail('glob', USE_ASM + I32 + "var f4d=i4.max; function f() {} return f"); From a0f306343e86abac65d5a0975b01981ecf42e75c Mon Sep 17 00:00:00 2001 From: Peter Van der Beken Date: Tue, 7 Oct 2014 11:44:48 +0200 Subject: [PATCH 31/84] Bug 808856 - Make not overriding WrapObject fail to build. r=ehsan. --HG-- extra : rebase_source : 4683c70c97f7eea454bc445331dbbbe7c4f2cec7 --- content/base/src/Attr.cpp | 2 +- content/base/src/Attr.h | 2 +- content/base/src/nsInProcessTabChildGlobal.h | 4 ++++ dom/base/nsWindowRoot.h | 5 +++++ dom/base/nsWrapperCache.h | 6 +----- dom/ipc/TabChild.h | 5 +++++ js/xpconnect/public/SandboxPrivate.h | 5 +++++ 7 files changed, 22 insertions(+), 7 deletions(-) diff --git a/content/base/src/Attr.cpp b/content/base/src/Attr.cpp index 78f359038abd..6ff1e03fd909 100644 --- a/content/base/src/Attr.cpp +++ b/content/base/src/Attr.cpp @@ -388,7 +388,7 @@ Attr::Shutdown() } JSObject* -Attr::WrapObject(JSContext* aCx) +Attr::WrapNode(JSContext* aCx) { return AttrBinding::Wrap(aCx, this); } diff --git a/content/base/src/Attr.h b/content/base/src/Attr.h index 756c260df65e..3305a9e75193 100644 --- a/content/base/src/Attr.h +++ b/content/base/src/Attr.h @@ -82,7 +82,7 @@ public: virtual nsIDOMNode* AsDOMNode() { return this; } // WebIDL - virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE; + virtual JSObject* WrapNode(JSContext* aCx) MOZ_OVERRIDE; // XPCOM GetName() is OK // XPCOM GetValue() is OK diff --git a/content/base/src/nsInProcessTabChildGlobal.h b/content/base/src/nsInProcessTabChildGlobal.h index dfd0db42930a..220dfbfa98b2 100644 --- a/content/base/src/nsInProcessTabChildGlobal.h +++ b/content/base/src/nsInProcessTabChildGlobal.h @@ -154,6 +154,10 @@ public: return mGlobal->GetJSObject(); } + virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE + { + MOZ_CRASH("nsInProcessTabChildGlobal doesn't use DOM bindings!"); + } protected: virtual ~nsInProcessTabChildGlobal(); diff --git a/dom/base/nsWindowRoot.h b/dom/base/nsWindowRoot.h index d798b77a4848..034dd2d21722 100644 --- a/dom/base/nsWindowRoot.h +++ b/dom/base/nsWindowRoot.h @@ -61,6 +61,11 @@ public: virtual mozilla::dom::EventTarget* GetParentTarget() MOZ_OVERRIDE { return mParent; } virtual nsIDOMWindow* GetOwnerGlobal() MOZ_OVERRIDE; + virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE + { + MOZ_CRASH("nsWindowRoot doesn't use DOM bindings!"); + } + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsWindowRoot, nsIDOMEventTarget) diff --git a/dom/base/nsWrapperCache.h b/dom/base/nsWrapperCache.h index 75224af6975f..f15cedbce6a4 100644 --- a/dom/base/nsWrapperCache.h +++ b/dom/base/nsWrapperCache.h @@ -150,11 +150,7 @@ public: * Wrap the object corresponding to this wrapper cache. If non-null is * returned, the object has already been stored in the wrapper cache. */ - virtual JSObject* WrapObject(JSContext* cx) - { - MOZ_ASSERT(!IsDOMBinding(), "Someone forgot to override WrapObject"); - return nullptr; - } + virtual JSObject* WrapObject(JSContext* cx) = 0; /** * Returns true if the object has a non-gray wrapper. diff --git a/dom/ipc/TabChild.h b/dom/ipc/TabChild.h index 7c5340490684..5fdc423a8a8b 100644 --- a/dom/ipc/TabChild.h +++ b/dom/ipc/TabChild.h @@ -138,6 +138,11 @@ public: virtual nsIPrincipal* GetPrincipal() MOZ_OVERRIDE; virtual JSObject* GetGlobalJSObject() MOZ_OVERRIDE; + virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE + { + MOZ_CRASH("TabChildGlobal doesn't use DOM bindings!"); + } + nsCOMPtr mMessageManager; nsRefPtr mTabChild; diff --git a/js/xpconnect/public/SandboxPrivate.h b/js/xpconnect/public/SandboxPrivate.h index b344b88fb2bb..d4999588e008 100644 --- a/js/xpconnect/public/SandboxPrivate.h +++ b/js/xpconnect/public/SandboxPrivate.h @@ -49,6 +49,11 @@ public: ClearWrapper(); } + virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE + { + MOZ_CRASH("SandboxPrivate doesn't use DOM bindings!"); + } + private: virtual ~SandboxPrivate() { } From 962c9a57429cc2cc7c340f6cc84188372398b0b2 Mon Sep 17 00:00:00 2001 From: Peter Van der Beken Date: Tue, 7 Oct 2014 11:44:48 +0200 Subject: [PATCH 32/84] Bug 1078744 - Replace SetIsDOMBinding with SetIsNonDOMBinding, invert the flag for dom bindings in nsWrapperCache and add SetIsNotDOMBinding. r=bz. --HG-- extra : rebase_source : 6ca1903658d3d6fe2634409cd39fa68c6b1219bd --- .../base/src/nsInProcessTabChildGlobal.cpp | 1 + dom/base/Navigator.cpp | 3 +- dom/base/nsWindowRoot.cpp | 1 + dom/base/nsWrapperCache.h | 41 ++++++++++++++----- dom/network/Connection.cpp | 13 ++---- dom/network/Connection.h | 3 +- js/xpconnect/public/SandboxPrivate.h | 1 + 7 files changed, 38 insertions(+), 25 deletions(-) diff --git a/content/base/src/nsInProcessTabChildGlobal.cpp b/content/base/src/nsInProcessTabChildGlobal.cpp index a80a5b2506c6..04500690f86c 100644 --- a/content/base/src/nsInProcessTabChildGlobal.cpp +++ b/content/base/src/nsInProcessTabChildGlobal.cpp @@ -103,6 +103,7 @@ nsInProcessTabChildGlobal::nsInProcessTabChildGlobal(nsIDocShell* aShell, : mDocShell(aShell), mInitialized(false), mLoadingScript(false), mOwner(aOwner), mChromeMessageManager(aChrome) { + SetIsNotDOMBinding(); mozilla::HoldJSObjects(this); // If owner corresponds to an