| 7078 | } |
| 7079 | |
| 7080 | static bool cli_checksum_line_digest(const unsigned char *line, size_t line_length, |
| 7081 | const char *archive_name, size_t archive_name_length, |
| 7082 | char digest[SHA256_BUF_SIZE]) { |
| 7083 | if (!line || line_length <= SHA256_HEX_LEN || |
| 7084 | (line[SHA256_HEX_LEN] != (unsigned char)' ' && |
| 7085 | line[SHA256_HEX_LEN] != (unsigned char)'\t')) { |
| 7086 | return false; |
| 7087 | } |
| 7088 | size_t filename_offset = SHA256_HEX_LEN; |
| 7089 | while (filename_offset < line_length && (line[filename_offset] == (unsigned char)' ' || |
| 7090 | line[filename_offset] == (unsigned char)'\t')) { |
| 7091 | filename_offset++; |
| 7092 | } |
| 7093 | if (filename_offset < line_length && line[filename_offset] == (unsigned char)'*') { |
| 7094 | filename_offset++; |
| 7095 | } |
| 7096 | if (line_length - filename_offset != archive_name_length || |
| 7097 | memcmp(line + filename_offset, archive_name, archive_name_length) != 0) { |
| 7098 | return false; |
| 7099 | } |
| 7100 | |
| 7101 | static const char lower_hex[] = "0123456789abcdef"; |
| 7102 | for (size_t i = 0; i < SHA256_HEX_LEN; i++) { |
| 7103 | int nibble = cli_checksum_hex_nibble(line[i]); |
| 7104 | if (nibble < 0) { |
| 7105 | return false; |
| 7106 | } |
| 7107 | digest[i] = lower_hex[nibble]; |
| 7108 | } |
| 7109 | digest[SHA256_HEX_LEN] = '\0'; |
| 7110 | return true; |
| 7111 | } |
| 7112 | |
| 7113 | /* Parse one downloaded checksum manifest without trusting line truncation or |
| 7114 | * substring matches. This non-header symbol is intentionally exercised by the |
no test coverage detected