Fix bool parser for map entries to look at the whole 64-bit varint and not just
the first 32 bits.
This is the expected narrowing for bool fields.
PiperOrigin-RevId: 504338621
diff --git a/src/google/protobuf/map_test.inc b/src/google/protobuf/map_test.inc
index 14146d8..6d1a70c 100644
--- a/src/google/protobuf/map_test.inc
+++ b/src/google/protobuf/map_test.inc
@@ -76,6 +76,9 @@
// Must be included last.
#include "google/protobuf/port_def.inc"
+using ::testing::ElementsAre;
+using ::testing::Pair;
+
namespace google {
namespace protobuf {
@@ -3639,6 +3642,35 @@
}
}
+std::string WriteVarint(int number, uint64_t v) {
+ uint8_t buf[16];
+ return std::string(buf, WireFormatLite::WriteUInt64ToArray(number, v, buf));
+}
+
+std::string WriteString(int number, const std::string& str) {
+ uint8_t buf[100];
+ return std::string(buf, WireFormatLite::WriteStringToArray(number, str, buf));
+}
+
+TEST(WireFormatForMapFieldTest, BoolWorksWithOverlongValues) {
+ // map<bool, bool> map_bool_bool = 13;
+ for (uint64_t v : {uint64_t{1}, uint64_t{1000}, uint64_t{100000},
+ uint64_t{1} << 32, uint64_t{1} << 63}) {
+ SCOPED_TRACE(v);
+ std::string payload =
+ WriteString(13, WriteVarint(1, v) + WriteVarint(2, v));
+ UNITTEST::TestMap obj;
+ ASSERT_TRUE(obj.ParseFromString(payload));
+ EXPECT_THAT(obj.map_bool_bool(), ElementsAre(Pair(true, true)));
+
+ io::ArrayInputStream raw_input(payload.data(), payload.size());
+ io::CodedInputStream input(&raw_input);
+ obj.Clear();
+ ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &obj));
+ EXPECT_THAT(obj.map_bool_bool(), ElementsAre(Pair(true, true)));
+ }
+}
+
// Deterministic Serialization Test ==========================================
template <typename T>
diff --git a/src/google/protobuf/map_type_handler.h b/src/google/protobuf/map_type_handler.h
index 8979734..2017cb1 100644
--- a/src/google/protobuf/map_type_handler.h
+++ b/src/google/protobuf/map_type_handler.h
@@ -434,7 +434,7 @@
return ptr;
}
inline const char* ReadBOOL(const char* ptr, bool* value) {
- *value = static_cast<bool>(ReadVarint32(&ptr));
+ *value = static_cast<bool>(ReadVarint64(&ptr));
return ptr;
}