diff --git a/src/google/protobuf/io/tokenizer.cc b/src/google/protobuf/io/tokenizer.cc index 6dc7d434f6d3d..4bf3efc84d40f 100644 --- a/src/google/protobuf/io/tokenizer.cc +++ b/src/google/protobuf/io/tokenizer.cc @@ -1177,7 +1177,9 @@ void Tokenizer::ParseStringAppend(const std::string& text, // downsize the output. const size_t new_len = text_size + output->size(); if (new_len > output->capacity()) { - output->reserve(new_len); + // Make sure to use amortized growth if we already have a value. + output->reserve( + output->empty() ? new_len : std::max(new_len, output->capacity() * 2)); } // Loop through the string copying characters to "output" and diff --git a/src/google/protobuf/text_format_unittest.cc b/src/google/protobuf/text_format_unittest.cc index 109257a2dc66f..28e84086e2c46 100644 --- a/src/google/protobuf/text_format_unittest.cc +++ b/src/google/protobuf/text_format_unittest.cc @@ -84,7 +84,9 @@ using ::absl_testing::StatusIs; using ::google::protobuf::internal::UnsetFieldsMetadataTextFormatTestUtil; using ::testing::_; using ::testing::AllOf; +using ::testing::Gt; using ::testing::HasSubstr; +using ::testing::Lt; using ::testing::UnorderedElementsAre; absl::string_view GetSubstring(absl::string_view input, @@ -1391,6 +1393,7 @@ TEST_F(TextFormatTest, ParseConcatenatedString) { EXPECT_EQ("foobar", proto_.optional_string()); } + TEST_F(TextFormatTest, ParseFloatWithSuffix) { // Test that we can parse a floating-point value with 'f' appended to the // end. This is needed for backwards-compatibility with proto1.