Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions port/protobuf.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,51 @@ namespace protobuf_mutator {

namespace protobuf = google::protobuf;

inline bool RequiresUtf8Validation(
const google::protobuf::FieldDescriptor& descriptor) {
// commit d8c2501b43c1b56e3efa74048a18f8ce06ba07fe of >= v3.22.0
#if GOOGLE_PROTOBUF_VERSION >= 4022000
return descriptor.requires_utf8_validation();
#else
return descriptor.type() == google::protobuf::FieldDescriptor::TYPE_STRING &&
descriptor.file()->syntax() ==
google::protobuf::FileDescriptor::SYNTAX_PROTO3;
#endif
}

inline bool HasPresence(const google::protobuf::FieldDescriptor& descriptor) {
// commit bb30225f06c36399757dc698b409d5f79738e8d1 of >=3.12.0
#if GOOGLE_PROTOBUF_VERSION >= 3012000
return descriptor.has_presence();
#else
// NOTE: This mimics Protobuf 3.21.12 ("3021012")
return !descriptor.is_repeated() &&
(descriptor.cpp_type() ==
google::protobuf::FieldDescriptor::CppType::CPPTYPE_MESSAGE ||
descriptor.containing_oneof() ||
descriptor.file()->syntax() ==
google::protobuf::FileDescriptor::SYNTAX_PROTO2);
#endif
}

inline void PrepareTextParser(google::protobuf::TextFormat::Parser& parser) {
// commit d8c2501b43c1b56e3efa74048a18f8ce06ba07fe of >=3.8.0
#if GOOGLE_PROTOBUF_VERSION >= 3008000
parser.SetRecursionLimit(100);
parser.AllowUnknownField(true);
#endif
}

constexpr bool TextParserCanSetRecursionLimit() {
// commit d8c2501b43c1b56e3efa74048a18f8ce06ba07fe of >=3.8.0
return GOOGLE_PROTOBUF_VERSION >= 3008000;
}

constexpr bool TextParserCanAllowUnknownField() {
// commit 176f7db11d8242b36a3ea6abb1cc436fca5bf75d of >=3.8.0
return GOOGLE_PROTOBUF_VERSION >= 3008000;
}

} // namespace protobuf_mutator

#endif // PORT_PROTOBUF_H_
10 changes: 1 addition & 9 deletions src/field_instance.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,15 +190,7 @@ class ConstFieldInstance {
return descriptor_->message_type();
}

bool EnforceUtf8() const {
#if GOOGLE_PROTOBUF_VERSION >= 4022000 // v3(!).22.0 (commit d85c9944c55fb38f4eae149979a0f680ea125ecb) for requires_utf8_validation
return descriptor_->requires_utf8_validation();
#else
return descriptor_->type() == protobuf::FieldDescriptor::TYPE_STRING &&
descriptor()->file()->syntax() ==
protobuf::FileDescriptor::SYNTAX_PROTO3;
#endif
}
bool EnforceUtf8() const { return RequiresUtf8Validation(*descriptor_); }

const protobuf::FieldDescriptor* descriptor() const { return descriptor_; }

Expand Down
26 changes: 3 additions & 23 deletions src/mutator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -87,17 +87,7 @@ bool GetRandomBool(RandomEngine* random, size_t n = 2) {
}

bool IsProto3SimpleField(const FieldDescriptor& field) {
#if GOOGLE_PROTOBUF_VERSION >= 3012000 // commit bb30225f06c36399757dc698b409d5f79738e8d1 of >=3.12.0
const bool has_presence = field.has_presence();
#else
// NOTE: This mimics Protobuf 3.21.12 ("3021012")
const bool has_presence = ! field.is_repeated() && (
field.cpp_type() == FieldDescriptor::CppType::CPPTYPE_MESSAGE
|| field.containing_oneof()
|| field.file()->syntax() == FileDescriptor::SYNTAX_PROTO2
);
#endif
return !field.is_repeated() && !has_presence;
return !field.is_repeated() && !HasPresence(field);
}

struct CreateDefaultField : public FieldFunction<CreateDefaultField> {
Expand Down Expand Up @@ -390,23 +380,13 @@ std::unique_ptr<Message> UnpackAny(const Any& any) {
}

const Any* CastToAny(const Message* message) {
#if GOOGLE_PROTOBUF_VERSION >= 3008000 // commit 1467e08d7c26a7087e5e5b14a4ab2755926e7249 of >=3.8.0
const Descriptor* any_descriptor = Any::GetDescriptor();
#else
const Descriptor* any_descriptor = Any::descriptor();
#endif
return any_descriptor == message->GetDescriptor()
return Any::descriptor() == message->GetDescriptor()
? protobuf::DownCastMessage<Any>(message)
: nullptr;
}

Any* CastToAny(Message* message) {
#if GOOGLE_PROTOBUF_VERSION >= 3008000 // commit 1467e08d7c26a7087e5e5b14a4ab2755926e7249 of >=3.8.0
const Descriptor* any_descriptor = Any::GetDescriptor();
#else
const Descriptor* any_descriptor = Any::descriptor();
#endif
return any_descriptor == message->GetDescriptor()
return Any::descriptor() == message->GetDescriptor()
? protobuf::DownCastMessage<Any>(message)
: nullptr;
}
Expand Down
10 changes: 4 additions & 6 deletions src/mutator_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -678,18 +678,16 @@ TYPED_TEST(MutatorTypedTest, Serialization) {
}

TYPED_TEST(MutatorTypedTest, UnknownFieldTextFormat) {
#if GOOGLE_PROTOBUF_VERSION < 3008000 // commit 176f7db11d8242b36a3ea6abb1cc436fca5bf75d of >=3.8.0
GTEST_SKIP() << "TextFormat::Parser::AllowUnknownField() is not available";
#endif // GOOGLE_PROTOBUF_VERSION
if (!TextParserCanAllowUnknownField())
GTEST_SKIP() << "TextFormat::Parser::AllowUnknownField() is not available";
typename TestFixture::Message parsed;
EXPECT_TRUE(ParseTextMessage(kUnknownFieldInput, &parsed));
EXPECT_EQ(SaveMessageAsText(parsed), kUnknownFieldExpected);
}

TYPED_TEST(MutatorTypedTest, DeepRecursion) {
#if GOOGLE_PROTOBUF_VERSION < 3008000 // commit d8c2501b43c1b56e3efa74048a18f8ce06ba07fe of >=3.8.0
GTEST_SKIP() << "TextFormat::Parser::SetRecursionLimit() is not available";
#endif // GOOGLE_PROTOBUF_VERSION
if (!TextParserCanSetRecursionLimit())
GTEST_SKIP() << "TextFormat::Parser::SetRecursionLimit() is not available";
typename TestFixture::Message message;
typename TestFixture::Message* last = &message;
for (int i = 0; i < 150; ++i) {
Expand Down
7 changes: 1 addition & 6 deletions src/text_format.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,8 @@ bool ParseTextMessage(const uint8_t* data, size_t size, Message* output) {
bool ParseTextMessage(const std::string& data, protobuf::Message* output) {
output->Clear();
TextFormat::Parser parser;
#if GOOGLE_PROTOBUF_VERSION >= 3008000 // commit d8c2501b43c1b56e3efa74048a18f8ce06ba07fe of >=3.8.0
parser.SetRecursionLimit(100);
#endif
parser.AllowPartialMessage(true);
#if GOOGLE_PROTOBUF_VERSION >= 3008000 // commit 176f7db11d8242b36a3ea6abb1cc436fca5bf75d of >=3.8.0
parser.AllowUnknownField(true);
#endif
PrepareTextParser(parser);
if (!parser.ParseFromString(data, output)) {
output->Clear();
return false;
Expand Down
Loading