diff --git a/src/disk.c b/src/disk.c index aaef23ea..be78a04d 100644 --- a/src/disk.c +++ b/src/disk.c @@ -798,33 +798,35 @@ const char *disk6_eject(int drive) { int ret = -1; off_t compressed_size = -1; - if (is_gz(disk6.disk[drive].file_name)) { + if (disk6.disk[drive].raw_image_data != MAP_FAILED) { + if (is_gz(disk6.disk[drive].file_name)) { - // backup uncompressed data ... - uint8_t *compressed_data = drive == 0 ? &disk_a_raw[0] : &disk_b_raw[0]; + // backup uncompressed data ... + uint8_t *compressed_data = drive == 0 ? &disk_a_raw[0] : &disk_b_raw[0]; - // re-compress in place ... - err = zlib_deflate_buffer(/*src:*/disk6.disk[drive].raw_image_data, disk6.disk[drive].whole_len, /*dst:*/compressed_data, &compressed_size); - if (err) { - ERRLOG("OOPS, error deflating %s : %s", disk6.disk[drive].file_name, err); - } + // re-compress in place ... + err = zlib_deflate_buffer(/*src:*/disk6.disk[drive].raw_image_data, disk6.disk[drive].whole_len, /*dst:*/compressed_data, &compressed_size); + if (err) { + ERRLOG("OOPS, error deflating %s : %s", disk6.disk[drive].file_name, err); + } - if (compressed_size > 0) { - assert(compressed_size < disk6.disk[drive].whole_len); + if (compressed_size > 0) { + assert(compressed_size < disk6.disk[drive].whole_len); - // overwrite portion of mmap()'d file with compressed data ... - memcpy(/*dst:*/disk6.disk[drive].raw_image_data, /*src:*/compressed_data, compressed_size); + // overwrite portion of mmap()'d file with compressed data ... + memcpy(/*dst:*/disk6.disk[drive].raw_image_data, /*src:*/compressed_data, compressed_size); - TEMP_FAILURE_RETRY(ret = msync(disk6.disk[drive].raw_image_data, disk6.disk[drive].whole_len, MS_SYNC)); - if (ret) { - ERRLOG("Error syncing file %s", disk6.disk[drive].file_name); + TEMP_FAILURE_RETRY(ret = msync(disk6.disk[drive].raw_image_data, disk6.disk[drive].whole_len, MS_SYNC)); + if (ret) { + ERRLOG("Error syncing file %s", disk6.disk[drive].file_name); + } } } - } - TEMP_FAILURE_RETRY(ret = munmap(disk6.disk[drive].raw_image_data, disk6.disk[drive].whole_len)); - if (ret) { - ERRLOG("Error munmap()ping file %s", disk6.disk[drive].file_name); + TEMP_FAILURE_RETRY(ret = munmap(disk6.disk[drive].raw_image_data, disk6.disk[drive].whole_len)); + if (ret) { + ERRLOG("Error munmap()ping file %s", disk6.disk[drive].file_name); + } } if (compressed_size > 0) { diff --git a/src/test/testcommon.c b/src/test/testcommon.c index fb9c90f7..fd9b065c 100644 --- a/src/test/testcommon.c +++ b/src/test/testcommon.c @@ -207,6 +207,14 @@ char **_copy_paths_main(const char *fileName) { #endif +char **test_copy_disk_paths(const char *fileName) { +#if defined(__APPLE__) + return _copy_paths_mac(fileName); +#else + return _copy_paths_main(fileName); +#endif +} + int test_setup_boot_disk(const char *fileName, int readonly) { #if defined(__APPLE__) diff --git a/src/test/testcommon.h b/src/test/testcommon.h index 7aa4610a..65d2f210 100644 --- a/src/test/testcommon.h +++ b/src/test/testcommon.h @@ -39,6 +39,7 @@ void test_common_init(void); void test_common_setup(void); void test_type_input(const char *input); void test_type_input_deterministically(const char *input); +char **test_copy_disk_paths(const char *fileName); int test_setup_boot_disk(const char *fileName, int readonly); void sha1_to_str(const uint8_t * const md, char *buf); diff --git a/src/test/testdisk.c b/src/test/testdisk.c index be255def..df4d7e35 100644 --- a/src/test/testdisk.c +++ b/src/test/testdisk.c @@ -1416,6 +1416,67 @@ TEST test_disk_image_with_gzip_header_rw() { return _test_disk_image_with_gzip_header(/*readonly:*/0); } +#define GZINVALID_DSK "CorruptedGzipped.dsk.gz" +static int _test_disk_invalid_gzipped(int readonly) { + + int found_disk_image_file = 0; + { + char **paths = test_copy_disk_paths(GZINVALID_DSK); + + char **path = &paths[0]; + while (*path) { + char *diskPath = *path; + ++path; + + int fd = -1; + TEMP_FAILURE_RETRY(fd = open(diskPath, readonly ? O_RDONLY : O_RDWR)); + if (fd != -1) { + + ++found_disk_image_file; + + int err = disk6_insert(fd, /*drive:*/0, diskPath, readonly) != NULL; + TEMP_FAILURE_RETRY(close(fd)); + ASSERT(err); + + // did not actually insert corruped disk image and did not crash + ASSERT(disk6.disk[0].file_name == NULL); + ASSERT(disk6.disk[0].fd == -1); + + ASSERT(disk6.disk[0].raw_image_data == (void *)-1/*MAP_FAILED*/); + ASSERT(disk6.disk[0].whole_len == 0); + ASSERT(disk6.disk[0].nib_image_data == NULL); + ASSERT(disk6.disk[0].nibblized == false); + ASSERT(disk6.disk[0].is_protected == false); + ASSERT(disk6.disk[0].track_valid == false); + ASSERT(disk6.disk[0].track_dirty == false); + ASSERT(disk6.disk[0].skew_table == NULL); + ASSERT(disk6.disk[0].track_width == 0); + } + } + + path = &paths[0]; + while (*path) { + char *diskPath = *path; + ++path; + FREE(diskPath); + } + + FREE(paths); + } + + ASSERT(found_disk_image_file > 0); + + PASS(); +} + +TEST test_disk_invalid_gzipped_ro() { + return _test_disk_invalid_gzipped(/*readonly:*/1); +} + +TEST test_disk_invalid_gzipped_rw() { + return _test_disk_invalid_gzipped(/*readonly:*/0); +} + #if TEST_DISK_EDGE_CASES #define DROL_DSK "Drol.dsk.gz" #define DROL_CRACK_SCREEN_SHA "FD7332529E117F14DA3880BB36FE8E23C3704799" @@ -1506,6 +1567,9 @@ GREATEST_SUITE(test_suite_disk) { RUN_TESTp(test_disk_image_with_gzip_header_ro); RUN_TESTp(test_disk_image_with_gzip_header_rw); + RUN_TESTp(test_disk_invalid_gzipped_ro); + RUN_TESTp(test_disk_invalid_gzipped_rw); + // edge-case tests may require testing copyrighted images (which I have in my possession by legally owning the // original disk image (yep, I do ;-) #if TEST_DISK_EDGE_CASES