Ensure that Apple2ix handles invalid gzipped files

This commit is contained in:
Aaron Culliney 2017-07-07 17:44:21 -10:00
parent 55cba116e4
commit 5102706441
4 changed files with 94 additions and 19 deletions

View File

@ -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) {

View File

@ -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__)

View File

@ -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);

View File

@ -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