GCC Code Coverage Report


Directory: ./
File: ValidateFileCommon.cpp
Date: 2026-09-03 22:13:09
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