1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
|
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "storage/browser/test/sandbox_database_test_helper.h"
#include <stdint.h>
#include <algorithm>
#include <functional>
#include <limits>
#include <vector>
#include "base/containers/span.h"
#include "base/files/file.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_util.h"
#include "storage/common/file_system/file_system_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/leveldatabase/leveldb_chrome.h"
namespace storage {
void CorruptDatabase(const base::FilePath& db_path,
leveldb::FileType type,
ptrdiff_t offset,
size_t size) {
base::FileEnumerator file_enum(db_path, false /* not recursive */,
base::FileEnumerator::DIRECTORIES | base::FileEnumerator::FILES);
base::FilePath file_path;
base::FilePath picked_file_path;
uint64_t picked_file_number = std::numeric_limits<uint64_t>::max();
while (!(file_path = file_enum.Next()).empty()) {
uint64_t number = std::numeric_limits<uint64_t>::max();
leveldb::FileType file_type;
EXPECT_TRUE(leveldb_chrome::ParseFileName(
FilePathToString(file_path.BaseName()), &number, &file_type));
if (file_type == type &&
(picked_file_number == std::numeric_limits<uint64_t>::max() ||
picked_file_number < number)) {
picked_file_path = file_path;
picked_file_number = number;
}
}
EXPECT_FALSE(picked_file_path.empty());
EXPECT_NE(std::numeric_limits<uint64_t>::max(), picked_file_number);
base::File file(picked_file_path,
base::File::FLAG_OPEN | base::File::FLAG_READ |
base::File::FLAG_WRITE);
ASSERT_TRUE(file.IsValid());
EXPECT_FALSE(file.created());
base::File::Info file_info;
EXPECT_TRUE(file.GetInfo(&file_info));
if (offset < 0)
offset += file_info.size;
EXPECT_GE(offset, 0);
EXPECT_LE(offset, file_info.size);
size = std::min(size, static_cast<size_t>(file_info.size - offset));
std::vector<char> buf(size);
std::optional<size_t> read_size =
file.Read(offset, base::as_writable_byte_span(buf));
ASSERT_TRUE(read_size.has_value());
EXPECT_GE(buf.size(), read_size.value());
buf.resize(read_size.value());
std::ranges::transform(buf, buf.begin(), std::logical_not<char>());
std::optional<size_t> written_size =
file.Write(offset, base::as_byte_span(buf));
ASSERT_TRUE(written_size.has_value());
EXPECT_EQ(buf.size(), written_size.value());
}
void DeleteDatabaseFile(const base::FilePath& db_path,
leveldb::FileType type) {
base::FileEnumerator file_enum(db_path, false /* not recursive */,
base::FileEnumerator::DIRECTORIES | base::FileEnumerator::FILES);
base::FilePath file_path;
while (!(file_path = file_enum.Next()).empty()) {
uint64_t number = std::numeric_limits<uint64_t>::max();
leveldb::FileType file_type;
EXPECT_TRUE(leveldb_chrome::ParseFileName(
FilePathToString(file_path.BaseName()), &number, &file_type));
if (file_type == type) {
base::DeleteFile(file_path);
// We may have multiple files for the same type, so don't break here.
}
}
}
} // namespace storage
|