Explicitly cast QuicIetfTransportErrorCodes to uint16_t when forwarded to QuicStrCat. Otherwise, if a QuicIetfTransportErrorCodes is forwarded to QuicStrCat, chromium QuicStrCatImpl will call operator << on QuicIetfTransportErrorCodes again, which introduces an infinite loop. gfe-relnote: n/a Version 99 only. PiperOrigin-RevId: 266411556 Change-Id: Idfb7956effb9c512869ec77f857df4be64d32227
diff --git a/quic/core/quic_types.cc b/quic/core/quic_types.cc index a7453e8..46f809d 100644 --- a/quic/core/quic_types.cc +++ b/quic/core/quic_types.cc
@@ -4,6 +4,8 @@ #include "net/third_party/quiche/src/quic/core/quic_types.h" +#include <cstdint> + #include "net/third_party/quiche/src/quic/platform/api/quic_str_cat.h" namespace quic { @@ -83,7 +85,7 @@ std::string QuicIetfTransportErrorCodeString(QuicIetfTransportErrorCodes c) { if (static_cast<uint16_t>(c) >= 0xff00u) { - return QuicStrCat("Private value: ", c); + return QuicStrCat("Private value: ", static_cast<uint16_t>(c)); } switch (c) { @@ -100,7 +102,8 @@ RETURN_STRING_LITERAL(PROTOCOL_VIOLATION); RETURN_STRING_LITERAL(INVALID_MIGRATION); default: - return QuicStrCat("Unknown Transport Error Code Value: ", c); + return QuicStrCat("Unknown Transport Error Code Value: ", + static_cast<uint16_t>(c)); } }
diff --git a/quic/core/quic_types_test.cc b/quic/core/quic_types_test.cc new file mode 100644 index 0000000..8b4df89 --- /dev/null +++ b/quic/core/quic_types_test.cc
@@ -0,0 +1,40 @@ +// Copyright (c) 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/third_party/quiche/src/quic/core/quic_types.h" + +#include <cstdint> + +#include "net/third_party/quiche/src/quic/platform/api/quic_str_cat.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_test.h" + +namespace quic { +namespace test { +namespace { + +class QuicUtilsTest : public QuicTest {}; + +TEST_F(QuicUtilsTest, QuicIetfTransportErrorCodeString) { + // QuicIetfTransportErrorCode out of bound. + for (quic::QuicErrorCode error = quic::QUIC_ENCRYPTION_FAILURE; + error < quic::QUIC_LAST_ERROR; + error = static_cast<quic::QuicErrorCode>(error + 1)) { + QuicErrorCodeToIetfMapping mapping = + QuicErrorCodeToTransportErrorCode(error); + if (mapping.is_transport_close_) { + EXPECT_EQ( + QuicIetfTransportErrorCodeString(mapping.transport_error_code_), + QuicStrCat("Unknown Transport Error Code Value: ", + static_cast<uint16_t>(mapping.transport_error_code_))); + } else { + // Some QuicErrorCodes are no longer valid. + EXPECT_EQ(QuicIetfTransportErrorCodeString(mapping.transport_error_code_), + "NO_IETF_QUIC_ERROR"); + } + } +} + +} // namespace +} // namespace test +} // namespace quic