blob: 0fa7b443b8cf11c0496ec01babf3444057afc44b [file] [log] [blame]
Avi Drissman8ba1bad2022-09-13 19:22:361// Copyright 2017 The Chromium Authors
huangsf953e4072017-07-28 01:16:212// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Samuel Huang577ef6c2018-03-13 18:19:345#include "components/zucchini/zucchini_commands.h"
huangsf953e4072017-07-28 01:16:216
Samuel Huange8d07b752017-08-21 16:05:257#include <stddef.h>
8#include <stdint.h>
9
huangs252600a2017-07-31 22:19:4810#include <ostream>
Samuel Huang73a64ff2018-04-30 22:47:5211#include <string>
Samuel Huang577ef6c2018-03-13 18:19:3412#include <utility>
huangs252600a2017-07-31 22:19:4813
14#include "base/command_line.h"
15#include "base/files/file.h"
16#include "base/files/file_path.h"
17#include "base/files/memory_mapped_file.h"
huangsf953e4072017-07-28 01:16:2118#include "base/logging.h"
Samuel Huang577ef6c2018-03-13 18:19:3419#include "components/zucchini/buffer_view.h"
20#include "components/zucchini/crc32.h"
Samuel Huang0fe9ae92022-10-31 17:30:1321#include "components/zucchini/encoded_view.h"
22#include "components/zucchini/image_index.h"
Samuel Huang577ef6c2018-03-13 18:19:3423#include "components/zucchini/io_utils.h"
24#include "components/zucchini/mapped_file.h"
25#include "components/zucchini/patch_writer.h"
Samuel Huang0fe9ae92022-10-31 17:30:1326#include "components/zucchini/suffix_array.h"
Samuel Huang577ef6c2018-03-13 18:19:3427#include "components/zucchini/zucchini_integration.h"
28#include "components/zucchini/zucchini_tools.h"
huangsf953e4072017-07-28 01:16:2129
30namespace {
31
Samuel Huang0fe9ae92022-10-31 17:30:1332using zucchini::status::kStatusFileReadError;
33using zucchini::status::kStatusSuccess;
34
Etienne Pierre-Doray73ed4232017-08-10 01:28:4135/******** Command-line Switches ********/
36
Samuel Huangd943db62017-08-23 21:46:5737constexpr char kSwitchDump[] = "dump";
Samuel Huang73a64ff2018-04-30 22:47:5238constexpr char kSwitchImpose[] = "impose";
Samuel Huang21879c32018-03-21 18:54:0339constexpr char kSwitchKeep[] = "keep";
Samuel Huangd943db62017-08-23 21:46:5740constexpr char kSwitchRaw[] = "raw";
Etienne Pierre-Doray73ed4232017-08-10 01:28:4141
Samuel Huang0fe9ae92022-10-31 17:30:1342class WrappedMappedFileReader : public zucchini::MappedFileReader {
43 public:
44 static constexpr uint32_t read_flags = base::File::FLAG_OPEN |
45 base::File::FLAG_READ |
46 base::File::FLAG_WIN_SHARE_DELETE;
47
48 explicit WrappedMappedFileReader(const base::FilePath& path)
49 : MappedFileReader(base::File(path, read_flags)) {
50 if (HasError()) {
51 LOG(ERROR) << "Error reading file " << path.value() << ": " << error();
52 status = kStatusFileReadError;
53 }
54 }
55
56 zucchini::status::Code status = kStatusSuccess;
57};
58
huangsf953e4072017-07-28 01:16:2159} // namespace
60
huangs252600a2017-07-31 22:19:4861zucchini::status::Code MainGen(MainParams params) {
Ali Hijazia709b48b2022-11-09 01:27:4462 CHECK_EQ(3U, params.file_paths->size());
Samuel Huang9f0f3252018-06-21 15:50:2263 return zucchini::Generate(
Ali Hijazia709b48b2022-11-09 01:27:4464 (*params.file_paths)[0], (*params.file_paths)[1], (*params.file_paths)[2],
65 params.command_line->HasSwitch(kSwitchKeep),
66 params.command_line->HasSwitch(kSwitchRaw),
67 params.command_line->GetSwitchValueASCII(kSwitchImpose));
huangsf953e4072017-07-28 01:16:2168}
69
huangs252600a2017-07-31 22:19:4870zucchini::status::Code MainApply(MainParams params) {
Ali Hijazia709b48b2022-11-09 01:27:4471 CHECK_EQ(3U, params.file_paths->size());
72 return zucchini::Apply((*params.file_paths)[0], (*params.file_paths)[1],
73 (*params.file_paths)[2],
74 params.command_line->HasSwitch(kSwitchKeep));
Samuel Huangd943db62017-08-23 21:46:5775}
76
Etienne Pierre-doray559d77a2021-10-28 21:16:0477zucchini::status::Code MainVerify(MainParams params) {
Ali Hijazia709b48b2022-11-09 01:27:4478 CHECK_EQ(1U, params.file_paths->size());
79 return zucchini::VerifyPatch((*params.file_paths)[0]);
Etienne Pierre-doray559d77a2021-10-28 21:16:0480}
81
Samuel Huangd943db62017-08-23 21:46:5782zucchini::status::Code MainRead(MainParams params) {
Ali Hijazia709b48b2022-11-09 01:27:4483 CHECK_EQ(1U, params.file_paths->size());
84 WrappedMappedFileReader input((*params.file_paths)[0]);
Samuel Huang0fe9ae92022-10-31 17:30:1385 if (input.status != kStatusSuccess)
86 return input.status;
Samuel Huangd943db62017-08-23 21:46:5787
Ali Hijazia709b48b2022-11-09 01:27:4488 bool do_dump = params.command_line->HasSwitch(kSwitchDump);
Samuel Huangd943db62017-08-23 21:46:5789 zucchini::status::Code status = zucchini::ReadReferences(
Ali Hijazia709b48b2022-11-09 01:27:4490 {input.data(), input.length()}, do_dump, *params.out);
Samuel Huang0fe9ae92022-10-31 17:30:1391 if (status != kStatusSuccess)
Ali Hijazia709b48b2022-11-09 01:27:4492 *params.err << "Fatal error found when dumping references." << std::endl;
Samuel Huangd943db62017-08-23 21:46:5793 return status;
huangs252600a2017-07-31 22:19:4894}
95
Samuel Huangdd90d832017-11-03 18:14:0296zucchini::status::Code MainDetect(MainParams params) {
Ali Hijazia709b48b2022-11-09 01:27:4497 CHECK_EQ(1U, params.file_paths->size());
98 WrappedMappedFileReader input((*params.file_paths)[0]);
Samuel Huang0fe9ae92022-10-31 17:30:1399 if (input.status != kStatusSuccess)
100 return input.status;
Samuel Huangdd90d832017-11-03 18:14:02101
102 std::vector<zucchini::ConstBufferView> sub_image_list;
103 zucchini::status::Code result = zucchini::DetectAll(
Ali Hijazia709b48b2022-11-09 01:27:44104 {input.data(), input.length()}, *params.out, &sub_image_list);
Samuel Huang0fe9ae92022-10-31 17:30:13105 if (result != kStatusSuccess)
Ali Hijazia709b48b2022-11-09 01:27:44106 *params.err << "Fatal error found when detecting executables." << std::endl;
Samuel Huangdd90d832017-11-03 18:14:02107 return result;
108}
109
Samuel Huangfdb2f3a2017-12-20 17:45:14110zucchini::status::Code MainMatch(MainParams params) {
Ali Hijazia709b48b2022-11-09 01:27:44111 CHECK_EQ(2U, params.file_paths->size());
112 WrappedMappedFileReader old_image((*params.file_paths)[0]);
Samuel Huang0fe9ae92022-10-31 17:30:13113 if (old_image.status != kStatusSuccess)
114 return old_image.status;
Ali Hijazia709b48b2022-11-09 01:27:44115 WrappedMappedFileReader new_image((*params.file_paths)[1]);
Samuel Huang0fe9ae92022-10-31 17:30:13116 if (new_image.status != kStatusSuccess)
117 return new_image.status;
Samuel Huang73a64ff2018-04-30 22:47:52118
119 std::string imposed_matches =
Ali Hijazia709b48b2022-11-09 01:27:44120 params.command_line->GetSwitchValueASCII(kSwitchImpose);
Samuel Huangfdb2f3a2017-12-20 17:45:14121 zucchini::status::Code status =
122 zucchini::MatchAll({old_image.data(), old_image.length()},
Samuel Huang73a64ff2018-04-30 22:47:52123 {new_image.data(), new_image.length()},
Ali Hijazia709b48b2022-11-09 01:27:44124 std::move(imposed_matches), *params.out);
Samuel Huang0fe9ae92022-10-31 17:30:13125 if (status != kStatusSuccess)
Ali Hijazia709b48b2022-11-09 01:27:44126 *params.err << "Fatal error found when matching executables." << std::endl;
Samuel Huangfdb2f3a2017-12-20 17:45:14127 return status;
128}
129
huangs252600a2017-07-31 22:19:48130zucchini::status::Code MainCrc32(MainParams params) {
Ali Hijazia709b48b2022-11-09 01:27:44131 CHECK_EQ(1U, params.file_paths->size());
132 WrappedMappedFileReader input((*params.file_paths)[0]);
Samuel Huang0fe9ae92022-10-31 17:30:13133 if (input.status != kStatusSuccess)
134 return input.status;
huangs252600a2017-07-31 22:19:48135
136 uint32_t crc =
Samuel Huang0fe9ae92022-10-31 17:30:13137 zucchini::CalculateCrc32(input.data(), input.data() + input.length());
Ali Hijazia709b48b2022-11-09 01:27:44138 *params.out << "CRC32: " << zucchini::AsHex<8>(crc) << std::endl;
Samuel Huang0fe9ae92022-10-31 17:30:13139 return kStatusSuccess;
140}
141
142zucchini::status::Code MainSuffixArray(MainParams params) {
Ali Hijazia709b48b2022-11-09 01:27:44143 CHECK_EQ(1U, params.file_paths->size());
144 WrappedMappedFileReader input((*params.file_paths)[0]);
Samuel Huang0fe9ae92022-10-31 17:30:13145 if (input.status != kStatusSuccess)
146 return input.status;
147
148 zucchini::ImageIndex image_index(input.region());
149 zucchini::EncodedView view_raw(image_index);
150 std::vector<zucchini::offset_t> sa_raw =
151 zucchini::MakeSuffixArray<zucchini::InducedSuffixSort>(view_raw,
152 size_t(256));
153 return kStatusSuccess;
huangsf953e4072017-07-28 01:16:21154}