| 198 | } |
| 199 | |
| 200 | void Key_file::load_header (std::istream& in) |
| 201 | { |
| 202 | while (true) { |
| 203 | uint32_t field_id; |
| 204 | if (!read_be32(in, field_id)) { |
| 205 | throw Malformed(); |
| 206 | } |
| 207 | if (field_id == HEADER_FIELD_END) { |
| 208 | break; |
| 209 | } |
| 210 | uint32_t field_len; |
| 211 | if (!read_be32(in, field_len)) { |
| 212 | throw Malformed(); |
| 213 | } |
| 214 | |
| 215 | if (field_id == HEADER_FIELD_KEY_NAME) { |
| 216 | if (field_len > KEY_NAME_MAX_LEN) { |
| 217 | throw Malformed(); |
| 218 | } |
| 219 | if (field_len == 0) { |
| 220 | // special case field_len==0 to avoid possible undefined behavior |
| 221 | // edge cases with an empty std::vector (particularly, &bytes[0]). |
| 222 | key_name.clear(); |
| 223 | } else { |
| 224 | std::vector<char> bytes(field_len); |
| 225 | in.read(&bytes[0], field_len); |
| 226 | if (in.gcount() != static_cast<std::streamsize>(field_len)) { |
| 227 | throw Malformed(); |
| 228 | } |
| 229 | key_name.assign(&bytes[0], field_len); |
| 230 | } |
| 231 | if (!validate_key_name(key_name.c_str())) { |
| 232 | key_name.clear(); |
| 233 | throw Malformed(); |
| 234 | } |
| 235 | } else if (field_id & 1) { // unknown critical field |
| 236 | throw Incompatible(); |
| 237 | } else { |
| 238 | // unknown non-critical field - safe to ignore |
| 239 | if (field_len > MAX_FIELD_LEN) { |
| 240 | throw Malformed(); |
| 241 | } |
| 242 | in.ignore(field_len); |
| 243 | if (in.gcount() != static_cast<std::streamsize>(field_len)) { |
| 244 | throw Malformed(); |
| 245 | } |
| 246 | } |
| 247 | } |
| 248 | } |
| 249 | |
| 250 | void Key_file::store (std::ostream& out) const |
| 251 | { |
nothing calls this directly
no test coverage detected