aboutsummaryrefslogtreecommitdiff
path: root/zucchini_commands.cc
diff options
context:
space:
mode:
authorSamuel Huang <huangs@chromium.org>2018-03-13 18:19:34 +0000
committerEdward Lesmes <ehmaldonado@google.com>2021-07-23 21:50:59 +0000
commit06f1ae9aaca969ee95ef840f22b6b461c304542d (patch)
treef1e5c6624e70628e81fbf38d6cd14b974abe5d93 /zucchini_commands.cc
downloadzucchini-06f1ae9aaca969ee95ef840f22b6b461c304542d.tar.gz
[Zucchini] Move Zucchini from /chrome/installer/ to /components/.
(Use "git log --follow" to see older revisions of files). /components/ is the most logical place to put Zucchini, which only depends on /base and /testing/gtest. This move also enables Zucchini to be used by the Component Updater. Details: - Move all files; run the following to change deps and guards: sed 's/chrome\/installer/components/' *.cc *.h -i sed 's/CHROME_INSTALLER/COMPONENTS/' *.cc *.h -i - Sorting works out pretty well! - Change all 'chrome/installer/zucchini' to 'components/zucchini' throughout other parts of the repo; sort if necessary. - Fix 6 'git cl lint' errors. - Change 1 Bind() usage to BindRepeated(). - Update OWNER. Bug: 729154 Change-Id: I50c5a7d411ea85f707b5994ab319dfb2a1acccf7 Reviewed-on: https://chromium-review.googlesource.com/954923 Reviewed-by: Greg Thompson <grt@chromium.org> Reviewed-by: Jochen Eisinger <jochen@chromium.org> Reviewed-by: Samuel Huang <huangs@chromium.org> Commit-Queue: Samuel Huang <huangs@chromium.org> Cr-Commit-Position: refs/heads/master@{#542857} NOKEYCHECK=True GitOrigin-RevId: 577ef6c435e8d43be6e3e60ccbcbd1881780f4ec
Diffstat (limited to 'zucchini_commands.cc')
-rw-r--r--zucchini_commands.cc176
1 files changed, 176 insertions, 0 deletions
diff --git a/zucchini_commands.cc b/zucchini_commands.cc
new file mode 100644
index 0000000..60b87cb
--- /dev/null
+++ b/zucchini_commands.cc
@@ -0,0 +1,176 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/zucchini/zucchini_commands.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <iostream>
+#include <ostream>
+#include <utility>
+
+#include "base/command_line.h"
+#include "base/files/file.h"
+#include "base/files/file_path.h"
+#include "base/files/memory_mapped_file.h"
+#include "base/logging.h"
+#include "base/macros.h"
+#include "components/zucchini/buffer_view.h"
+#include "components/zucchini/crc32.h"
+#include "components/zucchini/io_utils.h"
+#include "components/zucchini/mapped_file.h"
+#include "components/zucchini/patch_writer.h"
+#include "components/zucchini/zucchini_integration.h"
+#include "components/zucchini/zucchini_tools.h"
+
+namespace {
+
+/******** Command-line Switches ********/
+
+constexpr char kSwitchDump[] = "dump";
+constexpr char kSwitchRaw[] = "raw";
+
+} // namespace
+
+zucchini::status::Code MainGen(MainParams params) {
+ CHECK_EQ(3U, params.file_paths.size());
+
+ // TODO(huangs): Move implementation to zucchini_integration.cc.
+ using base::File;
+ File old_file(params.file_paths[0], File::FLAG_OPEN | File::FLAG_READ);
+ zucchini::MappedFileReader old_image(std::move(old_file));
+ if (old_image.HasError()) {
+ LOG(ERROR) << "Error with file " << params.file_paths[0].value() << ": "
+ << old_image.error();
+ return zucchini::status::kStatusFileReadError;
+ }
+ File new_file(params.file_paths[1], File::FLAG_OPEN | File::FLAG_READ);
+ zucchini::MappedFileReader new_image(std::move(new_file));
+ if (new_image.HasError()) {
+ LOG(ERROR) << "Error with file " << params.file_paths[1].value() << ": "
+ << new_image.error();
+ return zucchini::status::kStatusFileReadError;
+ }
+ zucchini::EnsemblePatchWriter patch_writer(old_image.region(),
+ new_image.region());
+
+ auto generate = params.command_line.HasSwitch(kSwitchRaw)
+ ? zucchini::GenerateRaw
+ : zucchini::GenerateEnsemble;
+ zucchini::status::Code result =
+ generate(old_image.region(), new_image.region(), &patch_writer);
+ if (result != zucchini::status::kStatusSuccess) {
+ params.out << "Fatal error encountered when generating patch." << std::endl;
+ return result;
+ }
+
+ // By default, delete patch on destruction, to avoid having lingering files in
+ // case of a failure. On Windows deletion can be done by the OS.
+ File patch_file(params.file_paths[2], File::FLAG_CREATE_ALWAYS |
+ File::FLAG_READ | File::FLAG_WRITE |
+ File::FLAG_SHARE_DELETE |
+ File::FLAG_CAN_DELETE_ON_CLOSE);
+ zucchini::MappedFileWriter patch(params.file_paths[2], std::move(patch_file),
+ patch_writer.SerializedSize());
+ if (patch.HasError()) {
+ LOG(ERROR) << "Error with file " << params.file_paths[2].value() << ": "
+ << patch.error();
+ return zucchini::status::kStatusFileWriteError;
+ }
+
+ if (!patch_writer.SerializeInto(patch.region()))
+ return zucchini::status::kStatusPatchWriteError;
+
+ // Successfully created patch. Explicitly request file to be kept.
+ if (!patch.Keep())
+ return zucchini::status::kStatusFileWriteError;
+ return zucchini::status::kStatusSuccess;
+}
+
+zucchini::status::Code MainApply(MainParams params) {
+ CHECK_EQ(3U, params.file_paths.size());
+ return zucchini::Apply(params.file_paths[0], params.file_paths[1],
+ params.file_paths[2]);
+}
+
+zucchini::status::Code MainRead(MainParams params) {
+ CHECK_EQ(1U, params.file_paths.size());
+ base::File input_file(params.file_paths[0],
+ base::File::FLAG_OPEN | base::File::FLAG_READ);
+ zucchini::MappedFileReader input(std::move(input_file));
+ if (input.HasError()) {
+ LOG(ERROR) << "Error with file " << params.file_paths[0].value() << ": "
+ << input.error();
+ return zucchini::status::kStatusFileReadError;
+ }
+
+ bool do_dump = params.command_line.HasSwitch(kSwitchDump);
+ zucchini::status::Code status = zucchini::ReadReferences(
+ {input.data(), input.length()}, do_dump, params.out);
+ if (status != zucchini::status::kStatusSuccess)
+ params.err << "Fatal error found when dumping references." << std::endl;
+ return status;
+}
+
+zucchini::status::Code MainDetect(MainParams params) {
+ CHECK_EQ(1U, params.file_paths.size());
+ base::File input_file(params.file_paths[0],
+ base::File::FLAG_OPEN | base::File::FLAG_READ);
+ zucchini::MappedFileReader input(std::move(input_file));
+ if (input.HasError()) {
+ LOG(ERROR) << "Error with file " << params.file_paths[0].value() << ": "
+ << input.error();
+ return zucchini::status::kStatusFileReadError;
+ }
+
+ std::vector<zucchini::ConstBufferView> sub_image_list;
+ zucchini::status::Code result = zucchini::DetectAll(
+ {input.data(), input.length()}, params.out, &sub_image_list);
+ if (result != zucchini::status::kStatusSuccess)
+ params.err << "Fatal error found when detecting executables." << std::endl;
+ return result;
+}
+
+zucchini::status::Code MainMatch(MainParams params) {
+ CHECK_EQ(2U, params.file_paths.size());
+ using base::File;
+ File old_file(params.file_paths[0], File::FLAG_OPEN | File::FLAG_READ);
+ zucchini::MappedFileReader old_image(std::move(old_file));
+ if (old_image.HasError()) {
+ LOG(ERROR) << "Error with file " << params.file_paths[0].value() << ": "
+ << old_image.error();
+ return zucchini::status::kStatusFileReadError;
+ }
+ File new_file(params.file_paths[1], File::FLAG_OPEN | File::FLAG_READ);
+ zucchini::MappedFileReader new_image(std::move(new_file));
+ if (old_image.HasError()) {
+ LOG(ERROR) << "Error with file " << params.file_paths[1].value() << ": "
+ << new_image.error();
+ return zucchini::status::kStatusFileReadError;
+ }
+ zucchini::status::Code status =
+ zucchini::MatchAll({old_image.data(), old_image.length()},
+ {new_image.data(), new_image.length()}, params.out);
+ if (status != zucchini::status::kStatusSuccess)
+ params.err << "Fatal error found when matching executables." << std::endl;
+ return status;
+}
+
+zucchini::status::Code MainCrc32(MainParams params) {
+ CHECK_EQ(1U, params.file_paths.size());
+ base::File image_file(params.file_paths[0],
+ base::File::FLAG_OPEN | base::File::FLAG_READ);
+ zucchini::MappedFileReader image(std::move(image_file));
+ if (image.HasError()) {
+ LOG(ERROR) << "Error with file " << params.file_paths[0].value() << ": "
+ << image.error();
+ return zucchini::status::kStatusFileReadError;
+ }
+
+ uint32_t crc =
+ zucchini::CalculateCrc32(image.data(), image.data() + image.length());
+ params.out << "CRC32: " << zucchini::AsHex<8>(crc) << std::endl;
+ return zucchini::status::kStatusSuccess;
+}