1 // Copyright 2013 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/disk_cache/simple/simple_test_util.h"
6
7 #include "base/compiler_specific.h"
8 #include "base/files/file.h"
9 #include "base/files/file_path.h"
10 #include "net/base/hash_value.h"
11 #include "net/disk_cache/simple/simple_entry_format.h"
12 #include "net/disk_cache/simple/simple_util.h"
13
14 namespace disk_cache::simple_util {
15
16 using base::File;
17 using base::FilePath;
18
CreateCorruptFileForTests(const std::string & key,const FilePath & cache_path)19 bool CreateCorruptFileForTests(const std::string& key,
20 const FilePath& cache_path) {
21 FilePath entry_file_path = cache_path.AppendASCII(
22 disk_cache::simple_util::GetFilenameFromKeyAndFileIndex(key, 0));
23 int flags = File::FLAG_CREATE_ALWAYS | File::FLAG_WRITE;
24 File entry_file(entry_file_path, flags);
25
26 if (!entry_file.IsValid())
27 return false;
28
29 return UNSAFE_TODO(entry_file.Write(0, "dummy", 1)) == 1;
30 }
31
RemoveKeySHA256FromEntry(const std::string & key,const FilePath & cache_path)32 bool RemoveKeySHA256FromEntry(const std::string& key,
33 const FilePath& cache_path) {
34 FilePath entry_file_path = cache_path.AppendASCII(
35 disk_cache::simple_util::GetFilenameFromKeyAndFileIndex(key, 0));
36 int flags = File::FLAG_OPEN | File::FLAG_READ | File::FLAG_WRITE;
37 File entry_file(entry_file_path, flags);
38 if (!entry_file.IsValid())
39 return false;
40 int64_t file_length = entry_file.GetLength();
41 SimpleFileEOF eof_record;
42 if (file_length < static_cast<int64_t>(sizeof(eof_record)))
43 return false;
44 if (UNSAFE_TODO(entry_file.Read(file_length - sizeof(eof_record),
45 reinterpret_cast<char*>(&eof_record),
46 sizeof(eof_record))) != sizeof(eof_record)) {
47 return false;
48 }
49 if (eof_record.final_magic_number != disk_cache::kSimpleFinalMagicNumber ||
50 (eof_record.flags & SimpleFileEOF::FLAG_HAS_KEY_SHA256) !=
51 SimpleFileEOF::FLAG_HAS_KEY_SHA256) {
52 return false;
53 }
54 // Remove the key SHA256 flag, and rewrite the header on top of the
55 // SHA256. Truncate the file afterwards, and we have an identical entry
56 // lacking a key SHA256.
57 eof_record.flags &= ~SimpleFileEOF::FLAG_HAS_KEY_SHA256;
58 if (UNSAFE_TODO(entry_file.Write(
59 file_length - sizeof(eof_record) - sizeof(net::SHA256HashValue),
60 reinterpret_cast<char*>(&eof_record), sizeof(eof_record))) !=
61 sizeof(eof_record)) {
62 return false;
63 }
64 if (!entry_file.SetLength(file_length - sizeof(net::SHA256HashValue))) {
65 return false;
66 }
67 return true;
68 }
69
CorruptKeySHA256FromEntry(const std::string & key,const base::FilePath & cache_path)70 bool CorruptKeySHA256FromEntry(const std::string& key,
71 const base::FilePath& cache_path) {
72 FilePath entry_file_path = cache_path.AppendASCII(
73 disk_cache::simple_util::GetFilenameFromKeyAndFileIndex(key, 0));
74 int flags = File::FLAG_OPEN | File::FLAG_READ | File::FLAG_WRITE;
75 File entry_file(entry_file_path, flags);
76 if (!entry_file.IsValid())
77 return false;
78 int64_t file_length = entry_file.GetLength();
79 SimpleFileEOF eof_record;
80 if (file_length < static_cast<int64_t>(sizeof(eof_record)))
81 return false;
82 if (UNSAFE_TODO(entry_file.Read(file_length - sizeof(eof_record),
83 reinterpret_cast<char*>(&eof_record),
84 sizeof(eof_record))) != sizeof(eof_record)) {
85 return false;
86 }
87 if (eof_record.final_magic_number != disk_cache::kSimpleFinalMagicNumber ||
88 (eof_record.flags & SimpleFileEOF::FLAG_HAS_KEY_SHA256) !=
89 SimpleFileEOF::FLAG_HAS_KEY_SHA256) {
90 return false;
91 }
92
93 const char corrupt_data[] = "corrupt data";
94 static_assert(sizeof(corrupt_data) <= sizeof(net::SHA256HashValue),
95 "corrupt data should not be larger than a SHA-256");
96 if (UNSAFE_TODO(entry_file.Write(
97 file_length - sizeof(eof_record) - sizeof(net::SHA256HashValue),
98 corrupt_data, sizeof(corrupt_data))) != sizeof(corrupt_data)) {
99 return false;
100 }
101 return true;
102 }
103
CorruptStream0LengthFromEntry(const std::string & key,const base::FilePath & cache_path)104 bool CorruptStream0LengthFromEntry(const std::string& key,
105 const base::FilePath& cache_path) {
106 FilePath entry_file_path = cache_path.AppendASCII(
107 disk_cache::simple_util::GetFilenameFromKeyAndFileIndex(key, 0));
108 int flags = File::FLAG_OPEN | File::FLAG_READ | File::FLAG_WRITE;
109 File entry_file(entry_file_path, flags);
110 if (!entry_file.IsValid())
111 return false;
112 int64_t file_length = entry_file.GetLength();
113 SimpleFileEOF eof_record;
114 if (file_length < static_cast<int64_t>(sizeof(eof_record)))
115 return false;
116 if (UNSAFE_TODO(entry_file.Read(file_length - sizeof(eof_record),
117 reinterpret_cast<char*>(&eof_record),
118 sizeof(eof_record))) != sizeof(eof_record)) {
119 return false;
120 }
121 if (eof_record.final_magic_number != disk_cache::kSimpleFinalMagicNumber)
122 return false;
123
124 // Set the stream size to a clearly invalidly large value.
125 eof_record.stream_size = std::numeric_limits<uint32_t>::max() - 50;
126 if (UNSAFE_TODO(entry_file.Write(file_length - sizeof(eof_record),
127 reinterpret_cast<char*>(&eof_record),
128 sizeof(eof_record))) != sizeof(eof_record)) {
129 return false;
130 }
131 return true;
132 }
133
134 } // namespace disk_cache::simple_util
135