patch_read_write_unittest.cc 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793
  1. // Copyright 2017 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 "components/zucchini/patch_reader.h"
  5. #include "components/zucchini/patch_writer.h"
  6. #include <stddef.h>
  7. #include <stdint.h>
  8. #include <utility>
  9. #include <vector>
  10. #include "components/zucchini/version_info.h"
  11. #include "testing/gtest/include/gtest/gtest.h"
  12. namespace zucchini {
  13. namespace {
  14. // Used for initialization of raw test data.
  15. using ByteVector = std::vector<uint8_t>;
  16. // Helper function that creates an object of type |T| and intializes it from
  17. // data in |buffer|. Ensures initialization is successful. |buffer| is passed as
  18. // pointer to avoid passing a temporay, which can causes dangling references.
  19. template <class T>
  20. T TestInitialize(const ByteVector* buffer) {
  21. T value;
  22. BufferSource buffer_source(buffer->data(), buffer->size());
  23. EXPECT_TRUE(value.Initialize(&buffer_source));
  24. EXPECT_TRUE(buffer_source.empty()); // Make sure all data has been consumed
  25. return value;
  26. }
  27. // Helper function that creates an object of type |T| and tries to intialize it
  28. // from invalid data in |buffer|, expecting the operation to fail. |buffer| is
  29. // passed as pointer to avoid passing a temporary, which can causes dangling
  30. // references.
  31. template <class T>
  32. void TestInvalidInitialize(const ByteVector* buffer) {
  33. T value;
  34. BufferSource buffer_source(buffer->data(), buffer->size());
  35. EXPECT_FALSE(value.Initialize(&buffer_source));
  36. }
  37. // Helper function that serializes |value| into a buffer. Ensures that
  38. // serialization is successful and that the result matches |expected|.
  39. template <class T>
  40. void TestSerialize(const ByteVector& expected, const T& value) {
  41. size_t size = value.SerializedSize();
  42. EXPECT_EQ(expected.size(), size);
  43. ByteVector buffer(size);
  44. BufferSink buffer_sink(buffer.data(), buffer.size());
  45. EXPECT_TRUE(value.SerializeInto(&buffer_sink));
  46. EXPECT_EQ(expected, buffer);
  47. }
  48. ByteVector CreatePatchElement() {
  49. return {
  50. // PatchElementHeader
  51. 0x01, 0, 0, 0, // old_offset
  52. 0x51, 0, 0, 0, // old_length
  53. 0x03, 0, 0, 0, // new_offset
  54. 0x13, 0, 0, 0, // new_length
  55. 'P', 'x', '8', '6', // exe_type = EXE_TYPE_WIN32_X86
  56. 0x01, 0x00, // element version
  57. // EquivalenceSource
  58. 1, 0, 0, 0, // src_skip size
  59. 0x10, // src_skip content
  60. 1, 0, 0, 0, // dst_skip size
  61. 0x00, // dst_skip content
  62. 1, 0, 0, 0, // copy_count size
  63. 0x12, // copy_count content
  64. // ExtraDataSource
  65. 1, 0, 0, 0, // extra_data size
  66. 0x13, // extra_data content
  67. // RawDeltaSource
  68. 1, 0, 0, 0, // raw_delta_skip size
  69. 0x14, // raw_delta_skip content
  70. 1, 0, 0, 0, // raw_delta_diff size
  71. 0x15, // raw_delta_diff content
  72. // ReferenceDeltaSource
  73. 1, 0, 0, 0, // reference_delta size
  74. 0x16, // reference_delta content
  75. // PatchElementReader
  76. 2, 0, 0, 0, // pool count
  77. 0, // pool_tag
  78. 1, 0, 0, 0, // extra_targets size
  79. 0x17, // extra_targets content
  80. 2, // pool_tag
  81. 1, 0, 0, 0, // extra_targets size
  82. 0x18, // extra_targets content
  83. };
  84. }
  85. ByteVector CreateElementMatch() {
  86. return {
  87. // PatchElementHeader
  88. 0x01, 0, 0, 0, // old_offset
  89. 0x02, 0, 0, 0, // old_length
  90. 0x03, 0, 0, 0, // new_offset
  91. 0x04, 0, 0, 0, // new_length
  92. 'D', 'E', 'X', ' ', // exe_type = kExeTypeDex
  93. 0x01, 0x00, // element version
  94. };
  95. }
  96. // Helper to mutate test |data| (e.g., from CreatePatchElement()) at |idx| from
  97. // |from_val| (as sanity check) to |to_val|.
  98. void ModifyByte(size_t idx,
  99. uint8_t from_val,
  100. uint8_t to_val,
  101. std::vector<uint8_t>* data) {
  102. ASSERT_EQ(from_val, (*data)[idx]);
  103. (*data)[idx] = to_val;
  104. }
  105. } // namespace
  106. bool operator==(const ByteVector& a, ConstBufferView b) {
  107. return a == ByteVector(b.begin(), b.end());
  108. }
  109. TEST(PatchTest, ParseSerializeElementMatch) {
  110. ByteVector data = CreateElementMatch();
  111. BufferSource buffer_source(data.data(), data.size());
  112. ElementMatch element_match = {};
  113. EXPECT_TRUE(patch::ParseElementMatch(&buffer_source, &element_match));
  114. EXPECT_EQ(kExeTypeDex, element_match.exe_type());
  115. EXPECT_EQ(kExeTypeDex, element_match.old_element.exe_type);
  116. EXPECT_EQ(kExeTypeDex, element_match.new_element.exe_type);
  117. EXPECT_EQ(0x1U, element_match.old_element.offset);
  118. EXPECT_EQ(0x2U, element_match.old_element.size);
  119. EXPECT_EQ(0x3U, element_match.new_element.offset);
  120. EXPECT_EQ(0x4U, element_match.new_element.size);
  121. size_t size = patch::SerializedElementMatchSize(element_match);
  122. EXPECT_EQ(data.size(), size);
  123. ByteVector buffer(size);
  124. BufferSink buffer_sink(buffer.data(), buffer.size());
  125. EXPECT_TRUE(patch::SerializeElementMatch(element_match, &buffer_sink));
  126. EXPECT_EQ(data, buffer);
  127. }
  128. TEST(PatchTest, ParseElementMatchTooSmall) {
  129. ByteVector data = {4};
  130. BufferSource buffer_source(data.data(), data.size());
  131. ElementMatch element_match = {};
  132. EXPECT_FALSE(patch::ParseElementMatch(&buffer_source, &element_match));
  133. }
  134. TEST(PatchTest, ParseElementMatchNoLength) {
  135. // Set old_length to 0 to trigger an error.
  136. {
  137. ByteVector data = CreateElementMatch();
  138. // old_length := 0.
  139. ModifyByte(offsetof(PatchElementHeader, old_length), 0x02, 0x00, &data);
  140. BufferSource buffer_source(data.data(), data.size());
  141. ElementMatch element_match = {};
  142. EXPECT_FALSE(patch::ParseElementMatch(&buffer_source, &element_match));
  143. }
  144. // Set new_length to 0 to trigger an error.
  145. {
  146. ByteVector data = CreateElementMatch();
  147. // new_length := 0.
  148. ModifyByte(offsetof(PatchElementHeader, new_length), 0x04, 0x00, &data);
  149. BufferSource buffer_source(data.data(), data.size());
  150. ElementMatch element_match = {};
  151. EXPECT_FALSE(patch::ParseElementMatch(&buffer_source, &element_match));
  152. }
  153. // Set both new_length and old_length to 0 to trigger an error.
  154. {
  155. ByteVector data = CreateElementMatch();
  156. // old_length := 0.
  157. ModifyByte(offsetof(PatchElementHeader, old_length), 0x02, 0x00, &data);
  158. // new_length := 0.
  159. ModifyByte(offsetof(PatchElementHeader, new_length), 0x04, 0x00, &data);
  160. BufferSource buffer_source(data.data(), data.size());
  161. ElementMatch element_match = {};
  162. EXPECT_FALSE(patch::ParseElementMatch(&buffer_source, &element_match));
  163. }
  164. }
  165. TEST(PatchTest, ParseSerializeElementMatchExeMismatch) {
  166. ByteVector buffer(28);
  167. BufferSink buffer_sink(buffer.data(), buffer.size());
  168. EXPECT_FALSE(patch::SerializeElementMatch(
  169. ElementMatch{{{1, 2}, kExeTypeNoOp}, {{3, 4}, kExeTypeWin32X86}},
  170. &buffer_sink));
  171. }
  172. TEST(PatchTest, SerializeElementMatchTooSmall) {
  173. ByteVector buffer(4);
  174. BufferSink buffer_sink(buffer.data(), buffer.size());
  175. EXPECT_FALSE(patch::SerializeElementMatch(
  176. ElementMatch{{{1, 2}, kExeTypeDex}, {{3, 4}, kExeTypeDex}},
  177. &buffer_sink));
  178. }
  179. TEST(PatchTest, ParseSerializeBuffer) {
  180. auto TestSerialize = [](const ByteVector& expected, const ByteVector& value) {
  181. size_t size = patch::SerializedBufferSize(value);
  182. EXPECT_EQ(expected.size(), size);
  183. ByteVector buffer(size);
  184. BufferSink buffer_sink(buffer.data(), buffer.size());
  185. EXPECT_TRUE(patch::SerializeBuffer(value, &buffer_sink));
  186. EXPECT_EQ(expected, buffer);
  187. };
  188. // |data| is passed as pointer to avoid passing a temporay, which can causes
  189. // dangling references.
  190. auto TestParse = [](const ByteVector* data) {
  191. BufferSource value;
  192. BufferSource buffer_source(data->data(), data->size());
  193. EXPECT_TRUE(patch::ParseBuffer(&buffer_source, &value));
  194. // Make sure all data has been consumed.
  195. EXPECT_TRUE(buffer_source.empty());
  196. return value;
  197. };
  198. ByteVector data = {
  199. 0, 0, 0, 0, // size
  200. };
  201. BufferSource buffer = TestParse(&data);
  202. EXPECT_TRUE(buffer.empty());
  203. TestSerialize(data, ByteVector({}));
  204. data = {
  205. 3, 0, 0, 0, // size
  206. 1, 2, 3 // content
  207. };
  208. buffer = TestParse(&data);
  209. EXPECT_EQ(3U, buffer.size());
  210. EXPECT_EQ(ByteVector({1, 2, 3}), ByteVector(buffer.begin(), buffer.end()));
  211. TestSerialize(data, ByteVector({1, 2, 3}));
  212. // Ill-formed input.
  213. data = {
  214. 3, 0, 0, 0, // size
  215. 1, 2 // insufficient content
  216. };
  217. BufferSource value;
  218. BufferSource buffer_source(data.data(), data.size());
  219. EXPECT_FALSE(patch::ParseBuffer(&buffer_source, &value));
  220. EXPECT_TRUE(value.empty());
  221. }
  222. TEST(PatchTest, SerializeBufferTooSmall) {
  223. ByteVector buffer(3);
  224. BufferSink buffer_sink(buffer.data(), buffer.size());
  225. EXPECT_FALSE(patch::SerializeBuffer(ByteVector(), &buffer_sink));
  226. }
  227. TEST(EquivalenceSinkSourceTest, Empty) {
  228. ByteVector data = {
  229. // EquivalenceSource
  230. 0, 0, 0, 0, // src_skip size
  231. 0, 0, 0, 0, // dst_skip size
  232. 0, 0, 0, 0, // copy_count size
  233. };
  234. EquivalenceSource equivalence_source =
  235. TestInitialize<EquivalenceSource>(&data);
  236. EXPECT_FALSE(equivalence_source.GetNext());
  237. EXPECT_TRUE(equivalence_source.Done());
  238. TestSerialize(data, EquivalenceSink());
  239. }
  240. TEST(EquivalenceSourceSinkTest, Normal) {
  241. ByteVector data = {
  242. // EquivalenceSource
  243. 2, 0, 0, 0, // src_skip size
  244. 6, 7, // src_skip content
  245. 2, 0, 0, 0, // dst_skip size
  246. 7, 1, // dst_skip content
  247. 2, 0, 0, 0, // copy_count size
  248. 2, 1 // copy_count content
  249. };
  250. EquivalenceSource equivalence_source =
  251. TestInitialize<EquivalenceSource>(&data);
  252. auto equivalence = equivalence_source.GetNext();
  253. EXPECT_FALSE(equivalence_source.Done());
  254. EXPECT_TRUE(equivalence.has_value());
  255. EXPECT_EQ(offset_t(3), equivalence->src_offset);
  256. EXPECT_EQ(offset_t(7), equivalence->dst_offset);
  257. EXPECT_EQ(offset_t(2), equivalence->length);
  258. equivalence = equivalence_source.GetNext();
  259. EXPECT_TRUE(equivalence_source.Done());
  260. EXPECT_TRUE(equivalence.has_value());
  261. EXPECT_EQ(offset_t(1), equivalence->src_offset);
  262. EXPECT_EQ(offset_t(10), equivalence->dst_offset);
  263. EXPECT_EQ(offset_t(1), equivalence->length);
  264. equivalence = equivalence_source.GetNext();
  265. EXPECT_FALSE(equivalence.has_value());
  266. EquivalenceSink equivalence_sink;
  267. equivalence_sink.PutNext(Equivalence{3, 7, 2});
  268. equivalence_sink.PutNext(Equivalence{1, 10, 1});
  269. TestSerialize(data, equivalence_sink);
  270. }
  271. TEST(ExtraDataSourceSinkTest, Empty) {
  272. ByteVector data = {
  273. // ExtraDataSource
  274. 0, 0, 0, 0, // extra_data size
  275. };
  276. ExtraDataSource extra_data_source = TestInitialize<ExtraDataSource>(&data);
  277. EXPECT_FALSE(extra_data_source.GetNext(2));
  278. EXPECT_TRUE(extra_data_source.Done());
  279. TestSerialize(data, ExtraDataSink());
  280. }
  281. TEST(ExtraDataSourceSinkTest, Normal) {
  282. ByteVector data = {
  283. // ExtraDataSource
  284. 5, 0, 0, 0, // extra_data size
  285. 1, 2, 3, 4, 5, // extra_data content
  286. };
  287. ExtraDataSource extra_data_source = TestInitialize<ExtraDataSource>(&data);
  288. EXPECT_FALSE(extra_data_source.Done());
  289. auto extra_data = extra_data_source.GetNext(3);
  290. EXPECT_FALSE(extra_data_source.Done());
  291. EXPECT_TRUE(extra_data.has_value());
  292. EXPECT_EQ(size_t(3), extra_data->size());
  293. EXPECT_EQ(ByteVector({1, 2, 3}),
  294. ByteVector(extra_data->begin(), extra_data->end()));
  295. extra_data = extra_data_source.GetNext(2);
  296. EXPECT_TRUE(extra_data_source.Done());
  297. EXPECT_TRUE(extra_data.has_value());
  298. EXPECT_EQ(ByteVector({4, 5}),
  299. ByteVector(extra_data->begin(), extra_data->end()));
  300. extra_data = extra_data_source.GetNext(2);
  301. EXPECT_FALSE(extra_data.has_value());
  302. ExtraDataSink extra_data_sink;
  303. ByteVector content = {1, 2, 3};
  304. extra_data_sink.PutNext({content.data(), content.size()});
  305. content = {4, 5};
  306. extra_data_sink.PutNext({content.data(), content.size()});
  307. TestSerialize(data, extra_data_sink);
  308. }
  309. TEST(RawDeltaSourceSinkTest, Empty) {
  310. ByteVector data = {
  311. // RawDeltaSource
  312. 0, 0, 0, 0, // raw_delta_skip size
  313. 0, 0, 0, 0, // raw_delta_diff size
  314. };
  315. RawDeltaSource raw_delta_source = TestInitialize<RawDeltaSource>(&data);
  316. EXPECT_FALSE(raw_delta_source.GetNext());
  317. EXPECT_TRUE(raw_delta_source.Done());
  318. TestSerialize(data, RawDeltaSink());
  319. }
  320. TEST(RawDeltaSinkSourceSinkTest, Normal) {
  321. ByteVector data = {
  322. // RawDeltaSource
  323. 3, 0, 0, 0, // raw_delta_skip size
  324. 1, 3, 0, // raw_delta_skip content
  325. 3, 0, 0, 0, // raw_delta_diff size
  326. 42, 24, 235, // raw_delta_diff content
  327. };
  328. RawDeltaSource raw_delta_source = TestInitialize<RawDeltaSource>(&data);
  329. EXPECT_FALSE(raw_delta_source.Done());
  330. auto raw_delta = raw_delta_source.GetNext();
  331. EXPECT_FALSE(raw_delta_source.Done());
  332. EXPECT_TRUE(raw_delta.has_value());
  333. EXPECT_EQ(1U, raw_delta->copy_offset);
  334. EXPECT_EQ(42, raw_delta->diff);
  335. raw_delta = raw_delta_source.GetNext();
  336. EXPECT_FALSE(raw_delta_source.Done());
  337. EXPECT_TRUE(raw_delta.has_value());
  338. EXPECT_EQ(5U, raw_delta->copy_offset);
  339. EXPECT_EQ(24, raw_delta->diff);
  340. raw_delta = raw_delta_source.GetNext();
  341. EXPECT_TRUE(raw_delta_source.Done());
  342. EXPECT_TRUE(raw_delta.has_value());
  343. EXPECT_EQ(6U, raw_delta->copy_offset);
  344. EXPECT_EQ(-21, raw_delta->diff);
  345. EXPECT_FALSE(raw_delta_source.GetNext());
  346. EXPECT_TRUE(raw_delta_source.Done());
  347. RawDeltaSink raw_delta_sink;
  348. raw_delta_sink.PutNext({1, 42});
  349. raw_delta_sink.PutNext({5, 24});
  350. raw_delta_sink.PutNext({6, -21});
  351. TestSerialize(data, raw_delta_sink);
  352. }
  353. TEST(RawDeltaSourceSinkTest, InvalidContent) {
  354. ByteVector data = {
  355. // RawDeltaSource
  356. 2, 0, 0, 0, // raw_delta_skip size
  357. 1, 3, // raw_delta_skip content
  358. 2, 0, 0, 0, // raw_delta_diff size
  359. 0, 4, // raw_delta_diff content
  360. };
  361. RawDeltaSource raw_delta_source = TestInitialize<RawDeltaSource>(&data);
  362. EXPECT_FALSE(raw_delta_source.GetNext());
  363. EXPECT_FALSE(raw_delta_source.Done());
  364. }
  365. TEST(ReferenceDeltaSourceSinkTest, Empty) {
  366. ByteVector data = {
  367. // ReferenceDeltaSource
  368. 0, 0, 0, 0, // reference_delta size
  369. };
  370. ReferenceDeltaSource reference_delta_source =
  371. TestInitialize<ReferenceDeltaSource>(&data);
  372. EXPECT_FALSE(reference_delta_source.GetNext());
  373. EXPECT_TRUE(reference_delta_source.Done());
  374. TestSerialize(data, ReferenceDeltaSink());
  375. }
  376. TEST(ReferenceDeltaSourceSinkTest, Normal) {
  377. ByteVector data = {
  378. // ReferenceDeltaSource
  379. 2, 0, 0, 0, // reference_delta size
  380. 84, 47, // reference_delta content
  381. };
  382. ReferenceDeltaSource reference_delta_source =
  383. TestInitialize<ReferenceDeltaSource>(&data);
  384. EXPECT_FALSE(reference_delta_source.Done());
  385. auto delta = reference_delta_source.GetNext();
  386. EXPECT_FALSE(reference_delta_source.Done());
  387. EXPECT_TRUE(delta.has_value());
  388. EXPECT_EQ(42, *delta);
  389. delta = reference_delta_source.GetNext();
  390. EXPECT_TRUE(reference_delta_source.Done());
  391. EXPECT_TRUE(delta.has_value());
  392. EXPECT_EQ(-24, *delta);
  393. EXPECT_FALSE(reference_delta_source.GetNext());
  394. EXPECT_TRUE(reference_delta_source.Done());
  395. ReferenceDeltaSink reference_delta;
  396. reference_delta.PutNext(42);
  397. reference_delta.PutNext(-24);
  398. TestSerialize(data, reference_delta);
  399. }
  400. TEST(TargetSourceSinkTest, Empty) {
  401. ByteVector data = {
  402. // TargetSource
  403. 0, 0, 0, 0, // extra_targets size
  404. };
  405. TargetSource target_source = TestInitialize<TargetSource>(&data);
  406. EXPECT_FALSE(target_source.GetNext());
  407. EXPECT_TRUE(target_source.Done());
  408. TestSerialize(data, TargetSink());
  409. }
  410. TEST(TargetSourceSinkTest, Normal) {
  411. ByteVector data = {
  412. // TargetSource
  413. 2, 0, 0, 0, // extra_targets size
  414. 3, 1, // extra_targets content
  415. };
  416. TargetSource target_source = TestInitialize<TargetSource>(&data);
  417. EXPECT_FALSE(target_source.Done());
  418. auto target = target_source.GetNext();
  419. EXPECT_FALSE(target_source.Done());
  420. EXPECT_TRUE(target.has_value());
  421. EXPECT_EQ(3U, *target);
  422. target = target_source.GetNext();
  423. EXPECT_TRUE(target_source.Done());
  424. EXPECT_TRUE(target.has_value());
  425. EXPECT_EQ(5U, *target);
  426. EXPECT_FALSE(target_source.GetNext());
  427. EXPECT_TRUE(target_source.Done());
  428. TargetSink target_sink;
  429. target_sink.PutNext(3);
  430. target_sink.PutNext(5);
  431. TestSerialize(data, target_sink);
  432. }
  433. TEST(PatchElementTest, Normal) {
  434. ByteVector data = CreatePatchElement();
  435. PatchElementReader patch_element_reader =
  436. TestInitialize<PatchElementReader>(&data);
  437. ElementMatch element_match = patch_element_reader.element_match();
  438. EXPECT_EQ(kExeTypeWin32X86, element_match.exe_type());
  439. EXPECT_EQ(kExeTypeWin32X86, element_match.old_element.exe_type);
  440. EXPECT_EQ(kExeTypeWin32X86, element_match.new_element.exe_type);
  441. EXPECT_EQ(0x1U, element_match.old_element.offset);
  442. EXPECT_EQ(0x51U, element_match.old_element.size);
  443. EXPECT_EQ(0x3U, element_match.new_element.offset);
  444. EXPECT_EQ(0x13U, element_match.new_element.size);
  445. EquivalenceSource equivalence_source =
  446. patch_element_reader.GetEquivalenceSource();
  447. EXPECT_EQ(ByteVector({0x10}), equivalence_source.src_skip());
  448. EXPECT_EQ(ByteVector({0x00}), equivalence_source.dst_skip());
  449. EXPECT_EQ(ByteVector({0x12}), equivalence_source.copy_count());
  450. ExtraDataSource extra_data_source = patch_element_reader.GetExtraDataSource();
  451. EXPECT_EQ(ByteVector({0x13}), extra_data_source.extra_data());
  452. RawDeltaSource raw_delta_source = patch_element_reader.GetRawDeltaSource();
  453. EXPECT_EQ(ByteVector({0x14}), raw_delta_source.raw_delta_skip());
  454. EXPECT_EQ(ByteVector({0x15}), raw_delta_source.raw_delta_diff());
  455. ReferenceDeltaSource reference_delta_source =
  456. patch_element_reader.GetReferenceDeltaSource();
  457. EXPECT_EQ(ByteVector({0x16}), reference_delta_source.reference_delta());
  458. TargetSource target_source1 =
  459. patch_element_reader.GetExtraTargetSource(PoolTag(0));
  460. EXPECT_EQ(ByteVector({0x17}), target_source1.extra_targets());
  461. TargetSource target_source2 =
  462. patch_element_reader.GetExtraTargetSource(PoolTag(1));
  463. EXPECT_EQ(ByteVector({}), target_source2.extra_targets());
  464. TargetSource target_source3 =
  465. patch_element_reader.GetExtraTargetSource(PoolTag(2));
  466. EXPECT_EQ(ByteVector({0x18}), target_source3.extra_targets());
  467. PatchElementWriter patch_element_writer(element_match);
  468. patch_element_writer.SetEquivalenceSink(
  469. EquivalenceSink({0x10}, {0x00}, {0x12}));
  470. patch_element_writer.SetExtraDataSink(ExtraDataSink({0x13}));
  471. patch_element_writer.SetRawDeltaSink(RawDeltaSink({0x14}, {0x15}));
  472. patch_element_writer.SetReferenceDeltaSink(ReferenceDeltaSink({0x16}));
  473. patch_element_writer.SetTargetSink(PoolTag(0), TargetSink({0x17}));
  474. patch_element_writer.SetTargetSink(PoolTag(2), TargetSink({0x18}));
  475. TestSerialize(data, patch_element_writer);
  476. }
  477. TEST(PatchElementTest, BadEquivalence) {
  478. // If the "old" element is too small then the test should fail.
  479. {
  480. ByteVector data = CreatePatchElement();
  481. // old_length := 0x4 (too small).
  482. ModifyByte(offsetof(PatchElementHeader, old_length), 0x51, 0x04, &data);
  483. TestInvalidInitialize<PatchElementReader>(&data);
  484. }
  485. // If the "new" element is too small then the test should fail.
  486. {
  487. ByteVector data = CreatePatchElement();
  488. // new_length := 0x5 (too small).
  489. ModifyByte(offsetof(PatchElementHeader, new_length), 0x13, 0x05, &data);
  490. TestInvalidInitialize<PatchElementReader>(&data);
  491. }
  492. }
  493. TEST(PatchElementTest, WrongExtraData) {
  494. // Make "new" too large so insufficient extra data exists to cover the image.
  495. {
  496. ByteVector data = CreatePatchElement();
  497. // new_length := 0x14 (too large).
  498. ModifyByte(offsetof(PatchElementHeader, new_length), 0x13, 0x14, &data);
  499. TestInvalidInitialize<PatchElementReader>(&data);
  500. }
  501. // Make "new" too small so there is too much extra data.
  502. {
  503. ByteVector data = CreatePatchElement();
  504. // new_length := 0x12 (too small).
  505. ModifyByte(offsetof(PatchElementHeader, new_length), 0x13, 0x12, &data);
  506. TestInvalidInitialize<PatchElementReader>(&data);
  507. }
  508. }
  509. TEST(PatchElementTest, WrongVersion) {
  510. // Bump element version to 2.
  511. {
  512. ByteVector data = CreatePatchElement();
  513. ModifyByte(offsetof(PatchElementHeader, version), 0x01, 0x02, &data);
  514. TestInvalidInitialize<PatchElementReader>(&data);
  515. }
  516. // Bump element version to 0.
  517. {
  518. ByteVector data = CreatePatchElement();
  519. ModifyByte(offsetof(PatchElementHeader, version), 0x01, 0x00, &data);
  520. TestInvalidInitialize<PatchElementReader>(&data);
  521. }
  522. }
  523. TEST(EnsemblePatchTest, RawPatch) {
  524. ByteVector data = {
  525. // PatchHeader
  526. 0x5A, 0x75, 0x63, 0x63, // magic
  527. 0x01, 0x00, 0x00, 0x00, // major/minor version
  528. 0x10, 0x32, 0x54, 0x76, // old_size
  529. 0x00, 0x11, 0x22, 0x33, // old_crc
  530. 0x01, 0, 0, 0, // new_size
  531. 0x44, 0x55, 0x66, 0x77, // new_crc
  532. 1, 0, 0, 0, // number of element
  533. // PatchElementHeader
  534. 0x01, 0, 0, 0, // old_offset
  535. 0x02, 0, 0, 0, // old_length
  536. 0x00, 0, 0, 0, // new_offset
  537. 0x01, 0, 0, 0, // new_length
  538. 'P', 'x', '8', '6', // exe_type = EXE_TYPE_WIN32_X8
  539. 0x01, 0x00, // element version
  540. // EquivalenceSource
  541. 0, 0, 0, 0, // src_skip size
  542. 0, 0, 0, 0, // dst_skip size
  543. 0, 0, 0, 0, // copy_count size
  544. // ExtraDataSource
  545. 0x01, 0, 0, 0, // extra_data size
  546. 0x04, // extra_data content
  547. // RawDeltaSource
  548. 0, 0, 0, 0, // raw_delta_skip size
  549. 0, 0, 0, 0, // raw_delta_diff size
  550. // ReferenceDeltaSource
  551. 0, 0, 0, 0, // reference_delta size
  552. // PatchElementReader
  553. 0, 0, 0, 0, // pool count
  554. };
  555. EnsemblePatchReader ensemble_patch_reader =
  556. TestInitialize<EnsemblePatchReader>(&data);
  557. PatchHeader header = ensemble_patch_reader.header();
  558. EXPECT_EQ(PatchHeader::kMagic, header.magic);
  559. EXPECT_EQ(kMajorVersion, header.major_version);
  560. EXPECT_EQ(kMinorVersion, header.minor_version);
  561. EXPECT_EQ(0x76543210U, header.old_size);
  562. EXPECT_EQ(0x33221100U, header.old_crc);
  563. EXPECT_EQ(0x01U, header.new_size);
  564. EXPECT_EQ(0x77665544U, header.new_crc);
  565. const std::vector<PatchElementReader>& elements =
  566. ensemble_patch_reader.elements();
  567. EXPECT_EQ(size_t(1), elements.size());
  568. EnsemblePatchWriter ensemble_patch_writer(header);
  569. PatchElementWriter patch_element_writer(elements[0].element_match());
  570. patch_element_writer.SetEquivalenceSink({});
  571. patch_element_writer.SetExtraDataSink(ExtraDataSink({0x04}));
  572. patch_element_writer.SetRawDeltaSink({});
  573. patch_element_writer.SetReferenceDeltaSink({});
  574. ensemble_patch_writer.AddElement(std::move(patch_element_writer));
  575. TestSerialize(data, ensemble_patch_writer);
  576. }
  577. TEST(EnsemblePatchTest, CheckFile) {
  578. ByteVector data = {
  579. // PatchHeader
  580. 0x5A, 0x75, 0x63, 0x63, // magic
  581. 0x01, 0x00, 0x00, 0x00, // major/minor version
  582. 0x05, 0x00, 0x00, 0x00, // old_size
  583. 0xDF, 0x13, 0xE4, 0x10, // old_crc
  584. 0x03, 0x00, 0x00, 0x00, // new_size
  585. 0xDC, 0xF7, 0x00, 0x40, // new_crc
  586. 1, 0, 0, 0, // number of element
  587. // PatchElementHeader
  588. 0x01, 0, 0, 0, // old_offset
  589. 0x02, 0, 0, 0, // old_length
  590. 0x00, 0, 0, 0, // new_offset
  591. 0x03, 0, 0, 0, // new_length
  592. 'P', 'x', '8', '6', // exe_type = EXE_TYPE_WIN32_X86
  593. 0x01, 0x00, // element version
  594. // EquivalenceSource
  595. 0, 0, 0, 0, // src_skip size
  596. 0, 0, 0, 0, // dst_skip size
  597. 0, 0, 0, 0, // copy_count size
  598. // ExtraDataSource
  599. 0x03, 0, 0, 0, // extra_data size
  600. 'A', 'B', 'C', // extra_data content
  601. // RawDeltaSource
  602. 0, 0, 0, 0, // raw_delta_skip size
  603. 0, 0, 0, 0, // raw_delta_diff size
  604. // ReferenceDeltaSource
  605. 0, 0, 0, 0, // reference_delta size
  606. // PatchElementReader
  607. 0, 0, 0, 0, // pool count
  608. };
  609. EnsemblePatchReader ensemble_patch_reader =
  610. TestInitialize<EnsemblePatchReader>(&data);
  611. ByteVector old_file = {0x10, 0x32, 0x54, 0x76, 0x98};
  612. ByteVector new_file = {0xBA, 0xDC, 0xFE};
  613. ConstBufferView old_image(old_file.data(), old_file.size());
  614. ConstBufferView new_image(new_file.data(), new_file.size());
  615. EXPECT_TRUE(ensemble_patch_reader.CheckOldFile(old_image));
  616. EXPECT_TRUE(ensemble_patch_reader.CheckNewFile(new_image));
  617. EXPECT_FALSE(ensemble_patch_reader.CheckOldFile(new_image));
  618. EXPECT_FALSE(ensemble_patch_reader.CheckNewFile(old_image));
  619. }
  620. TEST(EnsemblePatchTest, InvalidMagic) {
  621. ByteVector data = {
  622. // PatchHeader
  623. 0x42, 0x42, 0x42, 0x42, // magic
  624. 0x01, 0x00, 0x00, 0x00, // major/minor version
  625. 0x10, 0x32, 0x54, 0x76, // old_size
  626. 0x00, 0x11, 0x22, 0x33, // old_crc
  627. 0x03, 0x00, 0x00, 0x00, // new_size
  628. 0x44, 0x55, 0x66, 0x77, // new_crc
  629. 1, 0, 0, 0, // number of element
  630. // PatchElementHeader
  631. 0x01, 0, 0, 0, // old_offset
  632. 0x02, 0, 0, 0, // old_length
  633. 0x00, 0, 0, 0, // new_offset
  634. 0x03, 0, 0, 0, // new_length
  635. 'P', 'x', '8', '6', // exe_type = EXE_TYPE_WIN32_X86
  636. 0x01, 0x00, // element version
  637. // EquivalenceSource
  638. 0, 0, 0, 0, // src_skip size
  639. 0, 0, 0, 0, // dst_skip size
  640. 0, 0, 0, 0, // copy_count size
  641. // ExtraDataSource
  642. 0, 0, 0, 0, // extra_data size
  643. // RawDeltaSource
  644. 0, 0, 0, 0, // raw_delta_skip size
  645. 0, 0, 0, 0, // raw_delta_diff size
  646. // ReferenceDeltaSource
  647. 0, 0, 0, 0, // reference_delta size
  648. // PatchElementReader
  649. 0, 0, 0, 0, // pool count
  650. };
  651. TestInvalidInitialize<EnsemblePatchReader>(&data);
  652. }
  653. TEST(EnsemblePatchTest, InvalidVersion) {
  654. ByteVector data = {
  655. // PatchHeader
  656. 0x5A, 0x75, 0x63, 0x63, // magic
  657. 0x02, 0x01, 0x00, 0x00, // major/minor version
  658. 0x10, 0x32, 0x54, 0x76, // old_size
  659. 0x00, 0x11, 0x22, 0x33, // old_crc
  660. 0x03, 0x00, 0x00, 0x00, // new_size
  661. 0x44, 0x55, 0x66, 0x77, // new_crc
  662. 1, 0, 0, 0, // number of element
  663. // PatchElementHeader
  664. 0x01, 0, 0, 0, // old_offset
  665. 0x02, 0, 0, 0, // old_length
  666. 0x00, 0, 0, 0, // new_offset
  667. 0x03, 0, 0, 0, // new_length
  668. 'P', 'x', '8', '6', // exe_type = EXE_TYPE_WIN32_X86
  669. 0x01, 0x00, // element version
  670. // EquivalenceSource
  671. 0, 0, 0, 0, // src_skip size
  672. 0, 0, 0, 0, // dst_skip size
  673. 0, 0, 0, 0, // copy_count size
  674. // ExtraDataSource
  675. 0, 0, 0, 0, // extra_data size
  676. // RawDeltaSource
  677. 0, 0, 0, 0, // raw_delta_skip size
  678. 0, 0, 0, 0, // raw_delta_diff size
  679. // ReferenceDeltaSource
  680. 0, 0, 0, 0, // reference_delta size
  681. // PatchElementReader
  682. 0, 0, 0, 0, // pool count
  683. };
  684. TestInvalidInitialize<EnsemblePatchReader>(&data);
  685. }
  686. } // namespace zucchini