diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index 6e3ddbdc..fd079e6c 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn
@@ -1443,7 +1443,11 @@ # Favor size over speed. # TODO(crbug.com/718650): Fix -Os in PNaCl compiler and remove the is_nacl # guard above. - cflags = [ "-Os" ] + common_optimize_on_cflags + if (is_clang) { + cflags = [ "-Oz" ] + common_optimize_on_cflags + } else { + cflags = [ "-Os" ] + common_optimize_on_cflags + } } else { cflags = [ "-O2" ] + common_optimize_on_cflags } @@ -1460,7 +1464,11 @@ # Favor size over speed. # TODO(crbug.com/718650): Fix -Os in PNaCl compiler and remove the is_nacl # guard above. - cflags = [ "-Os" ] + common_optimize_on_cflags + if (is_clang) { + cflags = [ "-Oz" ] + common_optimize_on_cflags + } else { + cflags = [ "-Os" ] + common_optimize_on_cflags + } } else if (optimize_for_fuzzing) { cflags = [ "-O1" ] + common_optimize_on_cflags } else { @@ -1480,7 +1488,11 @@ } else if (is_android && !android_full_debug) { # On Android we kind of optimize some things that don't affect debugging # much even when optimization is disabled to get the binary size down. - cflags = [ "-Os" ] + if (is_clang) { + cflags = [ "-Oz" ] + common_optimize_on_cflags + } else { + cflags = [ "-Os" ] + common_optimize_on_cflags + } } else { cflags = [ "-O0" ] ldflags = []
diff --git a/net/quic/core/crypto/crypto_handshake_message.cc b/net/quic/core/crypto/crypto_handshake_message.cc index 220c46a..0d0813a 100644 --- a/net/quic/core/crypto/crypto_handshake_message.cc +++ b/net/quic/core/crypto/crypto_handshake_message.cc
@@ -79,9 +79,9 @@ tag_value_map_.erase(tag); } -QuicErrorCode CryptoHandshakeMessage::GetTaglist(QuicTag tag, - const QuicTag** out_tags, - size_t* out_len) const { +QuicErrorCode CryptoHandshakeMessage::GetTaglist( + QuicTag tag, + QuicTagVector* out_tags) const { QuicTagValueMap::const_iterator it = tag_value_map_.find(tag); QuicErrorCode ret = QUIC_NO_ERROR; @@ -92,13 +92,17 @@ } if (ret != QUIC_NO_ERROR) { - *out_tags = nullptr; - *out_len = 0; + out_tags->clear(); return ret; } - *out_tags = reinterpret_cast<const QuicTag*>(it->second.data()); - *out_len = it->second.size() / sizeof(QuicTag); + size_t num_tags = it->second.size() / sizeof(QuicTag); + out_tags->resize(num_tags); + for (size_t i = 0; i < num_tags; ++i) { + QuicTag tag; + memcpy(&tag, it->second.data() + i * sizeof(tag), sizeof(tag)); + (*out_tags)[i] = tag; + } return ret; }
diff --git a/net/quic/core/crypto/crypto_handshake_message.h b/net/quic/core/crypto/crypto_handshake_message.h index 6275faad4..f646ce59 100644 --- a/net/quic/core/crypto/crypto_handshake_message.h +++ b/net/quic/core/crypto/crypto_handshake_message.h
@@ -73,13 +73,8 @@ // GetTaglist finds an element with the given tag containing zero or more // tags. If such a tag doesn't exist, it returns an error code. Otherwise it - // sets |out_tags| and |out_len| to point to the array of tags and returns - // QUIC_NO_ERROR. The array points into the CryptoHandshakeMessage and is - // valid only for as long as the CryptoHandshakeMessage exists and is not - // modified. - QuicErrorCode GetTaglist(QuicTag tag, - const QuicTag** out_tags, - size_t* out_len) const; + // populates |out_tags| with the tags and returns QUIC_NO_ERROR. + QuicErrorCode GetTaglist(QuicTag tag, QuicTagVector* out_tags) const; bool GetStringPiece(QuicTag tag, QuicStringPiece* out) const; bool HasStringPiece(QuicTag tag) const;
diff --git a/net/quic/core/crypto/crypto_server_test.cc b/net/quic/core/crypto/crypto_server_test.cc index 13a040e..1ca1e1e 100644 --- a/net/quic/core/crypto/crypto_server_test.cc +++ b/net/quic/core/crypto/crypto_server_test.cc
@@ -216,11 +216,10 @@ }; void CheckServerHello(const CryptoHandshakeMessage& server_hello) { - const QuicTag* versions; - size_t num_versions; - server_hello.GetTaglist(kVER, &versions, &num_versions); - ASSERT_EQ(supported_versions_.size(), num_versions); - for (size_t i = 0; i < num_versions; ++i) { + QuicTagVector versions; + server_hello.GetTaglist(kVER, &versions); + ASSERT_EQ(supported_versions_.size(), versions.size()); + for (size_t i = 0; i < versions.size(); ++i) { EXPECT_EQ(QuicVersionToQuicTag(supported_versions_[i]), versions[i]); } @@ -340,15 +339,13 @@ void CheckRejectReasons( const HandshakeFailureReason* expected_handshake_failures, size_t expected_count) { - const uint32_t* reject_reasons; - size_t num_reject_reasons; + QuicTagVector reject_reasons; static_assert(sizeof(QuicTag) == sizeof(uint32_t), "header out of sync"); - QuicErrorCode error_code = - out_.GetTaglist(kRREJ, &reject_reasons, &num_reject_reasons); + QuicErrorCode error_code = out_.GetTaglist(kRREJ, &reject_reasons); ASSERT_EQ(QUIC_NO_ERROR, error_code); - EXPECT_EQ(expected_count, num_reject_reasons); - for (size_t i = 0; i < num_reject_reasons; ++i) { + EXPECT_EQ(expected_count, reject_reasons.size()); + for (size_t i = 0; i < reject_reasons.size(); ++i) { EXPECT_EQ(expected_handshake_failures[i], reject_reasons[i]); } }
diff --git a/net/quic/core/crypto/crypto_utils.cc b/net/quic/core/crypto/crypto_utils.cc index 0e005bff2..382acc7 100644 --- a/net/quic/core/crypto/crypto_utils.cc +++ b/net/quic/core/crypto/crypto_utils.cc
@@ -188,17 +188,14 @@ return QUIC_INVALID_CRYPTO_MESSAGE_TYPE; } - const QuicTag* supported_version_tags; - size_t num_supported_versions; - - if (server_hello.GetTaglist(kVER, &supported_version_tags, - &num_supported_versions) != QUIC_NO_ERROR) { + QuicTagVector supported_version_tags; + if (server_hello.GetTaglist(kVER, &supported_version_tags) != QUIC_NO_ERROR) { *error_details = "server hello missing version list"; return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; } if (!negotiated_versions.empty()) { - bool mismatch = num_supported_versions != negotiated_versions.size(); - for (size_t i = 0; i < num_supported_versions && !mismatch; ++i) { + bool mismatch = supported_version_tags.size() != negotiated_versions.size(); + for (size_t i = 0; i < supported_version_tags.size() && !mismatch; ++i) { mismatch = QuicTagToQuicVersion(supported_version_tags[i]) != negotiated_versions[i]; }
diff --git a/net/quic/core/crypto/quic_crypto_client_config.cc b/net/quic/core/crypto/quic_crypto_client_config.cc index 2a80d68..fcd630ac 100644 --- a/net/quic/core/crypto/quic_crypto_client_config.cc +++ b/net/quic/core/crypto/quic_crypto_client_config.cc
@@ -527,13 +527,10 @@ out->SetStringPiece(kCertificateSCTTag, ""); - const QuicTag* their_aeads; - const QuicTag* their_key_exchanges; - size_t num_their_aeads, num_their_key_exchanges; - if (scfg->GetTaglist(kAEAD, &their_aeads, &num_their_aeads) != - QUIC_NO_ERROR || - scfg->GetTaglist(kKEXS, &their_key_exchanges, &num_their_key_exchanges) != - QUIC_NO_ERROR) { + QuicTagVector their_aeads; + QuicTagVector their_key_exchanges; + if (scfg->GetTaglist(kAEAD, &their_aeads) != QUIC_NO_ERROR || + scfg->GetTaglist(kKEXS, &their_key_exchanges) != QUIC_NO_ERROR) { *error_details = "Missing AEAD or KEXS"; return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; } @@ -544,10 +541,11 @@ // Key exchange: the client does more work than the server, so favor the // client's preference. size_t key_exchange_index; - if (!FindMutualQuicTag(aead, their_aeads, num_their_aeads, &out_params->aead, - nullptr) || - !FindMutualQuicTag(kexs, their_key_exchanges, num_their_key_exchanges, - &out_params->key_exchange, &key_exchange_index)) { + if (!FindMutualQuicTag(aead, their_aeads.data(), their_aeads.size(), + &out_params->aead, nullptr) || + !FindMutualQuicTag(kexs, their_key_exchanges.data(), + their_key_exchanges.size(), &out_params->key_exchange, + &key_exchange_index)) { *error_details = "Unsupported AEAD or KEXS"; return QUIC_CRYPTO_NO_SUPPORT; } @@ -556,13 +554,13 @@ if (!tb_key_params.empty() && server_id.privacy_mode() == PRIVACY_MODE_DISABLED) { - const QuicTag* their_tbkps; - size_t num_their_tbkps; - switch (scfg->GetTaglist(kTBKP, &their_tbkps, &num_their_tbkps)) { + QuicTagVector their_tbkps; + switch (scfg->GetTaglist(kTBKP, &their_tbkps)) { case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND: break; case QUIC_NO_ERROR: - if (FindMutualQuicTag(tb_key_params, their_tbkps, num_their_tbkps, + if (FindMutualQuicTag(tb_key_params, their_tbkps.data(), + their_tbkps.size(), &out_params->token_binding_key_param, nullptr)) { out->SetVector(kTBKP, QuicTagVector{out_params->token_binding_key_param});
diff --git a/net/quic/core/crypto/quic_crypto_server_config.cc b/net/quic/core/crypto/quic_crypto_server_config.cc index f0f40a0..072085ea 100644 --- a/net/quic/core/crypto/quic_crypto_server_config.cc +++ b/net/quic/core/crypto/quic_crypto_server_config.cc
@@ -694,12 +694,8 @@ // No need to get a new proof if one was already generated. if (!signed_config->chain) { - const QuicTag* tag_ptr; - size_t num_tags; QuicTagVector connection_options; - if (client_hello.GetTaglist(kCOPT, &tag_ptr, &num_tags) == QUIC_NO_ERROR) { - connection_options.assign(tag_ptr, tag_ptr + num_tags); - } + client_hello.GetTaglist(kCOPT, &connection_options); std::unique_ptr<ProcessClientHelloCallback> cb( new ProcessClientHelloCallback( this, validate_chlo_result, reject_only, connection_id, @@ -790,39 +786,35 @@ return; } - const QuicTag* their_aeads; - const QuicTag* their_key_exchanges; - size_t num_their_aeads, num_their_key_exchanges; - if (client_hello.GetTaglist(kAEAD, &their_aeads, &num_their_aeads) != - QUIC_NO_ERROR || - client_hello.GetTaglist(kKEXS, &their_key_exchanges, - &num_their_key_exchanges) != QUIC_NO_ERROR || - num_their_aeads != 1 || num_their_key_exchanges != 1) { + QuicTagVector their_aeads; + QuicTagVector their_key_exchanges; + if (client_hello.GetTaglist(kAEAD, &their_aeads) != QUIC_NO_ERROR || + client_hello.GetTaglist(kKEXS, &their_key_exchanges) != QUIC_NO_ERROR || + their_aeads.size() != 1 || their_key_exchanges.size() != 1) { helper.Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, "Missing or invalid AEAD or KEXS"); return; } size_t key_exchange_index; - if (!FindMutualQuicTag(requested_config->aead, their_aeads, num_their_aeads, - ¶ms->aead, nullptr) || - !FindMutualQuicTag(requested_config->kexs, their_key_exchanges, - num_their_key_exchanges, ¶ms->key_exchange, + if (!FindMutualQuicTag(requested_config->aead, their_aeads.data(), + their_aeads.size(), ¶ms->aead, nullptr) || + !FindMutualQuicTag(requested_config->kexs, their_key_exchanges.data(), + their_key_exchanges.size(), ¶ms->key_exchange, &key_exchange_index)) { helper.Fail(QUIC_CRYPTO_NO_SUPPORT, "Unsupported AEAD or KEXS"); return; } if (!requested_config->tb_key_params.empty()) { - const QuicTag* their_tbkps; - size_t num_their_tbkps; - switch (client_hello.GetTaglist(kTBKP, &their_tbkps, &num_their_tbkps)) { + QuicTagVector their_tbkps; + switch (client_hello.GetTaglist(kTBKP, &their_tbkps)) { case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND: break; case QUIC_NO_ERROR: - if (FindMutualQuicTag(requested_config->tb_key_params, their_tbkps, - num_their_tbkps, ¶ms->token_binding_key_param, - nullptr)) { + if (FindMutualQuicTag(requested_config->tb_key_params, + their_tbkps.data(), their_tbkps.size(), + ¶ms->token_binding_key_param, nullptr)) { break; } default: @@ -1266,12 +1258,8 @@ Perspective::IS_SERVER); bool need_proof = true; need_proof = !signed_config->chain; - const QuicTag* tag_ptr; - size_t num_tags; QuicTagVector connection_options; - if (client_hello.GetTaglist(kCOPT, &tag_ptr, &num_tags) == QUIC_NO_ERROR) { - connection_options.assign(tag_ptr, tag_ptr + num_tags); - } + client_hello.GetTaglist(kCOPT, &connection_options); if (need_proof) { // Make an async call to GetProof and setup the callback to trampoline @@ -1623,31 +1611,24 @@ } config->id = scid.as_string(); - const QuicTag* aead_tags; - size_t aead_len; - if (msg->GetTaglist(kAEAD, &aead_tags, &aead_len) != QUIC_NO_ERROR) { + if (msg->GetTaglist(kAEAD, &config->aead) != QUIC_NO_ERROR) { QUIC_LOG(WARNING) << "Server config message is missing AEAD"; return nullptr; } - config->aead = std::vector<QuicTag>(aead_tags, aead_tags + aead_len); - const QuicTag* kexs_tags; - size_t kexs_len; - if (msg->GetTaglist(kKEXS, &kexs_tags, &kexs_len) != QUIC_NO_ERROR) { + QuicTagVector kexs_tags; + if (msg->GetTaglist(kKEXS, &kexs_tags) != QUIC_NO_ERROR) { QUIC_LOG(WARNING) << "Server config message is missing KEXS"; return nullptr; } - const QuicTag* tbkp_tags; - size_t tbkp_len; QuicErrorCode err; - if ((err = msg->GetTaglist(kTBKP, &tbkp_tags, &tbkp_len)) != + if ((err = msg->GetTaglist(kTBKP, &config->tb_key_params)) != QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND && err != QUIC_NO_ERROR) { QUIC_LOG(WARNING) << "Server config message is missing or has invalid TBKP"; return nullptr; } - config->tb_key_params = std::vector<QuicTag>(tbkp_tags, tbkp_tags + tbkp_len); QuicStringPiece orbit; if (!msg->GetStringPiece(kORBT, &orbit)) { @@ -1664,26 +1645,24 @@ static_assert(sizeof(config->orbit) == kOrbitSize, "incorrect orbit size"); memcpy(config->orbit, orbit.data(), sizeof(config->orbit)); - if (kexs_len != protobuf->key_size()) { - QUIC_LOG(WARNING) << "Server config has " << kexs_len + if (kexs_tags.size() != protobuf->key_size()) { + QUIC_LOG(WARNING) << "Server config has " << kexs_tags.size() << " key exchange methods configured, but " << protobuf->key_size() << " private keys"; return nullptr; } - const QuicTag* proof_demand_tags; - size_t num_proof_demand_tags; - if (msg->GetTaglist(kPDMD, &proof_demand_tags, &num_proof_demand_tags) == - QUIC_NO_ERROR) { - for (size_t i = 0; i < num_proof_demand_tags; i++) { - if (proof_demand_tags[i] == kCHID) { + QuicTagVector proof_demand_tags; + if (msg->GetTaglist(kPDMD, &proof_demand_tags) == QUIC_NO_ERROR) { + for (QuicTag tag : proof_demand_tags) { + if (tag == kCHID) { config->channel_id_enabled = true; break; } } } - for (size_t i = 0; i < kexs_len; i++) { + for (size_t i = 0; i < kexs_tags.size(); i++) { const QuicTag tag = kexs_tags[i]; string private_key; @@ -1941,18 +1920,15 @@ bool QuicCryptoServerConfig::ClientDemandsX509Proof( const CryptoHandshakeMessage& client_hello) const { - const QuicTag* their_proof_demands; - size_t num_their_proof_demands; + QuicTagVector their_proof_demands; - if (client_hello.GetTaglist(kPDMD, &their_proof_demands, - &num_their_proof_demands) != QUIC_NO_ERROR) { + if (client_hello.GetTaglist(kPDMD, &their_proof_demands) != QUIC_NO_ERROR) { return false; } - for (size_t i = 0; i < num_their_proof_demands; i++) { - switch (their_proof_demands[i]) { - case kX509: - return true; + for (const QuicTag tag : their_proof_demands) { + if (tag == kX509) { + return true; } } return false;
diff --git a/net/quic/core/crypto/quic_crypto_server_config_test.cc b/net/quic/core/crypto/quic_crypto_server_config_test.cc index 6c14076..381c82b 100644 --- a/net/quic/core/crypto/quic_crypto_server_config_test.cc +++ b/net/quic/core/crypto/quic_crypto_server_config_test.cc
@@ -39,10 +39,8 @@ // The default configuration should have AES-GCM and at least one ChaCha20 // cipher. - const QuicTag* aead_tags; - size_t aead_len; - ASSERT_EQ(QUIC_NO_ERROR, message->GetTaglist(kAEAD, &aead_tags, &aead_len)); - std::vector<QuicTag> aead(aead_tags, aead_tags + aead_len); + QuicTagVector aead; + ASSERT_EQ(QUIC_NO_ERROR, message->GetTaglist(kAEAD, &aead)); EXPECT_THAT(aead, ::testing::Contains(kAESG)); EXPECT_LE(1u, aead.size()); }
diff --git a/net/quic/core/quic_config.cc b/net/quic/core/quic_config.cc index 7453708..c6bab4f 100644 --- a/net/quic/core/quic_config.cc +++ b/net/quic/core/quic_config.cc
@@ -232,10 +232,8 @@ HelloType hello_type, string* error_details) { DCHECK(error_details != nullptr); - const QuicTag* received_tags; - size_t received_tags_length; - QuicErrorCode error = - peer_hello.GetTaglist(tag_, &received_tags, &received_tags_length); + QuicTagVector values; + QuicErrorCode error = peer_hello.GetTaglist(tag_, &values); switch (error) { case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND: if (presence_ == PRESENCE_OPTIONAL) { @@ -246,9 +244,8 @@ case QUIC_NO_ERROR: QUIC_DVLOG(1) << "Received Connection Option tags from receiver."; has_receive_values_ = true; - for (size_t i = 0; i < received_tags_length; ++i) { - receive_values_.push_back(received_tags[i]); - } + receive_values_.insert(receive_values_.end(), values.begin(), + values.end()); break; default: *error_details = "Bad " + QuicTagToString(tag_);
diff --git a/net/quic/core/quic_crypto_client_stream.cc b/net/quic/core/quic_crypto_client_stream.cc index 837ebeb..7f1cd9ef 100644 --- a/net/quic/core/quic_crypto_client_stream.cc +++ b/net/quic/core/quic_crypto_client_stream.cc
@@ -391,13 +391,11 @@ return; } - const uint32_t* reject_reasons; - size_t num_reject_reasons; + QuicTagVector reject_reasons; static_assert(sizeof(QuicTag) == sizeof(uint32_t), "header out of sync"); - if (in->GetTaglist(kRREJ, &reject_reasons, &num_reject_reasons) == - QUIC_NO_ERROR) { + if (in->GetTaglist(kRREJ, &reject_reasons) == QUIC_NO_ERROR) { uint32_t packed_error = 0; - for (size_t i = 0; i < num_reject_reasons; ++i) { + for (size_t i = 0; i < reject_reasons.size(); ++i) { // HANDSHAKE_OK is 0 and don't report that as error. if (reject_reasons[i] == HANDSHAKE_OK || reject_reasons[i] >= 32) { continue; @@ -663,14 +661,12 @@ if (!scfg) { // scfg may be null then we send an inchoate CHLO. return false; } - const QuicTag* their_proof_demands; - size_t num_their_proof_demands; - if (scfg->GetTaglist(kPDMD, &their_proof_demands, &num_their_proof_demands) != - QUIC_NO_ERROR) { + QuicTagVector their_proof_demands; + if (scfg->GetTaglist(kPDMD, &their_proof_demands) != QUIC_NO_ERROR) { return false; } - for (size_t i = 0; i < num_their_proof_demands; i++) { - if (their_proof_demands[i] == kCHID) { + for (const QuicTag tag : their_proof_demands) { + if (tag == kCHID) { return true; } }
diff --git a/net/quic/core/quic_crypto_server_stream.cc b/net/quic/core/quic_crypto_server_stream.cc index 6912d2f..61fbaab 100644 --- a/net/quic/core/quic_crypto_server_stream.cc +++ b/net/quic/core/quic_crypto_server_stream.cc
@@ -64,15 +64,13 @@ // static bool QuicCryptoServerStreamBase::DoesPeerSupportStatelessRejects( const CryptoHandshakeMessage& message) { - const QuicTag* received_tags; - size_t received_tags_length; - QuicErrorCode error = - message.GetTaglist(kCOPT, &received_tags, &received_tags_length); + QuicTagVector received_tags; + QuicErrorCode error = message.GetTaglist(kCOPT, &received_tags); if (error != QUIC_NO_ERROR) { return false; } - for (size_t i = 0; i < received_tags_length; ++i) { - if (received_tags[i] == kSREJ) { + for (const QuicTag tag : received_tags) { + if (tag == kSREJ) { return true; } }
diff --git a/net/tools/quic/stateless_rejector_test.cc b/net/tools/quic/stateless_rejector_test.cc index 190121cb..20fe8bc 100644 --- a/net/tools/quic/stateless_rejector_test.cc +++ b/net/tools/quic/stateless_rejector_test.cc
@@ -239,11 +239,9 @@ ASSERT_EQ(StatelessRejector::REJECTED, rejector_->state()); const CryptoHandshakeMessage& reply = rejector_->reply(); EXPECT_EQ(kSREJ, reply.tag()); - const uint32_t* reject_reasons; - size_t num_reject_reasons; - EXPECT_EQ(QUIC_NO_ERROR, - reply.GetTaglist(kRREJ, &reject_reasons, &num_reject_reasons)); - EXPECT_EQ(1u, num_reject_reasons); + QuicTagVector reject_reasons; + EXPECT_EQ(QUIC_NO_ERROR, reply.GetTaglist(kRREJ, &reject_reasons)); + EXPECT_EQ(1u, reject_reasons.size()); EXPECT_EQ(INVALID_EXPECTED_LEAF_CERTIFICATE, static_cast<HandshakeFailureReason>(reject_reasons[0])); }
diff --git a/third_party/expat/BUILD.gn b/third_party/expat/BUILD.gn index a2c2d0c..1ae296d 100644 --- a/third_party/expat/BUILD.gn +++ b/third_party/expat/BUILD.gn
@@ -33,6 +33,11 @@ public_configs = [ ":expat_config" ] + # TODO(thakis): Remove this once clang no longer crashes when building + # libexpat with -Oz. + configs -= [ "//build/config/compiler:default_optimization" ] + configs += [ "//build/config/compiler:optimize_max" ] + defines = [ "_LIB" ] if (is_win) { defines += [ "COMPILED_FROM_DSP" ]