|
44 | 44 | #include "google/protobuf/unittest_mset.pb.h" |
45 | 45 | #include "google/protobuf/unittest_mset_wire_format.pb.h" |
46 | 46 | #include "google/protobuf/unittest_proto3_extensions.pb.h" |
| 47 | +#include "google/protobuf/unittest_utf8_string_extensions.pb.h" |
47 | 48 | #include "google/protobuf/wire_format.h" |
48 | 49 | #include "google/protobuf/wire_format_lite.h" |
| 50 | +#include "utf8_validity.h" |
49 | 51 |
|
| 52 | +#include "google/protobuf/test_textproto.h" |
50 | 53 |
|
51 | 54 | // Must be included last. |
52 | 55 | #include "google/protobuf/port_def.inc" |
@@ -1975,6 +1978,55 @@ INSTANTIATE_TEST_SUITE_P( |
1975 | 1978 | return name; |
1976 | 1979 | }); |
1977 | 1980 |
|
| 1981 | +TEST(ExtensionSet, StringWithInvalidUTF8FailsToParse) { |
| 1982 | + // Sanity check that the extension field is marked as requiring UTF-8 |
| 1983 | + // validation. `requires_utf8_validation` can only be true for string fields |
| 1984 | + // where feature.utf8_validation = VERIFY. |
| 1985 | + const google::protobuf::DescriptorPool* pool = google::protobuf::DescriptorPool::generated_pool(); |
| 1986 | + ASSERT_NE(pool, nullptr); |
| 1987 | + const google::protobuf::FieldDescriptor* string_ext_fd = pool->FindExtensionByName( |
| 1988 | + "proto2_unittest.optional_utf8_string_extension"); |
| 1989 | + ASSERT_NE(string_ext_fd, nullptr); |
| 1990 | + ASSERT_TRUE(string_ext_fd->requires_utf8_validation()); |
| 1991 | + std::string invalid_utf8 = "\xFF"; |
| 1992 | + ASSERT_FALSE(utf8_range::IsStructurallyValid(invalid_utf8)); |
| 1993 | + |
| 1994 | + proto2_unittest::TestUtf8ValidationOfExtensions test_message; |
| 1995 | + // It is reasonable to debate that UTF-8 validation should be checked in the |
| 1996 | + // setter, but it is not currently done because the setter doesn't have a way |
| 1997 | + // to report errors. |
| 1998 | + test_message.SetExtension(proto2_unittest::optional_utf8_string_extension, |
| 1999 | + invalid_utf8); |
| 2000 | + std::string data; |
| 2001 | + ASSERT_TRUE(test_message.SerializeToString(&data)); |
| 2002 | + proto2_unittest::TestUtf8ValidationOfExtensions parsed_message; |
| 2003 | + ASSERT_FALSE(parsed_message.ParseFromString(data)); |
| 2004 | +} |
| 2005 | + |
| 2006 | +TEST(ExtensionSet, BytesWithInvalidUTF8Succeeds) { |
| 2007 | + // Sanity check that the extension field is not marked as requiring UTF-8 |
| 2008 | + // validation. `requires_utf8_validation` can only be true for string fields. |
| 2009 | + const google::protobuf::DescriptorPool* pool = google::protobuf::DescriptorPool::generated_pool(); |
| 2010 | + ASSERT_NE(pool, nullptr); |
| 2011 | + const google::protobuf::FieldDescriptor* string_ext_fd = |
| 2012 | + pool->FindExtensionByName("proto2_unittest.optional_bytes_extension"); |
| 2013 | + ASSERT_NE(string_ext_fd, nullptr); |
| 2014 | + ASSERT_FALSE(string_ext_fd->requires_utf8_validation()); |
| 2015 | + std::string invalid_utf8 = "\xFF"; |
| 2016 | + ASSERT_FALSE(utf8_range::IsStructurallyValid(invalid_utf8)); |
| 2017 | + |
| 2018 | + proto2_unittest::TestAllExtensions test_message; |
| 2019 | + test_message.SetExtension(proto2_unittest::optional_bytes_extension, |
| 2020 | + invalid_utf8); |
| 2021 | + std::string data; |
| 2022 | + ASSERT_TRUE(test_message.SerializeToString(&data)); |
| 2023 | + proto2_unittest::TestAllExtensions parsed_message; |
| 2024 | + EXPECT_TRUE(parsed_message.ParseFromString(data)); |
| 2025 | + EXPECT_THAT(parsed_message, google::protobuf::EqualsProto(R"pb( |
| 2026 | + [proto2_unittest.optional_bytes_extension]: "\xFF" |
| 2027 | + )pb")); |
| 2028 | +} |
| 2029 | + |
1978 | 2030 | } // namespace |
1979 | 2031 | } // namespace internal |
1980 | 2032 | } // namespace protobuf |
|
0 commit comments