| 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 |