49
49
# include <google/protobuf/stubs/casts.h>
50
50
# include <google/protobuf/stubs/strutil.h>
51
51
# include <google/protobuf/stubs/stl_util.h>
52
+ # include <google/protobuf/dynamic_message.h>
52
53
53
54
// clang-format off
54
55
# include <google/protobuf/port_def.inc>
@@ -580,28 +581,54 @@ TEST(WireFormatTest, ParseMessageSet) {
580
581
EXPECT_EQ (message_set.DebugString (), dynamic_message_set.DebugString ());
581
582
}
582
583
583
- TEST (WireFormatTest, ParseMessageSetWithReverseTagOrder) {
584
+ namespace {
585
+ std ::string BuildMessageSetItemStart () {
584
586
std ::string data;
585
587
{
586
- UNITTEST ::TestMessageSetExtension1 message;
587
- message.set_i (123 );
588
- // Build a MessageSet manually with its message content put before its
589
- // type_id.
590
588
io ::StringOutputStream output_stream (& data);
591
589
io ::CodedOutputStream coded_output (& output_stream);
592
590
coded_output.WriteTag (WireFormatLite ::kMessageSetItemStartTag);
591
+ }
592
+ return data;
593
+ }
594
+ std ::string BuildMessageSetItemEnd () {
595
+ std ::string data;
596
+ {
597
+ io ::StringOutputStream output_stream (& data);
598
+ io ::CodedOutputStream coded_output (& output_stream);
599
+ coded_output.WriteTag (WireFormatLite ::kMessageSetItemEndTag);
600
+ }
601
+ return data;
602
+ }
603
+ std ::string BuildMessageSetTestExtension1 (int value = 123 ) {
604
+ std ::string data;
605
+ {
606
+ UNITTEST ::TestMessageSetExtension1 message;
607
+ message.set_i (value);
608
+ io ::StringOutputStream output_stream (& data);
609
+ io ::CodedOutputStream coded_output (& output_stream);
593
610
// Write the message content first.
594
611
WireFormatLite ::WriteTag (WireFormatLite ::kMessageSetMessageNumber,
595
612
WireFormatLite ::WIRETYPE_LENGTH_DELIMITED,
596
613
& coded_output);
597
614
coded_output.WriteVarint32 (message.ByteSizeLong ());
598
615
message.SerializeWithCachedSizes (& coded_output);
599
- // Write the type id.
600
- uint32 type_id = message.GetDescriptor ()- > extension (0 )- > number ();
616
+ }
617
+ return data;
618
+ }
619
+ std ::string BuildMessageSetItemTypeId (int extension_number) {
620
+ std ::string data;
621
+ {
622
+ io ::StringOutputStream output_stream (& data);
623
+ io ::CodedOutputStream coded_output (& output_stream);
601
624
WireFormatLite ::WriteUInt32 (WireFormatLite ::kMessageSetTypeIdNumber,
602
- type_id, & coded_output);
603
- coded_output.WriteTag (WireFormatLite ::kMessageSetItemEndTag);
625
+ extension_number, & coded_output);
604
626
}
627
+ return data;
628
+ }
629
+ void ValidateTestMessageSet (const std ::string& test_case,
630
+ const std ::string& data) {
631
+ SCOPED_TRACE (test_case);
605
632
{
606
633
PROTO2_WIREFORMAT_UNITTEST ::TestMessageSet message_set;
607
634
ASSERT_TRUE (message_set.ParseFromString (data));
@@ -611,6 +638,11 @@ TEST(WireFormatTest, ParseMessageSetWithReverseTagOrder) {
611
638
.GetExtension (
612
639
UNITTEST ::TestMessageSetExtension1 ::message_set_extension)
613
640
.i ());
641
+
642
+ // Make sure it does not contain anything else.
643
+ message_set.ClearExtension (
644
+ UNITTEST ::TestMessageSetExtension1 ::message_set_extension);
645
+ EXPECT_EQ (message_set.SerializeAsString (), " " );
614
646
}
615
647
{
616
648
// Test parse the message via Reflection.
@@ -626,6 +658,61 @@ TEST(WireFormatTest, ParseMessageSetWithReverseTagOrder) {
626
658
UNITTEST ::TestMessageSetExtension1 ::message_set_extension)
627
659
.i ());
628
660
}
661
+ {
662
+ // Test parse the message via DynamicMessage.
663
+ DynamicMessageFactory factory;
664
+ std ::unique_ptr< Message> msg (
665
+ factory
666
+ .GetPrototype (
667
+ PROTO2_WIREFORMAT_UNITTEST ::TestMessageSet ::descriptor ())
668
+ - > New ());
669
+ msg- > ParseFromString (data);
670
+ auto* reflection = msg- > GetReflection ();
671
+ std ::vector< const FieldDescriptor* > fields;
672
+ reflection- > ListFields (* msg, & fields);
673
+ ASSERT_EQ (fields.size (), 1 );
674
+ const auto& sub = reflection- > GetMessage (* msg, fields[0 ]);
675
+ reflection = sub.GetReflection ();
676
+ EXPECT_EQ (123 , reflection- > GetInt32 (
677
+ sub, sub.GetDescriptor ()- > FindFieldByName (" i" )));
678
+ }
679
+ }
680
+ } // namespace
681
+
682
+ TEST (WireFormatTest, ParseMessageSetWithAnyTagOrder) {
683
+ std ::string start = BuildMessageSetItemStart ();
684
+ std ::string end = BuildMessageSetItemEnd ();
685
+ std ::string id = BuildMessageSetItemTypeId (
686
+ UNITTEST ::TestMessageSetExtension1 ::descriptor ()- > extension (0 )- > number ());
687
+ std ::string message = BuildMessageSetTestExtension1 ();
688
+
689
+ ValidateTestMessageSet (" id + message" , start + id + message + end);
690
+ ValidateTestMessageSet (" message + id" , start + message + id + end);
691
+ }
692
+
693
+ TEST (WireFormatTest, ParseMessageSetWithDuplicateTags) {
694
+ std ::string start = BuildMessageSetItemStart ();
695
+ std ::string end = BuildMessageSetItemEnd ();
696
+ std ::string id = BuildMessageSetItemTypeId (
697
+ UNITTEST ::TestMessageSetExtension1 ::descriptor ()- > extension (0 )- > number ());
698
+ std ::string other_id = BuildMessageSetItemTypeId (123456 );
699
+ std ::string message = BuildMessageSetTestExtension1 ();
700
+ std ::string other_message = BuildMessageSetTestExtension1 (321 );
701
+
702
+ // Double id
703
+ ValidateTestMessageSet (" id + other_id + message" ,
704
+ start + id + other_id + message + end);
705
+ ValidateTestMessageSet (" id + message + other_id" ,
706
+ start + id + message + other_id + end);
707
+ ValidateTestMessageSet (" message + id + other_id" ,
708
+ start + message + id + other_id + end);
709
+ // Double message
710
+ ValidateTestMessageSet (" id + message + other_message" ,
711
+ start + id + message + other_message + end);
712
+ ValidateTestMessageSet (" message + id + other_message" ,
713
+ start + message + id + other_message + end);
714
+ ValidateTestMessageSet (" message + other_message + id" ,
715
+ start + message + other_message + id + end);
629
716
}
630
717
631
718
void SerializeReverseOrder (
0 commit comments