text_format_conformance_suite.cc 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. // Protocol Buffers - Google's data interchange format
  2. // Copyright 2008 Google Inc. All rights reserved.
  3. // https://developers.google.com/protocol-buffers/
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are
  7. // met:
  8. //
  9. // * Redistributions of source code must retain the above copyright
  10. // notice, this list of conditions and the following disclaimer.
  11. // * Redistributions in binary form must reproduce the above
  12. // copyright notice, this list of conditions and the following disclaimer
  13. // in the documentation and/or other materials provided with the
  14. // distribution.
  15. // * Neither the name of Google Inc. nor the names of its
  16. // contributors may be used to endorse or promote products derived from
  17. // this software without specific prior written permission.
  18. //
  19. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. #include "text_format_conformance_suite.h"
  31. #include <google/protobuf/any.pb.h>
  32. #include <google/protobuf/text_format.h>
  33. #include "conformance_test.h"
  34. #include <google/protobuf/test_messages_proto2.pb.h>
  35. #include <google/protobuf/test_messages_proto3.pb.h>
  36. namespace proto2_messages = protobuf_test_messages::proto2;
  37. using conformance::ConformanceRequest;
  38. using conformance::ConformanceResponse;
  39. using conformance::WireFormat;
  40. using google::protobuf::Message;
  41. using google::protobuf::TextFormat;
  42. using proto2_messages::TestAllTypesProto2;
  43. using proto2_messages::UnknownToTestAllTypes;
  44. using protobuf_test_messages::proto3::TestAllTypesProto3;
  45. using std::string;
  46. namespace google {
  47. namespace protobuf {
  48. TextFormatConformanceTestSuite::TextFormatConformanceTestSuite() {
  49. SetFailureListFlagName("--text_format_failure_list");
  50. }
  51. bool TextFormatConformanceTestSuite::ParseTextFormatResponse(
  52. const ConformanceResponse& response,
  53. const ConformanceRequestSetting& setting, Message* test_message) {
  54. TextFormat::Parser parser;
  55. const ConformanceRequest& request = setting.GetRequest();
  56. if (request.print_unknown_fields()) {
  57. parser.AllowFieldNumber(true);
  58. }
  59. if (!parser.ParseFromString(response.text_payload(), test_message)) {
  60. GOOGLE_LOG(ERROR) << "INTERNAL ERROR: internal text->protobuf transcode "
  61. << "yielded unparseable proto. Text payload: "
  62. << response.text_payload();
  63. return false;
  64. }
  65. return true;
  66. }
  67. bool TextFormatConformanceTestSuite::ParseResponse(
  68. const ConformanceResponse& response,
  69. const ConformanceRequestSetting& setting, Message* test_message) {
  70. const ConformanceRequest& request = setting.GetRequest();
  71. WireFormat requested_output = request.requested_output_format();
  72. const string& test_name = setting.GetTestName();
  73. ConformanceLevel level = setting.GetLevel();
  74. switch (response.result_case()) {
  75. case ConformanceResponse::kProtobufPayload: {
  76. if (requested_output != conformance::PROTOBUF) {
  77. ReportFailure(test_name, level, request, response,
  78. StrCat("Test was asked for ",
  79. WireFormatToString(requested_output),
  80. " output but provided PROTOBUF instead.")
  81. .c_str());
  82. return false;
  83. }
  84. if (!test_message->ParseFromString(response.protobuf_payload())) {
  85. ReportFailure(test_name, level, request, response,
  86. "Protobuf output we received from test was unparseable.");
  87. return false;
  88. }
  89. break;
  90. }
  91. case ConformanceResponse::kTextPayload: {
  92. if (requested_output != conformance::TEXT_FORMAT) {
  93. ReportFailure(test_name, level, request, response,
  94. StrCat("Test was asked for ",
  95. WireFormatToString(requested_output),
  96. " output but provided TEXT_FORMAT instead.")
  97. .c_str());
  98. return false;
  99. }
  100. if (!ParseTextFormatResponse(response, setting, test_message)) {
  101. ReportFailure(
  102. test_name, level, request, response,
  103. "TEXT_FORMAT output we received from test was unparseable.");
  104. return false;
  105. }
  106. break;
  107. }
  108. default:
  109. GOOGLE_LOG(FATAL) << test_name
  110. << ": unknown payload type: " << response.result_case();
  111. }
  112. return true;
  113. }
  114. void TextFormatConformanceTestSuite::ExpectParseFailure(const string& test_name,
  115. ConformanceLevel level,
  116. const string& input) {
  117. TestAllTypesProto3 prototype;
  118. // We don't expect output, but if the program erroneously accepts the protobuf
  119. // we let it send its response as this. We must not leave it unspecified.
  120. ConformanceRequestSetting setting(
  121. level, conformance::TEXT_FORMAT, conformance::TEXT_FORMAT,
  122. conformance::TEXT_FORMAT_TEST, prototype, test_name, input);
  123. const ConformanceRequest& request = setting.GetRequest();
  124. ConformanceResponse response;
  125. string effective_test_name =
  126. StrCat(setting.ConformanceLevelToString(level),
  127. ".Proto3.TextFormatInput.", test_name);
  128. RunTest(effective_test_name, request, &response);
  129. if (response.result_case() == ConformanceResponse::kParseError) {
  130. ReportSuccess(effective_test_name);
  131. } else if (response.result_case() == ConformanceResponse::kSkipped) {
  132. ReportSkip(effective_test_name, request, response);
  133. } else {
  134. ReportFailure(effective_test_name, level, request, response,
  135. "Should have failed to parse, but didn't.");
  136. }
  137. }
  138. void TextFormatConformanceTestSuite::RunValidTextFormatTest(
  139. const string& test_name, ConformanceLevel level, const string& input_text) {
  140. TestAllTypesProto3 prototype;
  141. RunValidTextFormatTestWithMessage(test_name, level, input_text, prototype);
  142. }
  143. void TextFormatConformanceTestSuite::RunValidTextFormatTestProto2(
  144. const string& test_name, ConformanceLevel level, const string& input_text) {
  145. TestAllTypesProto2 prototype;
  146. RunValidTextFormatTestWithMessage(test_name, level, input_text, prototype);
  147. }
  148. void TextFormatConformanceTestSuite::RunValidTextFormatTestWithMessage(
  149. const string& test_name, ConformanceLevel level, const string& input_text,
  150. const Message& prototype) {
  151. ConformanceRequestSetting setting1(
  152. level, conformance::TEXT_FORMAT, conformance::PROTOBUF,
  153. conformance::TEXT_FORMAT_TEST, prototype, test_name, input_text);
  154. RunValidInputTest(setting1, input_text);
  155. ConformanceRequestSetting setting2(
  156. level, conformance::TEXT_FORMAT, conformance::TEXT_FORMAT,
  157. conformance::TEXT_FORMAT_TEST, prototype, test_name, input_text);
  158. RunValidInputTest(setting2, input_text);
  159. }
  160. void TextFormatConformanceTestSuite::RunValidUnknownTextFormatTest(
  161. const string& test_name, const Message& message) {
  162. string serialized_input;
  163. message.SerializeToString(&serialized_input);
  164. TestAllTypesProto3 prototype;
  165. ConformanceRequestSetting setting1(
  166. RECOMMENDED, conformance::PROTOBUF, conformance::TEXT_FORMAT,
  167. conformance::TEXT_FORMAT_TEST, prototype, test_name + "_Drop",
  168. serialized_input);
  169. setting1.SetPrototypeMessageForCompare(message);
  170. RunValidBinaryInputTest(setting1, "");
  171. ConformanceRequestSetting setting2(
  172. RECOMMENDED, conformance::PROTOBUF, conformance::TEXT_FORMAT,
  173. conformance::TEXT_FORMAT_TEST, prototype, test_name + "_Print",
  174. serialized_input);
  175. setting2.SetPrototypeMessageForCompare(message);
  176. setting2.SetPrintUnknownFields(true);
  177. RunValidBinaryInputTest(setting2, serialized_input);
  178. }
  179. void TextFormatConformanceTestSuite::RunSuiteImpl() {
  180. RunValidTextFormatTest("HelloWorld", REQUIRED,
  181. "optional_string: 'Hello, World!'");
  182. // Integer fields.
  183. RunValidTextFormatTest("Int32FieldMaxValue", REQUIRED,
  184. "optional_int32: 2147483647");
  185. RunValidTextFormatTest("Int32FieldMinValue", REQUIRED,
  186. "optional_int32: -2147483648");
  187. RunValidTextFormatTest("Uint32FieldMaxValue", REQUIRED,
  188. "optional_uint32: 4294967295");
  189. RunValidTextFormatTest("Int64FieldMaxValue", REQUIRED,
  190. "optional_int64: 9223372036854775807");
  191. RunValidTextFormatTest("Int64FieldMinValue", REQUIRED,
  192. "optional_int64: -9223372036854775808");
  193. RunValidTextFormatTest("Uint64FieldMaxValue", REQUIRED,
  194. "optional_uint64: 18446744073709551615");
  195. // Parsers reject out-of-bound integer values.
  196. ExpectParseFailure("Int32FieldTooLarge", REQUIRED,
  197. "optional_int32: 2147483648");
  198. ExpectParseFailure("Int32FieldTooSmall", REQUIRED,
  199. "optional_int32: -2147483649");
  200. ExpectParseFailure("Uint32FieldTooLarge", REQUIRED,
  201. "optional_uint32: 4294967296");
  202. ExpectParseFailure("Int64FieldTooLarge", REQUIRED,
  203. "optional_int64: 9223372036854775808");
  204. ExpectParseFailure("Int64FieldTooSmall", REQUIRED,
  205. "optional_int64: -9223372036854775809");
  206. ExpectParseFailure("Uint64FieldTooLarge", REQUIRED,
  207. "optional_uint64: 18446744073709551616");
  208. // Floating point fields
  209. RunValidTextFormatTest("FloatField", REQUIRED,
  210. "optional_float: 3.192837");
  211. RunValidTextFormatTest("FloatFieldWithVeryPreciseNumber", REQUIRED,
  212. "optional_float: 3.123456789123456789");
  213. RunValidTextFormatTest("FloatFieldMaxValue", REQUIRED,
  214. "optional_float: 3.4028235e+38");
  215. RunValidTextFormatTest("FloatFieldMinValue", REQUIRED,
  216. "optional_float: 1.17549e-38");
  217. RunValidTextFormatTest("FloatFieldNaNValue", REQUIRED,
  218. "optional_float: NaN");
  219. RunValidTextFormatTest("FloatFieldPosInfValue", REQUIRED,
  220. "optional_float: inf");
  221. RunValidTextFormatTest("FloatFieldNegInfValue", REQUIRED,
  222. "optional_float: -inf");
  223. RunValidTextFormatTest("FloatFieldWithInt32Max", REQUIRED,
  224. "optional_float: 4294967296");
  225. RunValidTextFormatTest("FloatFieldLargerThanInt64", REQUIRED,
  226. "optional_float: 9223372036854775808");
  227. RunValidTextFormatTest("FloatFieldTooLarge", REQUIRED,
  228. "optional_float: 3.4028235e+39");
  229. RunValidTextFormatTest("FloatFieldTooSmall", REQUIRED,
  230. "optional_float: 1.17549e-39");
  231. RunValidTextFormatTest("FloatFieldLargerThanUint64", REQUIRED,
  232. "optional_float: 18446744073709551616");
  233. // String literals x {Strings, Bytes}
  234. for (const auto& field_type :
  235. std::vector<const std::string>{"String", "Bytes"}) {
  236. const std::string field_name =
  237. field_type == "String" ? "optional_string" : "optional_bytes";
  238. RunValidTextFormatTest(
  239. StrCat("StringLiteralConcat", field_type), REQUIRED,
  240. StrCat(field_name, ": 'first' \"second\"\n'third'"));
  241. RunValidTextFormatTest(
  242. StrCat("StringLiteralBasicEscapes", field_type), REQUIRED,
  243. StrCat(field_name, ": '\\a\\b\\f\\n\\r\\t\\v\\?\\\\\\'\\\"'"));
  244. RunValidTextFormatTest(
  245. StrCat("StringLiteralOctalEscapes", field_type), REQUIRED,
  246. StrCat(field_name, ": '\\341\\210\\264'"));
  247. RunValidTextFormatTest(StrCat("StringLiteralHexEscapes", field_type),
  248. REQUIRED,
  249. StrCat(field_name, ": '\\xe1\\x88\\xb4'"));
  250. RunValidTextFormatTest(
  251. StrCat("StringLiteralShortUnicodeEscape", field_type),
  252. RECOMMENDED, StrCat(field_name, ": '\\u1234'"));
  253. RunValidTextFormatTest(
  254. StrCat("StringLiteralLongUnicodeEscapes", field_type),
  255. RECOMMENDED, StrCat(field_name, ": '\\U00001234\\U00010437'"));
  256. // String literals don't include line feeds.
  257. ExpectParseFailure(StrCat("StringLiteralIncludesLF", field_type),
  258. REQUIRED,
  259. StrCat(field_name, ": 'first line\nsecond line'"));
  260. // Unicode escapes don't include code points that lie beyond the planes
  261. // (> 0x10ffff).
  262. ExpectParseFailure(
  263. StrCat("StringLiteralLongUnicodeEscapeTooLarge", field_type),
  264. REQUIRED, StrCat(field_name, ": '\\U00110000'"));
  265. // Unicode escapes don't include surrogates.
  266. ExpectParseFailure(
  267. StrCat("StringLiteralShortUnicodeEscapeSurrogatePair",
  268. field_type),
  269. RECOMMENDED, StrCat(field_name, ": '\\ud801\\udc37'"));
  270. ExpectParseFailure(
  271. StrCat("StringLiteralShortUnicodeEscapeSurrogateFirstOnly",
  272. field_type),
  273. RECOMMENDED, StrCat(field_name, ": '\\ud800'"));
  274. ExpectParseFailure(
  275. StrCat("StringLiteralShortUnicodeEscapeSurrogateSecondOnly",
  276. field_type),
  277. RECOMMENDED, StrCat(field_name, ": '\\udc00'"));
  278. ExpectParseFailure(
  279. StrCat("StringLiteralLongUnicodeEscapeSurrogateFirstOnly",
  280. field_type),
  281. RECOMMENDED, StrCat(field_name, ": '\\U0000d800'"));
  282. ExpectParseFailure(
  283. StrCat("StringLiteralLongUnicodeEscapeSurrogateSecondOnly",
  284. field_type),
  285. RECOMMENDED, StrCat(field_name, ": '\\U0000dc00'"));
  286. ExpectParseFailure(
  287. StrCat("StringLiteralLongUnicodeEscapeSurrogatePair", field_type),
  288. RECOMMENDED, StrCat(field_name, ": '\\U0000d801\\U00000dc37'"));
  289. ExpectParseFailure(
  290. StrCat("StringLiteralUnicodeEscapeSurrogatePairLongShort",
  291. field_type),
  292. RECOMMENDED, StrCat(field_name, ": '\\U0000d801\\udc37'"));
  293. ExpectParseFailure(
  294. StrCat("StringLiteralUnicodeEscapeSurrogatePairShortLong",
  295. field_type),
  296. RECOMMENDED, StrCat(field_name, ": '\\ud801\\U0000dc37'"));
  297. // The following method depend on the type of field, as strings have extra
  298. // validation.
  299. const auto test_method =
  300. field_type == "String"
  301. ? &TextFormatConformanceTestSuite::ExpectParseFailure
  302. : &TextFormatConformanceTestSuite::RunValidTextFormatTest;
  303. // String fields reject invalid UTF-8 byte sequences; bytes fields don't.
  304. (this->*test_method)(StrCat(field_type, "FieldBadUTF8Octal"),
  305. REQUIRED, StrCat(field_name, ": '\\300'"));
  306. (this->*test_method)(StrCat(field_type, "FieldBadUTF8Hex"), REQUIRED,
  307. StrCat(field_name, ": '\\xc0'"));
  308. }
  309. // Group fields
  310. RunValidTextFormatTestProto2("GroupFieldNoColon", REQUIRED,
  311. "Data { group_int32: 1 }");
  312. RunValidTextFormatTestProto2("GroupFieldWithColon", REQUIRED,
  313. "Data: { group_int32: 1 }");
  314. RunValidTextFormatTestProto2("GroupFieldEmpty", REQUIRED,
  315. "Data {}");
  316. // Unknown Fields
  317. UnknownToTestAllTypes message;
  318. // Unable to print unknown Fixed32/Fixed64 fields as if they are known.
  319. // Fixed32/Fixed64 fields are not added in the tests.
  320. message.set_optional_int32(123);
  321. message.set_optional_string("hello");
  322. message.set_optional_bool(true);
  323. RunValidUnknownTextFormatTest("ScalarUnknownFields", message);
  324. message.Clear();
  325. message.mutable_nested_message()->set_c(111);
  326. RunValidUnknownTextFormatTest("MessageUnknownFields", message);
  327. message.Clear();
  328. message.mutable_optionalgroup()->set_a(321);
  329. RunValidUnknownTextFormatTest("GroupUnknownFields", message);
  330. message.add_repeated_int32(1);
  331. message.add_repeated_int32(2);
  332. message.add_repeated_int32(3);
  333. RunValidUnknownTextFormatTest("RepeatedUnknownFields", message);
  334. // Any fields
  335. RunValidTextFormatTest("AnyField", REQUIRED,
  336. R"(
  337. optional_any: {
  338. [type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3] {
  339. optional_int32: 12345
  340. }
  341. }
  342. )");
  343. RunValidTextFormatTest("AnyFieldWithRawBytes", REQUIRED,
  344. R"(
  345. optional_any: {
  346. type_url: "type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3"
  347. value: "\b\271`"
  348. }
  349. )");
  350. ExpectParseFailure("AnyFieldWithInvalidType", REQUIRED,
  351. R"(
  352. optional_any: {
  353. [type.googleapis.com/unknown] {
  354. optional_int32: 12345
  355. }
  356. }
  357. )");
  358. // Map fields
  359. TestAllTypesProto3 prototype;
  360. (*prototype.mutable_map_string_string())["c"] = "value";
  361. (*prototype.mutable_map_string_string())["b"] = "value";
  362. (*prototype.mutable_map_string_string())["a"] = "value";
  363. RunValidTextFormatTestWithMessage("AlphabeticallySortedMapStringKeys",
  364. REQUIRED,
  365. R"(
  366. map_string_string {
  367. key: "a"
  368. value: "value"
  369. }
  370. map_string_string {
  371. key: "b"
  372. value: "value"
  373. }
  374. map_string_string {
  375. key: "c"
  376. value: "value"
  377. }
  378. )",
  379. prototype);
  380. prototype.Clear();
  381. (*prototype.mutable_map_int32_int32())[3] = 0;
  382. (*prototype.mutable_map_int32_int32())[2] = 0;
  383. (*prototype.mutable_map_int32_int32())[1] = 0;
  384. RunValidTextFormatTestWithMessage("AlphabeticallySortedMapIntKeys", REQUIRED,
  385. R"(
  386. map_int32_int32 {
  387. key: 1
  388. value: 0
  389. }
  390. map_int32_int32 {
  391. key: 2
  392. value: 0
  393. }
  394. map_int32_int32 {
  395. key: 3
  396. value: 0
  397. }
  398. )",
  399. prototype);
  400. prototype.Clear();
  401. (*prototype.mutable_map_bool_bool())[true] = false;
  402. (*prototype.mutable_map_bool_bool())[false] = false;
  403. RunValidTextFormatTestWithMessage("AlphabeticallySortedMapBoolKeys", REQUIRED,
  404. R"(
  405. map_bool_bool {
  406. key: false
  407. value: false
  408. }
  409. map_bool_bool {
  410. key: true
  411. value: false
  412. }
  413. )",
  414. prototype);
  415. }
  416. } // namespace protobuf
  417. } // namespace google