1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7
8 // Author: jschorr@google.com (Joseph Schorr)
9 // Based on original Protocol Buffers design by
10 // Sanjay Ghemawat, Jeff Dean, and others.
11
12 #include "google/protobuf/text_format.h"
13
14 #include <math.h>
15 #include <stdlib.h>
16
17 #include <atomic>
18 #include <cstdint>
19 #include <limits>
20 #include <memory>
21 #include <string>
22 #include <vector>
23
24 #include "google/protobuf/testing/file.h"
25 #include "google/protobuf/testing/file.h"
26 #include "google/protobuf/any.pb.h"
27 #include <gmock/gmock.h>
28 #include "google/protobuf/testing/googletest.h"
29 #include <gtest/gtest.h>
30 #include "absl/log/absl_check.h"
31 #include "absl/log/die_if_null.h"
32 #include "absl/log/scoped_mock_log.h"
33 #include "absl/strings/cord.h"
34 #include "absl/strings/escaping.h"
35 #include "absl/strings/str_cat.h"
36 #include "absl/strings/str_format.h"
37 #include "absl/strings/str_replace.h"
38 #include "absl/strings/substitute.h"
39 #include "google/protobuf/descriptor.h"
40 #include "google/protobuf/io/tokenizer.h"
41 #include "google/protobuf/io/zero_copy_stream_impl.h"
42 #include "google/protobuf/io/zero_copy_stream_impl_lite.h"
43 #include "google/protobuf/map_unittest.pb.h"
44 #include "google/protobuf/message.h"
45 #include "google/protobuf/test_util.h"
46 #include "google/protobuf/test_util2.h"
47 #include "google/protobuf/unittest.pb.h"
48 #include "google/protobuf/unittest_delimited.pb.h"
49 #include "google/protobuf/unittest_mset.pb.h"
50 #include "google/protobuf/unittest_mset_wire_format.pb.h"
51 #include "google/protobuf/unittest_proto3.pb.h"
52 #include "utf8_validity.h"
53
54
55 // Must be included last.
56 #include "google/protobuf/port_def.inc"
57
58 namespace google {
59 namespace protobuf {
60
61 namespace internal {
62 class UnsetFieldsMetadataTextFormatTestUtil {
63 public:
GetRawIds(const TextFormat::Parser::UnsetFieldsMetadata & metadata)64 static const auto& GetRawIds(
65 const TextFormat::Parser::UnsetFieldsMetadata& metadata) {
66 return metadata.ids_;
67 }
GetId(const Message & message,absl::string_view field)68 static auto GetId(const Message& message, absl::string_view field) {
69 return TextFormat::Parser::UnsetFieldsMetadata::GetUnsetFieldId(
70 message, *message.GetDescriptor()->FindFieldByName(field));
71 }
72 };
73 } // namespace internal
74
75 // Can't use an anonymous namespace here due to brokenness of Tru64 compiler.
76 namespace text_format_unittest {
77
78 using ::google::protobuf::internal::kDebugStringSilentMarker;
79 using ::google::protobuf::internal::UnsetFieldsMetadataTextFormatTestUtil;
80 using ::testing::AllOf;
81 using ::testing::HasSubstr;
82 using ::testing::UnorderedElementsAre;
83
84 // A basic string with different escapable characters for testing.
85 constexpr absl::string_view kEscapeTestString =
86 "\"A string with ' characters \n and \r newlines and \t tabs and \001 "
87 "slashes \\ and multiple spaces";
88
89 // A representation of the above string with all the characters escaped.
90 constexpr absl::string_view kEscapeTestStringEscaped =
91 "\"\\\"A string with \\' characters \\n and \\r newlines "
92 "and \\t tabs and \\001 slashes \\\\ and multiple spaces\"";
93
94 constexpr absl::string_view value_replacement = "\\[REDACTED\\]";
95
96 class TextFormatTestBase : public testing::Test {
97 public:
SetUp()98 void SetUp() override {
99 single_line_debug_format_prefix_ = "";
100 multi_line_debug_format_prefix_ = proto_.DebugString();
101 }
102
103 protected:
104 unittest::TestAllTypes proto_;
105 std::string single_line_debug_format_prefix_;
106 std::string multi_line_debug_format_prefix_;
107 };
108
109 class TextFormatTest : public TextFormatTestBase {
110 public:
SetUpTestSuite()111 static void SetUpTestSuite() {
112 ABSL_CHECK_OK(File::GetContents(
113 TestUtil::GetTestDataPath(
114 "google/protobuf/"
115 "testdata/text_format_unittest_data_oneof_implemented.txt"),
116 &static_proto_text_format_, true));
117 }
118
TextFormatTest()119 TextFormatTest() : proto_text_format_(static_proto_text_format_) {}
120
121 protected:
122 // Text format read from text_format_unittest_data.txt.
123 const std::string proto_text_format_;
124
125 private:
126 static std::string static_proto_text_format_;
127 };
128 std::string TextFormatTest::static_proto_text_format_;
129
130 class TextFormatExtensionsTest : public testing::Test {
131 public:
SetUpTestSuite()132 static void SetUpTestSuite() {
133 ABSL_CHECK_OK(File::GetContents(
134 TestUtil::GetTestDataPath("google/protobuf/testdata/"
135 "text_format_unittest_extensions_data.txt"),
136 &static_proto_text_format_, true));
137 }
138
TextFormatExtensionsTest()139 TextFormatExtensionsTest() : proto_text_format_(static_proto_text_format_) {}
140
141 protected:
142 // Debug string read from text_format_unittest_data.txt.
143 const std::string proto_text_format_;
144 unittest::TestAllExtensions proto_;
145
146 private:
147 static std::string static_proto_text_format_;
148 };
149 std::string TextFormatExtensionsTest::static_proto_text_format_;
150
TEST_F(TextFormatTest,Basic)151 TEST_F(TextFormatTest, Basic) {
152 TestUtil::SetAllFields(&proto_);
153 std::string actual_proto_text_format;
154 TextFormat::PrintToString(proto_, &actual_proto_text_format);
155 EXPECT_EQ(actual_proto_text_format, proto_text_format_);
156 }
157
TEST_F(TextFormatExtensionsTest,Extensions)158 TEST_F(TextFormatExtensionsTest, Extensions) {
159 TestUtil::SetAllExtensions(&proto_);
160 std::string actual_proto_text_format;
161 TextFormat::PrintToString(proto_, &actual_proto_text_format);
162 EXPECT_EQ(actual_proto_text_format, proto_text_format_);
163 }
164
TEST_F(TextFormatTest,ShortDebugString)165 TEST_F(TextFormatTest, ShortDebugString) {
166 proto_.set_optional_int32(1);
167 proto_.set_optional_string("hello");
168 proto_.mutable_optional_nested_message()->set_bb(2);
169 proto_.mutable_optional_foreign_message();
170
171 EXPECT_EQ(proto_.ShortDebugString(),
172 absl::StrCat(single_line_debug_format_prefix_,
173 "optional_int32: 1 "
174 "optional_string: \"hello\" "
175 "optional_nested_message { bb: 2 } "
176 "optional_foreign_message { }"));
177 }
178
179
TEST_F(TextFormatTest,ShortFormat)180 TEST_F(TextFormatTest, ShortFormat) {
181 unittest::RedactedFields proto;
182 unittest::TestNestedMessageRedaction redacted_nested_proto;
183 unittest::TestNestedMessageRedaction unredacted_nested_proto;
184 redacted_nested_proto.set_optional_unredacted_nested_string("hello");
185 unredacted_nested_proto.set_optional_unredacted_nested_string("world");
186 proto.set_optional_redacted_string("foo");
187 proto.set_optional_unredacted_string("bar");
188 proto.add_repeated_redacted_string("1");
189 proto.add_repeated_redacted_string("2");
190 proto.add_repeated_unredacted_string("3");
191 proto.add_repeated_unredacted_string("4");
192 *proto.mutable_optional_redacted_message() = redacted_nested_proto;
193 *proto.mutable_optional_unredacted_message() = unredacted_nested_proto;
194 unittest::TestNestedMessageRedaction* redacted_message_1 =
195 proto.add_repeated_redacted_message();
196 unittest::TestNestedMessageRedaction* redacted_message_2 =
197 proto.add_repeated_redacted_message();
198 unittest::TestNestedMessageRedaction* unredacted_message_1 =
199 proto.add_repeated_unredacted_message();
200 unittest::TestNestedMessageRedaction* unredacted_message_2 =
201 proto.add_repeated_unredacted_message();
202 redacted_message_1->set_optional_unredacted_nested_string("5");
203 redacted_message_2->set_optional_unredacted_nested_string("6");
204 unredacted_message_1->set_optional_unredacted_nested_string("7");
205 unredacted_message_2->set_optional_unredacted_nested_string("8");
206 (*proto.mutable_map_redacted_string())["abc"] = "def";
207 (*proto.mutable_map_unredacted_string())["ghi"] = "jkl";
208
209 std::string value_replacement = "\\[REDACTED\\]";
210 EXPECT_THAT(google::protobuf::ShortFormat(proto),
211 testing::MatchesRegex(absl::Substitute(
212 "optional_redacted_string: $0 "
213 "optional_unredacted_string: \"bar\" "
214 "repeated_redacted_string: $0 "
215 "repeated_redacted_string: $0 "
216 "repeated_unredacted_string: \"3\" "
217 "repeated_unredacted_string: \"4\" "
218 "optional_redacted_message: $0 "
219 "optional_unredacted_message \\{ "
220 "optional_unredacted_nested_string: \"world\" \\} "
221 "repeated_redacted_message: $0 "
222 "repeated_unredacted_message "
223 "\\{ optional_unredacted_nested_string: \"7\" \\} "
224 "repeated_unredacted_message "
225 "\\{ optional_unredacted_nested_string: \"8\" \\} "
226 "map_redacted_string: $0 "
227 "map_unredacted_string \\{ key: \"ghi\" value: \"jkl\" \\}",
228 value_replacement)));
229 }
230
TEST_F(TextFormatTest,Utf8Format)231 TEST_F(TextFormatTest, Utf8Format) {
232 unittest::RedactedFields proto;
233 unittest::TestNestedMessageRedaction redacted_nested_proto;
234 unittest::TestNestedMessageRedaction unredacted_nested_proto;
235 redacted_nested_proto.set_optional_unredacted_nested_string(
236 "\350\260\267\346\255\214");
237 unredacted_nested_proto.set_optional_unredacted_nested_string(
238 "\350\260\267\346\255\214");
239 proto.set_optional_redacted_string("foo");
240 proto.set_optional_unredacted_string("bar");
241 proto.add_repeated_redacted_string("1");
242 proto.add_repeated_redacted_string("2");
243 proto.add_repeated_unredacted_string("3");
244 proto.add_repeated_unredacted_string("4");
245 *proto.mutable_optional_redacted_message() = redacted_nested_proto;
246 *proto.mutable_optional_unredacted_message() = unredacted_nested_proto;
247 unittest::TestNestedMessageRedaction* redacted_message_1 =
248 proto.add_repeated_redacted_message();
249 unittest::TestNestedMessageRedaction* redacted_message_2 =
250 proto.add_repeated_redacted_message();
251 unittest::TestNestedMessageRedaction* unredacted_message_1 =
252 proto.add_repeated_unredacted_message();
253 unittest::TestNestedMessageRedaction* unredacted_message_2 =
254 proto.add_repeated_unredacted_message();
255 redacted_message_1->set_optional_unredacted_nested_string("5");
256 redacted_message_2->set_optional_unredacted_nested_string("6");
257 unredacted_message_1->set_optional_unredacted_nested_string("7");
258 unredacted_message_2->set_optional_unredacted_nested_string("8");
259 (*proto.mutable_map_redacted_string())["abc"] = "def";
260 (*proto.mutable_map_unredacted_string())["ghi"] = "jkl";
261
262 EXPECT_THAT(google::protobuf::Utf8Format(proto),
263 testing::MatchesRegex(absl::Substitute(
264 "optional_redacted_string: $0\n"
265 "optional_unredacted_string: \"bar\"\n"
266 "repeated_redacted_string: $0\n"
267 "repeated_redacted_string: $0\n"
268 "repeated_unredacted_string: \"3\"\n"
269 "repeated_unredacted_string: \"4\"\n"
270 "optional_redacted_message: $0\n"
271 "optional_unredacted_message \\{\n "
272 "optional_unredacted_nested_string: "
273 "\"\xE8\xB0\xB7\xE6\xAD\x8C\"\n\\}\n"
274 "repeated_redacted_message: $0\n"
275 "repeated_unredacted_message \\{\n "
276 "optional_unredacted_nested_string: \"7\"\n\\}\n"
277 "repeated_unredacted_message \\{\n "
278 "optional_unredacted_nested_string: \"8\"\n\\}\n"
279 "map_redacted_string: $0\n"
280 "map_unredacted_string \\{\n "
281 "key: \"ghi\"\n value: \"jkl\"\n\\}\n",
282 value_replacement)));
283 }
284
TEST_F(TextFormatTest,ShortPrimitiveRepeateds)285 TEST_F(TextFormatTest, ShortPrimitiveRepeateds) {
286 proto_.set_optional_int32(123);
287 proto_.add_repeated_int32(456);
288 proto_.add_repeated_int32(789);
289 proto_.add_repeated_string("foo");
290 proto_.add_repeated_string("bar");
291 proto_.add_repeated_nested_message()->set_bb(2);
292 proto_.add_repeated_nested_message()->set_bb(3);
293 proto_.add_repeated_nested_enum(unittest::TestAllTypes::FOO);
294 proto_.add_repeated_nested_enum(unittest::TestAllTypes::BAR);
295
296 TextFormat::Printer printer;
297 printer.SetUseShortRepeatedPrimitives(true);
298 std::string text;
299 EXPECT_TRUE(printer.PrintToString(proto_, &text));
300
301 EXPECT_EQ(
302 "optional_int32: 123\n"
303 "repeated_int32: [456, 789]\n"
304 "repeated_string: \"foo\"\n"
305 "repeated_string: \"bar\"\n"
306 "repeated_nested_message {\n bb: 2\n}\n"
307 "repeated_nested_message {\n bb: 3\n}\n"
308 "repeated_nested_enum: [FOO, BAR]\n",
309 text);
310
311 // Verify that any existing data in the string is cleared when PrintToString()
312 // is called.
313 text = "just some data here...\n\nblah blah";
314 EXPECT_TRUE(printer.PrintToString(proto_, &text));
315
316 EXPECT_EQ(
317 "optional_int32: 123\n"
318 "repeated_int32: [456, 789]\n"
319 "repeated_string: \"foo\"\n"
320 "repeated_string: \"bar\"\n"
321 "repeated_nested_message {\n bb: 2\n}\n"
322 "repeated_nested_message {\n bb: 3\n}\n"
323 "repeated_nested_enum: [FOO, BAR]\n",
324 text);
325
326 // Try in single-line mode.
327 printer.SetSingleLineMode(true);
328 EXPECT_TRUE(printer.PrintToString(proto_, &text));
329
330 EXPECT_EQ(
331 "optional_int32: 123 "
332 "repeated_int32: [456, 789] "
333 "repeated_string: \"foo\" "
334 "repeated_string: \"bar\" "
335 "repeated_nested_message { bb: 2 } "
336 "repeated_nested_message { bb: 3 } "
337 "repeated_nested_enum: [FOO, BAR] ",
338 text);
339 }
340
341
TEST_F(TextFormatTest,StringEscape)342 TEST_F(TextFormatTest, StringEscape) {
343 // Set the string value to test.
344 proto_.set_optional_string(kEscapeTestString);
345
346 // Get the DebugString from the proto.
347 std::string debug_string = proto_.DebugString();
348 std::string utf8_debug_string = proto_.Utf8DebugString();
349
350 // Hardcode a correct value to test against.
351 std::string correct_string =
352 absl::StrCat(multi_line_debug_format_prefix_,
353 "optional_string: ", kEscapeTestStringEscaped, "\n");
354
355 // Compare.
356 EXPECT_EQ(correct_string, debug_string);
357 // UTF-8 string is the same as non-UTF-8 because
358 // the protocol buffer contains no UTF-8 text.
359 EXPECT_EQ(correct_string, utf8_debug_string);
360
361 std::string expected_short_debug_string =
362 absl::StrCat(single_line_debug_format_prefix_,
363 "optional_string: ", kEscapeTestStringEscaped);
364 EXPECT_EQ(expected_short_debug_string, proto_.ShortDebugString());
365 }
366
TEST_F(TextFormatTest,Utf8DebugString)367 TEST_F(TextFormatTest, Utf8DebugString) {
368 // Set the string value to test.
369 proto_.set_optional_string("\350\260\267\346\255\214");
370 proto_.set_optional_bytes("\350\260\267\346\255\214");
371
372 // Get the DebugString from the proto.
373 std::string debug_string = proto_.DebugString();
374 std::string utf8_debug_string = proto_.Utf8DebugString();
375
376 // Hardcode a correct value to test against.
377 std::string correct_utf8_string =
378 absl::StrCat(multi_line_debug_format_prefix_,
379 "optional_string: \"\350\260\267\346\255\214\"\n"
380 "optional_bytes: \"\\350\\260\\267\\346\\255\\214\"\n");
381 std::string correct_string =
382 absl::StrCat(multi_line_debug_format_prefix_,
383 "optional_string: \"\\350\\260\\267\\346\\255\\214\"\n"
384 "optional_bytes: \"\\350\\260\\267\\346\\255\\214\"\n");
385
386 // Compare.
387 EXPECT_EQ(correct_utf8_string, utf8_debug_string);
388 EXPECT_EQ(correct_string, debug_string);
389 }
390
TEST_F(TextFormatTest,DelimitedPrintToString)391 TEST_F(TextFormatTest, DelimitedPrintToString) {
392 editions_unittest::TestDelimited proto;
393 proto.mutable_grouplike()->set_a(9);
394 proto.mutable_notgrouplike()->set_b(8);
395 proto.mutable_nested()->mutable_notgrouplike()->set_a(7);
396
397 std::string output;
398 TextFormat::PrintToString(proto, &output);
399 EXPECT_EQ(output,
400 "nested {\n notgrouplike {\n a: 7\n }\n}\nGroupLike {\n a: "
401 "9\n}\nnotgrouplike {\n b: 8\n}\n");
402 }
403
TEST_F(TextFormatTest,PrintUnknownFields)404 TEST_F(TextFormatTest, PrintUnknownFields) {
405 // Test printing of unknown fields in a message.
406
407 unittest::TestEmptyMessage message;
408 UnknownFieldSet* unknown_fields = message.mutable_unknown_fields();
409
410 unknown_fields->AddVarint(5, 1);
411 unknown_fields->AddFixed32(5, 2);
412 unknown_fields->AddFixed64(5, 3);
413 unknown_fields->AddLengthDelimited(5, "4");
414 unknown_fields->AddGroup(5)->AddVarint(10, 5);
415
416 unknown_fields->AddVarint(8, 1);
417 unknown_fields->AddVarint(8, 2);
418 unknown_fields->AddVarint(8, 3);
419
420 std::string message_text;
421 TextFormat::PrintToString(message, &message_text);
422 EXPECT_EQ(absl::StrCat("5: 1\n"
423 "5: 0x00000002\n"
424 "5: 0x0000000000000003\n"
425 "5: \"4\"\n"
426 "5 {\n"
427 " 10: 5\n"
428 "}\n"
429 "8: 1\n"
430 "8: 2\n"
431 "8: 3\n"),
432 message_text);
433
434 EXPECT_THAT(absl::StrCat(message), testing::MatchesRegex(absl::Substitute(
435 "5: UNKNOWN_VARINT $0\n"
436 "5: UNKNOWN_FIXED32 $0\n"
437 "5: UNKNOWN_FIXED64 $0\n"
438 "5: UNKNOWN_STRING $0\n"
439 "5: UNKNOWN_GROUP $0\n"
440 "8: UNKNOWN_VARINT $0\n"
441 "8: UNKNOWN_VARINT $0\n"
442 "8: UNKNOWN_VARINT $0\n",
443 value_replacement)));
444 }
445
TEST_F(TextFormatTest,PrintUnknownFieldsDeepestStackWorks)446 TEST_F(TextFormatTest, PrintUnknownFieldsDeepestStackWorks) {
447 // Test printing of unknown fields in a message.
448
449 unittest::TestEmptyMessage message;
450 UnknownFieldSet* unknown_fields = message.mutable_unknown_fields();
451
452 for (int i = 0; i < 200; ++i) {
453 unknown_fields = unknown_fields->AddGroup(1);
454 }
455
456 unknown_fields->AddVarint(2, 100);
457
458 std::string str;
459 EXPECT_TRUE(TextFormat::PrintToString(message, &str));
460 }
461
TEST_F(TextFormatTest,PrintUnknownFieldsHidden)462 TEST_F(TextFormatTest, PrintUnknownFieldsHidden) {
463 // Test printing of unknown fields in a message when suppressed.
464
465 unittest::OneString message;
466 message.set_data("data");
467 UnknownFieldSet* unknown_fields = message.mutable_unknown_fields();
468
469 unknown_fields->AddVarint(5, 1);
470 unknown_fields->AddFixed32(5, 2);
471 unknown_fields->AddFixed64(5, 3);
472 unknown_fields->AddLengthDelimited(5, "4");
473 unknown_fields->AddGroup(5)->AddVarint(10, 5);
474
475 unknown_fields->AddVarint(8, 1);
476 unknown_fields->AddVarint(8, 2);
477 unknown_fields->AddVarint(8, 3);
478
479 TextFormat::Printer printer;
480 printer.SetHideUnknownFields(true);
481 std::string output;
482 printer.PrintToString(message, &output);
483
484 EXPECT_EQ("data: \"data\"\n", output);
485 }
486
TEST_F(TextFormatTest,PrintUnknownMessage)487 TEST_F(TextFormatTest, PrintUnknownMessage) {
488 // Test heuristic printing of messages in an UnknownFieldSet.
489
490 protobuf_unittest::TestAllTypes message;
491
492 // Cases which should not be interpreted as sub-messages.
493
494 // 'a' is a valid FIXED64 tag, so for the string to be parseable as a message
495 // it should be followed by 8 bytes. Since this string only has two
496 // subsequent bytes, it should be treated as a string.
497 message.add_repeated_string("abc");
498
499 // 'd' happens to be a valid ENDGROUP tag. So,
500 // UnknownFieldSet::MergeFromCodedStream() will successfully parse "def", but
501 // the ConsumedEntireMessage() check should fail.
502 message.add_repeated_string("def");
503
504 // A zero-length string should never be interpreted as a message even though
505 // it is technically valid as one.
506 message.add_repeated_string("");
507
508 // Case which should be interpreted as a sub-message.
509
510 // An actual nested message with content should always be interpreted as a
511 // nested message.
512 message.add_repeated_nested_message()->set_bb(123);
513
514 std::string data;
515 message.SerializeToString(&data);
516
517 std::string text;
518 UnknownFieldSet unknown_fields;
519 EXPECT_TRUE(unknown_fields.ParseFromString(data));
520 EXPECT_TRUE(TextFormat::PrintUnknownFieldsToString(unknown_fields, &text));
521 // Field 44 and 48 can be printed in any order.
522 EXPECT_THAT(text, testing::HasSubstr("44: \"abc\"\n"
523 "44: \"def\"\n"
524 "44: \"\"\n"));
525 EXPECT_THAT(text, testing::HasSubstr("48 {\n"
526 " 1: 123\n"
527 "}\n"));
528 }
529
TEST_F(TextFormatTest,PrintDeeplyNestedUnknownMessage)530 TEST_F(TextFormatTest, PrintDeeplyNestedUnknownMessage) {
531 // Create a deeply nested message.
532 static constexpr int kNestingDepth = 25000;
533 static constexpr int kUnknownFieldNumber = 1;
534 std::vector<int> lengths;
535 lengths.reserve(kNestingDepth);
536 lengths.push_back(0);
537 for (int i = 0; i < kNestingDepth - 1; ++i) {
538 lengths.push_back(
539 internal::WireFormatLite::TagSize(
540 kUnknownFieldNumber, internal::WireFormatLite::TYPE_BYTES) +
541 internal::WireFormatLite::LengthDelimitedSize(lengths.back()));
542 }
543 std::string serialized;
544 {
545 io::StringOutputStream zero_copy_stream(&serialized);
546 io::CodedOutputStream coded_stream(&zero_copy_stream);
547 for (int i = kNestingDepth - 1; i >= 0; --i) {
548 internal::WireFormatLite::WriteTag(
549 kUnknownFieldNumber,
550 internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, &coded_stream);
551 coded_stream.WriteVarint32(lengths[i]);
552 }
553 }
554
555 // Parse the data and verify that we can print it without overflowing the
556 // stack.
557 unittest::TestEmptyMessage message;
558 ASSERT_TRUE(message.ParseFromString(serialized));
559 std::string text;
560 EXPECT_TRUE(TextFormat::PrintToString(message, &text));
561 }
562
TEST_F(TextFormatTest,PrintMessageWithIndent)563 TEST_F(TextFormatTest, PrintMessageWithIndent) {
564 // Test adding an initial indent to printing.
565
566 protobuf_unittest::TestAllTypes message;
567
568 message.add_repeated_string("abc");
569 message.add_repeated_string("def");
570 message.add_repeated_nested_message()->set_bb(123);
571
572 std::string text;
573 TextFormat::Printer printer;
574 printer.SetInitialIndentLevel(1);
575 EXPECT_TRUE(printer.PrintToString(message, &text));
576 EXPECT_EQ(
577 " repeated_string: \"abc\"\n"
578 " repeated_string: \"def\"\n"
579 " repeated_nested_message {\n"
580 " bb: 123\n"
581 " }\n",
582 text);
583 }
584
TEST_F(TextFormatTest,PrintMessageSingleLine)585 TEST_F(TextFormatTest, PrintMessageSingleLine) {
586 // Test printing a message on a single line.
587
588 protobuf_unittest::TestAllTypes message;
589
590 message.add_repeated_string("abc");
591 message.add_repeated_string("def");
592 message.add_repeated_nested_message()->set_bb(123);
593
594 std::string text;
595 TextFormat::Printer printer;
596 printer.SetInitialIndentLevel(1);
597 printer.SetSingleLineMode(true);
598 EXPECT_TRUE(printer.PrintToString(message, &text));
599 EXPECT_EQ(
600 " repeated_string: \"abc\" repeated_string: \"def\" "
601 "repeated_nested_message { bb: 123 } ",
602 text);
603 }
604
TEST_F(TextFormatTest,PrintBufferTooSmall)605 TEST_F(TextFormatTest, PrintBufferTooSmall) {
606 // Test printing a message to a buffer that is too small.
607
608 protobuf_unittest::TestAllTypes message;
609
610 message.add_repeated_string("abc");
611 message.add_repeated_string("def");
612
613 char buffer[1] = "";
614 io::ArrayOutputStream output_stream(buffer, 1);
615 EXPECT_FALSE(TextFormat::Print(message, &output_stream));
616 EXPECT_EQ(buffer[0], 'r');
617 EXPECT_EQ(output_stream.ByteCount(), 1);
618 }
619
620 // A printer that appends 'u' to all unsigned int32.
621 class CustomUInt32FieldValuePrinter : public TextFormat::FieldValuePrinter {
622 public:
PrintUInt32(uint32_t val) const623 std::string PrintUInt32(uint32_t val) const override {
624 return absl::StrCat(FieldValuePrinter::PrintUInt32(val), "u");
625 }
626 };
627
TEST_F(TextFormatTest,DefaultCustomFieldPrinter)628 TEST_F(TextFormatTest, DefaultCustomFieldPrinter) {
629 protobuf_unittest::TestAllTypes message;
630
631 message.set_optional_uint32(42);
632 message.add_repeated_uint32(1);
633 message.add_repeated_uint32(2);
634 message.add_repeated_uint32(3);
635
636 TextFormat::Printer printer;
637 printer.SetDefaultFieldValuePrinter(new CustomUInt32FieldValuePrinter());
638 // Let's see if that works well together with the repeated primitives:
639 printer.SetUseShortRepeatedPrimitives(true);
640 std::string text;
641 printer.PrintToString(message, &text);
642 EXPECT_EQ("optional_uint32: 42u\nrepeated_uint32: [1u, 2u, 3u]\n", text);
643 }
644
645 class CustomInt32FieldValuePrinter : public TextFormat::FieldValuePrinter {
646 public:
PrintInt32(int32_t val) const647 std::string PrintInt32(int32_t val) const override {
648 return absl::StrCat("value-is(", FieldValuePrinter::PrintInt32(val), ")");
649 }
650 };
651
TEST_F(TextFormatTest,FieldSpecificCustomPrinter)652 TEST_F(TextFormatTest, FieldSpecificCustomPrinter) {
653 protobuf_unittest::TestAllTypes message;
654
655 message.set_optional_int32(42); // This will be handled by our Printer.
656 message.add_repeated_int32(42); // This will be printed as number.
657
658 TextFormat::Printer printer;
659 EXPECT_TRUE(printer.RegisterFieldValuePrinter(
660 message.GetDescriptor()->FindFieldByName("optional_int32"),
661 new CustomInt32FieldValuePrinter()));
662 std::string text;
663 printer.PrintToString(message, &text);
664 EXPECT_EQ("optional_int32: value-is(42)\nrepeated_int32: 42\n", text);
665 }
666
TEST_F(TextFormatTest,FieldSpecificCustomPrinterRegisterSameFieldTwice)667 TEST_F(TextFormatTest, FieldSpecificCustomPrinterRegisterSameFieldTwice) {
668 protobuf_unittest::TestAllTypes message;
669 TextFormat::Printer printer;
670 const FieldDescriptor* const field =
671 message.GetDescriptor()->FindFieldByName("optional_int32");
672 ASSERT_TRUE(printer.RegisterFieldValuePrinter(
673 field, new CustomInt32FieldValuePrinter()));
674 const TextFormat::FieldValuePrinter* const rejected =
675 new CustomInt32FieldValuePrinter();
676 ASSERT_FALSE(printer.RegisterFieldValuePrinter(field, rejected));
677 delete rejected;
678 }
679
TEST_F(TextFormatTest,ErrorCasesRegisteringFieldValuePrinterShouldFail)680 TEST_F(TextFormatTest, ErrorCasesRegisteringFieldValuePrinterShouldFail) {
681 protobuf_unittest::TestAllTypes message;
682 TextFormat::Printer printer;
683 // nullptr printer.
684 EXPECT_FALSE(printer.RegisterFieldValuePrinter(
685 message.GetDescriptor()->FindFieldByName("optional_int32"),
686 static_cast<const TextFormat::FieldValuePrinter*>(nullptr)));
687 EXPECT_FALSE(printer.RegisterFieldValuePrinter(
688 message.GetDescriptor()->FindFieldByName("optional_int32"),
689 static_cast<const TextFormat::FastFieldValuePrinter*>(nullptr)));
690 // Because registration fails, the ownership of this printer is never taken.
691 TextFormat::FieldValuePrinter my_field_printer;
692 // nullptr field
693 EXPECT_FALSE(printer.RegisterFieldValuePrinter(nullptr, &my_field_printer));
694 }
695
696 class CustomMessageFieldValuePrinter : public TextFormat::FieldValuePrinter {
697 public:
PrintInt32(int32_t v) const698 std::string PrintInt32(int32_t v) const override {
699 return absl::StrCat(FieldValuePrinter::PrintInt32(v), " # x",
700 absl::Hex(v));
701 }
702
PrintMessageStart(const Message & message,int field_index,int field_count,bool single_line_mode) const703 std::string PrintMessageStart(const Message& message, int field_index,
704 int field_count,
705 bool single_line_mode) const override {
706 if (single_line_mode) {
707 return " { ";
708 }
709 return absl::StrCat(" { # ", message.GetDescriptor()->name(), ": ",
710 field_index, "\n");
711 }
712 };
713
TEST_F(TextFormatTest,CustomPrinterForComments)714 TEST_F(TextFormatTest, CustomPrinterForComments) {
715 protobuf_unittest::TestAllTypes message;
716 message.mutable_optional_nested_message();
717 message.mutable_optional_import_message()->set_d(42);
718 message.add_repeated_nested_message();
719 message.add_repeated_nested_message();
720 message.add_repeated_import_message()->set_d(43);
721 message.add_repeated_import_message()->set_d(44);
722 TextFormat::Printer printer;
723 CustomMessageFieldValuePrinter my_field_printer;
724 printer.SetDefaultFieldValuePrinter(new CustomMessageFieldValuePrinter());
725 std::string text;
726 printer.PrintToString(message, &text);
727 EXPECT_EQ(
728 "optional_nested_message { # NestedMessage: -1\n"
729 "}\n"
730 "optional_import_message { # ImportMessage: -1\n"
731 " d: 42 # x2a\n"
732 "}\n"
733 "repeated_nested_message { # NestedMessage: 0\n"
734 "}\n"
735 "repeated_nested_message { # NestedMessage: 1\n"
736 "}\n"
737 "repeated_import_message { # ImportMessage: 0\n"
738 " d: 43 # x2b\n"
739 "}\n"
740 "repeated_import_message { # ImportMessage: 1\n"
741 " d: 44 # x2c\n"
742 "}\n",
743 text);
744 }
745
746 class CustomMessageContentFieldValuePrinter
747 : public TextFormat::FastFieldValuePrinter {
748 public:
PrintMessageContent(const Message & message,int field_index,int field_count,bool single_line_mode,TextFormat::BaseTextGenerator * generator) const749 bool PrintMessageContent(
750 const Message& message, int field_index, int field_count,
751 bool single_line_mode,
752 TextFormat::BaseTextGenerator* generator) const override {
753 if (message.ByteSizeLong() > 0) {
754 generator->PrintString(
755 absl::Substitute("# REDACTED, $0 bytes\n", message.ByteSizeLong()));
756 }
757 return true;
758 }
759 };
760
TEST_F(TextFormatTest,CustomPrinterForMessageContent)761 TEST_F(TextFormatTest, CustomPrinterForMessageContent) {
762 protobuf_unittest::TestAllTypes message;
763 message.mutable_optional_nested_message();
764 message.mutable_optional_import_message()->set_d(42);
765 message.add_repeated_nested_message();
766 message.add_repeated_nested_message();
767 message.add_repeated_import_message()->set_d(43);
768 message.add_repeated_import_message()->set_d(44);
769 TextFormat::Printer printer;
770 CustomMessageContentFieldValuePrinter my_field_printer;
771 printer.SetDefaultFieldValuePrinter(
772 new CustomMessageContentFieldValuePrinter());
773 std::string text;
774 printer.PrintToString(message, &text);
775 EXPECT_EQ(
776 "optional_nested_message {\n"
777 "}\n"
778 "optional_import_message {\n"
779 " # REDACTED, 2 bytes\n"
780 "}\n"
781 "repeated_nested_message {\n"
782 "}\n"
783 "repeated_nested_message {\n"
784 "}\n"
785 "repeated_import_message {\n"
786 " # REDACTED, 2 bytes\n"
787 "}\n"
788 "repeated_import_message {\n"
789 " # REDACTED, 2 bytes\n"
790 "}\n",
791 text);
792 }
793
794 class CustomMultilineCommentPrinter : public TextFormat::FieldValuePrinter {
795 public:
PrintMessageStart(const Message & message,int field_index,int field_count,bool single_line_comment) const796 std::string PrintMessageStart(const Message& message, int field_index,
797 int field_count,
798 bool single_line_comment) const override {
799 return absl::StrCat(" { # 1\n", " # 2\n");
800 }
801 };
802
TEST_F(TextFormatTest,CustomPrinterForMultilineComments)803 TEST_F(TextFormatTest, CustomPrinterForMultilineComments) {
804 protobuf_unittest::TestAllTypes message;
805 message.mutable_optional_nested_message();
806 message.mutable_optional_import_message()->set_d(42);
807 TextFormat::Printer printer;
808 CustomMessageFieldValuePrinter my_field_printer;
809 printer.SetDefaultFieldValuePrinter(new CustomMultilineCommentPrinter());
810 std::string text;
811 printer.PrintToString(message, &text);
812 EXPECT_EQ(
813 "optional_nested_message { # 1\n"
814 " # 2\n"
815 "}\n"
816 "optional_import_message { # 1\n"
817 " # 2\n"
818 " d: 42\n"
819 "}\n",
820 text);
821 }
822
823 // Achieve effects similar to SetUseShortRepeatedPrimitives for messages, using
824 // RegisterFieldValuePrinter. Use this to test the version of PrintFieldName
825 // that accepts repeated field index and count.
826 class CompactRepeatedFieldPrinter : public TextFormat::FastFieldValuePrinter {
827 public:
PrintFieldName(const Message & message,int field_index,int field_count,const Reflection * reflection,const FieldDescriptor * field,TextFormat::BaseTextGenerator * generator) const828 void PrintFieldName(const Message& message, int field_index, int field_count,
829 const Reflection* reflection,
830 const FieldDescriptor* field,
831 TextFormat::BaseTextGenerator* generator) const override {
832 if (field_index == 0 || field_index == -1) {
833 generator->PrintString(field->name());
834 }
835 }
836 // To prevent compiler complaining about Woverloaded-virtual
PrintFieldName(const Message & message,const Reflection * reflection,const FieldDescriptor * field,TextFormat::BaseTextGenerator * generator) const837 void PrintFieldName(const Message& message, const Reflection* reflection,
838 const FieldDescriptor* field,
839 TextFormat::BaseTextGenerator* generator) const override {
840 }
PrintMessageStart(const Message & message,int field_index,int field_count,bool single_line_mode,TextFormat::BaseTextGenerator * generator) const841 void PrintMessageStart(
842 const Message& message, int field_index, int field_count,
843 bool single_line_mode,
844 TextFormat::BaseTextGenerator* generator) const override {
845 if (field_index == 0 || field_index == -1) {
846 if (single_line_mode) {
847 generator->PrintLiteral(" { ");
848 } else {
849 generator->PrintLiteral(" {\n");
850 }
851 }
852 }
PrintMessageEnd(const Message & message,int field_index,int field_count,bool single_line_mode,TextFormat::BaseTextGenerator * generator) const853 void PrintMessageEnd(
854 const Message& message, int field_index, int field_count,
855 bool single_line_mode,
856 TextFormat::BaseTextGenerator* generator) const override {
857 if (field_index == field_count - 1 || field_index == -1) {
858 if (single_line_mode) {
859 generator->PrintLiteral("} ");
860 } else {
861 generator->PrintLiteral("}\n");
862 }
863 }
864 }
865 };
866
TEST_F(TextFormatTest,CompactRepeatedFieldPrinter)867 TEST_F(TextFormatTest, CompactRepeatedFieldPrinter) {
868 TextFormat::Printer printer;
869 ASSERT_TRUE(printer.RegisterFieldValuePrinter(
870 unittest::TestAllTypes::default_instance()
871 .descriptor()
872 ->FindFieldByNumber(
873 unittest::TestAllTypes::kRepeatedNestedMessageFieldNumber),
874 new CompactRepeatedFieldPrinter));
875
876 protobuf_unittest::TestAllTypes message;
877 message.add_repeated_nested_message()->set_bb(1);
878 message.add_repeated_nested_message()->set_bb(2);
879 message.add_repeated_nested_message()->set_bb(3);
880
881 std::string text;
882 ASSERT_TRUE(printer.PrintToString(message, &text));
883 EXPECT_EQ(
884 "repeated_nested_message {\n"
885 " bb: 1\n"
886 " bb: 2\n"
887 " bb: 3\n"
888 "}\n",
889 text);
890 }
891
892 // Print strings into multiple line, with indentation. Use this to test
893 // BaseTextGenerator::Indent and BaseTextGenerator::Outdent.
894 class MultilineStringPrinter : public TextFormat::FastFieldValuePrinter {
895 public:
PrintString(const std::string & val,TextFormat::BaseTextGenerator * generator) const896 void PrintString(const std::string& val,
897 TextFormat::BaseTextGenerator* generator) const override {
898 generator->Indent();
899 int last_pos = 0;
900 int newline_pos = val.find('\n');
901 while (newline_pos != std::string::npos) {
902 generator->PrintLiteral("\n");
903 TextFormat::FastFieldValuePrinter::PrintString(
904 val.substr(last_pos, newline_pos + 1 - last_pos), generator);
905 last_pos = newline_pos + 1;
906 newline_pos = val.find('\n', last_pos);
907 }
908 if (last_pos < val.size()) {
909 generator->PrintLiteral("\n");
910 TextFormat::FastFieldValuePrinter::PrintString(val.substr(last_pos),
911 generator);
912 }
913 generator->Outdent();
914 }
915 };
916
TEST_F(TextFormatTest,MultilineStringPrinter)917 TEST_F(TextFormatTest, MultilineStringPrinter) {
918 TextFormat::Printer printer;
919 ASSERT_TRUE(printer.RegisterFieldValuePrinter(
920 unittest::TestAllTypes::default_instance()
921 .descriptor()
922 ->FindFieldByNumber(
923 unittest::TestAllTypes::kOptionalStringFieldNumber),
924 new MultilineStringPrinter));
925
926 protobuf_unittest::TestAllTypes message;
927 message.set_optional_string("first line\nsecond line\nthird line");
928
929 std::string text;
930 ASSERT_TRUE(printer.PrintToString(message, &text));
931 EXPECT_EQ(
932 "optional_string: \n"
933 " \"first line\\n\"\n"
934 " \"second line\\n\"\n"
935 " \"third line\"\n",
936 text);
937 }
938
939 class CustomNestedMessagePrinter : public TextFormat::MessagePrinter {
940 public:
CustomNestedMessagePrinter()941 CustomNestedMessagePrinter() {}
~CustomNestedMessagePrinter()942 ~CustomNestedMessagePrinter() override {}
Print(const Message & message,bool single_line_mode,TextFormat::BaseTextGenerator * generator) const943 void Print(const Message& message, bool single_line_mode,
944 TextFormat::BaseTextGenerator* generator) const override {
945 generator->PrintLiteral("// custom\n");
946 if (printer_ != nullptr) {
947 printer_->PrintMessage(message, generator);
948 }
949 }
950
SetPrinter(TextFormat::Printer * printer)951 void SetPrinter(TextFormat::Printer* printer) { printer_ = printer; }
952
953 private:
954 TextFormat::Printer* printer_ = nullptr;
955 };
956
TEST_F(TextFormatTest,CustomMessagePrinter)957 TEST_F(TextFormatTest, CustomMessagePrinter) {
958 TextFormat::Printer printer;
959 auto* custom_printer = new CustomNestedMessagePrinter;
960 printer.RegisterMessagePrinter(
961 unittest::TestAllTypes::NestedMessage::default_instance().descriptor(),
962 custom_printer);
963
964 unittest::TestAllTypes message;
965 std::string text;
966 EXPECT_TRUE(printer.PrintToString(message, &text));
967 EXPECT_EQ("", text);
968
969 message.mutable_optional_nested_message()->set_bb(1);
970 EXPECT_TRUE(printer.PrintToString(message, &text));
971 EXPECT_EQ("optional_nested_message {\n // custom\n}\n", text);
972
973 custom_printer->SetPrinter(&printer);
974 EXPECT_TRUE(printer.PrintToString(message, &text));
975 EXPECT_EQ("optional_nested_message {\n // custom\n bb: 1\n}\n", text);
976 }
977
TEST_F(TextFormatTest,ParseBasic)978 TEST_F(TextFormatTest, ParseBasic) {
979 io::ArrayInputStream input_stream(proto_text_format_.data(),
980 proto_text_format_.size());
981 TextFormat::Parse(&input_stream, &proto_);
982 TestUtil::ExpectAllFieldsSet(proto_);
983 }
984
TEST_F(TextFormatTest,ParseCordBasic)985 TEST_F(TextFormatTest, ParseCordBasic) {
986 absl::Cord cord(proto_text_format_);
987 TextFormat::ParseFromCord(cord, &proto_);
988 TestUtil::ExpectAllFieldsSet(proto_);
989 }
990
TEST_F(TextFormatExtensionsTest,ParseExtensions)991 TEST_F(TextFormatExtensionsTest, ParseExtensions) {
992 io::ArrayInputStream input_stream(proto_text_format_.data(),
993 proto_text_format_.size());
994 TextFormat::Parse(&input_stream, &proto_);
995 TestUtil::ExpectAllExtensionsSet(proto_);
996 }
997
998
TEST_F(TextFormatTest,ParseEnumFieldFromNumber)999 TEST_F(TextFormatTest, ParseEnumFieldFromNumber) {
1000 // Create a parse string with a numerical value for an enum field.
1001 std::string parse_string =
1002 absl::Substitute("optional_nested_enum: $0", unittest::TestAllTypes::BAZ);
1003 EXPECT_TRUE(TextFormat::ParseFromString(parse_string, &proto_));
1004 EXPECT_TRUE(proto_.has_optional_nested_enum());
1005 EXPECT_EQ(unittest::TestAllTypes::BAZ, proto_.optional_nested_enum());
1006 }
1007
TEST_F(TextFormatTest,ParseEnumFieldFromNegativeNumber)1008 TEST_F(TextFormatTest, ParseEnumFieldFromNegativeNumber) {
1009 ASSERT_LT(unittest::SPARSE_E, 0);
1010 std::string parse_string =
1011 absl::Substitute("sparse_enum: $0", unittest::SPARSE_E);
1012 unittest::SparseEnumMessage proto;
1013 EXPECT_TRUE(TextFormat::ParseFromString(parse_string, &proto));
1014 EXPECT_TRUE(proto.has_sparse_enum());
1015 EXPECT_EQ(unittest::SPARSE_E, proto.sparse_enum());
1016 }
1017
TEST_F(TextFormatTest,PrintUnknownEnumFieldProto3)1018 TEST_F(TextFormatTest, PrintUnknownEnumFieldProto3) {
1019 proto3_unittest::TestAllTypes proto;
1020
1021 proto.add_repeated_nested_enum(
1022 static_cast<proto3_unittest::TestAllTypes::NestedEnum>(10));
1023 proto.add_repeated_nested_enum(
1024 static_cast<proto3_unittest::TestAllTypes::NestedEnum>(-10));
1025 proto.add_repeated_nested_enum(
1026 static_cast<proto3_unittest::TestAllTypes::NestedEnum>(2147483647));
1027 proto.add_repeated_nested_enum(
1028 static_cast<proto3_unittest::TestAllTypes::NestedEnum>(-2147483648));
1029
1030 EXPECT_EQ(absl::StrCat(multi_line_debug_format_prefix_,
1031 "repeated_nested_enum: 10\n"
1032 "repeated_nested_enum: -10\n"
1033 "repeated_nested_enum: 2147483647\n"
1034 "repeated_nested_enum: -2147483648\n"),
1035 proto.DebugString());
1036 }
1037
TEST_F(TextFormatTest,ParseUnknownEnumFieldProto3)1038 TEST_F(TextFormatTest, ParseUnknownEnumFieldProto3) {
1039 proto3_unittest::TestAllTypes proto;
1040 std::string parse_string =
1041 "repeated_nested_enum: [10, -10, 2147483647, -2147483648]";
1042 EXPECT_TRUE(TextFormat::ParseFromString(parse_string, &proto));
1043 ASSERT_EQ(4, proto.repeated_nested_enum_size());
1044 EXPECT_EQ(10, proto.repeated_nested_enum(0));
1045 EXPECT_EQ(-10, proto.repeated_nested_enum(1));
1046 EXPECT_EQ(2147483647, proto.repeated_nested_enum(2));
1047 EXPECT_EQ(-2147483648, proto.repeated_nested_enum(3));
1048 }
1049
TEST_F(TextFormatTest,PopulatesNoOpFields)1050 TEST_F(TextFormatTest, PopulatesNoOpFields) {
1051 proto3_unittest::TestAllTypes proto;
1052 TextFormat::Parser parser;
1053 TextFormat::Parser::UnsetFieldsMetadata no_op_fields;
1054 parser.OutputNoOpFields(&no_op_fields);
1055 using Peer = UnsetFieldsMetadataTextFormatTestUtil;
1056
1057 {
1058 no_op_fields = {};
1059 const absl::string_view singular_int_parse_string = "optional_int32: 0";
1060 EXPECT_TRUE(TextFormat::ParseFromString(singular_int_parse_string, &proto));
1061 EXPECT_TRUE(parser.ParseFromString(singular_int_parse_string, &proto));
1062 EXPECT_THAT(Peer::GetRawIds(no_op_fields),
1063 UnorderedElementsAre(Peer::GetId(proto, "optional_int32")));
1064 }
1065 {
1066 no_op_fields = {};
1067 const absl::string_view singular_bool_parse_string = "optional_bool: false";
1068 EXPECT_TRUE(
1069 TextFormat::ParseFromString(singular_bool_parse_string, &proto));
1070 EXPECT_TRUE(parser.ParseFromString(singular_bool_parse_string, &proto));
1071 EXPECT_THAT(Peer::GetRawIds(no_op_fields),
1072 UnorderedElementsAre(Peer::GetId(proto, "optional_bool")));
1073 }
1074 {
1075 no_op_fields = {};
1076 const absl::string_view singular_string_parse_string =
1077 "optional_string: ''";
1078 EXPECT_TRUE(
1079 TextFormat::ParseFromString(singular_string_parse_string, &proto));
1080 EXPECT_TRUE(parser.ParseFromString(singular_string_parse_string, &proto));
1081 EXPECT_THAT(Peer::GetRawIds(no_op_fields),
1082 UnorderedElementsAre(Peer::GetId(proto, "optional_string")));
1083 }
1084 {
1085 no_op_fields = {};
1086 const absl::string_view nested_message_parse_string =
1087 "optional_nested_message { bb: 0 } ";
1088 EXPECT_TRUE(
1089 TextFormat::ParseFromString(nested_message_parse_string, &proto));
1090 EXPECT_TRUE(parser.ParseFromString(nested_message_parse_string, &proto));
1091 EXPECT_THAT(Peer::GetRawIds(no_op_fields),
1092 UnorderedElementsAre(
1093 Peer::GetId(proto.optional_nested_message(), "bb")));
1094 }
1095 {
1096 no_op_fields = {};
1097 const absl::string_view nested_message_parse_string =
1098 "optional_nested_message { bb: 1 } ";
1099 EXPECT_TRUE(
1100 TextFormat::ParseFromString(nested_message_parse_string, &proto));
1101 EXPECT_TRUE(parser.ParseFromString(nested_message_parse_string, &proto));
1102 EXPECT_THAT(Peer::GetRawIds(no_op_fields), UnorderedElementsAre());
1103 }
1104 {
1105 no_op_fields = {};
1106 const absl::string_view foreign_message_parse_string =
1107 "optional_foreign_message { c: 0 } ";
1108 EXPECT_TRUE(
1109 TextFormat::ParseFromString(foreign_message_parse_string, &proto));
1110 EXPECT_TRUE(parser.ParseFromString(foreign_message_parse_string, &proto));
1111 EXPECT_THAT(Peer::GetRawIds(no_op_fields),
1112 UnorderedElementsAre(
1113 Peer::GetId(proto.optional_foreign_message(), "c")));
1114 }
1115 {
1116 no_op_fields = {};
1117 const absl::string_view nested_enum_parse_string =
1118 "optional_nested_enum: ZERO ";
1119 EXPECT_TRUE(TextFormat::ParseFromString(nested_enum_parse_string, &proto));
1120 EXPECT_TRUE(parser.ParseFromString(nested_enum_parse_string, &proto));
1121 EXPECT_THAT(
1122 Peer::GetRawIds(no_op_fields),
1123 UnorderedElementsAre(Peer::GetId(proto, "optional_nested_enum")));
1124 }
1125 {
1126 no_op_fields = {};
1127 const absl::string_view foreign_enum_parse_string =
1128 "optional_foreign_enum: FOREIGN_ZERO ";
1129 EXPECT_TRUE(TextFormat::ParseFromString(foreign_enum_parse_string, &proto));
1130 EXPECT_TRUE(parser.ParseFromString(foreign_enum_parse_string, &proto));
1131 EXPECT_THAT(
1132 Peer::GetRawIds(no_op_fields),
1133 UnorderedElementsAre(Peer::GetId(proto, "optional_foreign_enum")));
1134 }
1135 {
1136 no_op_fields = {};
1137 const absl::string_view string_piece_parse_string =
1138 "optional_string_piece: '' ";
1139 EXPECT_TRUE(TextFormat::ParseFromString(string_piece_parse_string, &proto));
1140 EXPECT_TRUE(parser.ParseFromString(string_piece_parse_string, &proto));
1141 EXPECT_THAT(
1142 Peer::GetRawIds(no_op_fields),
1143 UnorderedElementsAre(Peer::GetId(proto, "optional_string_piece")));
1144 }
1145 {
1146 no_op_fields = {};
1147 const absl::string_view cord_parse_string = "optional_cord: '' ";
1148 EXPECT_TRUE(TextFormat::ParseFromString(cord_parse_string, &proto));
1149 EXPECT_TRUE(parser.ParseFromString(cord_parse_string, &proto));
1150 EXPECT_THAT(Peer::GetRawIds(no_op_fields),
1151 UnorderedElementsAre(Peer::GetId(proto, "optional_cord")));
1152 }
1153 {
1154 no_op_fields = {};
1155 // Sanity check that repeated fields work the same.
1156 const absl::string_view repeated_int32_parse_string = "repeated_int32: 0 ";
1157 EXPECT_TRUE(
1158 TextFormat::ParseFromString(repeated_int32_parse_string, &proto));
1159 EXPECT_TRUE(parser.ParseFromString(repeated_int32_parse_string, &proto));
1160 EXPECT_THAT(Peer::GetRawIds(no_op_fields), UnorderedElementsAre());
1161 }
1162 {
1163 no_op_fields = {};
1164 const absl::string_view repeated_bool_parse_string =
1165 "repeated_bool: false ";
1166 EXPECT_TRUE(
1167 TextFormat::ParseFromString(repeated_bool_parse_string, &proto));
1168 EXPECT_TRUE(parser.ParseFromString(repeated_bool_parse_string, &proto));
1169 EXPECT_THAT(Peer::GetRawIds(no_op_fields), UnorderedElementsAre());
1170 }
1171 {
1172 no_op_fields = {};
1173 const absl::string_view repeated_string_parse_string =
1174 "repeated_string: '' ";
1175 EXPECT_TRUE(
1176 TextFormat::ParseFromString(repeated_string_parse_string, &proto));
1177 EXPECT_TRUE(parser.ParseFromString(repeated_string_parse_string, &proto));
1178 EXPECT_THAT(Peer::GetRawIds(no_op_fields), UnorderedElementsAre());
1179 }
1180 }
1181
TEST_F(TextFormatTest,FieldsPopulatedCorrectly)1182 TEST_F(TextFormatTest, FieldsPopulatedCorrectly) {
1183 using Peer = UnsetFieldsMetadataTextFormatTestUtil;
1184 proto3_unittest::TestAllTypes proto;
1185 TextFormat::Parser parser;
1186 TextFormat::Parser::UnsetFieldsMetadata no_op_fields;
1187 parser.OutputNoOpFields(&no_op_fields);
1188 {
1189 no_op_fields = {};
1190 const absl::string_view parse_string = R"pb(
1191 optional_int32: 0
1192 optional_uint32: 10
1193 optional_nested_message { bb: 0 }
1194 )pb";
1195 EXPECT_TRUE(parser.ParseFromString(parse_string, &proto));
1196 EXPECT_THAT(Peer::GetRawIds(no_op_fields),
1197 UnorderedElementsAre(
1198 Peer::GetId(proto, "optional_int32"),
1199 Peer::GetId(proto.optional_nested_message(), "bb")));
1200 }
1201 {
1202 no_op_fields = {};
1203 const absl::string_view parse_string = R"pb(
1204 optional_bool: false
1205 optional_uint32: 10
1206 optional_nested_message { bb: 20 }
1207 )pb";
1208 EXPECT_TRUE(parser.ParseFromString(parse_string, &proto));
1209 EXPECT_THAT(Peer::GetRawIds(no_op_fields),
1210 UnorderedElementsAre(Peer::GetId(proto, "optional_bool")));
1211 }
1212 {
1213 // The address returned by the field is a string_view, which is a separate
1214 // allocation. Check address directly.
1215 no_op_fields = {};
1216 const absl::string_view parse_string = "optional_string: \"\"";
1217 EXPECT_TRUE(parser.ParseFromString(parse_string, &proto));
1218 EXPECT_THAT(Peer::GetRawIds(no_op_fields),
1219 UnorderedElementsAre(Peer::GetId(proto, "optional_string")));
1220 }
1221 {
1222 // The address returned by the field is a string_view, which is a separate
1223 // allocation. Check address directly.
1224 no_op_fields = {};
1225 const absl::string_view parse_string = "optional_bytes: \"\"";
1226 EXPECT_TRUE(parser.ParseFromString(parse_string, &proto));
1227 EXPECT_THAT(Peer::GetRawIds(no_op_fields),
1228 UnorderedElementsAre(Peer::GetId(proto, "optional_bytes")));
1229 }
1230 }
1231
TEST_F(TextFormatTest,ParseStringEscape)1232 TEST_F(TextFormatTest, ParseStringEscape) {
1233 // Create a parse string with escaped characters in it.
1234 std::string parse_string =
1235 absl::StrCat("optional_string: ", kEscapeTestStringEscaped, "\n");
1236
1237 io::ArrayInputStream input_stream(parse_string.data(), parse_string.size());
1238 TextFormat::Parse(&input_stream, &proto_);
1239
1240 // Compare.
1241 EXPECT_EQ(kEscapeTestString, proto_.optional_string());
1242 }
1243
TEST_F(TextFormatTest,ParseConcatenatedString)1244 TEST_F(TextFormatTest, ParseConcatenatedString) {
1245 // Create a parse string with multiple parts on one line.
1246 std::string parse_string = "optional_string: \"foo\" \"bar\"\n";
1247
1248 io::ArrayInputStream input_stream1(parse_string.data(), parse_string.size());
1249 TextFormat::Parse(&input_stream1, &proto_);
1250
1251 // Compare.
1252 EXPECT_EQ("foobar", proto_.optional_string());
1253
1254 // Create a parse string with multiple parts on separate lines.
1255 parse_string =
1256 "optional_string: \"foo\"\n"
1257 "\"bar\"\n";
1258
1259 io::ArrayInputStream input_stream2(parse_string.data(), parse_string.size());
1260 TextFormat::Parse(&input_stream2, &proto_);
1261
1262 // Compare.
1263 EXPECT_EQ("foobar", proto_.optional_string());
1264 }
1265
TEST_F(TextFormatTest,ParseFloatWithSuffix)1266 TEST_F(TextFormatTest, ParseFloatWithSuffix) {
1267 // Test that we can parse a floating-point value with 'f' appended to the
1268 // end. This is needed for backwards-compatibility with proto1.
1269
1270 // Have it parse a float with the 'f' suffix.
1271 std::string parse_string = "optional_float: 1.0f\n";
1272
1273 io::ArrayInputStream input_stream(parse_string.data(), parse_string.size());
1274
1275 TextFormat::Parse(&input_stream, &proto_);
1276
1277 // Compare.
1278 EXPECT_EQ(1.0, proto_.optional_float());
1279 }
1280
TEST_F(TextFormatTest,ParseShortRepeatedForm)1281 TEST_F(TextFormatTest, ParseShortRepeatedForm) {
1282 std::string parse_string =
1283 // Mixed short-form and long-form are simply concatenated.
1284 "repeated_int32: 1\n"
1285 "repeated_int32: [456, 789]\n"
1286 "repeated_nested_enum: [ FOO ,BAR, # comment\n"
1287 " 3]\n"
1288 // Note that while the printer won't print repeated strings in short-form,
1289 // the parser will accept them.
1290 "repeated_string: [ \"foo\", 'bar' ]\n"
1291 // Repeated message
1292 "repeated_nested_message: [ { bb: 1 }, { bb : 2 }]\n"
1293 // Repeated group
1294 "RepeatedGroup [{ a: 3 },{ a: 4 }]\n";
1295
1296 ASSERT_TRUE(TextFormat::ParseFromString(parse_string, &proto_));
1297
1298 ASSERT_EQ(3, proto_.repeated_int32_size());
1299 EXPECT_EQ(1, proto_.repeated_int32(0));
1300 EXPECT_EQ(456, proto_.repeated_int32(1));
1301 EXPECT_EQ(789, proto_.repeated_int32(2));
1302
1303 ASSERT_EQ(3, proto_.repeated_nested_enum_size());
1304 EXPECT_EQ(unittest::TestAllTypes::FOO, proto_.repeated_nested_enum(0));
1305 EXPECT_EQ(unittest::TestAllTypes::BAR, proto_.repeated_nested_enum(1));
1306 EXPECT_EQ(unittest::TestAllTypes::BAZ, proto_.repeated_nested_enum(2));
1307
1308 ASSERT_EQ(2, proto_.repeated_string_size());
1309 EXPECT_EQ("foo", proto_.repeated_string(0));
1310 EXPECT_EQ("bar", proto_.repeated_string(1));
1311
1312 ASSERT_EQ(2, proto_.repeated_nested_message_size());
1313 EXPECT_EQ(1, proto_.repeated_nested_message(0).bb());
1314 EXPECT_EQ(2, proto_.repeated_nested_message(1).bb());
1315
1316 ASSERT_EQ(2, proto_.repeatedgroup_size());
1317 EXPECT_EQ(3, proto_.repeatedgroup(0).a());
1318 EXPECT_EQ(4, proto_.repeatedgroup(1).a());
1319 }
1320
TEST_F(TextFormatTest,ParseShortRepeatedWithTrailingComma)1321 TEST_F(TextFormatTest, ParseShortRepeatedWithTrailingComma) {
1322 std::string parse_string = "repeated_int32: [456,]\n";
1323 ASSERT_FALSE(TextFormat::ParseFromString(parse_string, &proto_));
1324 parse_string = "repeated_nested_enum: [ FOO , ]";
1325 ASSERT_FALSE(TextFormat::ParseFromString(parse_string, &proto_));
1326 parse_string = "repeated_string: [ \"foo\", ]";
1327 ASSERT_FALSE(TextFormat::ParseFromString(parse_string, &proto_));
1328 parse_string = "repeated_nested_message: [ { bb: 1 }, ]";
1329 ASSERT_FALSE(TextFormat::ParseFromString(parse_string, &proto_));
1330 parse_string = "RepeatedGroup [{ a: 3 },]\n";
1331 ASSERT_FALSE(TextFormat::ParseFromString(parse_string, &proto_));
1332 }
1333
TEST_F(TextFormatTest,ParseShortRepeatedEmpty)1334 TEST_F(TextFormatTest, ParseShortRepeatedEmpty) {
1335 std::string parse_string =
1336 "repeated_int32: []\n"
1337 "repeated_nested_enum: []\n"
1338 "repeated_string: []\n"
1339 "repeated_nested_message: []\n"
1340 "RepeatedGroup []\n";
1341
1342 ASSERT_TRUE(TextFormat::ParseFromString(parse_string, &proto_));
1343
1344 EXPECT_EQ(0, proto_.repeated_int32_size());
1345 EXPECT_EQ(0, proto_.repeated_nested_enum_size());
1346 EXPECT_EQ(0, proto_.repeated_string_size());
1347 EXPECT_EQ(0, proto_.repeated_nested_message_size());
1348 EXPECT_EQ(0, proto_.repeatedgroup_size());
1349 }
1350
TEST_F(TextFormatTest,ParseShortRepeatedConcatenatedWithEmpty)1351 TEST_F(TextFormatTest, ParseShortRepeatedConcatenatedWithEmpty) {
1352 std::string parse_string =
1353 // Starting with empty [] should have no impact.
1354 "repeated_int32: []\n"
1355 "repeated_nested_enum: []\n"
1356 "repeated_string: []\n"
1357 "repeated_nested_message: []\n"
1358 "RepeatedGroup []\n"
1359 // Mixed short-form and long-form are simply concatenated.
1360 "repeated_int32: 1\n"
1361 "repeated_int32: [456, 789]\n"
1362 "repeated_nested_enum: [ FOO ,BAR, # comment\n"
1363 " 3]\n"
1364 // Note that while the printer won't print repeated strings in short-form,
1365 // the parser will accept them.
1366 "repeated_string: [ \"foo\", 'bar' ]\n"
1367 // Repeated message
1368 "repeated_nested_message: [ { bb: 1 }, { bb : 2 }]\n"
1369 // Repeated group
1370 "RepeatedGroup [{ a: 3 },{ a: 4 }]\n"
1371 // Adding empty [] should have no impact.
1372 "repeated_int32: []\n"
1373 "repeated_nested_enum: []\n"
1374 "repeated_string: []\n"
1375 "repeated_nested_message: []\n"
1376 "RepeatedGroup []\n";
1377
1378 ASSERT_TRUE(TextFormat::ParseFromString(parse_string, &proto_));
1379
1380 ASSERT_EQ(3, proto_.repeated_int32_size());
1381 EXPECT_EQ(1, proto_.repeated_int32(0));
1382 EXPECT_EQ(456, proto_.repeated_int32(1));
1383 EXPECT_EQ(789, proto_.repeated_int32(2));
1384
1385 ASSERT_EQ(3, proto_.repeated_nested_enum_size());
1386 EXPECT_EQ(unittest::TestAllTypes::FOO, proto_.repeated_nested_enum(0));
1387 EXPECT_EQ(unittest::TestAllTypes::BAR, proto_.repeated_nested_enum(1));
1388 EXPECT_EQ(unittest::TestAllTypes::BAZ, proto_.repeated_nested_enum(2));
1389
1390 ASSERT_EQ(2, proto_.repeated_string_size());
1391 EXPECT_EQ("foo", proto_.repeated_string(0));
1392 EXPECT_EQ("bar", proto_.repeated_string(1));
1393
1394 ASSERT_EQ(2, proto_.repeated_nested_message_size());
1395 EXPECT_EQ(1, proto_.repeated_nested_message(0).bb());
1396 EXPECT_EQ(2, proto_.repeated_nested_message(1).bb());
1397
1398 ASSERT_EQ(2, proto_.repeatedgroup_size());
1399 EXPECT_EQ(3, proto_.repeatedgroup(0).a());
1400 EXPECT_EQ(4, proto_.repeatedgroup(1).a());
1401 }
1402
TEST_F(TextFormatTest,ParseShortRepeatedUnknownEmpty)1403 TEST_F(TextFormatTest, ParseShortRepeatedUnknownEmpty) {
1404 std::string parse_string =
1405 "repeated_string: \"before\"\n"
1406 "unknown_field: []\n"
1407 "repeated_string: \"after\"\n";
1408 TextFormat::Parser parser;
1409 parser.AllowUnknownField(true);
1410
1411 ASSERT_TRUE(parser.ParseFromString(parse_string, &proto_));
1412
1413 EXPECT_EQ(2, proto_.repeated_string_size());
1414 }
1415
1416
TEST_F(TextFormatTest,Comments)1417 TEST_F(TextFormatTest, Comments) {
1418 // Test that comments are ignored.
1419
1420 std::string parse_string =
1421 "optional_int32: 1 # a comment\n"
1422 "optional_int64: 2 # another comment";
1423
1424 io::ArrayInputStream input_stream(parse_string.data(), parse_string.size());
1425
1426 TextFormat::Parse(&input_stream, &proto_);
1427
1428 // Compare.
1429 EXPECT_EQ(1, proto_.optional_int32());
1430 EXPECT_EQ(2, proto_.optional_int64());
1431 }
1432
TEST_F(TextFormatTest,OptionalColon)1433 TEST_F(TextFormatTest, OptionalColon) {
1434 // Test that we can place a ':' after the field name of a nested message,
1435 // even though we don't have to.
1436
1437 std::string parse_string = "optional_nested_message: { bb: 1}\n";
1438
1439 io::ArrayInputStream input_stream(parse_string.data(), parse_string.size());
1440
1441 TextFormat::Parse(&input_stream, &proto_);
1442
1443 // Compare.
1444 EXPECT_TRUE(proto_.has_optional_nested_message());
1445 EXPECT_EQ(1, proto_.optional_nested_message().bb());
1446 }
1447
1448 // Some platforms (e.g. Windows) insist on padding the exponent to three
1449 // digits when one or two would be just fine.
RemoveRedundantZeros(absl::string_view text)1450 static std::string RemoveRedundantZeros(absl::string_view text) {
1451 return absl::StrReplaceAll(text, {{"e+0", "e+"}, {"e-0", "e-"}});
1452 }
1453
TEST_F(TextFormatTest,PrintExotic)1454 TEST_F(TextFormatTest, PrintExotic) {
1455 unittest::TestAllTypes message;
1456
1457 message.add_repeated_int64(int64_t{-9223372036854775807} - 1);
1458 message.add_repeated_uint64(uint64_t{18446744073709551615u});
1459 message.add_repeated_double(123.456);
1460 message.add_repeated_double(1.23e21);
1461 message.add_repeated_double(1.23e-18);
1462 message.add_repeated_double(std::numeric_limits<double>::infinity());
1463 message.add_repeated_double(-std::numeric_limits<double>::infinity());
1464 message.add_repeated_double(std::numeric_limits<double>::quiet_NaN());
1465 message.add_repeated_double(-std::numeric_limits<double>::quiet_NaN());
1466 message.add_repeated_double(std::numeric_limits<double>::signaling_NaN());
1467 message.add_repeated_double(-std::numeric_limits<double>::signaling_NaN());
1468 message.add_repeated_string(std::string("\000\001\a\b\f\n\r\t\v\\\'\"", 12));
1469
1470 // Fun story: We used to use 1.23e22 instead of 1.23e21 above, but this
1471 // seemed to trigger an odd case on MinGW/GCC 3.4.5 where GCC's parsing of
1472 // the value differed from strtod()'s parsing. That is to say, the
1473 // following assertion fails on MinGW:
1474 // assert(1.23e22 == strtod("1.23e22", nullptr));
1475 // As a result, SimpleDtoa() would print the value as
1476 // "1.2300000000000001e+22" to make sure strtod() produce the exact same
1477 // result. Our goal is to test runtime parsing, not compile-time parsing,
1478 // so this wasn't our problem. It was found that using 1.23e21 did not
1479 // have this problem, so we switched to that instead.
1480
1481 EXPECT_EQ(
1482 absl::StrCat(multi_line_debug_format_prefix_,
1483 "repeated_int64: -9223372036854775808\n"
1484 "repeated_uint64: 18446744073709551615\n"
1485 "repeated_double: 123.456\n"
1486 "repeated_double: 1.23e+21\n"
1487 "repeated_double: 1.23e-18\n"
1488 "repeated_double: inf\n"
1489 "repeated_double: -inf\n"
1490 "repeated_double: nan\n"
1491 "repeated_double: nan\n"
1492 "repeated_double: nan\n"
1493 "repeated_double: nan\n"
1494 "repeated_string: "
1495 "\"\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\'\\\"\"\n"),
1496 RemoveRedundantZeros(message.DebugString()));
1497 }
1498
TEST_F(TextFormatTest,PrintFloatPrecision)1499 TEST_F(TextFormatTest, PrintFloatPrecision) {
1500 unittest::TestAllTypes message;
1501
1502 message.add_repeated_float(1.0);
1503 message.add_repeated_float(1.2);
1504 message.add_repeated_float(1.23);
1505 message.add_repeated_float(1.234);
1506 message.add_repeated_float(1.2345);
1507 message.add_repeated_float(1.23456);
1508 message.add_repeated_float(1.2e10);
1509 message.add_repeated_float(1.23e10);
1510 message.add_repeated_float(1.234e10);
1511 message.add_repeated_float(1.2345e10);
1512 message.add_repeated_float(1.23456e10);
1513 message.add_repeated_double(1.2);
1514 message.add_repeated_double(1.23);
1515 message.add_repeated_double(1.234);
1516 message.add_repeated_double(1.2345);
1517 message.add_repeated_double(1.23456);
1518 message.add_repeated_double(1.234567);
1519 message.add_repeated_double(1.2345678);
1520 message.add_repeated_double(1.23456789);
1521 message.add_repeated_double(1.234567898);
1522 message.add_repeated_double(1.2345678987);
1523 message.add_repeated_double(1.23456789876);
1524 message.add_repeated_double(1.234567898765);
1525 message.add_repeated_double(1.2345678987654);
1526 message.add_repeated_double(1.23456789876543);
1527 message.add_repeated_double(1.2e100);
1528 message.add_repeated_double(1.23e100);
1529 message.add_repeated_double(1.234e100);
1530 message.add_repeated_double(1.2345e100);
1531 message.add_repeated_double(1.23456e100);
1532 message.add_repeated_double(1.234567e100);
1533 message.add_repeated_double(1.2345678e100);
1534 message.add_repeated_double(1.23456789e100);
1535 message.add_repeated_double(1.234567898e100);
1536 message.add_repeated_double(1.2345678987e100);
1537 message.add_repeated_double(1.23456789876e100);
1538 message.add_repeated_double(1.234567898765e100);
1539 message.add_repeated_double(1.2345678987654e100);
1540 message.add_repeated_double(1.23456789876543e100);
1541
1542 EXPECT_EQ(absl::StrCat(multi_line_debug_format_prefix_,
1543 "repeated_float: 1\n"
1544 "repeated_float: 1.2\n"
1545 "repeated_float: 1.23\n"
1546 "repeated_float: 1.234\n"
1547 "repeated_float: 1.2345\n"
1548 "repeated_float: 1.23456\n"
1549 "repeated_float: 1.2e+10\n"
1550 "repeated_float: 1.23e+10\n"
1551 "repeated_float: 1.234e+10\n"
1552 "repeated_float: 1.2345e+10\n"
1553 "repeated_float: 1.23456e+10\n"
1554 "repeated_double: 1.2\n"
1555 "repeated_double: 1.23\n"
1556 "repeated_double: 1.234\n"
1557 "repeated_double: 1.2345\n"
1558 "repeated_double: 1.23456\n"
1559 "repeated_double: 1.234567\n"
1560 "repeated_double: 1.2345678\n"
1561 "repeated_double: 1.23456789\n"
1562 "repeated_double: 1.234567898\n"
1563 "repeated_double: 1.2345678987\n"
1564 "repeated_double: 1.23456789876\n"
1565 "repeated_double: 1.234567898765\n"
1566 "repeated_double: 1.2345678987654\n"
1567 "repeated_double: 1.23456789876543\n"
1568 "repeated_double: 1.2e+100\n"
1569 "repeated_double: 1.23e+100\n"
1570 "repeated_double: 1.234e+100\n"
1571 "repeated_double: 1.2345e+100\n"
1572 "repeated_double: 1.23456e+100\n"
1573 "repeated_double: 1.234567e+100\n"
1574 "repeated_double: 1.2345678e+100\n"
1575 "repeated_double: 1.23456789e+100\n"
1576 "repeated_double: 1.234567898e+100\n"
1577 "repeated_double: 1.2345678987e+100\n"
1578 "repeated_double: 1.23456789876e+100\n"
1579 "repeated_double: 1.234567898765e+100\n"
1580 "repeated_double: 1.2345678987654e+100\n"
1581 "repeated_double: 1.23456789876543e+100\n"),
1582 RemoveRedundantZeros(message.DebugString()));
1583 }
1584
TEST_F(TextFormatTest,AllowPartial)1585 TEST_F(TextFormatTest, AllowPartial) {
1586 unittest::TestRequired message;
1587 TextFormat::Parser parser;
1588 parser.AllowPartialMessage(true);
1589 EXPECT_TRUE(parser.ParseFromString("a: 1", &message));
1590 EXPECT_EQ(1, message.a());
1591 EXPECT_FALSE(message.has_b());
1592 EXPECT_FALSE(message.has_c());
1593 }
1594
TEST_F(TextFormatTest,ParseExotic)1595 TEST_F(TextFormatTest, ParseExotic) {
1596 unittest::TestAllTypes message;
1597 ASSERT_TRUE(TextFormat::ParseFromString(
1598 "repeated_int32: -1\n"
1599 "repeated_int32: -2147483648\n"
1600 "repeated_int64: -1\n"
1601 "repeated_int64: -9223372036854775808\n"
1602 "repeated_uint32: 4294967295\n"
1603 "repeated_uint32: 2147483648\n"
1604 "repeated_uint64: 18446744073709551615\n"
1605 "repeated_uint64: 9223372036854775808\n"
1606 "repeated_double: 123.0\n"
1607 "repeated_double: 123.5\n"
1608 "repeated_double: 0.125\n"
1609 "repeated_double: 1.23E17\n"
1610 "repeated_double: 1.235E+22\n"
1611 "repeated_double: 1.235e-18\n"
1612 "repeated_double: 123.456789\n"
1613 "repeated_double: inf\n"
1614 "repeated_double: Infinity\n"
1615 "repeated_double: -inf\n"
1616 "repeated_double: -Infinity\n"
1617 "repeated_double: nan\n"
1618 "repeated_double: NaN\n"
1619 "repeated_string: \"\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"\"\n",
1620 &message));
1621
1622 ASSERT_EQ(2, message.repeated_int32_size());
1623 EXPECT_EQ(-1, message.repeated_int32(0));
1624 EXPECT_EQ(-2147483648, message.repeated_int32(1));
1625
1626 ASSERT_EQ(2, message.repeated_int64_size());
1627 EXPECT_EQ(-1, message.repeated_int64(0));
1628 EXPECT_EQ(int64_t{-9223372036854775807} - 1, message.repeated_int64(1));
1629
1630 ASSERT_EQ(2, message.repeated_uint32_size());
1631 EXPECT_EQ(4294967295u, message.repeated_uint32(0));
1632 EXPECT_EQ(2147483648u, message.repeated_uint32(1));
1633
1634 ASSERT_EQ(2, message.repeated_uint64_size());
1635 EXPECT_EQ(uint64_t{18446744073709551615u}, message.repeated_uint64(0));
1636 EXPECT_EQ(uint64_t{9223372036854775808u}, message.repeated_uint64(1));
1637
1638 ASSERT_EQ(13, message.repeated_double_size());
1639 EXPECT_EQ(123.0, message.repeated_double(0));
1640 EXPECT_EQ(123.5, message.repeated_double(1));
1641 EXPECT_EQ(0.125, message.repeated_double(2));
1642 EXPECT_EQ(1.23E17, message.repeated_double(3));
1643 EXPECT_EQ(1.235E22, message.repeated_double(4));
1644 EXPECT_EQ(1.235E-18, message.repeated_double(5));
1645 EXPECT_EQ(123.456789, message.repeated_double(6));
1646 EXPECT_EQ(message.repeated_double(7),
1647 std::numeric_limits<double>::infinity());
1648 EXPECT_EQ(message.repeated_double(8),
1649 std::numeric_limits<double>::infinity());
1650 EXPECT_EQ(message.repeated_double(9),
1651 -std::numeric_limits<double>::infinity());
1652 EXPECT_EQ(message.repeated_double(10),
1653 -std::numeric_limits<double>::infinity());
1654 EXPECT_TRUE(std::isnan(message.repeated_double(11)));
1655 EXPECT_TRUE(std::isnan(message.repeated_double(12)));
1656
1657 // Note: Since these string literals have \0's in them, we must explicitly
1658 // pass their sizes to string's constructor.
1659 ASSERT_EQ(1, message.repeated_string_size());
1660 EXPECT_EQ(std::string("\000\001\a\b\f\n\r\t\v\\\'\"", 12),
1661 message.repeated_string(0));
1662
1663 ASSERT_TRUE(
1664 TextFormat::ParseFromString("repeated_float: 3.4028235e+38\n"
1665 "repeated_float: -3.4028235e+38\n"
1666 "repeated_float: 3.402823567797337e+38\n"
1667 "repeated_float: -3.402823567797337e+38\n",
1668 &message));
1669 EXPECT_EQ(message.repeated_float(0), std::numeric_limits<float>::max());
1670 EXPECT_EQ(message.repeated_float(1), -std::numeric_limits<float>::max());
1671 EXPECT_EQ(message.repeated_float(2), std::numeric_limits<float>::infinity());
1672 EXPECT_EQ(message.repeated_float(3), -std::numeric_limits<float>::infinity());
1673
1674 }
1675
TEST_F(TextFormatTest,PrintFieldsInIndexOrder)1676 TEST_F(TextFormatTest, PrintFieldsInIndexOrder) {
1677 protobuf_unittest::TestFieldOrderings message;
1678 // Fields are listed in index order instead of field number.
1679 message.set_my_string("str"); // Field number 11
1680 message.set_my_int(12345); // Field number 1
1681 message.set_my_float(0.999); // Field number 101
1682 // Extensions are listed based on the order of extension number.
1683 // Extension number 12.
1684 message
1685 .MutableExtension(
1686 protobuf_unittest::TestExtensionOrderings2::test_ext_orderings2)
1687 ->set_my_string("ext_str2");
1688 // Extension number 13.
1689 message
1690 .MutableExtension(
1691 protobuf_unittest::TestExtensionOrderings1::test_ext_orderings1)
1692 ->set_my_string("ext_str1");
1693 // Extension number 14.
1694 message
1695 .MutableExtension(protobuf_unittest::TestExtensionOrderings2::
1696 TestExtensionOrderings3::test_ext_orderings3)
1697 ->set_my_string("ext_str3");
1698 // Extension number 50.
1699 *message.MutableExtension(protobuf_unittest::my_extension_string) = "ext_str0";
1700
1701 TextFormat::Printer printer;
1702 std::string text;
1703
1704 // By default, print in field number order.
1705 // my_int: 12345
1706 // my_string: "str"
1707 // [protobuf_unittest.TestExtensionOrderings2.test_ext_orderings2] {
1708 // my_string: "ext_str2"
1709 // }
1710 // [protobuf_unittest.TestExtensionOrderings1.test_ext_orderings1] {
1711 // my_string: "ext_str1"
1712 // }
1713 // [protobuf_unittest.TestExtensionOrderings2.TestExtensionOrderings3.test_ext_orderings3]
1714 // {
1715 // my_string: "ext_str3"
1716 // }
1717 // [protobuf_unittest.my_extension_string]: "ext_str0"
1718 // my_float: 0.999
1719 printer.PrintToString(message, &text);
1720 EXPECT_EQ(
1721 "my_int: 12345\nmy_string: "
1722 "\"str\"\n[protobuf_unittest.TestExtensionOrderings2.test_ext_orderings2] "
1723 "{\n my_string: "
1724 "\"ext_str2\"\n}\n[protobuf_unittest.TestExtensionOrderings1.test_ext_"
1725 "orderings1] {\n my_string: "
1726 "\"ext_str1\"\n}\n[protobuf_unittest.TestExtensionOrderings2."
1727 "TestExtensionOrderings3.test_ext_orderings3] {\n my_string: "
1728 "\"ext_str3\"\n}\n[protobuf_unittest.my_extension_string]: "
1729 "\"ext_str0\"\nmy_float: 0.999\n",
1730 text);
1731
1732 // Print in index order.
1733 // my_string: "str"
1734 // my_int: 12345
1735 // my_float: 0.999
1736 // [protobuf_unittest.TestExtensionOrderings2.test_ext_orderings2] {
1737 // my_string: "ext_str2"
1738 // }
1739 // [protobuf_unittest.TestExtensionOrderings1.test_ext_orderings1] {
1740 // my_string: "ext_str1"
1741 // }
1742 // [protobuf_unittest.TestExtensionOrderings2.TestExtensionOrderings3.test_ext_orderings3]
1743 // {
1744 // my_string: "ext_str3"
1745 // }
1746 // [protobuf_unittest.my_extension_string]: "ext_str0"
1747 printer.SetPrintMessageFieldsInIndexOrder(true);
1748 printer.PrintToString(message, &text);
1749 EXPECT_EQ(
1750 "my_string: \"str\"\nmy_int: 12345\nmy_float: "
1751 "0.999\n[protobuf_unittest.TestExtensionOrderings2.test_ext_orderings2] "
1752 "{\n my_string: "
1753 "\"ext_str2\"\n}\n[protobuf_unittest.TestExtensionOrderings1.test_ext_"
1754 "orderings1] {\n my_string: "
1755 "\"ext_str1\"\n}\n[protobuf_unittest.TestExtensionOrderings2."
1756 "TestExtensionOrderings3.test_ext_orderings3] {\n my_string: "
1757 "\"ext_str3\"\n}\n[protobuf_unittest.my_extension_string]: \"ext_str0\"\n",
1758 text);
1759 }
1760
1761 class TextFormatParserTest : public testing::Test {
1762 protected:
ExpectFailure(const std::string & input,const std::string & message,int line,int col)1763 void ExpectFailure(const std::string& input, const std::string& message,
1764 int line, int col) {
1765 std::unique_ptr<unittest::TestAllTypes> proto(new unittest::TestAllTypes);
1766 ExpectFailure(input, message, line, col, proto.get());
1767 }
1768
ExpectFailure(const std::string & input,const std::string & message,int line,int col,Message * proto)1769 void ExpectFailure(const std::string& input, const std::string& message,
1770 int line, int col, Message* proto) {
1771 ExpectMessage(input, message, line, col, proto, false);
1772 }
1773
ExpectMessage(const std::string & input,const std::string & message,int line,int col,Message * proto,bool expected_result)1774 void ExpectMessage(const std::string& input, const std::string& message,
1775 int line, int col, Message* proto, bool expected_result) {
1776 MockErrorCollector error_collector;
1777 parser_.RecordErrorsTo(&error_collector);
1778 EXPECT_EQ(expected_result, parser_.ParseFromString(input, proto))
1779 << input << " -> " << proto->DebugString();
1780 EXPECT_EQ(absl::StrCat(line, ":", col, ": ", message, "\n"),
1781 error_collector.text_);
1782 parser_.RecordErrorsTo(nullptr);
1783 }
1784
ExpectSuccessAndTree(const std::string & input,Message * proto,TextFormat::ParseInfoTree * info_tree)1785 void ExpectSuccessAndTree(const std::string& input, Message* proto,
1786 TextFormat::ParseInfoTree* info_tree) {
1787 MockErrorCollector error_collector;
1788 parser_.RecordErrorsTo(&error_collector);
1789 parser_.WriteLocationsTo(info_tree);
1790 EXPECT_TRUE(parser_.ParseFromString(input, proto));
1791 parser_.WriteLocationsTo(nullptr);
1792 parser_.RecordErrorsTo(nullptr);
1793 }
1794
ExpectLocation(TextFormat::ParseInfoTree * tree,const Descriptor * d,const std::string & field_name,int index,int start_line,int start_column,int end_line,int end_column)1795 void ExpectLocation(TextFormat::ParseInfoTree* tree, const Descriptor* d,
1796 const std::string& field_name, int index, int start_line,
1797 int start_column, int end_line, int end_column) {
1798 TextFormat::ParseLocationRange range =
1799 tree->GetLocationRange(d->FindFieldByName(field_name), index);
1800 EXPECT_EQ(start_line, range.start.line);
1801 EXPECT_EQ(start_column, range.start.column);
1802 EXPECT_EQ(end_line, range.end.line);
1803 EXPECT_EQ(end_column, range.end.column);
1804 TextFormat::ParseLocation start_location =
1805 tree->GetLocation(d->FindFieldByName(field_name), index);
1806 EXPECT_EQ(start_line, start_location.line);
1807 EXPECT_EQ(start_column, start_location.column);
1808 }
1809
1810 // An error collector which simply concatenates all its errors into a big
1811 // block of text which can be checked.
1812 class MockErrorCollector : public io::ErrorCollector {
1813 public:
MockErrorCollector()1814 MockErrorCollector() {}
~MockErrorCollector()1815 ~MockErrorCollector() override {}
1816
1817 std::string text_;
1818
1819 // implements ErrorCollector -------------------------------------
RecordError(int line,int column,absl::string_view message)1820 void RecordError(int line, int column, absl::string_view message) override {
1821 absl::SubstituteAndAppend(&text_, "$0:$1: $2\n", line + 1, column + 1,
1822 message);
1823 }
1824
RecordWarning(int line,int column,absl::string_view message)1825 void RecordWarning(int line, int column,
1826 absl::string_view message) override {
1827 RecordError(line, column, absl::StrCat("WARNING:", message));
1828 }
1829 };
1830
1831 TextFormat::Parser parser_;
1832 };
1833
TEST_F(TextFormatParserTest,ParseInfoTreeBuilding)1834 TEST_F(TextFormatParserTest, ParseInfoTreeBuilding) {
1835 std::unique_ptr<unittest::TestAllTypes> message(new unittest::TestAllTypes);
1836 const Descriptor* d = message->GetDescriptor();
1837
1838 std::string stringData =
1839 "optional_int32: 1\n"
1840 "optional_int64: 2\n"
1841 " optional_double: 2.4\n"
1842 "repeated_int32: 5\n"
1843 "repeated_int32: 10\n"
1844 "optional_nested_message <\n"
1845 " bb: 78\n"
1846 ">\n"
1847 "repeated_nested_message <\n"
1848 " bb: 79\n"
1849 ">\n"
1850 "repeated_nested_message <\n"
1851 " bb: 80\n"
1852 ">";
1853
1854 TextFormat::ParseInfoTree tree;
1855 ExpectSuccessAndTree(stringData, message.get(), &tree);
1856
1857 // Verify that the tree has the correct positions.
1858 ExpectLocation(&tree, d, "optional_int32", -1, 0, 0, 0, 17);
1859 ExpectLocation(&tree, d, "optional_int64", -1, 1, 0, 1, 17);
1860 ExpectLocation(&tree, d, "optional_double", -1, 2, 2, 2, 22);
1861
1862 ExpectLocation(&tree, d, "repeated_int32", 0, 3, 0, 3, 17);
1863 ExpectLocation(&tree, d, "repeated_int32", 1, 4, 0, 4, 18);
1864
1865 ExpectLocation(&tree, d, "optional_nested_message", -1, 5, 0, 7, 1);
1866 ExpectLocation(&tree, d, "repeated_nested_message", 0, 8, 0, 10, 1);
1867 ExpectLocation(&tree, d, "repeated_nested_message", 1, 11, 0, 13, 1);
1868
1869 // Check for fields not set. For an invalid field, the start and end locations
1870 // returned should be -1, -1.
1871 ExpectLocation(&tree, d, "repeated_int64", 0, -1, -1, -1, -1);
1872 ExpectLocation(&tree, d, "repeated_int32", 6, -1, -1, -1, -1);
1873 ExpectLocation(&tree, d, "some_unknown_field", -1, -1, -1, -1, -1);
1874
1875 // Verify inside the nested message.
1876 const FieldDescriptor* nested_field =
1877 d->FindFieldByName("optional_nested_message");
1878
1879 TextFormat::ParseInfoTree* nested_tree =
1880 tree.GetTreeForNested(nested_field, -1);
1881 ExpectLocation(nested_tree, nested_field->message_type(), "bb", -1, 6, 2, 6,
1882 8);
1883
1884 // Verify inside another nested message.
1885 nested_field = d->FindFieldByName("repeated_nested_message");
1886 nested_tree = tree.GetTreeForNested(nested_field, 0);
1887 ExpectLocation(nested_tree, nested_field->message_type(), "bb", -1, 9, 2, 9,
1888 8);
1889
1890 nested_tree = tree.GetTreeForNested(nested_field, 1);
1891 ExpectLocation(nested_tree, nested_field->message_type(), "bb", -1, 12, 2, 12,
1892 8);
1893
1894 // Verify a nullptr tree for an unknown nested field.
1895 TextFormat::ParseInfoTree* unknown_nested_tree =
1896 tree.GetTreeForNested(nested_field, 2);
1897
1898 EXPECT_EQ(nullptr, unknown_nested_tree);
1899 }
1900
TEST_F(TextFormatParserTest,ParseFieldValueFromString)1901 TEST_F(TextFormatParserTest, ParseFieldValueFromString) {
1902 std::unique_ptr<unittest::TestAllTypes> message(new unittest::TestAllTypes);
1903 const Descriptor* d = message->GetDescriptor();
1904
1905 #define EXPECT_FIELD(name, value, valuestring) \
1906 EXPECT_TRUE(TextFormat::ParseFieldValueFromString( \
1907 valuestring, d->FindFieldByName("optional_" #name), message.get())); \
1908 EXPECT_EQ(value, message->optional_##name()); \
1909 EXPECT_TRUE(message->has_optional_##name());
1910
1911 #define EXPECT_BOOL_FIELD(name, value, valuestring) \
1912 EXPECT_TRUE(TextFormat::ParseFieldValueFromString( \
1913 valuestring, d->FindFieldByName("optional_" #name), message.get())); \
1914 EXPECT_TRUE(message->optional_##name() == value); \
1915 EXPECT_TRUE(message->has_optional_##name());
1916
1917 #define EXPECT_FLOAT_FIELD(name, value, valuestring) \
1918 EXPECT_TRUE(TextFormat::ParseFieldValueFromString( \
1919 valuestring, d->FindFieldByName("optional_" #name), message.get())); \
1920 EXPECT_FLOAT_EQ(value, message->optional_##name()); \
1921 EXPECT_TRUE(message->has_optional_##name());
1922
1923 #define EXPECT_DOUBLE_FIELD(name, value, valuestring) \
1924 EXPECT_TRUE(TextFormat::ParseFieldValueFromString( \
1925 valuestring, d->FindFieldByName("optional_" #name), message.get())); \
1926 EXPECT_DOUBLE_EQ(value, message->optional_##name()); \
1927 EXPECT_TRUE(message->has_optional_##name());
1928
1929 #define EXPECT_INVALID(name, valuestring) \
1930 EXPECT_FALSE(TextFormat::ParseFieldValueFromString( \
1931 valuestring, d->FindFieldByName("optional_" #name), message.get()));
1932
1933 // int32
1934 EXPECT_FIELD(int32, 1, "1");
1935 EXPECT_FIELD(int32, -1, "-1");
1936 EXPECT_FIELD(int32, 0x1234, "0x1234");
1937 EXPECT_INVALID(int32, "a");
1938 EXPECT_INVALID(int32, "999999999999999999999999999999999999");
1939 EXPECT_INVALID(int32, "1,2");
1940
1941 // int64
1942 EXPECT_FIELD(int64, 1, "1");
1943 EXPECT_FIELD(int64, -1, "-1");
1944 EXPECT_FIELD(int64, 0x1234567812345678LL, "0x1234567812345678");
1945 EXPECT_INVALID(int64, "a");
1946 EXPECT_INVALID(int64, "999999999999999999999999999999999999");
1947 EXPECT_INVALID(int64, "1,2");
1948
1949 // uint64
1950 EXPECT_FIELD(uint64, 1, "1");
1951 EXPECT_FIELD(uint64, 0xf234567812345678ULL, "0xf234567812345678");
1952 EXPECT_INVALID(uint64, "-1");
1953 EXPECT_INVALID(uint64, "a");
1954 EXPECT_INVALID(uint64, "999999999999999999999999999999999999");
1955 EXPECT_INVALID(uint64, "1,2");
1956
1957 // fixed32
1958 EXPECT_FIELD(fixed32, 1, "1");
1959 EXPECT_FIELD(fixed32, 0x12345678, "0x12345678");
1960 EXPECT_INVALID(fixed32, "-1");
1961 EXPECT_INVALID(fixed32, "a");
1962 EXPECT_INVALID(fixed32, "999999999999999999999999999999999999");
1963 EXPECT_INVALID(fixed32, "1,2");
1964
1965 // fixed64
1966 EXPECT_FIELD(fixed64, 1, "1");
1967 EXPECT_FIELD(fixed64, 0x1234567812345678ULL, "0x1234567812345678");
1968 EXPECT_INVALID(fixed64, "-1");
1969 EXPECT_INVALID(fixed64, "a");
1970 EXPECT_INVALID(fixed64, "999999999999999999999999999999999999");
1971 EXPECT_INVALID(fixed64, "1,2");
1972
1973 // bool
1974 EXPECT_BOOL_FIELD(bool, true, "true");
1975 EXPECT_BOOL_FIELD(bool, false, "false");
1976 EXPECT_BOOL_FIELD(bool, true, "1");
1977 EXPECT_BOOL_FIELD(bool, true, "t");
1978 EXPECT_BOOL_FIELD(bool, false, "0");
1979 EXPECT_BOOL_FIELD(bool, false, "f");
1980 EXPECT_FIELD(bool, true, "True");
1981 EXPECT_FIELD(bool, false, "False");
1982 EXPECT_INVALID(bool, "tRue");
1983 EXPECT_INVALID(bool, "faLse");
1984 EXPECT_INVALID(bool, "2");
1985 EXPECT_INVALID(bool, "-0");
1986 EXPECT_INVALID(bool, "on");
1987 EXPECT_INVALID(bool, "a");
1988
1989 // float
1990 EXPECT_FIELD(float, 1, "1");
1991 EXPECT_FLOAT_FIELD(float, 1.5, "1.5");
1992 EXPECT_FLOAT_FIELD(float, 1.5e3, "1.5e3");
1993 EXPECT_FLOAT_FIELD(float, -4.55, "-4.55");
1994 EXPECT_INVALID(float, "a");
1995 EXPECT_INVALID(float, "1,2");
1996
1997 // double
1998 EXPECT_FIELD(double, 1, "1");
1999 EXPECT_FIELD(double, -1, "-1");
2000 EXPECT_DOUBLE_FIELD(double, 2.3, "2.3");
2001 EXPECT_DOUBLE_FIELD(double, 3e5, "3e5");
2002 EXPECT_INVALID(double, "a");
2003 EXPECT_INVALID(double, "1,2");
2004 // Rejects hex and oct numbers for a double field.
2005 EXPECT_INVALID(double, "0xf");
2006 EXPECT_INVALID(double, "012");
2007
2008 // string
2009 EXPECT_FIELD(string, "hello", "\"hello\"");
2010 EXPECT_FIELD(string, "-1.87", "'-1.87'");
2011 EXPECT_INVALID(string, "hello"); // without quote for value
2012
2013 // enum
2014 EXPECT_FIELD(nested_enum, unittest::TestAllTypes::BAR, "BAR");
2015 EXPECT_FIELD(nested_enum, unittest::TestAllTypes::BAZ,
2016 absl::StrCat(unittest::TestAllTypes::BAZ));
2017 EXPECT_INVALID(nested_enum, "FOOBAR");
2018
2019 // message
2020 EXPECT_TRUE(TextFormat::ParseFieldValueFromString(
2021 "<bb:12>", d->FindFieldByName("optional_nested_message"), message.get()));
2022 EXPECT_EQ(12, message->optional_nested_message().bb());
2023 EXPECT_TRUE(message->has_optional_nested_message());
2024 EXPECT_INVALID(nested_message, "any");
2025
2026 #undef EXPECT_FIELD
2027 #undef EXPECT_BOOL_FIELD
2028 #undef EXPECT_FLOAT_FIELD
2029 #undef EXPECT_DOUBLE_FIELD
2030 #undef EXPECT_INVALID
2031 }
2032
TEST_F(TextFormatParserTest,InvalidToken)2033 TEST_F(TextFormatParserTest, InvalidToken) {
2034 ExpectFailure("optional_bool: true\n-5\n", "Expected identifier, got: -", 2,
2035 1);
2036
2037 ExpectFailure("optional_bool: true!\n", "Expected identifier, got: !", 1, 20);
2038 ExpectFailure("\"some string\"", "Expected identifier, got: \"some string\"",
2039 1, 1);
2040 }
2041
2042
TEST_F(TextFormatParserTest,InvalidFieldName)2043 TEST_F(TextFormatParserTest, InvalidFieldName) {
2044 ExpectFailure(
2045 "invalid_field: somevalue\n",
2046 "Message type \"protobuf_unittest.TestAllTypes\" has no field named "
2047 "\"invalid_field\".",
2048 1, 14);
2049 }
2050
TEST_F(TextFormatParserTest,GroupCapitalization)2051 TEST_F(TextFormatParserTest, GroupCapitalization) {
2052 // We allow group names to be the field or message name.
2053 unittest::TestAllTypes proto;
2054 EXPECT_TRUE(parser_.ParseFromString("optionalgroup {\na: 15\n}\n", &proto));
2055 EXPECT_TRUE(parser_.ParseFromString("OptionalGroup {\na: 15\n}\n", &proto));
2056
2057 ExpectFailure(
2058 "OPTIONALgroup {\na: 15\n}\n",
2059 "Message type \"protobuf_unittest.TestAllTypes\" has no field named "
2060 "\"OPTIONALgroup\".",
2061 1, 15);
2062 ExpectFailure(
2063 "Optional_Double: 10.0\n",
2064 "Message type \"protobuf_unittest.TestAllTypes\" has no field named "
2065 "\"Optional_Double\".",
2066 1, 16);
2067 }
2068
TEST_F(TextFormatParserTest,DelimitedCapitalization)2069 TEST_F(TextFormatParserTest, DelimitedCapitalization) {
2070 editions_unittest::TestDelimited proto;
2071 EXPECT_TRUE(parser_.ParseFromString("grouplike {\na: 1\n}\n", &proto));
2072 EXPECT_EQ(proto.grouplike().a(), 1);
2073 EXPECT_TRUE(parser_.ParseFromString("GroupLike {\na: 12\n}\n", &proto));
2074 EXPECT_EQ(proto.grouplike().a(), 12);
2075 EXPECT_TRUE(parser_.ParseFromString("notgrouplike {\na: 15\n}\n", &proto));
2076 EXPECT_EQ(proto.notgrouplike().a(), 15);
2077
2078 ExpectFailure(
2079 "groupLike {\na: 15\n}\n",
2080 "Message type \"editions_unittest.TestDelimited\" has no field named "
2081 "\"groupLike\".",
2082 1, 11, &proto);
2083 ExpectFailure(
2084 "notGroupLike {\na: 15\n}\n",
2085 "Message type \"editions_unittest.TestDelimited\" has no field named "
2086 "\"notGroupLike\".",
2087 1, 14, &proto);
2088 }
2089
TEST_F(TextFormatParserTest,AllowIgnoreCapitalizationError)2090 TEST_F(TextFormatParserTest, AllowIgnoreCapitalizationError) {
2091 TextFormat::Parser parser;
2092 protobuf_unittest::TestAllTypes proto;
2093
2094 // These fields have a mismatching case.
2095 EXPECT_FALSE(parser.ParseFromString("Optional_Double: 10.0", &proto));
2096 EXPECT_FALSE(parser.ParseFromString("oPtIoNaLgRoUp { a: 15 }", &proto));
2097
2098 // ... but are parsed correctly if we match case insensitive.
2099 parser.AllowCaseInsensitiveField(true);
2100 EXPECT_TRUE(parser.ParseFromString("Optional_Double: 10.0", &proto));
2101 EXPECT_EQ(10.0, proto.optional_double());
2102 EXPECT_TRUE(parser.ParseFromString("oPtIoNaLgRoUp { a: 15 }", &proto));
2103 EXPECT_EQ(15, proto.optionalgroup().a());
2104 }
2105
TEST_F(TextFormatParserTest,InvalidFieldValues)2106 TEST_F(TextFormatParserTest, InvalidFieldValues) {
2107 // Invalid values for a double/float field.
2108 ExpectFailure("optional_double: \"hello\"\n",
2109 "Expected double, got: \"hello\"", 1, 18);
2110 ExpectFailure("optional_double: true\n", "Expected double, got: true", 1, 18);
2111 ExpectFailure("optional_double: !\n", "Expected double, got: !", 1, 18);
2112 ExpectFailure("optional_double {\n \n}\n", "Expected \":\", found \"{\".", 1,
2113 17);
2114
2115 // Invalid values for a signed integer field.
2116 ExpectFailure("optional_int32: \"hello\"\n",
2117 "Expected integer, got: \"hello\"", 1, 17);
2118 ExpectFailure("optional_int32: true\n", "Expected integer, got: true", 1, 17);
2119 ExpectFailure("optional_int32: 4.5\n", "Expected integer, got: 4.5", 1, 17);
2120 ExpectFailure("optional_int32: !\n", "Expected integer, got: !", 1, 17);
2121 ExpectFailure("optional_int32 {\n \n}\n", "Expected \":\", found \"{\".", 1,
2122 16);
2123 ExpectFailure("optional_int32: 0x80000000\n",
2124 "Integer out of range (0x80000000)", 1, 17);
2125 ExpectFailure("optional_int64: 0x8000000000000000\n",
2126 "Integer out of range (0x8000000000000000)", 1, 17);
2127 ExpectFailure("optional_int32: -0x80000001\n",
2128 "Integer out of range (0x80000001)", 1, 18);
2129 ExpectFailure("optional_int64: -0x8000000000000001\n",
2130 "Integer out of range (0x8000000000000001)", 1, 18);
2131
2132 // Invalid values for an unsigned integer field.
2133 ExpectFailure("optional_uint64: \"hello\"\n",
2134 "Expected integer, got: \"hello\"", 1, 18);
2135 ExpectFailure("optional_uint64: true\n", "Expected integer, got: true", 1,
2136 18);
2137 ExpectFailure("optional_uint64: 4.5\n", "Expected integer, got: 4.5", 1, 18);
2138 ExpectFailure("optional_uint64: -5\n", "Expected integer, got: -", 1, 18);
2139 ExpectFailure("optional_uint64: !\n", "Expected integer, got: !", 1, 18);
2140 ExpectFailure("optional_uint64 {\n \n}\n", "Expected \":\", found \"{\".", 1,
2141 17);
2142 ExpectFailure("optional_uint32: 0x100000000\n",
2143 "Integer out of range (0x100000000)", 1, 18);
2144 ExpectFailure("optional_uint64: 0x10000000000000000\n",
2145 "Integer out of range (0x10000000000000000)", 1, 18);
2146
2147 // Invalid values for a boolean field.
2148 ExpectFailure("optional_bool: \"hello\"\n",
2149 "Expected identifier, got: \"hello\"", 1, 16);
2150 ExpectFailure("optional_bool: 5\n", "Integer out of range (5)", 1, 16);
2151 ExpectFailure("optional_bool: -7.5\n", "Expected identifier, got: -", 1, 16);
2152 ExpectFailure("optional_bool: !\n", "Expected identifier, got: !", 1, 16);
2153
2154 ExpectFailure(
2155 "optional_bool: meh\n",
2156 "Invalid value for boolean field \"optional_bool\". Value: \"meh\".", 2,
2157 1);
2158
2159 ExpectFailure("optional_bool {\n \n}\n", "Expected \":\", found \"{\".", 1,
2160 15);
2161
2162 // Invalid values for a string field.
2163 ExpectFailure("optional_string: true\n", "Expected string, got: true", 1, 18);
2164 ExpectFailure("optional_string: 5\n", "Expected string, got: 5", 1, 18);
2165 ExpectFailure("optional_string: -7.5\n", "Expected string, got: -", 1, 18);
2166 ExpectFailure("optional_string: !\n", "Expected string, got: !", 1, 18);
2167 ExpectFailure("optional_string {\n \n}\n", "Expected \":\", found \"{\".", 1,
2168 17);
2169
2170 // Invalid values for an enumeration field.
2171 ExpectFailure("optional_nested_enum: \"hello\"\n",
2172 "Expected integer or identifier, got: \"hello\"", 1, 23);
2173
2174 // Valid token, but enum value is not defined.
2175 ExpectFailure("optional_nested_enum: 5\n",
2176 "Unknown enumeration value of \"5\" for field "
2177 "\"optional_nested_enum\".",
2178 2, 1);
2179 // We consume the negative sign, so the error position starts one character
2180 // later.
2181 ExpectFailure("optional_nested_enum: -7.5\n", "Expected integer, got: 7.5", 1,
2182 24);
2183 ExpectFailure("optional_nested_enum: !\n",
2184 "Expected integer or identifier, got: !", 1, 23);
2185
2186 ExpectFailure("optional_nested_enum: grah\n",
2187 "Unknown enumeration value of \"grah\" for field "
2188 "\"optional_nested_enum\".",
2189 2, 1);
2190
2191 ExpectFailure("optional_nested_enum {\n \n}\n",
2192 "Expected \":\", found \"{\".", 1, 22);
2193 }
2194
TEST_F(TextFormatParserTest,MessageDelimiters)2195 TEST_F(TextFormatParserTest, MessageDelimiters) {
2196 // Non-matching delimiters.
2197 ExpectFailure("OptionalGroup <\n \n}\n", "Expected \">\", found \"}\".", 3,
2198 1);
2199
2200 // Invalid delimiters.
2201 ExpectFailure("OptionalGroup [\n \n]\n", "Expected \"{\", found \"[\".", 1,
2202 15);
2203
2204 // Unending message.
2205 ExpectFailure("optional_nested_message {\n \nbb: 118\n",
2206 "Expected identifier, got: ", 4, 1);
2207 }
2208
TEST_F(TextFormatParserTest,UnknownExtension)2209 TEST_F(TextFormatParserTest, UnknownExtension) {
2210 // Non-matching delimiters.
2211 ExpectFailure("[blahblah]: 123",
2212 "Extension \"blahblah\" is not defined or is not an "
2213 "extension of \"protobuf_unittest.TestAllTypes\".",
2214 1, 11);
2215 }
2216
TEST_F(TextFormatParserTest,MissingRequired)2217 TEST_F(TextFormatParserTest, MissingRequired) {
2218 unittest::TestRequired message;
2219 ExpectFailure("a: 1", "Message missing required fields: b, c", 0, 1,
2220 &message);
2221 }
2222
TEST_F(TextFormatParserTest,ParseDuplicateRequired)2223 TEST_F(TextFormatParserTest, ParseDuplicateRequired) {
2224 unittest::TestRequired message;
2225 ExpectFailure("a: 1 b: 2 c: 3 a: 1",
2226 "Non-repeated field \"a\" is specified multiple times.", 1, 17,
2227 &message);
2228 }
2229
TEST_F(TextFormatParserTest,ParseDuplicateOptional)2230 TEST_F(TextFormatParserTest, ParseDuplicateOptional) {
2231 unittest::ForeignMessage message;
2232 ExpectFailure("c: 1 c: 2",
2233 "Non-repeated field \"c\" is specified multiple times.", 1, 7,
2234 &message);
2235 }
2236
TEST_F(TextFormatParserTest,MergeDuplicateRequired)2237 TEST_F(TextFormatParserTest, MergeDuplicateRequired) {
2238 unittest::TestRequired message;
2239 TextFormat::Parser parser;
2240 EXPECT_TRUE(parser.MergeFromString("a: 1 b: 2 c: 3 a: 4", &message));
2241 EXPECT_EQ(4, message.a());
2242 }
2243
TEST_F(TextFormatParserTest,MergeDuplicateOptional)2244 TEST_F(TextFormatParserTest, MergeDuplicateOptional) {
2245 unittest::ForeignMessage message;
2246 TextFormat::Parser parser;
2247 EXPECT_TRUE(parser.MergeFromString("c: 1 c: 2", &message));
2248 EXPECT_EQ(2, message.c());
2249 }
2250
TEST_F(TextFormatParserTest,ExplicitDelimiters)2251 TEST_F(TextFormatParserTest, ExplicitDelimiters) {
2252 unittest::TestRequired message;
2253 EXPECT_TRUE(TextFormat::ParseFromString("a:1,b:2;c:3", &message));
2254 EXPECT_EQ(1, message.a());
2255 EXPECT_EQ(2, message.b());
2256 EXPECT_EQ(3, message.c());
2257 }
2258
TEST_F(TextFormatParserTest,PrintErrorsToStderr)2259 TEST_F(TextFormatParserTest, PrintErrorsToStderr) {
2260 {
2261 absl::ScopedMockLog log(absl::MockLogDefault::kDisallowUnexpected);
2262 EXPECT_CALL(
2263 log,
2264 Log(absl::LogSeverity::kError, testing::_,
2265 "Error parsing text-format protobuf_unittest.TestAllTypes: "
2266 "1:14: Message type \"protobuf_unittest.TestAllTypes\" has no field "
2267 "named \"no_such_field\"."))
2268 .Times(1);
2269 log.StartCapturingLogs();
2270 unittest::TestAllTypes proto;
2271 EXPECT_FALSE(TextFormat::ParseFromString("no_such_field: 1", &proto));
2272 }
2273 }
2274
TEST_F(TextFormatParserTest,FailsOnTokenizationError)2275 TEST_F(TextFormatParserTest, FailsOnTokenizationError) {
2276 {
2277 absl::ScopedMockLog log(absl::MockLogDefault::kDisallowUnexpected);
2278 EXPECT_CALL(log,
2279 Log(absl::LogSeverity::kError, testing::_,
2280 "Error parsing text-format protobuf_unittest.TestAllTypes: "
2281 "1:1: Invalid control characters encountered in text."))
2282 .Times(1);
2283 log.StartCapturingLogs();
2284 unittest::TestAllTypes proto;
2285 EXPECT_FALSE(TextFormat::ParseFromString("\020", &proto));
2286 }
2287 }
2288
TEST_F(TextFormatParserTest,ParseDeprecatedField)2289 TEST_F(TextFormatParserTest, ParseDeprecatedField) {
2290 unittest::TestDeprecatedFields message;
2291 ExpectMessage("deprecated_int32: 42",
2292 "WARNING:text format contains deprecated field "
2293 "\"deprecated_int32\"",
2294 1, 17, &message, true);
2295 ExpectMessage("deprecated_message {\n#blah\n#blah\n#blah\n}\n",
2296 "WARNING:text format contains deprecated field "
2297 "\"deprecated_message\"",
2298 1, 20, &message, true);
2299 }
2300
TEST_F(TextFormatParserTest,SetRecursionLimit)2301 TEST_F(TextFormatParserTest, SetRecursionLimit) {
2302 const char* format = "child: { $0 }";
2303 std::string input;
2304 for (int i = 0; i < 100; ++i) input = absl::Substitute(format, input);
2305
2306 unittest::NestedTestAllTypes message;
2307 ExpectSuccessAndTree(input, &message, nullptr);
2308
2309 input = absl::Substitute(format, input);
2310 parser_.SetRecursionLimit(100);
2311 ExpectMessage(input,
2312 "Message is too deep, the parser exceeded the configured "
2313 "recursion limit of 100.",
2314 1, 908, &message, false);
2315
2316 parser_.SetRecursionLimit(101);
2317 ExpectSuccessAndTree(input, &message, nullptr);
2318 }
2319
TEST_F(TextFormatParserTest,SetRecursionLimitUnknownFieldValue)2320 TEST_F(TextFormatParserTest, SetRecursionLimitUnknownFieldValue) {
2321 const char* format = "[$0]";
2322 std::string input = "\"test_value\"";
2323 for (int i = 0; i < 99; ++i) input = absl::Substitute(format, input);
2324 std::string not_deep_input = absl::StrCat("unknown_nested_array: ", input);
2325
2326 parser_.AllowUnknownField(true);
2327 parser_.SetRecursionLimit(100);
2328
2329 unittest::NestedTestAllTypes message;
2330 ExpectSuccessAndTree(not_deep_input, &message, nullptr);
2331
2332 input = absl::Substitute(format, input);
2333 std::string deep_input = absl::StrCat("unknown_nested_array: ", input);
2334 ExpectMessage(
2335 deep_input,
2336 "WARNING:Message type \"protobuf_unittest.NestedTestAllTypes\" has no "
2337 "field named \"unknown_nested_array\".\n1:123: Message is too deep, the "
2338 "parser exceeded the configured recursion limit of 100.",
2339 1, 21, &message, false);
2340
2341 parser_.SetRecursionLimit(101);
2342 ExpectSuccessAndTree(deep_input, &message, nullptr);
2343 }
2344
TEST_F(TextFormatParserTest,SetRecursionLimitUnknownFieldMessage)2345 TEST_F(TextFormatParserTest, SetRecursionLimitUnknownFieldMessage) {
2346 const char* format = "unknown_child: { $0 }";
2347 std::string input;
2348 for (int i = 0; i < 100; ++i) input = absl::Substitute(format, input);
2349
2350 parser_.AllowUnknownField(true);
2351 parser_.SetRecursionLimit(100);
2352
2353 unittest::NestedTestAllTypes message;
2354 ExpectSuccessAndTree(input, &message, nullptr);
2355
2356 input = absl::Substitute(format, input);
2357 ExpectMessage(
2358 input,
2359 "WARNING:Message type \"protobuf_unittest.NestedTestAllTypes\" has no "
2360 "field named \"unknown_child\".\n1:1716: Message is too deep, the parser "
2361 "exceeded the configured recursion limit of 100.",
2362 1, 14, &message, false);
2363
2364 parser_.SetRecursionLimit(101);
2365 ExpectSuccessAndTree(input, &message, nullptr);
2366 }
2367
TEST_F(TextFormatParserTest,ParseAnyFieldWithAdditionalWhiteSpaces)2368 TEST_F(TextFormatParserTest, ParseAnyFieldWithAdditionalWhiteSpaces) {
2369 Any any;
2370 std::string parse_string =
2371 "[type.googleapis.com/protobuf_unittest.TestAllTypes] \t : \t {\n"
2372 " optional_int32: 321\n"
2373 " optional_string: \"teststr0\"\n"
2374 "}\n";
2375
2376 ASSERT_TRUE(TextFormat::ParseFromString(parse_string, &any));
2377
2378 TextFormat::Printer printer;
2379 printer.SetExpandAny(true);
2380 std::string text;
2381 ASSERT_TRUE(printer.PrintToString(any, &text));
2382 EXPECT_EQ(text,
2383 "[type.googleapis.com/protobuf_unittest.TestAllTypes] {\n"
2384 " optional_int32: 321\n"
2385 " optional_string: \"teststr0\"\n"
2386 "}\n");
2387 }
2388
TEST_F(TextFormatParserTest,ParseExtensionFieldWithAdditionalWhiteSpaces)2389 TEST_F(TextFormatParserTest, ParseExtensionFieldWithAdditionalWhiteSpaces) {
2390 unittest::TestAllExtensions proto;
2391 std::string parse_string =
2392 "[protobuf_unittest.optional_int32_extension] : \t 101\n"
2393 "[protobuf_unittest.optional_int64_extension] \t : 102\n";
2394
2395 ASSERT_TRUE(TextFormat::ParseFromString(parse_string, &proto));
2396
2397 TextFormat::Printer printer;
2398 std::string text;
2399 ASSERT_TRUE(printer.PrintToString(proto, &text));
2400 EXPECT_EQ(text,
2401 "[protobuf_unittest.optional_int32_extension]: 101\n"
2402 "[protobuf_unittest.optional_int64_extension]: 102\n");
2403 }
2404
TEST_F(TextFormatParserTest,ParseNormalFieldWithAdditionalWhiteSpaces)2405 TEST_F(TextFormatParserTest, ParseNormalFieldWithAdditionalWhiteSpaces) {
2406 unittest::TestAllTypes proto;
2407 std::string parse_string =
2408 "repeated_int32 : \t 1\n"
2409 "repeated_int32: 2\n"
2410 "repeated_nested_message: {\n"
2411 " bb: 3\n"
2412 "}\n"
2413 "repeated_nested_message : \t {\n"
2414 " bb: 4\n"
2415 "}\n"
2416 "repeated_nested_message {\n"
2417 " bb: 5\n"
2418 "}\n";
2419
2420 ASSERT_TRUE(TextFormat::ParseFromString(parse_string, &proto));
2421
2422 TextFormat::Printer printer;
2423 std::string text;
2424 ASSERT_TRUE(printer.PrintToString(proto, &text));
2425 EXPECT_EQ(text,
2426 "repeated_int32: 1\n"
2427 "repeated_int32: 2\n"
2428 "repeated_nested_message {\n"
2429 " bb: 3\n"
2430 "}\n"
2431 "repeated_nested_message {\n"
2432 " bb: 4\n"
2433 "}\n"
2434 "repeated_nested_message {\n"
2435 " bb: 5\n"
2436 "}\n");
2437 }
2438
TEST_F(TextFormatParserTest,ParseSkippedFieldWithAdditionalWhiteSpaces)2439 TEST_F(TextFormatParserTest, ParseSkippedFieldWithAdditionalWhiteSpaces) {
2440 protobuf_unittest::TestAllTypes proto;
2441 TextFormat::Parser parser;
2442 parser.AllowUnknownField(true);
2443 EXPECT_TRUE(
2444 parser.ParseFromString("optional_int32: 321\n"
2445 "unknown_field1 : \t 12345\n"
2446 "[somewhere.unknown_extension1] {\n"
2447 " unknown_field2 \t : 12345\n"
2448 "}\n"
2449 "[somewhere.unknown_extension2] : \t {\n"
2450 " unknown_field3 \t : 12345\n"
2451 " [somewhere.unknown_extension3] \t : {\n"
2452 " unknown_field4: 10\n"
2453 " }\n"
2454 " [somewhere.unknown_extension4] \t {\n"
2455 " }\n"
2456 "}\n",
2457 &proto));
2458 std::string text;
2459 TextFormat::Printer printer;
2460 ASSERT_TRUE(printer.PrintToString(proto, &text));
2461 EXPECT_EQ(text, "optional_int32: 321\n");
2462 }
2463
2464 class TextFormatMessageSetTest : public testing::Test {
2465 protected:
2466 static const char proto_text_format_[];
2467 };
2468 const char TextFormatMessageSetTest::proto_text_format_[] =
2469 "message_set {\n"
2470 " [protobuf_unittest.TestMessageSetExtension1] {\n"
2471 " i: 23\n"
2472 " }\n"
2473 " [protobuf_unittest.TestMessageSetExtension2] {\n"
2474 " str: \"foo\"\n"
2475 " }\n"
2476 "}\n";
2477
TEST_F(TextFormatMessageSetTest,Serialize)2478 TEST_F(TextFormatMessageSetTest, Serialize) {
2479 protobuf_unittest::TestMessageSetContainer proto;
2480 protobuf_unittest::TestMessageSetExtension1* item_a =
2481 proto.mutable_message_set()->MutableExtension(
2482 protobuf_unittest::TestMessageSetExtension1::message_set_extension);
2483 item_a->set_i(23);
2484 protobuf_unittest::TestMessageSetExtension2* item_b =
2485 proto.mutable_message_set()->MutableExtension(
2486 protobuf_unittest::TestMessageSetExtension2::message_set_extension);
2487 item_b->set_str("foo");
2488 std::string actual_proto_text_format;
2489 TextFormat::PrintToString(proto, &actual_proto_text_format);
2490 EXPECT_EQ(proto_text_format_, actual_proto_text_format);
2491 }
2492
TEST_F(TextFormatMessageSetTest,Deserialize)2493 TEST_F(TextFormatMessageSetTest, Deserialize) {
2494 protobuf_unittest::TestMessageSetContainer proto;
2495 ASSERT_TRUE(TextFormat::ParseFromString(proto_text_format_, &proto));
2496 EXPECT_EQ(
2497 23,
2498 proto.message_set()
2499 .GetExtension(
2500 protobuf_unittest::TestMessageSetExtension1::message_set_extension)
2501 .i());
2502 EXPECT_EQ(
2503 "foo",
2504 proto.message_set()
2505 .GetExtension(
2506 protobuf_unittest::TestMessageSetExtension2::message_set_extension)
2507 .str());
2508
2509 // Ensure that these are the only entries present.
2510 std::vector<const FieldDescriptor*> descriptors;
2511 proto.message_set().GetReflection()->ListFields(proto.message_set(),
2512 &descriptors);
2513 EXPECT_EQ(2, descriptors.size());
2514 }
2515
TEST(TextFormatUnknownFieldTest,TestUnknownField)2516 TEST(TextFormatUnknownFieldTest, TestUnknownField) {
2517 protobuf_unittest::TestAllTypes proto;
2518 TextFormat::Parser parser;
2519 // Unknown field is not permitted by default.
2520 EXPECT_FALSE(parser.ParseFromString("unknown_field: 12345", &proto));
2521 EXPECT_FALSE(parser.ParseFromString("12345678: 12345", &proto));
2522
2523 parser.AllowUnknownField(true);
2524 EXPECT_TRUE(parser.ParseFromString("unknown_field: 12345", &proto));
2525 EXPECT_TRUE(parser.ParseFromString("unknown_field: -12345", &proto));
2526 EXPECT_TRUE(parser.ParseFromString("unknown_field: 1.2345", &proto));
2527 EXPECT_TRUE(parser.ParseFromString("unknown_field: -1.2345", &proto));
2528 EXPECT_TRUE(parser.ParseFromString("unknown_field: 1.2345f", &proto));
2529 EXPECT_TRUE(parser.ParseFromString("unknown_field: -1.2345f", &proto));
2530 EXPECT_TRUE(parser.ParseFromString("unknown_field: inf", &proto));
2531 EXPECT_TRUE(parser.ParseFromString("unknown_field: -inf", &proto));
2532 EXPECT_TRUE(parser.ParseFromString("unknown_field: TYPE_STRING", &proto));
2533 EXPECT_TRUE(
2534 parser.ParseFromString("unknown_field: \"string value\"", &proto));
2535 // Invalid field value
2536 EXPECT_FALSE(parser.ParseFromString("unknown_field: -TYPE_STRING", &proto));
2537 // Two or more unknown fields
2538 EXPECT_TRUE(
2539 parser.ParseFromString("unknown_field1: TYPE_STRING\n"
2540 "unknown_field2: 12345",
2541 &proto));
2542 // Unknown nested message
2543 EXPECT_TRUE(
2544 parser.ParseFromString("unknown_message1: {}\n"
2545 "unknown_message2 {\n"
2546 " unknown_field: 12345\n"
2547 "}\n"
2548 "unknown_message3 <\n"
2549 " unknown_nested_message {\n"
2550 " unknown_field: 12345\n"
2551 " }\n"
2552 ">",
2553 &proto));
2554 // Unmatched delimiters for message body
2555 EXPECT_FALSE(parser.ParseFromString("unknown_message: {>", &proto));
2556 // Unknown extension
2557 EXPECT_TRUE(
2558 parser.ParseFromString("[somewhere.unknown_extension1]: 12345\n"
2559 "[somewhere.unknown_extension2] {\n"
2560 " unknown_field: 12345\n"
2561 "}",
2562 &proto));
2563 // Unknown fields between known fields
2564 ASSERT_TRUE(
2565 parser.ParseFromString("optional_int32: 1\n"
2566 "unknown_field: 12345\n"
2567 "optional_string: \"string\"\n"
2568 "unknown_message { unknown: 0 }\n"
2569 "optional_nested_message { bb: 2 }",
2570 &proto));
2571 EXPECT_EQ(1, proto.optional_int32());
2572 EXPECT_EQ("string", proto.optional_string());
2573 EXPECT_EQ(2, proto.optional_nested_message().bb());
2574
2575 // Unknown field with numeric tag number instead of identifier.
2576 EXPECT_TRUE(parser.ParseFromString("12345678: 12345", &proto));
2577
2578 // Nested unknown extensions.
2579 EXPECT_TRUE(
2580 parser.ParseFromString("[test.extension1] <\n"
2581 " unknown_nested_message <\n"
2582 " [test.extension2] <\n"
2583 " unknown_field: 12345\n"
2584 " >\n"
2585 " >\n"
2586 ">",
2587 &proto));
2588 EXPECT_TRUE(
2589 parser.ParseFromString("[test.extension1] {\n"
2590 " unknown_nested_message {\n"
2591 " [test.extension2] {\n"
2592 " unknown_field: 12345\n"
2593 " }\n"
2594 " }\n"
2595 "}",
2596 &proto));
2597 EXPECT_TRUE(
2598 parser.ParseFromString("[test.extension1] <\n"
2599 " some_unknown_fields: <\n"
2600 " unknown_field: 12345\n"
2601 " >\n"
2602 ">",
2603 &proto));
2604 EXPECT_TRUE(
2605 parser.ParseFromString("[test.extension1] {\n"
2606 " some_unknown_fields: {\n"
2607 " unknown_field: 12345\n"
2608 " }\n"
2609 "}",
2610 &proto));
2611
2612 // Unknown field with compact repetition.
2613 EXPECT_TRUE(parser.ParseFromString("unknown_field: [1, 2]", &proto));
2614 // Unknown field with compact repetition of some unknown enum.
2615 EXPECT_TRUE(parser.ParseFromString("unknown_field: [VAL1, VAL2]", &proto));
2616 // Unknown field with compact repetition with sub-message.
2617 EXPECT_TRUE(parser.ParseFromString("unknown_field: [{a:1}, <b:2>]", &proto));
2618 }
2619
TEST(TextFormatUnknownFieldTest,TestAnyInUnknownField)2620 TEST(TextFormatUnknownFieldTest, TestAnyInUnknownField) {
2621 protobuf_unittest::TestAllTypes proto;
2622 TextFormat::Parser parser;
2623 parser.AllowUnknownField(true);
2624 EXPECT_TRUE(
2625 parser.ParseFromString("unknown {\n"
2626 " [type.googleapis.com/foo.bar] {\n"
2627 " }\n"
2628 "}",
2629 &proto));
2630 }
2631
TEST(TextFormatUnknownFieldTest,TestUnknownExtension)2632 TEST(TextFormatUnknownFieldTest, TestUnknownExtension) {
2633 protobuf_unittest::TestAllTypes proto;
2634 TextFormat::Parser parser;
2635 std::string message_with_ext =
2636 "[test.extension1] {\n"
2637 " some_unknown_fields: {\n"
2638 " unknown_field: 12345\n"
2639 " }\n"
2640 "}";
2641 // Unknown extensions are not permitted by default.
2642 EXPECT_FALSE(parser.ParseFromString(message_with_ext, &proto));
2643 // AllowUnknownField implies AllowUnknownExtension.
2644 parser.AllowUnknownField(true);
2645 EXPECT_TRUE(parser.ParseFromString(message_with_ext, &proto));
2646
2647 parser.AllowUnknownField(false);
2648 EXPECT_FALSE(parser.ParseFromString(message_with_ext, &proto));
2649 parser.AllowUnknownExtension(true);
2650 EXPECT_TRUE(parser.ParseFromString(message_with_ext, &proto));
2651 // Unknown fields are still not accepted.
2652 EXPECT_FALSE(parser.ParseFromString("unknown_field: 1", &proto));
2653 }
2654
2655
TEST(TextFormatFloatingPointTest,PreservesNegative0)2656 TEST(TextFormatFloatingPointTest, PreservesNegative0) {
2657 proto3_unittest::TestAllTypes in_message;
2658 in_message.set_optional_float(-0.0f);
2659 in_message.set_optional_double(-0.0);
2660 TextFormat::Printer printer;
2661 std::string serialized;
2662 EXPECT_TRUE(printer.PrintToString(in_message, &serialized));
2663 proto3_unittest::TestAllTypes out_message;
2664 TextFormat::Parser parser;
2665 EXPECT_TRUE(parser.ParseFromString(serialized, &out_message));
2666 EXPECT_EQ(in_message.optional_float(), out_message.optional_float());
2667 EXPECT_EQ(std::signbit(in_message.optional_float()),
2668 std::signbit(out_message.optional_float()));
2669 EXPECT_EQ(in_message.optional_double(), out_message.optional_double());
2670 EXPECT_EQ(std::signbit(in_message.optional_double()),
2671 std::signbit(out_message.optional_double()));
2672 }
2673
2674
2675 } // namespace text_format_unittest
2676 } // namespace protobuf
2677 } // namespace google
2678
2679 #include "google/protobuf/port_undef.inc"
2680