| 452 | } |
| 453 | |
| 454 | static unsigned char *mcp_read_file_bytes(const char *path, long *out_len) { |
| 455 | if (!out_len) { |
| 456 | return NULL; |
| 457 | } |
| 458 | *out_len = 0; |
| 459 | FILE *fp = cbm_fopen(path, "rb"); |
| 460 | if (!fp) { |
| 461 | return NULL; |
| 462 | } |
| 463 | if (fseek(fp, 0, SEEK_END) != 0) { |
| 464 | fclose(fp); |
| 465 | return NULL; |
| 466 | } |
| 467 | long size = ftell(fp); |
| 468 | if (size < 0 || fseek(fp, 0, SEEK_SET) != 0) { |
| 469 | fclose(fp); |
| 470 | return NULL; |
| 471 | } |
| 472 | unsigned char *bytes = malloc(size > 0 ? (size_t)size : 1); |
| 473 | if (!bytes) { |
| 474 | fclose(fp); |
| 475 | return NULL; |
| 476 | } |
| 477 | size_t read_count = fread(bytes, 1, (size_t)size, fp); |
| 478 | fclose(fp); |
| 479 | if (read_count != (size_t)size) { |
| 480 | free(bytes); |
| 481 | return NULL; |
| 482 | } |
| 483 | *out_len = size; |
| 484 | return bytes; |
| 485 | } |
| 486 | |
| 487 | static bool mcp_file_matches_snapshot(const char *path, const unsigned char *expected, |
| 488 | long expected_len) { |
no test coverage detected