Skip to content

Commit 08355bd

Browse files
protobuf-github-botJasonLunn
authored andcommitted
Improve wire compatibility of TestAllTypes with TestAllExtensions.
1. Refactor fields that exercises UTF-8 validation into a dedicated message 1. Reserve some field numbers in `TestAllTypes` that are used by nested extensions. PiperOrigin-RevId: 861188481
1 parent 659e0f3 commit 08355bd

File tree

3 files changed

+359
-6
lines changed

3 files changed

+359
-6
lines changed

src/google/protobuf/unittest.proto

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ option java_outer_classname = "UnittestProto";
4343

4444
// This proto includes every type of field in both singular and repeated
4545
// forms.
46+
// Warning: Many tests make assume about the number of fields in TestAllTypes,
47+
// including assumptions about wire compatibility of overlay messages.
48+
// Take care when adding or modifying fields in this message to check
49+
// TGP results and fix any issues.
4650
message TestAllTypes {
4751
message NestedMessage {
4852
// The field name "b" fails to compile in proto1 because it conflicts with
@@ -252,6 +256,9 @@ message TestAllTypes {
252256
lazy = true
253257
];
254258
}
259+
260+
// Field numbers used by TestAllExtensions.
261+
reserved 1001, 1002, 1003;
255262
}
256263

257264
// This proto includes a recursively nested message.
@@ -327,6 +334,10 @@ message TestAllExtensions {
327334
extensions 1 to max;
328335
}
329336

337+
// Warning: some tests assume that TestAllTypes and TestAllExtensions are
338+
// wire compatible. Take care when adding or modifying fields in this message
339+
// to add a corresponding field in TestAllTypes and vice versa, ensuring that
340+
// they have the same field number and have compatible wire formats.
330341
extend TestAllExtensions {
331342
// Singular
332343
int32 optional_int32_extension = 1;
@@ -501,12 +512,9 @@ extend TestAllExtensions {
501512
string oneof_string_extension = 113;
502513
bytes oneof_bytes_extension = 114;
503514

504-
string optional_utf8_string_extension = 115 [
505-
features.utf8_validation = VERIFY
506-
];
507-
repeated string repeated_utf8_string_extension = 116 [
508-
features.utf8_validation = VERIFY
509-
];
515+
// Don't use field numbers 115 through 117, they are used by
516+
// TestAllTypes.oneof_field. Use of 117 below for TestRequired (rather than
517+
// TestAllTypes.NestedMessage) is a bug and should be fixed.
510518

511519
// Singular message containing required fields; used to test initialization.
512520
TestRequired required_message_extension = 117;
Lines changed: 329 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,329 @@
1+
edition = "2024";
2+
3+
package fuzz_unittest;
4+
5+
import "google/protobuf/cpp_features.proto";
6+
import "google/protobuf/unittest_import.proto";
7+
8+
option features = { enum_type : CLOSED repeated_field_encoding : EXPANDED utf8_validation : NONE };
9+
10+
// Protos optimized for SPEED use a strict superset of the generated code
11+
// of equivalent ones optimized for CODE_SIZE, so we should optimize all our
12+
// tests for speed unless explicitly testing code size optimization.
13+
option optimize_for = SPEED;
14+
15+
// This proto includes every type of field in both singular and repeated
16+
// forms.
17+
// Warning: This test is used by a fuzz test that requires the invariant that
18+
// FuzzMostTypes and FuzzMostExtensions are strictly wire-compatible, meaning:
19+
// 1. *Any* random bytes that can be parsed successfully by one can be parsed by
20+
// the other. This means that any submessage fields must be have the same
21+
// field numbers and message types in both protos.
22+
// 2. If parsing is successful, the resulting messages are identical. This means
23+
// that oneofs cannot be used, since oneofs cannot be extensions, and thus if
24+
// multiples fields from the same oneof are parsed, the messages will not be
25+
// identical, even if the field numbers are the same and the field types are
26+
// compatible.
27+
message FuzzMostTypes {
28+
message NestedMessage {
29+
int32 bb = 1;
30+
}
31+
32+
enum NestedEnum {
33+
FOO = 1;
34+
BAR = 2;
35+
BAZ = 3;
36+
NEG = -1; // Intentionally negative.
37+
}
38+
39+
// Singular
40+
int32 optional_int32 = 1;
41+
int64 optional_int64 = 2;
42+
uint32 optional_uint32 = 3;
43+
uint64 optional_uint64 = 4;
44+
sint32 optional_sint32 = 5;
45+
sint64 optional_sint64 = 6;
46+
fixed32 optional_fixed32 = 7;
47+
fixed64 optional_fixed64 = 8;
48+
sfixed32 optional_sfixed32 = 9;
49+
sfixed64 optional_sfixed64 = 10;
50+
float optional_float = 11;
51+
double optional_double = 12;
52+
bool optional_bool = 13;
53+
string optional_string = 14;
54+
bytes optional_bytes = 15;
55+
56+
message OptionalGroup {
57+
int32 a = 17;
58+
}
59+
60+
OptionalGroup optionalgroup = 16 [features.message_encoding = DELIMITED];
61+
62+
NestedMessage optional_nested_message = 18;
63+
ForeignMessage optional_foreign_message = 19;
64+
proto2_unittest_import.ImportMessage optional_import_message = 20;
65+
NestedEnum optional_nested_enum = 21;
66+
ForeignEnum optional_foreign_enum = 22;
67+
proto2_unittest_import.ImportEnum optional_import_enum = 23;
68+
69+
string optional_cord = 25 [features.(pb.cpp).string_type = CORD];
70+
bytes optional_bytes_cord = 86 [features.(pb.cpp).string_type = CORD];
71+
72+
// Defined in unittest_import_public.proto
73+
proto2_unittest_import.PublicImportMessage optional_public_import_message =
74+
26;
75+
NestedMessage optional_lazy_message = 27 [lazy = true];
76+
77+
// Repeated
78+
repeated int32 repeated_int32 = 31;
79+
repeated int64 repeated_int64 = 32;
80+
repeated uint32 repeated_uint32 = 33;
81+
repeated uint64 repeated_uint64 = 34;
82+
repeated sint32 repeated_sint32 = 35;
83+
repeated sint64 repeated_sint64 = 36;
84+
repeated fixed32 repeated_fixed32 = 37;
85+
repeated fixed64 repeated_fixed64 = 38;
86+
repeated sfixed32 repeated_sfixed32 = 39;
87+
repeated sfixed64 repeated_sfixed64 = 40;
88+
repeated float repeated_float = 41;
89+
repeated double repeated_double = 42;
90+
repeated bool repeated_bool = 43;
91+
repeated string repeated_string = 44;
92+
repeated bytes repeated_bytes = 45;
93+
94+
message RepeatedGroup {
95+
int32 a = 47;
96+
}
97+
98+
repeated RepeatedGroup repeatedgroup = 46
99+
[features.message_encoding = DELIMITED];
100+
101+
repeated NestedMessage repeated_nested_message = 48;
102+
repeated ForeignMessage repeated_foreign_message = 49;
103+
repeated proto2_unittest_import.ImportMessage repeated_import_message = 50;
104+
repeated NestedEnum repeated_nested_enum = 51;
105+
repeated ForeignEnum repeated_foreign_enum = 52;
106+
repeated proto2_unittest_import.ImportEnum repeated_import_enum = 53;
107+
108+
repeated string repeated_cord = 55 [features.(pb.cpp).string_type = CORD];
109+
110+
// Singular with defaults
111+
int32 default_int32 = 61 [default = 41];
112+
113+
int64 default_int64 = 62 [default = 42];
114+
115+
uint32 default_uint32 = 63 [default = 43];
116+
117+
uint64 default_uint64 = 64 [default = 44];
118+
119+
sint32 default_sint32 = 65 [default = -45];
120+
121+
sint64 default_sint64 = 66 [default = 46];
122+
123+
fixed32 default_fixed32 = 67 [default = 47];
124+
125+
fixed64 default_fixed64 = 68 [default = 48];
126+
127+
sfixed32 default_sfixed32 = 69 [default = 49];
128+
129+
sfixed64 default_sfixed64 = 70 [default = -50];
130+
131+
float default_float = 71 [default = 51.5];
132+
133+
double default_double = 72 [default = 5.2e4];
134+
135+
bool default_bool = 73 [default = true];
136+
137+
string default_string = 74 [default = "hello"];
138+
139+
bytes default_bytes = 75 [default = "world"];
140+
141+
NestedEnum default_nested_enum = 81 [default = BAR];
142+
143+
ForeignEnum default_foreign_enum = 82 [default = FOREIGN_BAR];
144+
145+
proto2_unittest_import.ImportEnum default_import_enum = 83
146+
[default = IMPORT_BAR];
147+
148+
string default_cord = 85
149+
[features.(pb.cpp).string_type = CORD, default = "123"];
150+
151+
string optional_utf8_string = 90 [features.utf8_validation = VERIFY];
152+
repeated string repeated_utf8_string = 91 [features.utf8_validation = VERIFY];
153+
154+
TestRequired single = 1000;
155+
repeated TestRequired multi = 1001;
156+
string test = 1002 [default = "test"];
157+
string nested_string = 1003;
158+
}
159+
160+
message ForeignMessage {
161+
int32 c = 1;
162+
int32 d = 2;
163+
}
164+
165+
enum ForeignEnum {
166+
FOREIGN_FOO = 4;
167+
FOREIGN_BAR = 5;
168+
FOREIGN_BAZ = 6;
169+
FOREIGN_BAX = 32; // (1 << 32) to generate a 64b bitmask would be incorrect.
170+
FOREIGN_LARGE = 123456; // Large enough to escape the Boxed Integer cache.
171+
}
172+
173+
message FuzzMostExtensions {
174+
extensions 1 to max;
175+
}
176+
177+
// Warning: FuzzMostTypes and FuzzMostExtensions must be kept strictly
178+
// wire compatible. See the warning on FuzzMostTypes for more details.
179+
extend FuzzMostExtensions {
180+
// Singular
181+
int32 optional_int32_extension = 1;
182+
int64 optional_int64_extension = 2;
183+
uint32 optional_uint32_extension = 3;
184+
uint64 optional_uint64_extension = 4;
185+
sint32 optional_sint32_extension = 5;
186+
sint64 optional_sint64_extension = 6;
187+
fixed32 optional_fixed32_extension = 7;
188+
fixed64 optional_fixed64_extension = 8;
189+
sfixed32 optional_sfixed32_extension = 9;
190+
sfixed64 optional_sfixed64_extension = 10;
191+
float optional_float_extension = 11;
192+
double optional_double_extension = 12;
193+
bool optional_bool_extension = 13;
194+
string optional_string_extension = 14;
195+
bytes optional_bytes_extension = 15;
196+
OptionalGroupExtension optional_group_extension = 16
197+
[features.message_encoding = DELIMITED];
198+
199+
FuzzMostTypes.NestedMessage optional_nested_message_extension = 18;
200+
ForeignMessage optional_foreign_message_extension = 19;
201+
proto2_unittest_import.ImportMessage optional_import_message_extension = 20;
202+
FuzzMostTypes.NestedEnum optional_nested_enum_extension = 21;
203+
ForeignEnum optional_foreign_enum_extension = 22;
204+
proto2_unittest_import.ImportEnum optional_import_enum_extension = 23;
205+
206+
// TODO: features.(pb.cpp).string_type=CORD is not supported for
207+
// extension. Add features.(pb.cpp).string_type=CORD option back after it is
208+
// supported.
209+
string optional_cord_extension = 25;
210+
bytes optional_bytes_cord_extension = 86;
211+
212+
proto2_unittest_import.PublicImportMessage
213+
optional_public_import_message_extension = 26;
214+
FuzzMostTypes.NestedMessage optional_lazy_message_extension = 27
215+
[lazy = true];
216+
217+
// Repeated
218+
repeated int32 repeated_int32_extension = 31;
219+
repeated int64 repeated_int64_extension = 32;
220+
repeated uint32 repeated_uint32_extension = 33;
221+
repeated uint64 repeated_uint64_extension = 34;
222+
repeated sint32 repeated_sint32_extension = 35;
223+
repeated sint64 repeated_sint64_extension = 36;
224+
repeated fixed32 repeated_fixed32_extension = 37;
225+
repeated fixed64 repeated_fixed64_extension = 38;
226+
repeated sfixed32 repeated_sfixed32_extension = 39;
227+
repeated sfixed64 repeated_sfixed64_extension = 40;
228+
repeated float repeated_float_extension = 41;
229+
repeated double repeated_double_extension = 42;
230+
repeated bool repeated_bool_extension = 43;
231+
repeated string repeated_string_extension = 44;
232+
repeated bytes repeated_bytes_extension = 45;
233+
repeated RepeatedGroupExtension repeated_group_extension = 46
234+
[features.message_encoding = DELIMITED];
235+
236+
repeated FuzzMostTypes.NestedMessage repeated_nested_message_extension = 48;
237+
repeated ForeignMessage repeated_foreign_message_extension = 49;
238+
repeated proto2_unittest_import.ImportMessage
239+
repeated_import_message_extension = 50;
240+
repeated FuzzMostTypes.NestedEnum repeated_nested_enum_extension = 51;
241+
repeated ForeignEnum repeated_foreign_enum_extension = 52;
242+
repeated proto2_unittest_import.ImportEnum repeated_import_enum_extension =
243+
53;
244+
245+
// TODO: features.(pb.cpp).string_type=CORD is not supported for
246+
// extension. Add features.(pb.cpp).string_type=CORD option back after it is
247+
// supported.
248+
repeated string repeated_cord_extension = 55;
249+
250+
// Singular with defaults
251+
int32 default_int32_extension = 61 [default = 41];
252+
253+
int64 default_int64_extension = 62 [default = 42];
254+
255+
uint32 default_uint32_extension = 63 [default = 43];
256+
257+
uint64 default_uint64_extension = 64 [default = 44];
258+
259+
sint32 default_sint32_extension = 65 [default = -45];
260+
261+
sint64 default_sint64_extension = 66 [default = 46];
262+
263+
fixed32 default_fixed32_extension = 67 [default = 47];
264+
265+
fixed64 default_fixed64_extension = 68 [default = 48];
266+
267+
sfixed32 default_sfixed32_extension = 69 [default = 49];
268+
269+
sfixed64 default_sfixed64_extension = 70 [default = -50];
270+
271+
float default_float_extension = 71 [default = 51.5];
272+
273+
double default_double_extension = 72 [default = 5.2e4];
274+
275+
bool default_bool_extension = 73 [default = true];
276+
277+
string default_string_extension = 74 [default = "hello"];
278+
279+
bytes default_bytes_extension = 75 [default = "world"];
280+
281+
FuzzMostTypes.NestedEnum default_nested_enum_extension = 81 [default = BAR];
282+
283+
ForeignEnum default_foreign_enum_extension = 82 [default = FOREIGN_BAR];
284+
285+
proto2_unittest_import.ImportEnum default_import_enum_extension = 83
286+
[default = IMPORT_BAR];
287+
288+
// TODO: features.(pb.cpp).string_type=CORD is not supported for
289+
// extension. Add features.(pb.cpp).string_type=CORD option back after it is
290+
// supported.
291+
string default_cord_extension = 85 [default = "123"];
292+
293+
string optional_utf8_string_extension = 90
294+
[features.utf8_validation = VERIFY];
295+
repeated string repeated_utf8_string_extension = 91
296+
[features.utf8_validation = VERIFY];
297+
}
298+
299+
message TestRequired {
300+
int32 a = 1 [features.field_presence = LEGACY_REQUIRED];
301+
extend FuzzMostExtensions {
302+
TestRequired single = 1000;
303+
repeated TestRequired multi = 1001;
304+
}
305+
}
306+
307+
message OptionalGroupExtension {
308+
int32 a = 17;
309+
}
310+
311+
message RepeatedGroupExtension {
312+
int32 a = 47;
313+
}
314+
315+
message TestNestedExtension {
316+
extend FuzzMostExtensions {
317+
// Check for bug where string extensions declared in tested scope did not
318+
// compile.
319+
string test = 1002 [default = "test"];
320+
321+
// Used to test if generated extension name is correct when there are
322+
// underscores.
323+
string nested_string_extension = 1003;
324+
}
325+
326+
message OptionalGroupExtension {
327+
int32 a = 17;
328+
}
329+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
edition = "2024";
2+
3+
// This proto is used to test UTF-8 validation of extensions. Tests enforce the
4+
// understanding that the utf8_validation feature is set to VERIFY in the
5+
// edition specified above.
6+
7+
package proto2_unittest;
8+
9+
message TestUtf8ValidationOfExtensions {
10+
extensions 1 to max;
11+
}
12+
13+
extend TestUtf8ValidationOfExtensions {
14+
string optional_utf8_string_extension = 1;
15+
repeated string repeated_utf8_string_extension = 2;
16+
}

0 commit comments

Comments
 (0)