GCC Code Coverage Report


Directory: ./
File: Os/ValidateFileCommon.cpp
Date: 2026-09-03 21:13:48
Exec Total Coverage
Lines: 100 139 71.9%
Functions: 9 9 100.0%
Branches: 69 96 71.9%

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 33 File::Status computeHash(const char* fileName, Utils::HashBuffer& hashBuffer) {
9 File::Status status;
10
11 // Open file:
12
1/1
✓ Branch 2 taken 33 times.
33 File file;
13
1/1
✓ Branch 2 taken 33 times.
33 status = file.open(fileName, File::OPEN_READ);
14
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 27 times.
33 if (File::OP_OK != status) {
15 6 return status;
16 }
17
18 // Get the file size:
19 FileSystem::Status fs_status;
20 27 FwSizeType fileSize = 0;
21
1/1
✓ Branch 1 taken 27 times.
27 fs_status = FileSystem::getFileSize(fileName, fileSize); //!< gets the size of the file (in bytes) at location path
22
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
27 if (FileSystem::OP_OK != fs_status) {
23 return File::BAD_SIZE;
24 }
25 27 const FwSizeType max_itr = (fileSize / VFILE_HASH_CHUNK_SIZE + 1);
26
27 // Read all data from file and update hash:
28
1/1
✓ Branch 2 taken 27 times.
27 Utils::Hash hash;
29
1/1
✓ Branch 1 taken 27 times.
27 hash.init();
30 27 U8 buffer[VFILE_HASH_CHUNK_SIZE];
31 27 FwSizeType size = 0;
32 27 FwSizeType cnt = 0;
33
1/2
✓ Branch 0 taken 244615 times.
✗ Branch 1 not taken.
244615 while (cnt <= max_itr) {
34 // Read out chunk from file:
35 244615 size = sizeof(buffer);
36
1/1
✓ Branch 2 taken 244615 times.
244615 status = file.read(buffer, size, Os::File::WaitType::NO_WAIT);
37
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 244615 times.
244615 if (File::OP_OK != status) {
38 return status;
39 }
40 // If end of file, break:
41
2/2
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 244588 times.
244615 if (size == 0) {
42 27 break;
43 }
44 // Add chunk to hash calculation:
45
1/1
✓ Branch 1 taken 244588 times.
244588 hash.update(&buffer, static_cast<FwSizeType>(size));
46 244588 cnt++;
47 }
48
1/1
✓ Branch 2 taken 27 times.
27 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
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
27 if (size != 0) {
53 return File::BAD_SIZE;
54 }
55
56 // Calculate hash:
57
1/1
✓ Branch 2 taken 27 times.
27 Utils::HashBuffer computedHashBuffer;
58
1/1
✓ Branch 1 taken 27 times.
27 hash.finalize(computedHashBuffer);
59
1/1
✓ Branch 4 taken 27 times.
27 hashBuffer = computedHashBuffer;
60
61 27 return status;
62 33 }
63
64 17 File::Status readHash(const char* hashFileName, Utils::HashBuffer& hashBuffer) {
65 File::Status status;
66
67 // Open hash file:
68
1/1
✓ Branch 2 taken 17 times.
17 File hashFile;
69
1/1
✓ Branch 2 taken 17 times.
17 status = hashFile.open(hashFileName, File::OPEN_READ);
70
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if (File::OP_OK != status) {
71 return status;
72 }
73
74 // Read hash from checksum file:
75 17 U8 savedHash[HASH_DIGEST_LENGTH];
76
1/1
✓ Branch 11 taken 17 times.
17 FwSizeType size = static_cast<FwSizeType>(hashBuffer.getCapacity());
77
1/1
✓ Branch 2 taken 17 times.
17 status = hashFile.read(savedHash, size);
78
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if (File::OP_OK != status) {
79 return status;
80 }
81
2/3
✓ Branch 10 taken 17 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 17 times.
17 if (static_cast<FwSizeType>(size) != hashBuffer.getCapacity()) {
82 return File::BAD_SIZE;
83 }
84
1/1
✓ Branch 2 taken 17 times.
17 hashFile.close();
85
86 // Return the hash buffer:
87
1/1
✓ Branch 2 taken 17 times.
17 Utils::HashBuffer savedHashBuffer(savedHash, static_cast<FwSizeType>(size));
88
1/1
✓ Branch 4 taken 17 times.
17 hashBuffer = savedHashBuffer;
89
90 17 return status;
91 17 }
92
93 23 File::Status writeHash(const char* hashFileName, Utils::HashBuffer hashBuffer) {
94 // Open hash file:
95
1/1
✓ Branch 2 taken 23 times.
23 File hashFile;
96 File::Status status;
97
1/1
✓ Branch 2 taken 23 times.
23 status = hashFile.open(hashFileName, File::OPEN_WRITE);
98
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 21 times.
23 if (File::OP_OK != status) {
99 2 return status;
100 }
101
102 // Write out the hash
103
1/1
✓ Branch 6 taken 21 times.
21 FwSizeType size = static_cast<FwSizeType>(hashBuffer.getSize());
104
1/1
✓ Branch 7 taken 21 times.
21 status = hashFile.write(hashBuffer.getBuffAddr(), size, Os::File::WaitType::NO_WAIT);
105
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (File::OP_OK != status) {
106 return status;
107 }
108
2/3
✓ Branch 5 taken 21 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 21 times.
21 if (static_cast<FwSizeType>(size) != hashBuffer.getSize()) {
109 return File::BAD_SIZE;
110 }
111
1/1
✓ Branch 2 taken 21 times.
21 hashFile.close();
112
113 21 return status;
114 23 }
115
116 // Enum and function for translating from a status to a validation status:
117 typedef enum { FileType, HashFileType } StatusFileType;
118
119 8 ValidateFile::Status translateStatus(File::Status status, StatusFileType type) {
120
2/3
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
8 switch (type) {
121 6 case FileType:
122
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
6 switch (status) {
123 case File::OP_OK:
124 return ValidateFile::VALIDATION_OK;
125 6 case File::DOESNT_EXIST:
126 6 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 2 case HashFileType:
144
2/8
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
2 switch (status) {
145 case File::OP_OK:
146 return ValidateFile::VALIDATION_OK;
147 1 case File::DOESNT_EXIST:
148 1 return ValidateFile::VALIDATION_FILE_DOESNT_EXIST;
149 case File::NO_SPACE:
150 return ValidateFile::NO_SPACE;
151 1 case File::NO_PERMISSION:
152 1 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 11 ValidateFile::Status ValidateFile::validate(const char* fileName, const char* hashFileName) {
173
1/1
✓ Branch 2 taken 11 times.
11 Utils::HashBuffer hashBuffer; // pass by reference - final value is unused
174
1/1
✓ Branch 1 taken 11 times.
22 return validate(fileName, hashFileName, hashBuffer);
175 11 }
176
177 17 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
1/1
✓ Branch 2 taken 17 times.
17 Utils::HashBuffer savedHash;
184
1/1
✓ Branch 1 taken 17 times.
17 status = readHash(hashFileName, savedHash);
185
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if (File::OP_OK != status) {
186 return translateStatus(status, HashFileType);
187 }
188
189 // Compute the file's hash:
190
1/1
✓ Branch 2 taken 17 times.
17 Utils::HashBuffer computedHash;
191
1/1
✓ Branch 1 taken 17 times.
17 status = computeHash(fileName, computedHash);
192
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if (File::OP_OK != status) {
193 return translateStatus(status, FileType);
194 }
195
196 // Compare hashes and return:
197
3/3
✓ Branch 2 taken 17 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 16 times.
17 if (savedHash != computedHash) {
198 1 return ValidateFile::VALIDATION_FAIL;
199 }
200
201
1/1
✓ Branch 4 taken 16 times.
16 hashBuffer = savedHash;
202
203 16 return ValidateFile::VALIDATION_OK;
204 17 }
205
206 16 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 16 status = computeHash(fileName, hashBuffer);
213
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 10 times.
16 if (File::OP_OK != status) {
214 6 return translateStatus(status, FileType);
215 }
216
217
2/2
✓ Branch 3 taken 10 times.
✓ Branch 6 taken 10 times.
10 status = writeHash(hashFileName, hashBuffer);
218
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 9 times.
10 if (File::OP_OK != status) {
219 1 return translateStatus(status, HashFileType);
220 }
221
222 9 return ValidateFile::VALIDATION_OK;
223 }
224
225 16 ValidateFile::Status ValidateFile::createValidation(const char* fileName, const char* hashFileName) {
226
1/1
✓ Branch 2 taken 16 times.
16 Utils::HashBuffer hashBuffer; // pass by reference - final value is unused
227
1/1
✓ Branch 1 taken 16 times.
32 return createValidation(fileName, hashFileName, hashBuffer);
228 16 }
229
230 13 ValidateFile::Status ValidateFile::createValidation(const char* hashFileName, const Utils::HashBuffer& hashBuffer) {
231 File::Status status;
232
233
2/2
✓ Branch 2 taken 13 times.
✓ Branch 5 taken 13 times.
13 status = writeHash(hashFileName, hashBuffer);
234
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 12 times.
13 if (File::OP_OK != status) {
235 1 return translateStatus(status, HashFileType);
236 }
237
238 12 return ValidateFile::VALIDATION_OK;
239 }
240
241 } // namespace Os
242