| 398 | } |
| 399 | |
| 400 | static unsigned char *mcp_read_file_bytes(const char *path, long *out_len) { |
| 401 | if (!out_len) { |
| 402 | return NULL; |
| 403 | } |
| 404 | *out_len = 0; |
| 405 | FILE *fp = cbm_fopen(path, "rb"); |
| 406 | if (!fp) { |
| 407 | return NULL; |
| 408 | } |
| 409 | if (fseek(fp, 0, SEEK_END) != 0) { |
| 410 | fclose(fp); |
| 411 | return NULL; |
| 412 | } |
| 413 | long size = ftell(fp); |
| 414 | if (size < 0 || fseek(fp, 0, SEEK_SET) != 0) { |
| 415 | fclose(fp); |
| 416 | return NULL; |
| 417 | } |
| 418 | unsigned char *bytes = malloc(size > 0 ? (size_t)size : 1); |
| 419 | if (!bytes) { |
| 420 | fclose(fp); |
| 421 | return NULL; |
| 422 | } |
| 423 | size_t read_count = fread(bytes, 1, (size_t)size, fp); |
| 424 | fclose(fp); |
| 425 | if (read_count != (size_t)size) { |
| 426 | free(bytes); |
| 427 | return NULL; |
| 428 | } |
| 429 | *out_len = size; |
| 430 | return bytes; |
| 431 | } |
| 432 | |
| 433 | static bool mcp_file_matches_snapshot(const char *path, const unsigned char *expected, |
| 434 | long expected_len) { |
no test coverage detected