pickle_unittest.cc 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "base/pickle.h"
  5. #include <limits.h>
  6. #include <stddef.h>
  7. #include <stdint.h>
  8. #include <memory>
  9. #include <string>
  10. #include <tuple>
  11. #include "base/strings/utf_string_conversions.h"
  12. #include "build/build_config.h"
  13. #include "testing/gtest/include/gtest/gtest.h"
  14. namespace base {
  15. namespace {
  16. const bool testbool1 = false;
  17. const bool testbool2 = true;
  18. const int testint = 2'093'847'192;
  19. const long testlong = 1'093'847'192;
  20. const uint16_t testuint16 = 32123;
  21. const uint32_t testuint32 = 1593847192;
  22. const int64_t testint64 = -0x7E8CA925'3104BDFCLL;
  23. const uint64_t testuint64 = 0xCE8CA925'3104BDF7ULL;
  24. const float testfloat = 3.1415926935f;
  25. const double testdouble = 2.71828182845904523;
  26. const std::string teststring("Hello world"); // note non-aligned string length
  27. const std::wstring testwstring(L"Hello, world");
  28. const std::u16string teststring16(u"Hello, world");
  29. const char testrawstring[] = "Hello new world"; // Test raw string writing
  30. // Test raw char16_t writing, assumes UTF16 encoding is ANSI for alpha chars.
  31. const char16_t testrawstring16[] = {'A', 'l', 'o', 'h', 'a', 0};
  32. const char testdata[] = "AAA\0BBB\0";
  33. const size_t testdatalen = std::size(testdata) - 1;
  34. // checks that the results can be read correctly from the Pickle
  35. void VerifyResult(const Pickle& pickle) {
  36. PickleIterator iter(pickle);
  37. bool outbool;
  38. EXPECT_TRUE(iter.ReadBool(&outbool));
  39. EXPECT_FALSE(outbool);
  40. EXPECT_TRUE(iter.ReadBool(&outbool));
  41. EXPECT_TRUE(outbool);
  42. int outint;
  43. EXPECT_TRUE(iter.ReadInt(&outint));
  44. EXPECT_EQ(testint, outint);
  45. long outlong;
  46. EXPECT_TRUE(iter.ReadLong(&outlong));
  47. EXPECT_EQ(testlong, outlong);
  48. uint16_t outuint16;
  49. EXPECT_TRUE(iter.ReadUInt16(&outuint16));
  50. EXPECT_EQ(testuint16, outuint16);
  51. uint32_t outuint32;
  52. EXPECT_TRUE(iter.ReadUInt32(&outuint32));
  53. EXPECT_EQ(testuint32, outuint32);
  54. int64_t outint64;
  55. EXPECT_TRUE(iter.ReadInt64(&outint64));
  56. EXPECT_EQ(testint64, outint64);
  57. uint64_t outuint64;
  58. EXPECT_TRUE(iter.ReadUInt64(&outuint64));
  59. EXPECT_EQ(testuint64, outuint64);
  60. float outfloat;
  61. EXPECT_TRUE(iter.ReadFloat(&outfloat));
  62. EXPECT_EQ(testfloat, outfloat);
  63. double outdouble;
  64. EXPECT_TRUE(iter.ReadDouble(&outdouble));
  65. EXPECT_EQ(testdouble, outdouble);
  66. std::string outstring;
  67. EXPECT_TRUE(iter.ReadString(&outstring));
  68. EXPECT_EQ(teststring, outstring);
  69. std::u16string outstring16;
  70. EXPECT_TRUE(iter.ReadString16(&outstring16));
  71. EXPECT_EQ(teststring16, outstring16);
  72. StringPiece outstringpiece;
  73. EXPECT_TRUE(iter.ReadStringPiece(&outstringpiece));
  74. EXPECT_EQ(testrawstring, outstringpiece);
  75. StringPiece16 outstringpiece16;
  76. EXPECT_TRUE(iter.ReadStringPiece16(&outstringpiece16));
  77. EXPECT_EQ(testrawstring16, outstringpiece16);
  78. const char* outdata;
  79. size_t outdatalen;
  80. EXPECT_TRUE(iter.ReadData(&outdata, &outdatalen));
  81. EXPECT_EQ(testdatalen, outdatalen);
  82. EXPECT_EQ(memcmp(testdata, outdata, outdatalen), 0);
  83. // reads past the end should fail
  84. EXPECT_FALSE(iter.ReadInt(&outint));
  85. }
  86. } // namespace
  87. TEST(PickleTest, EncodeDecode) {
  88. Pickle pickle;
  89. pickle.WriteBool(testbool1);
  90. pickle.WriteBool(testbool2);
  91. pickle.WriteInt(testint);
  92. pickle.WriteLong(testlong);
  93. pickle.WriteUInt16(testuint16);
  94. pickle.WriteUInt32(testuint32);
  95. pickle.WriteInt64(testint64);
  96. pickle.WriteUInt64(testuint64);
  97. pickle.WriteFloat(testfloat);
  98. pickle.WriteDouble(testdouble);
  99. pickle.WriteString(teststring);
  100. pickle.WriteString16(teststring16);
  101. pickle.WriteString(testrawstring);
  102. pickle.WriteString16(testrawstring16);
  103. pickle.WriteData(testdata, testdatalen);
  104. VerifyResult(pickle);
  105. // test copy constructor
  106. Pickle pickle2(pickle);
  107. VerifyResult(pickle2);
  108. // test operator=
  109. Pickle pickle3;
  110. pickle3 = pickle;
  111. VerifyResult(pickle3);
  112. }
  113. // Tests that reading/writing a long works correctly when the source process
  114. // is 64-bit. We rely on having both 32- and 64-bit trybots to validate both
  115. // arms of the conditional in this test.
  116. TEST(PickleTest, LongFrom64Bit) {
  117. Pickle pickle;
  118. // Under the hood long is always written as a 64-bit value, so simulate a
  119. // 64-bit long even on 32-bit architectures by explicitly writing an int64_t.
  120. pickle.WriteInt64(testint64);
  121. PickleIterator iter(pickle);
  122. long outlong;
  123. if (sizeof(long) < sizeof(int64_t)) {
  124. // ReadLong() should return false when the original written value can't be
  125. // represented as a long.
  126. #if GTEST_HAS_DEATH_TEST
  127. EXPECT_DEATH(std::ignore = iter.ReadLong(&outlong), "");
  128. #endif
  129. } else {
  130. EXPECT_TRUE(iter.ReadLong(&outlong));
  131. EXPECT_EQ(testint64, outlong);
  132. }
  133. }
  134. // Tests that we can handle really small buffers.
  135. TEST(PickleTest, SmallBuffer) {
  136. std::unique_ptr<char[]> buffer(new char[1]);
  137. // We should not touch the buffer.
  138. Pickle pickle(buffer.get(), 1);
  139. PickleIterator iter(pickle);
  140. int data;
  141. EXPECT_FALSE(iter.ReadInt(&data));
  142. }
  143. // Tests that we can handle improper headers.
  144. TEST(PickleTest, BigSize) {
  145. int buffer[] = { 0x56035200, 25, 40, 50 };
  146. Pickle pickle(reinterpret_cast<char*>(buffer), sizeof(buffer));
  147. EXPECT_EQ(0U, pickle.size());
  148. PickleIterator iter(pickle);
  149. int data;
  150. EXPECT_FALSE(iter.ReadInt(&data));
  151. }
  152. // Tests that instances constructed with invalid parameter combinations can be
  153. // properly copied. Regression test for https://crbug.com/1271311.
  154. TEST(PickleTest, CopyWithInvalidHeader) {
  155. // 1. Actual header size (calculated based on the input buffer) > passed in
  156. // buffer size. Which results in Pickle's internal |header_| = null.
  157. {
  158. Pickle::Header header = {.payload_size = 100};
  159. const char* data = reinterpret_cast<char*>(&header);
  160. const Pickle pickle(data, sizeof(header));
  161. EXPECT_EQ(0U, pickle.size());
  162. EXPECT_FALSE(pickle.data());
  163. Pickle copy_built_with_op = pickle;
  164. EXPECT_EQ(0U, copy_built_with_op.size());
  165. EXPECT_FALSE(copy_built_with_op.data());
  166. Pickle copy_built_with_ctor(pickle);
  167. EXPECT_EQ(0U, copy_built_with_ctor.size());
  168. EXPECT_FALSE(copy_built_with_ctor.data());
  169. }
  170. // 2. Input buffer's size < sizeof(Pickle::Header). Which must also result in
  171. // Pickle's internal |header_| = null.
  172. {
  173. const char data[2] = {0x00, 0x00};
  174. const Pickle pickle(data, sizeof(data));
  175. static_assert(sizeof(Pickle::Header) > sizeof(data));
  176. EXPECT_EQ(0U, pickle.size());
  177. EXPECT_FALSE(pickle.data());
  178. Pickle copy_built_with_op = pickle;
  179. EXPECT_EQ(0U, copy_built_with_op.size());
  180. EXPECT_FALSE(copy_built_with_op.data());
  181. Pickle copy_built_with_ctor(pickle);
  182. EXPECT_EQ(0U, copy_built_with_ctor.size());
  183. EXPECT_FALSE(copy_built_with_ctor.data());
  184. }
  185. }
  186. TEST(PickleTest, UnalignedSize) {
  187. int buffer[] = { 10, 25, 40, 50 };
  188. Pickle pickle(reinterpret_cast<char*>(buffer), sizeof(buffer));
  189. PickleIterator iter(pickle);
  190. int data;
  191. EXPECT_FALSE(iter.ReadInt(&data));
  192. }
  193. TEST(PickleTest, ZeroLenStr) {
  194. Pickle pickle;
  195. pickle.WriteString(std::string());
  196. PickleIterator iter(pickle);
  197. std::string outstr;
  198. EXPECT_TRUE(iter.ReadString(&outstr));
  199. EXPECT_EQ("", outstr);
  200. }
  201. TEST(PickleTest, ZeroLenStr16) {
  202. Pickle pickle;
  203. pickle.WriteString16(std::u16string());
  204. PickleIterator iter(pickle);
  205. std::string outstr;
  206. EXPECT_TRUE(iter.ReadString(&outstr));
  207. EXPECT_EQ("", outstr);
  208. }
  209. TEST(PickleTest, BadLenStr) {
  210. Pickle pickle;
  211. pickle.WriteInt(-2);
  212. PickleIterator iter(pickle);
  213. std::string outstr;
  214. EXPECT_FALSE(iter.ReadString(&outstr));
  215. }
  216. TEST(PickleTest, BadLenStr16) {
  217. Pickle pickle;
  218. pickle.WriteInt(-1);
  219. PickleIterator iter(pickle);
  220. std::u16string outstr;
  221. EXPECT_FALSE(iter.ReadString16(&outstr));
  222. }
  223. TEST(PickleTest, PeekNext) {
  224. struct CustomHeader : base::Pickle::Header {
  225. int cookies[10];
  226. };
  227. Pickle pickle(sizeof(CustomHeader));
  228. pickle.WriteString("Goooooooooooogle");
  229. const char* pickle_data = static_cast<const char*>(pickle.data());
  230. size_t pickle_size;
  231. // Data range doesn't contain header
  232. EXPECT_FALSE(Pickle::PeekNext(
  233. sizeof(CustomHeader),
  234. pickle_data,
  235. pickle_data + sizeof(CustomHeader) - 1,
  236. &pickle_size));
  237. // Data range contains header
  238. EXPECT_TRUE(Pickle::PeekNext(
  239. sizeof(CustomHeader),
  240. pickle_data,
  241. pickle_data + sizeof(CustomHeader),
  242. &pickle_size));
  243. EXPECT_EQ(pickle_size, pickle.size());
  244. // Data range contains header and some other data
  245. EXPECT_TRUE(Pickle::PeekNext(
  246. sizeof(CustomHeader),
  247. pickle_data,
  248. pickle_data + sizeof(CustomHeader) + 1,
  249. &pickle_size));
  250. EXPECT_EQ(pickle_size, pickle.size());
  251. // Data range contains full pickle
  252. EXPECT_TRUE(Pickle::PeekNext(
  253. sizeof(CustomHeader),
  254. pickle_data,
  255. pickle_data + pickle.size(),
  256. &pickle_size));
  257. EXPECT_EQ(pickle_size, pickle.size());
  258. }
  259. TEST(PickleTest, PeekNextOverflow) {
  260. struct CustomHeader : base::Pickle::Header {
  261. int cookies[10];
  262. };
  263. CustomHeader header;
  264. // Check if we can wrap around at all
  265. if (sizeof(size_t) > sizeof(header.payload_size))
  266. return;
  267. const char* pickle_data = reinterpret_cast<const char*>(&header);
  268. size_t pickle_size;
  269. // Wrapping around is detected and reported as maximum size_t value
  270. header.payload_size = static_cast<uint32_t>(
  271. 1 - static_cast<int32_t>(sizeof(CustomHeader)));
  272. EXPECT_TRUE(Pickle::PeekNext(
  273. sizeof(CustomHeader),
  274. pickle_data,
  275. pickle_data + sizeof(CustomHeader),
  276. &pickle_size));
  277. EXPECT_EQ(pickle_size, std::numeric_limits<size_t>::max());
  278. // Ridiculous pickle sizes are fine (callers are supposed to
  279. // verify them)
  280. header.payload_size =
  281. std::numeric_limits<uint32_t>::max() / 2 - sizeof(CustomHeader);
  282. EXPECT_TRUE(Pickle::PeekNext(
  283. sizeof(CustomHeader),
  284. pickle_data,
  285. pickle_data + sizeof(CustomHeader),
  286. &pickle_size));
  287. EXPECT_EQ(pickle_size, std::numeric_limits<uint32_t>::max() / 2);
  288. }
  289. TEST(PickleTest, FindNext) {
  290. Pickle pickle;
  291. pickle.WriteInt(1);
  292. pickle.WriteString("Domo");
  293. const char* start = reinterpret_cast<const char*>(pickle.data());
  294. const char* end = start + pickle.size();
  295. EXPECT_EQ(end, Pickle::FindNext(pickle.header_size_, start, end));
  296. EXPECT_EQ(nullptr, Pickle::FindNext(pickle.header_size_, start, end - 1));
  297. EXPECT_EQ(end, Pickle::FindNext(pickle.header_size_, start, end + 1));
  298. }
  299. TEST(PickleTest, FindNextWithIncompleteHeader) {
  300. size_t header_size = sizeof(Pickle::Header);
  301. std::unique_ptr<char[]> buffer(new char[header_size - 1]);
  302. memset(buffer.get(), 0x1, header_size - 1);
  303. const char* start = buffer.get();
  304. const char* end = start + header_size - 1;
  305. EXPECT_EQ(nullptr, Pickle::FindNext(header_size, start, end));
  306. }
  307. #if defined(COMPILER_MSVC)
  308. #pragma warning(push)
  309. #pragma warning(disable: 4146)
  310. #endif
  311. TEST(PickleTest, FindNextOverflow) {
  312. size_t header_size = sizeof(Pickle::Header);
  313. size_t header_size2 = 2 * header_size;
  314. size_t payload_received = 100;
  315. std::unique_ptr<char[]> buffer(new char[header_size2 + payload_received]);
  316. const char* start = buffer.get();
  317. Pickle::Header* header = reinterpret_cast<Pickle::Header*>(buffer.get());
  318. const char* end = start + header_size2 + payload_received;
  319. // It is impossible to construct an overflow test otherwise.
  320. if (sizeof(size_t) > sizeof(header->payload_size) ||
  321. sizeof(uintptr_t) > sizeof(header->payload_size))
  322. return;
  323. header->payload_size = -(reinterpret_cast<uintptr_t>(start) + header_size2);
  324. EXPECT_EQ(nullptr, Pickle::FindNext(header_size2, start, end));
  325. header->payload_size = -header_size2;
  326. EXPECT_EQ(nullptr, Pickle::FindNext(header_size2, start, end));
  327. header->payload_size = 0;
  328. end = start + header_size;
  329. EXPECT_EQ(nullptr, Pickle::FindNext(header_size2, start, end));
  330. }
  331. #if defined(COMPILER_MSVC)
  332. #pragma warning(pop)
  333. #endif
  334. TEST(PickleTest, GetReadPointerAndAdvance) {
  335. Pickle pickle;
  336. PickleIterator iter(pickle);
  337. EXPECT_FALSE(iter.GetReadPointerAndAdvance(1));
  338. pickle.WriteInt(1);
  339. pickle.WriteInt(2);
  340. int bytes = sizeof(int) * 2;
  341. EXPECT_TRUE(PickleIterator(pickle).GetReadPointerAndAdvance(0));
  342. EXPECT_TRUE(PickleIterator(pickle).GetReadPointerAndAdvance(1));
  343. EXPECT_FALSE(PickleIterator(pickle).GetReadPointerAndAdvance(-1));
  344. EXPECT_TRUE(PickleIterator(pickle).GetReadPointerAndAdvance(bytes));
  345. EXPECT_FALSE(PickleIterator(pickle).GetReadPointerAndAdvance(bytes + 1));
  346. EXPECT_FALSE(PickleIterator(pickle).GetReadPointerAndAdvance(INT_MAX));
  347. EXPECT_FALSE(PickleIterator(pickle).GetReadPointerAndAdvance(INT_MIN));
  348. }
  349. TEST(PickleTest, Resize) {
  350. size_t unit = Pickle::kPayloadUnit;
  351. std::unique_ptr<char[]> data(new char[unit]);
  352. char* data_ptr = data.get();
  353. for (size_t i = 0; i < unit; i++)
  354. data_ptr[i] = 'G';
  355. // construct a message that will be exactly the size of one payload unit,
  356. // note that any data will have a 4-byte header indicating the size
  357. const size_t payload_size_after_header = unit - sizeof(uint32_t);
  358. Pickle pickle;
  359. pickle.WriteData(data_ptr, payload_size_after_header - sizeof(uint32_t));
  360. size_t cur_payload = payload_size_after_header;
  361. // note: we assume 'unit' is a power of 2
  362. EXPECT_EQ(unit, pickle.capacity_after_header());
  363. EXPECT_EQ(pickle.payload_size(), payload_size_after_header);
  364. // fill out a full page (noting data header)
  365. pickle.WriteData(data_ptr, unit - sizeof(uint32_t));
  366. cur_payload += unit;
  367. EXPECT_EQ(unit * 2, pickle.capacity_after_header());
  368. EXPECT_EQ(cur_payload, pickle.payload_size());
  369. // one more byte should double the capacity
  370. pickle.WriteData(data_ptr, 1);
  371. cur_payload += 8;
  372. EXPECT_EQ(unit * 4, pickle.capacity_after_header());
  373. EXPECT_EQ(cur_payload, pickle.payload_size());
  374. }
  375. namespace {
  376. struct CustomHeader : Pickle::Header {
  377. int blah;
  378. };
  379. } // namespace
  380. TEST(PickleTest, HeaderPadding) {
  381. const uint32_t kMagic = 0x12345678;
  382. Pickle pickle(sizeof(CustomHeader));
  383. pickle.WriteInt(kMagic);
  384. // this should not overwrite the 'int' payload
  385. pickle.headerT<CustomHeader>()->blah = 10;
  386. PickleIterator iter(pickle);
  387. int result;
  388. ASSERT_TRUE(iter.ReadInt(&result));
  389. EXPECT_EQ(static_cast<uint32_t>(result), kMagic);
  390. }
  391. TEST(PickleTest, EqualsOperator) {
  392. Pickle source;
  393. source.WriteInt(1);
  394. Pickle copy_refs_source_buffer(static_cast<const char*>(source.data()),
  395. source.size());
  396. Pickle copy;
  397. copy = copy_refs_source_buffer;
  398. ASSERT_EQ(source.size(), copy.size());
  399. }
  400. TEST(PickleTest, EvilLengths) {
  401. Pickle source;
  402. std::string str(100000, 'A');
  403. source.WriteData(str.c_str(), 100000);
  404. // ReadString16 used to have its read buffer length calculation wrong leading
  405. // to out-of-bounds reading.
  406. PickleIterator iter(source);
  407. std::u16string str16;
  408. EXPECT_FALSE(iter.ReadString16(&str16));
  409. // And check we didn't break ReadString16.
  410. str16 = (wchar_t) 'A';
  411. Pickle str16_pickle;
  412. str16_pickle.WriteString16(str16);
  413. iter = PickleIterator(str16_pickle);
  414. EXPECT_TRUE(iter.ReadString16(&str16));
  415. EXPECT_EQ(1U, str16.length());
  416. // Check we don't fail in a length check with invalid String16 size.
  417. // (1<<31) * sizeof(char16_t) == 0, so this is particularly evil.
  418. Pickle bad_len;
  419. bad_len.WriteInt(1 << 31);
  420. iter = PickleIterator(bad_len);
  421. EXPECT_FALSE(iter.ReadString16(&str16));
  422. }
  423. // Check we can write zero bytes of data and 'data' can be NULL.
  424. TEST(PickleTest, ZeroLength) {
  425. Pickle pickle;
  426. pickle.WriteData(nullptr, 0);
  427. PickleIterator iter(pickle);
  428. const char* outdata;
  429. size_t outdatalen;
  430. EXPECT_TRUE(iter.ReadData(&outdata, &outdatalen));
  431. EXPECT_EQ(0u, outdatalen);
  432. // We can't assert that outdata is NULL.
  433. }
  434. // Check that ReadBytes works properly with an iterator initialized to NULL.
  435. TEST(PickleTest, ReadBytes) {
  436. Pickle pickle;
  437. int data = 0x7abcd;
  438. pickle.WriteBytes(&data, sizeof(data));
  439. PickleIterator iter(pickle);
  440. const char* outdata_char = nullptr;
  441. EXPECT_TRUE(iter.ReadBytes(&outdata_char, sizeof(data)));
  442. int outdata;
  443. memcpy(&outdata, outdata_char, sizeof(outdata));
  444. EXPECT_EQ(data, outdata);
  445. }
  446. // Checks that when a pickle is deep-copied, the result is not larger than
  447. // needed.
  448. TEST(PickleTest, DeepCopyResize) {
  449. Pickle pickle;
  450. while (pickle.capacity_after_header() != pickle.payload_size())
  451. pickle.WriteBool(true);
  452. // Make a deep copy.
  453. Pickle pickle2(pickle);
  454. // Check that there isn't any extraneous capacity.
  455. EXPECT_EQ(pickle.capacity_after_header(), pickle2.capacity_after_header());
  456. }
  457. namespace {
  458. // Publicly exposes the ClaimBytes interface for testing.
  459. class TestingPickle : public Pickle {
  460. public:
  461. TestingPickle() = default;
  462. void* ClaimBytes(size_t num_bytes) { return Pickle::ClaimBytes(num_bytes); }
  463. };
  464. } // namespace
  465. // Checks that claimed bytes are zero-initialized.
  466. TEST(PickleTest, ClaimBytesInitialization) {
  467. static const int kChunkSize = 64;
  468. TestingPickle pickle;
  469. const char* bytes = static_cast<const char*>(pickle.ClaimBytes(kChunkSize));
  470. for (size_t i = 0; i < kChunkSize; ++i) {
  471. EXPECT_EQ(0, bytes[i]);
  472. }
  473. }
  474. // Checks that ClaimBytes properly advances the write offset.
  475. TEST(PickleTest, ClaimBytes) {
  476. std::string data("Hello, world!");
  477. TestingPickle pickle;
  478. pickle.WriteUInt32(data.size());
  479. void* bytes = pickle.ClaimBytes(data.size());
  480. pickle.WriteInt(42);
  481. memcpy(bytes, data.data(), data.size());
  482. PickleIterator iter(pickle);
  483. uint32_t out_data_length;
  484. EXPECT_TRUE(iter.ReadUInt32(&out_data_length));
  485. EXPECT_EQ(data.size(), out_data_length);
  486. const char* out_data = nullptr;
  487. EXPECT_TRUE(iter.ReadBytes(&out_data, out_data_length));
  488. EXPECT_EQ(data, std::string(out_data, out_data_length));
  489. int out_value;
  490. EXPECT_TRUE(iter.ReadInt(&out_value));
  491. EXPECT_EQ(42, out_value);
  492. }
  493. TEST(PickleTest, ReachedEnd) {
  494. Pickle pickle;
  495. pickle.WriteInt(1);
  496. pickle.WriteInt(2);
  497. pickle.WriteInt(3);
  498. PickleIterator iter(pickle);
  499. int out;
  500. EXPECT_FALSE(iter.ReachedEnd());
  501. EXPECT_TRUE(iter.ReadInt(&out));
  502. EXPECT_EQ(1, out);
  503. EXPECT_FALSE(iter.ReachedEnd());
  504. EXPECT_TRUE(iter.ReadInt(&out));
  505. EXPECT_EQ(2, out);
  506. EXPECT_FALSE(iter.ReachedEnd());
  507. EXPECT_TRUE(iter.ReadInt(&out));
  508. EXPECT_EQ(3, out);
  509. EXPECT_TRUE(iter.ReachedEnd());
  510. EXPECT_FALSE(iter.ReadInt(&out));
  511. EXPECT_TRUE(iter.ReachedEnd());
  512. }
  513. } // namespace base