aboutsummaryrefslogtreecommitdiff
path: root/zucchini_integration.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_integration.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_integration.cc')
-rw-r--r--zucchini_integration.cc122
1 files changed, 122 insertions, 0 deletions
diff --git a/zucchini_integration.cc b/zucchini_integration.cc
new file mode 100644
index 0000000..3ca4601
--- /dev/null
+++ b/zucchini_integration.cc
@@ -0,0 +1,122 @@
+// 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_integration.h"
+
+#include <utility>
+
+#include "base/logging.h"
+#include "components/zucchini/buffer_view.h"
+#include "components/zucchini/mapped_file.h"
+#include "components/zucchini/patch_reader.h"
+
+namespace zucchini {
+
+namespace {
+
+struct FileNames {
+ FileNames() : is_dummy(true) {
+ // Use fake names. If |is_dummy| is true these files are only used for error
+ // output.
+ old_name = old_name.AppendASCII("old_name");
+ patch_name = patch_name.AppendASCII("patch_name");
+ new_name = new_name.AppendASCII("new_name");
+ }
+
+ FileNames(const base::FilePath& old_name,
+ const base::FilePath& patch_name,
+ const base::FilePath& new_name)
+ : old_name(old_name),
+ patch_name(patch_name),
+ new_name(new_name),
+ is_dummy(false) {}
+
+ base::FilePath old_name;
+ base::FilePath patch_name;
+ base::FilePath new_name;
+ const bool is_dummy;
+};
+
+status::Code ApplyCommon(base::File&& old_file_handle,
+ base::File&& patch_file_handle,
+ base::File&& new_file_handle,
+ const FileNames& names) {
+ MappedFileReader patch_file(std::move(patch_file_handle));
+ if (patch_file.HasError()) {
+ LOG(ERROR) << "Error with file " << names.patch_name.value() << ": "
+ << patch_file.error();
+ return status::kStatusFileReadError;
+ }
+
+ auto patch_reader =
+ zucchini::EnsemblePatchReader::Create(patch_file.region());
+ if (!patch_reader.has_value()) {
+ LOG(ERROR) << "Error reading patch header.";
+ return status::kStatusPatchReadError;
+ }
+
+ MappedFileReader old_file(std::move(old_file_handle));
+ if (old_file.HasError()) {
+ LOG(ERROR) << "Error with file " << names.old_name.value() << ": "
+ << old_file.error();
+ return status::kStatusFileReadError;
+ }
+ if (!patch_reader->CheckOldFile(old_file.region())) {
+ LOG(ERROR) << "Invalid old_file.";
+ return status::kStatusInvalidOldImage;
+ }
+
+ zucchini::PatchHeader header = patch_reader->header();
+ // By default, delete output on destruction, to avoid having lingering files
+ // in case of a failure. On Windows deletion can be done by the OS.
+ base::FilePath file_path;
+ if (!names.is_dummy)
+ file_path = base::FilePath(names.new_name);
+
+ MappedFileWriter new_file(file_path, std::move(new_file_handle),
+ header.new_size);
+ if (new_file.HasError()) {
+ LOG(ERROR) << "Error with file " << names.new_name.value() << ": "
+ << new_file.error();
+ return status::kStatusFileWriteError;
+ }
+
+ zucchini::status::Code result =
+ zucchini::Apply(old_file.region(), *patch_reader, new_file.region());
+ if (result != status::kStatusSuccess) {
+ LOG(ERROR) << "Fatal error encountered while applying patch.";
+ return result;
+ }
+
+ // Successfully patch |new_file|. Explicitly request file to be kept.
+ if (!new_file.Keep())
+ return status::kStatusFileWriteError;
+ return status::kStatusSuccess;
+}
+
+} // namespace
+
+status::Code Apply(base::File old_file_handle,
+ base::File patch_file_handle,
+ base::File new_file_handle) {
+ const FileNames file_names = FileNames();
+ return ApplyCommon(std::move(old_file_handle), std::move(patch_file_handle),
+ std::move(new_file_handle), file_names);
+}
+
+status::Code Apply(const base::FilePath& old_path,
+ const base::FilePath& patch_path,
+ const base::FilePath& new_path) {
+ using base::File;
+ File old_file(old_path, File::FLAG_OPEN | File::FLAG_READ);
+ File patch_file(patch_path, File::FLAG_OPEN | File::FLAG_READ);
+ File new_file(new_path, File::FLAG_CREATE_ALWAYS | File::FLAG_READ |
+ File::FLAG_WRITE | File::FLAG_SHARE_DELETE |
+ File::FLAG_CAN_DELETE_ON_CLOSE);
+ const FileNames file_names(old_path, patch_path, new_path);
+ return ApplyCommon(std::move(old_file), std::move(patch_file),
+ std::move(new_file), file_names);
+}
+
+} // namespace zucchini