GCC Code Coverage Report


Directory: ./
File: Os/ValidateFileCommon.cpp
Date: 2026-09-23 22:11:34
Exec Total Coverage
Lines: 0 137 0.0%
Functions: 0 9 0.0%
Branches: 0 96 0.0%

Line Branch Exec Source
1 #include <Os/File.hpp>
2 #include <Os/FileSystem.hpp>
3 #include <Os/ValidateFile.hpp>
4 #include <Utils/Hash/Hash.hpp>
5
6 namespace Os {
7
8 ✗ File::Status computeHash(const char* fileName, Utils::HashBuffer& hashBuffer) {
9 File::Status status;
10
11 // Open file:
12 ✗ File file;
13 ✗ status = file.open(fileName, File::OPEN_READ);
14 ✗ if (File::OP_OK != status) {
15 ✗ return status;
16 }
17
18 // Get the file size:
19 FileSystem::Status fs_status;
20 ✗ FwSizeType fileSize = 0;
21 ✗ fs_status = FileSystem::getFileSize(fileName, fileSize); //!< gets the size of the file (in bytes) at location path
22 ✗ if (FileSystem::OP_OK != fs_status) {
23 ✗ return File::BAD_SIZE;
24 }
25 ✗ const FwSizeType max_itr = (fileSize / VFILE_HASH_CHUNK_SIZE + 1);
26
27 // Read all data from file and update hash:
28 ✗ Utils::Hash hash;
29 ✗ hash.init();
30 U8 buffer[VFILE_HASH_CHUNK_SIZE];
31 ✗ FwSizeType size = 0;
32 ✗ FwSizeType cnt = 0;
33 ✗ while (cnt <= max_itr) {
34 // Read out chunk from file:
35 ✗ size = sizeof(buffer);
36 ✗ status = file.read(buffer, size, Os::File::WaitType::NO_WAIT);
37 ✗ if (File::OP_OK != status) {
38 ✗ return status;
39 }
40 // If end of file, break:
41 ✗ if (size == 0) {
42 ✗ break;
43 }
44 // Add chunk to hash calculation:
45 ✗ hash.update(&buffer, static_cast<FwSizeType>(size));
46 ✗ cnt++;
47 }
48 ✗ file.close();
49
50 // The iteration bound is computed from the size at open; a file that grows while
51 // being hashed exhausts it with data still unread, which is an error, not a bug
52 ✗ if (size != 0) {
53 ✗ return File::BAD_SIZE;
54 }
55
56 // Calculate hash:
57 ✗ Utils::HashBuffer computedHashBuffer;
58 ✗ hash.finalize(computedHashBuffer);
59 ✗ hashBuffer = computedHashBuffer;
60
61 ✗ return status;
62 ✗ }
63
64 ✗ File::Status readHash(const char* hashFileName, Utils::HashBuffer& hashBuffer) {
65 File::Status status;
66
67 // Open hash file:
68 ✗ File hashFile;
69 ✗ status = hashFile.open(hashFileName, File::OPEN_READ);
70 ✗ if (File::OP_OK != status) {
71 ✗ return status;
72 }
73
74 // Read hash from checksum file:
75 U8 savedHash[HASH_DIGEST_LENGTH];
76 ✗ FwSizeType size = static_cast<FwSizeType>(hashBuffer.getCapacity());
77 ✗ status = hashFile.read(savedHash, size);
78 ✗ if (File::OP_OK != status) {
79 ✗ return status;
80 }
81 ✗ if (static_cast<FwSizeType>(size) != hashBuffer.getCapacity()) {
82 ✗ return File::BAD_SIZE;
83 }
84 ✗ hashFile.close();
85
86 // Return the hash buffer:
87 ✗ Utils::HashBuffer savedHashBuffer(savedHash, static_cast<FwSizeType>(size));
88 ✗ hashBuffer = savedHashBuffer;
89
90 ✗ return status;
91 ✗ }
92
93 ✗ File::Status writeHash(const char* hashFileName, Utils::HashBuffer hashBuffer) {
94 // Open hash file:
95 ✗ File hashFile;
96 File::Status status;
97 ✗ status = hashFile.open(hashFileName, File::OPEN_WRITE);
98 ✗ if (File::OP_OK != status) {
99 ✗ return status;
100 }
101
102 // Write out the hash
103 ✗ FwSizeType size = static_cast<FwSizeType>(hashBuffer.getSize());
104 ✗ status = hashFile.write(hashBuffer.getBuffAddr(), size, Os::File::WaitType::NO_WAIT);
105 ✗ if (File::OP_OK != status) {
106 ✗ return status;
107 }
108 ✗ if (static_cast<FwSizeType>(size) != hashBuffer.getSize()) {
109 ✗ return File::BAD_SIZE;
110 }
111 ✗ hashFile.close();
112
113 ✗ return status;
114 ✗ }
115
116 // Enum and function for translating from a status to a validation status:
117 typedef enum { FileType, HashFileType } StatusFileType;
118
119 ✗ ValidateFile::Status translateStatus(File::Status status, StatusFileType type) {
120 ✗ switch (type) {
121 ✗ case FileType:
122 ✗ switch (status) {
123 ✗ case File::OP_OK:
124 ✗ return ValidateFile::VALIDATION_OK;
125 ✗ case File::DOESNT_EXIST:
126 ✗ return ValidateFile::FILE_DOESNT_EXIST;
127 ✗ case File::NO_SPACE:
128 ✗ return ValidateFile::NO_SPACE;
129 ✗ case File::NO_PERMISSION:
130 ✗ return ValidateFile::FILE_NO_PERMISSION;
131 ✗ case File::BAD_SIZE:
132 ✗ return ValidateFile::FILE_BAD_SIZE;
133 ✗ case File::NOT_OPENED:
134 ✗ return ValidateFile::OTHER_ERROR;
135 ✗ case File::OTHER_ERROR:
136 ✗ return ValidateFile::OTHER_ERROR;
137 ✗ default:
138 // Unlisted statuses (e.g. NOT_SUPPORTED, INVALID_ARGUMENT) can
139 // legitimately come from the OS layer; report rather than assert
140 ✗ return ValidateFile::OTHER_ERROR;
141 }
142 break;
143 ✗ case HashFileType:
144 ✗ switch (status) {
145 ✗ case File::OP_OK:
146 ✗ return ValidateFile::VALIDATION_OK;
147 ✗ case File::DOESNT_EXIST:
148 ✗ return ValidateFile::VALIDATION_FILE_DOESNT_EXIST;
149 ✗ case File::NO_SPACE:
150 ✗ return ValidateFile::NO_SPACE;
151 ✗ case File::NO_PERMISSION:
152 ✗ return ValidateFile::VALIDATION_FILE_NO_PERMISSION;
153 ✗ case File::BAD_SIZE:
154 ✗ return ValidateFile::VALIDATION_FILE_BAD_SIZE;
155 ✗ case File::NOT_OPENED:
156 ✗ return ValidateFile::OTHER_ERROR;
157 ✗ case File::OTHER_ERROR:
158 ✗ return ValidateFile::OTHER_ERROR;
159 ✗ default:
160 // Unlisted statuses (e.g. NOT_SUPPORTED, INVALID_ARGUMENT) can
161 // legitimately come from the OS layer; report rather than assert
162 ✗ return ValidateFile::OTHER_ERROR;
163 }
164 break;
165 ✗ default:
166 ✗ FW_ASSERT(false, type);
167 }
168
169 ✗ return ValidateFile::OTHER_ERROR;
170 }
171
172 ✗ ValidateFile::Status ValidateFile::validate(const char* fileName, const char* hashFileName) {
173 ✗ Utils::HashBuffer hashBuffer; // pass by reference - final value is unused
174 ✗ return validate(fileName, hashFileName, hashBuffer);
175 ✗ }
176
177 ✗ ValidateFile::Status ValidateFile::validate(const char* fileName,
178 const char* hashFileName,
179 Utils::HashBuffer& hashBuffer) {
180 File::Status status;
181
182 // Read the hash file:
183 ✗ Utils::HashBuffer savedHash;
184 ✗ status = readHash(hashFileName, savedHash);
185 ✗ if (File::OP_OK != status) {
186 ✗ return translateStatus(status, HashFileType);
187 }
188
189 // Compute the file's hash:
190 ✗ Utils::HashBuffer computedHash;
191 ✗ status = computeHash(fileName, computedHash);
192 ✗ if (File::OP_OK != status) {
193 ✗ return translateStatus(status, FileType);
194 }
195
196 // Compare hashes and return:
197 ✗ if (savedHash != computedHash) {
198 ✗ return ValidateFile::VALIDATION_FAIL;
199 }
200
201 ✗ hashBuffer = savedHash;
202
203 ✗ return ValidateFile::VALIDATION_OK;
204 ✗ }
205
206 ✗ ValidateFile::Status ValidateFile::createValidation(const char* fileName,
207 const char* hashFileName,
208 Utils::HashBuffer& hashBuffer) {
209 File::Status status;
210
211 // Compute the file's hash:
212 ✗ status = computeHash(fileName, hashBuffer);
213 ✗ if (File::OP_OK != status) {
214 ✗ return translateStatus(status, FileType);
215 }
216
217 ✗ status = writeHash(hashFileName, hashBuffer);
218 ✗ if (File::OP_OK != status) {
219 ✗ return translateStatus(status, HashFileType);
220 }
221
222 ✗ return ValidateFile::VALIDATION_OK;
223 }
224
225 ✗ ValidateFile::Status ValidateFile::createValidation(const char* fileName, const char* hashFileName) {
226 ✗ Utils::HashBuffer hashBuffer; // pass by reference - final value is unused
227 ✗ return createValidation(fileName, hashFileName, hashBuffer);
228 ✗ }
229
230 ✗ ValidateFile::Status ValidateFile::createValidation(const char* hashFileName, const Utils::HashBuffer& hashBuffer) {
231 File::Status status;
232
233 ✗ status = writeHash(hashFileName, hashBuffer);
234 ✗ if (File::OP_OK != status) {
235 ✗ return translateStatus(status, HashFileType);
236 }
237
238 ✗ return ValidateFile::VALIDATION_OK;
239 }
240
241 } // namespace Os
242