json_util_test.cc 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565
  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 <google/protobuf/util/json_util.h>
  31. #include <list>
  32. #include <string>
  33. #include <google/protobuf/io/zero_copy_stream.h>
  34. #include <google/protobuf/io/zero_copy_stream_impl.h>
  35. #include <google/protobuf/descriptor_database.h>
  36. #include <google/protobuf/dynamic_message.h>
  37. #include <google/protobuf/util/internal/testdata/maps.pb.h>
  38. #include <google/protobuf/util/json_format_proto3.pb.h>
  39. #include <google/protobuf/util/type_resolver.h>
  40. #include <google/protobuf/util/type_resolver_util.h>
  41. #include <gtest/gtest.h>
  42. namespace google {
  43. namespace protobuf {
  44. namespace util {
  45. namespace {
  46. using google::protobuf::testing::MapIn;
  47. using proto3::FOO;
  48. using proto3::BAR;
  49. using proto3::TestMessage;
  50. using proto3::TestMap;
  51. using proto3::TestOneof;
  52. using proto3::TestEnumValue;
  53. static const char kTypeUrlPrefix[] = "type.googleapis.com";
  54. // As functions defined in json_util.h are just thin wrappers around the
  55. // JSON conversion code in //net/proto2/util/converter, in this test we
  56. // only cover some very basic cases to make sure the wrappers have forwarded
  57. // parameters to the underlying implementation correctly. More detailed
  58. // tests are contained in the //net/proto2/util/converter directory.
  59. class JsonUtilTest : public ::testing::Test {
  60. protected:
  61. JsonUtilTest() {
  62. }
  63. string ToJson(const Message& message, const JsonPrintOptions& options) {
  64. string result;
  65. GOOGLE_CHECK_OK(MessageToJsonString(message, &result, options));
  66. return result;
  67. }
  68. bool FromJson(const string& json, Message* message,
  69. const JsonParseOptions& options) {
  70. return JsonStringToMessage(json, message, options).ok();
  71. }
  72. bool FromJson(const string& json, Message* message) {
  73. return FromJson(json, message, JsonParseOptions());
  74. }
  75. std::unique_ptr<TypeResolver> resolver_;
  76. };
  77. TEST_F(JsonUtilTest, TestWhitespaces) {
  78. TestMessage m;
  79. m.mutable_message_value();
  80. JsonPrintOptions options;
  81. EXPECT_EQ("{\"messageValue\":{}}", ToJson(m, options));
  82. options.add_whitespace = true;
  83. EXPECT_EQ(
  84. "{\n"
  85. " \"messageValue\": {}\n"
  86. "}\n",
  87. ToJson(m, options));
  88. }
  89. TEST_F(JsonUtilTest, TestDefaultValues) {
  90. TestMessage m;
  91. JsonPrintOptions options;
  92. EXPECT_EQ("{}", ToJson(m, options));
  93. options.always_print_primitive_fields = true;
  94. EXPECT_EQ(
  95. "{\"boolValue\":false,"
  96. "\"int32Value\":0,"
  97. "\"int64Value\":\"0\","
  98. "\"uint32Value\":0,"
  99. "\"uint64Value\":\"0\","
  100. "\"floatValue\":0,"
  101. "\"doubleValue\":0,"
  102. "\"stringValue\":\"\","
  103. "\"bytesValue\":\"\","
  104. "\"enumValue\":\"FOO\","
  105. "\"repeatedBoolValue\":[],"
  106. "\"repeatedInt32Value\":[],"
  107. "\"repeatedInt64Value\":[],"
  108. "\"repeatedUint32Value\":[],"
  109. "\"repeatedUint64Value\":[],"
  110. "\"repeatedFloatValue\":[],"
  111. "\"repeatedDoubleValue\":[],"
  112. "\"repeatedStringValue\":[],"
  113. "\"repeatedBytesValue\":[],"
  114. "\"repeatedEnumValue\":[],"
  115. "\"repeatedMessageValue\":[]"
  116. "}",
  117. ToJson(m, options));
  118. options.always_print_primitive_fields = true;
  119. m.set_string_value("i am a test string value");
  120. m.set_bytes_value("i am a test bytes value");
  121. EXPECT_EQ(
  122. "{\"boolValue\":false,"
  123. "\"int32Value\":0,"
  124. "\"int64Value\":\"0\","
  125. "\"uint32Value\":0,"
  126. "\"uint64Value\":\"0\","
  127. "\"floatValue\":0,"
  128. "\"doubleValue\":0,"
  129. "\"stringValue\":\"i am a test string value\","
  130. "\"bytesValue\":\"aSBhbSBhIHRlc3QgYnl0ZXMgdmFsdWU=\","
  131. "\"enumValue\":\"FOO\","
  132. "\"repeatedBoolValue\":[],"
  133. "\"repeatedInt32Value\":[],"
  134. "\"repeatedInt64Value\":[],"
  135. "\"repeatedUint32Value\":[],"
  136. "\"repeatedUint64Value\":[],"
  137. "\"repeatedFloatValue\":[],"
  138. "\"repeatedDoubleValue\":[],"
  139. "\"repeatedStringValue\":[],"
  140. "\"repeatedBytesValue\":[],"
  141. "\"repeatedEnumValue\":[],"
  142. "\"repeatedMessageValue\":[]"
  143. "}",
  144. ToJson(m, options));
  145. options.preserve_proto_field_names = true;
  146. m.set_string_value("i am a test string value");
  147. m.set_bytes_value("i am a test bytes value");
  148. EXPECT_EQ(
  149. "{\"bool_value\":false,"
  150. "\"int32_value\":0,"
  151. "\"int64_value\":\"0\","
  152. "\"uint32_value\":0,"
  153. "\"uint64_value\":\"0\","
  154. "\"float_value\":0,"
  155. "\"double_value\":0,"
  156. "\"string_value\":\"i am a test string value\","
  157. "\"bytes_value\":\"aSBhbSBhIHRlc3QgYnl0ZXMgdmFsdWU=\","
  158. "\"enum_value\":\"FOO\","
  159. "\"repeated_bool_value\":[],"
  160. "\"repeated_int32_value\":[],"
  161. "\"repeated_int64_value\":[],"
  162. "\"repeated_uint32_value\":[],"
  163. "\"repeated_uint64_value\":[],"
  164. "\"repeated_float_value\":[],"
  165. "\"repeated_double_value\":[],"
  166. "\"repeated_string_value\":[],"
  167. "\"repeated_bytes_value\":[],"
  168. "\"repeated_enum_value\":[],"
  169. "\"repeated_message_value\":[]"
  170. "}",
  171. ToJson(m, options));
  172. }
  173. TEST_F(JsonUtilTest, TestPreserveProtoFieldNames) {
  174. TestMessage m;
  175. m.mutable_message_value();
  176. JsonPrintOptions options;
  177. options.preserve_proto_field_names = true;
  178. EXPECT_EQ("{\"message_value\":{}}", ToJson(m, options));
  179. }
  180. TEST_F(JsonUtilTest, TestAlwaysPrintEnumsAsInts) {
  181. TestMessage orig;
  182. orig.set_enum_value(proto3::BAR);
  183. orig.add_repeated_enum_value(proto3::FOO);
  184. orig.add_repeated_enum_value(proto3::BAR);
  185. JsonPrintOptions print_options;
  186. print_options.always_print_enums_as_ints = true;
  187. string expected_json = "{\"enumValue\":1,\"repeatedEnumValue\":[0,1]}";
  188. EXPECT_EQ(expected_json, ToJson(orig, print_options));
  189. TestMessage parsed;
  190. JsonParseOptions parse_options;
  191. ASSERT_TRUE(FromJson(expected_json, &parsed, parse_options));
  192. EXPECT_EQ(proto3::BAR, parsed.enum_value());
  193. EXPECT_EQ(2, parsed.repeated_enum_value_size());
  194. EXPECT_EQ(proto3::FOO, parsed.repeated_enum_value(0));
  195. EXPECT_EQ(proto3::BAR, parsed.repeated_enum_value(1));
  196. }
  197. TEST_F(JsonUtilTest, TestPrintEnumsAsIntsWithDefaultValue) {
  198. TestEnumValue orig;
  199. //orig.set_enum_value1(proto3::FOO)
  200. orig.set_enum_value2(proto3::FOO);
  201. orig.set_enum_value3(proto3::BAR);
  202. JsonPrintOptions print_options;
  203. print_options.always_print_enums_as_ints = true;
  204. print_options.always_print_primitive_fields = true;
  205. string expected_json = "{\"enumValue1\":0,\"enumValue2\":0,\"enumValue3\":1}";
  206. EXPECT_EQ(expected_json, ToJson(orig, print_options));
  207. TestEnumValue parsed;
  208. JsonParseOptions parse_options;
  209. ASSERT_TRUE(FromJson(expected_json, &parsed, parse_options));
  210. EXPECT_EQ(proto3::FOO, parsed.enum_value1());
  211. EXPECT_EQ(proto3::FOO, parsed.enum_value2());
  212. EXPECT_EQ(proto3::BAR, parsed.enum_value3());
  213. }
  214. TEST_F(JsonUtilTest, ParseMessage) {
  215. // Some random message but good enough to verify that the parsing warpper
  216. // functions are working properly.
  217. string input =
  218. "{\n"
  219. " \"int32Value\": 1024,\n"
  220. " \"repeatedInt32Value\": [1, 2],\n"
  221. " \"messageValue\": {\n"
  222. " \"value\": 2048\n"
  223. " },\n"
  224. " \"repeatedMessageValue\": [\n"
  225. " {\"value\": 40}, {\"value\": 96}\n"
  226. " ]\n"
  227. "}\n";
  228. JsonParseOptions options;
  229. TestMessage m;
  230. ASSERT_TRUE(FromJson(input, &m, options));
  231. EXPECT_EQ(1024, m.int32_value());
  232. ASSERT_EQ(2, m.repeated_int32_value_size());
  233. EXPECT_EQ(1, m.repeated_int32_value(0));
  234. EXPECT_EQ(2, m.repeated_int32_value(1));
  235. EXPECT_EQ(2048, m.message_value().value());
  236. ASSERT_EQ(2, m.repeated_message_value_size());
  237. EXPECT_EQ(40, m.repeated_message_value(0).value());
  238. EXPECT_EQ(96, m.repeated_message_value(1).value());
  239. }
  240. TEST_F(JsonUtilTest, ParseMap) {
  241. TestMap message;
  242. (*message.mutable_string_map())["hello"] = 1234;
  243. JsonPrintOptions print_options;
  244. JsonParseOptions parse_options;
  245. EXPECT_EQ("{\"stringMap\":{\"hello\":1234}}", ToJson(message, print_options));
  246. TestMap other;
  247. ASSERT_TRUE(FromJson(ToJson(message, print_options), &other, parse_options));
  248. EXPECT_EQ(message.DebugString(), other.DebugString());
  249. }
  250. TEST_F(JsonUtilTest, ParsePrimitiveMapIn) {
  251. MapIn message;
  252. JsonPrintOptions print_options;
  253. print_options.always_print_primitive_fields = true;
  254. JsonParseOptions parse_options;
  255. EXPECT_EQ("{\"other\":\"\",\"things\":[],\"mapInput\":{}}",
  256. ToJson(message, print_options));
  257. MapIn other;
  258. ASSERT_TRUE(FromJson(ToJson(message, print_options), &other, parse_options));
  259. EXPECT_EQ(message.DebugString(), other.DebugString());
  260. }
  261. TEST_F(JsonUtilTest, PrintPrimitiveOneof) {
  262. TestOneof message;
  263. JsonPrintOptions options;
  264. options.always_print_primitive_fields = true;
  265. message.mutable_oneof_message_value();
  266. EXPECT_EQ("{\"oneofMessageValue\":{\"value\":0}}", ToJson(message, options));
  267. message.set_oneof_int32_value(1);
  268. EXPECT_EQ("{\"oneofInt32Value\":1}", ToJson(message, options));
  269. }
  270. TEST_F(JsonUtilTest, TestParseIgnoreUnknownFields) {
  271. TestMessage m;
  272. JsonParseOptions options;
  273. options.ignore_unknown_fields = true;
  274. EXPECT_TRUE(FromJson("{\"unknownName\":0}", &m, options));
  275. }
  276. TEST_F(JsonUtilTest, TestParseErrors) {
  277. TestMessage m;
  278. JsonParseOptions options;
  279. // Parsing should fail if the field name can not be recognized.
  280. EXPECT_FALSE(FromJson("{\"unknownName\":0}", &m, options));
  281. // Parsing should fail if the value is invalid.
  282. EXPECT_FALSE(FromJson("{\"int32Value\":2147483648}", &m, options));
  283. }
  284. TEST_F(JsonUtilTest, TestDynamicMessage) {
  285. // Some random message but good enough to test the wrapper functions.
  286. string input =
  287. "{\n"
  288. " \"int32Value\": 1024,\n"
  289. " \"repeatedInt32Value\": [1, 2],\n"
  290. " \"messageValue\": {\n"
  291. " \"value\": 2048\n"
  292. " },\n"
  293. " \"repeatedMessageValue\": [\n"
  294. " {\"value\": 40}, {\"value\": 96}\n"
  295. " ]\n"
  296. "}\n";
  297. // Create a new DescriptorPool with the same protos as the generated one.
  298. DescriptorPoolDatabase database(*DescriptorPool::generated_pool());
  299. DescriptorPool pool(&database);
  300. // A dynamic version of the test proto.
  301. DynamicMessageFactory factory;
  302. std::unique_ptr<Message> message(factory.GetPrototype(
  303. pool.FindMessageTypeByName("proto3.TestMessage"))->New());
  304. EXPECT_TRUE(FromJson(input, message.get()));
  305. // Convert to generated message for easy inspection.
  306. TestMessage generated;
  307. EXPECT_TRUE(generated.ParseFromString(message->SerializeAsString()));
  308. EXPECT_EQ(1024, generated.int32_value());
  309. ASSERT_EQ(2, generated.repeated_int32_value_size());
  310. EXPECT_EQ(1, generated.repeated_int32_value(0));
  311. EXPECT_EQ(2, generated.repeated_int32_value(1));
  312. EXPECT_EQ(2048, generated.message_value().value());
  313. ASSERT_EQ(2, generated.repeated_message_value_size());
  314. EXPECT_EQ(40, generated.repeated_message_value(0).value());
  315. EXPECT_EQ(96, generated.repeated_message_value(1).value());
  316. JsonOptions options;
  317. EXPECT_EQ(ToJson(generated, options), ToJson(*message, options));
  318. }
  319. TEST_F(JsonUtilTest, TestParsingUnknownEnumsAs0) {
  320. TestMessage m;
  321. {
  322. JsonParseOptions options;
  323. ASSERT_FALSE(options.ignore_unknown_fields);
  324. string input =
  325. "{\n"
  326. " \"enum_value\":\"UNKNOWN_VALUE\"\n"
  327. "}";
  328. m.set_enum_value(proto3::BAR);
  329. EXPECT_FALSE(FromJson(input, &m, options));
  330. ASSERT_EQ(proto3::BAR, m.enum_value()); // Keep previous value
  331. options.ignore_unknown_fields = true;
  332. EXPECT_TRUE(FromJson(input, &m, options));
  333. EXPECT_EQ(0, m.enum_value()); // Unknown enum value must be decoded as 0
  334. }
  335. // Integer values are read as usual
  336. {
  337. JsonParseOptions options;
  338. string input =
  339. "{\n"
  340. " \"enum_value\":12345\n"
  341. "}";
  342. m.set_enum_value(proto3::BAR);
  343. EXPECT_TRUE(FromJson(input, &m, options));
  344. ASSERT_EQ(12345, m.enum_value());
  345. options.ignore_unknown_fields = true;
  346. EXPECT_TRUE(FromJson(input, &m, options));
  347. EXPECT_EQ(12345, m.enum_value());
  348. }
  349. // Trying to pass an object as an enum field value is always treated as an error
  350. {
  351. JsonParseOptions options;
  352. string input =
  353. "{\n"
  354. " \"enum_value\":{}\n"
  355. "}";
  356. options.ignore_unknown_fields = true;
  357. EXPECT_FALSE(FromJson(input, &m, options));
  358. options.ignore_unknown_fields = false;
  359. EXPECT_FALSE(FromJson(input, &m, options));
  360. }
  361. // Trying to pass an array as an enum field value is always treated as an error
  362. {
  363. JsonParseOptions options;
  364. string input =
  365. "{\n"
  366. " \"enum_value\":[]\n"
  367. "}";
  368. EXPECT_FALSE(FromJson(input, &m, options));
  369. options.ignore_unknown_fields = true;
  370. EXPECT_FALSE(FromJson(input, &m, options));
  371. }
  372. }
  373. typedef std::pair<char*, int> Segment;
  374. // A ZeroCopyOutputStream that writes to multiple buffers.
  375. class SegmentedZeroCopyOutputStream : public io::ZeroCopyOutputStream {
  376. public:
  377. explicit SegmentedZeroCopyOutputStream(std::list<Segment> segments)
  378. : segments_(segments), last_segment_(static_cast<char*>(NULL), 0), byte_count_(0) {}
  379. virtual bool Next(void** buffer, int* length) {
  380. if (segments_.empty()) {
  381. return false;
  382. }
  383. last_segment_ = segments_.front();
  384. segments_.pop_front();
  385. *buffer = last_segment_.first;
  386. *length = last_segment_.second;
  387. byte_count_ += *length;
  388. return true;
  389. }
  390. virtual void BackUp(int length) {
  391. GOOGLE_CHECK(length <= last_segment_.second);
  392. segments_.push_front(
  393. Segment(last_segment_.first + last_segment_.second - length, length));
  394. last_segment_ = Segment(last_segment_.first, last_segment_.second - length);
  395. byte_count_ -= length;
  396. }
  397. virtual int64 ByteCount() const { return byte_count_; }
  398. private:
  399. std::list<Segment> segments_;
  400. Segment last_segment_;
  401. int64 byte_count_;
  402. };
  403. // This test splits the output buffer and also the input data into multiple
  404. // segments and checks that the implementation of ZeroCopyStreamByteSink
  405. // handles all possible cases correctly.
  406. TEST(ZeroCopyStreamByteSinkTest, TestAllInputOutputPatterns) {
  407. static const int kOutputBufferLength = 10;
  408. // An exhaustive test takes too long, skip some combinations to make the test
  409. // run faster.
  410. static const int kSkippedPatternCount = 7;
  411. char buffer[kOutputBufferLength];
  412. for (int split_pattern = 0; split_pattern < (1 << (kOutputBufferLength - 1));
  413. split_pattern += kSkippedPatternCount) {
  414. // Split the buffer into small segments according to the split_pattern.
  415. std::list<Segment> segments;
  416. int segment_start = 0;
  417. for (int i = 0; i < kOutputBufferLength - 1; ++i) {
  418. if (split_pattern & (1 << i)) {
  419. segments.push_back(
  420. Segment(buffer + segment_start, i - segment_start + 1));
  421. segment_start = i + 1;
  422. }
  423. }
  424. segments.push_back(
  425. Segment(buffer + segment_start, kOutputBufferLength - segment_start));
  426. // Write exactly 10 bytes through the ByteSink.
  427. string input_data = "0123456789";
  428. for (int input_pattern = 0; input_pattern < (1 << (input_data.size() - 1));
  429. input_pattern += kSkippedPatternCount) {
  430. memset(buffer, 0, sizeof(buffer));
  431. {
  432. SegmentedZeroCopyOutputStream output_stream(segments);
  433. internal::ZeroCopyStreamByteSink byte_sink(&output_stream);
  434. int start = 0;
  435. for (int j = 0; j < input_data.length() - 1; ++j) {
  436. if (input_pattern & (1 << j)) {
  437. byte_sink.Append(&input_data[start], j - start + 1);
  438. start = j + 1;
  439. }
  440. }
  441. byte_sink.Append(&input_data[start], input_data.length() - start);
  442. }
  443. EXPECT_EQ(input_data, string(buffer, input_data.length()));
  444. }
  445. // Write only 9 bytes through the ByteSink.
  446. input_data = "012345678";
  447. for (int input_pattern = 0; input_pattern < (1 << (input_data.size() - 1));
  448. input_pattern += kSkippedPatternCount) {
  449. memset(buffer, 0, sizeof(buffer));
  450. {
  451. SegmentedZeroCopyOutputStream output_stream(segments);
  452. internal::ZeroCopyStreamByteSink byte_sink(&output_stream);
  453. int start = 0;
  454. for (int j = 0; j < input_data.length() - 1; ++j) {
  455. if (input_pattern & (1 << j)) {
  456. byte_sink.Append(&input_data[start], j - start + 1);
  457. start = j + 1;
  458. }
  459. }
  460. byte_sink.Append(&input_data[start], input_data.length() - start);
  461. }
  462. EXPECT_EQ(input_data, string(buffer, input_data.length()));
  463. EXPECT_EQ(0, buffer[input_data.length()]);
  464. }
  465. // Write 11 bytes through the ByteSink. The extra byte will just
  466. // be ignored.
  467. input_data = "0123456789A";
  468. for (int input_pattern = 0; input_pattern < (1 << (input_data.size() - 1));
  469. input_pattern += kSkippedPatternCount) {
  470. memset(buffer, 0, sizeof(buffer));
  471. {
  472. SegmentedZeroCopyOutputStream output_stream(segments);
  473. internal::ZeroCopyStreamByteSink byte_sink(&output_stream);
  474. int start = 0;
  475. for (int j = 0; j < input_data.length() - 1; ++j) {
  476. if (input_pattern & (1 << j)) {
  477. byte_sink.Append(&input_data[start], j - start + 1);
  478. start = j + 1;
  479. }
  480. }
  481. byte_sink.Append(&input_data[start], input_data.length() - start);
  482. }
  483. EXPECT_EQ(input_data.substr(0, kOutputBufferLength),
  484. string(buffer, kOutputBufferLength));
  485. }
  486. }
  487. }
  488. TEST_F(JsonUtilTest, TestWrongJsonInput) {
  489. const char json[] = "{\"unknown_field\":\"some_value\"}";
  490. io::ArrayInputStream input_stream(json, strlen(json));
  491. char proto_buffer[10000];
  492. io::ArrayOutputStream output_stream(proto_buffer, sizeof(proto_buffer));
  493. std::string message_type = "type.googleapis.com/proto3.TestMessage";
  494. TypeResolver* resolver = NewTypeResolverForDescriptorPool(
  495. "type.googleapis.com", DescriptorPool::generated_pool());
  496. auto result_status = util::JsonToBinaryStream(
  497. resolver, message_type, &input_stream, &output_stream);
  498. delete resolver;
  499. EXPECT_FALSE(result_status.ok());
  500. EXPECT_EQ(result_status.error_code(),
  501. util::error::INVALID_ARGUMENT);
  502. }
  503. } // namespace
  504. } // namespace util
  505. } // namespace protobuf
  506. } // namespace google