/* CHM regression test suite */ #ifdef HAVE_CONFIG_H #include <config.h> #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #include <mspack.h> #include <system.h> unsigned int test_count = 0; #define TEST(x) do {\ test_count++; \ if (!(x)) {printf("%s:%d FAILED %s\n",__func__,__LINE__,#x);exit(1);} \ } while (0) /* check opening bad files is rejected */ void chmd_open_test_01() { struct mschm_decompressor *chmd; struct mschmd_header *chm; unsigned int i; const char *files[] = { "test_files/chmd/cve-2017-6419-lzx-negative-spaninfo.chm" }; chmd = mspack_create_chm_decompressor(NULL); TEST(chmd != NULL); for (i = 0; i < (sizeof(files)/sizeof(char *)); i++) { chm = chmd->open(chmd, files[i]); TEST(chm == NULL); } mspack_destroy_chm_decompressor(chmd); } /* check no files are returned with blank filenames */ void chmd_open_test_02() { struct mschm_decompressor *chmd; struct mschmd_header *chm; struct mschmd_file *f; unsigned int i; const char *files[] = { "test_files/chmd/blank-filenames.chm" }; chmd = mspack_create_chm_decompressor(NULL); TEST(chmd != NULL); for (i = 0; i < (sizeof(files)/sizeof(char *)); i++) { chm = chmd->open(chmd, files[i]); TEST(chm != NULL); for (f = chm->files; f; f = f->next) { TEST(f->filename && f->filename[0]); } for (f = chm->sysfiles; f; f = f->next) { TEST(f->filename && f->filename[0]); } } mspack_destroy_chm_decompressor(chmd); } /* check searching bad files doesn't crash */ void chmd_search_test_01() { struct mschm_decompressor *chmd; struct mschmd_header *chm1, *chm2; struct mschmd_file *f, result; unsigned int i; const char *files[] = { "test_files/chmd/cve-2015-4468-namelen-bounds.chm", "test_files/chmd/cve-2015-4469-namelen-bounds.chm", "test_files/chmd/cve-2015-4472-namelen-bounds.chm" }; chmd = mspack_create_chm_decompressor(NULL); TEST(chmd != NULL); for (i = 0; i < (sizeof(files)/sizeof(char *)); i++) { chm1 = chmd->open(chmd, files[i]); TEST(chm1 != NULL); chm2 = chmd->fast_open(chmd, files[i]); TEST(chm2 != NULL); for (f = chm1->files; f; f = f->next) { if (!chmd->fast_find(chmd, chm2, f->filename, &result, sizeof(result))) { TEST(f->offset == result.offset); TEST(f->length == result.length); } } chmd->close(chmd, chm2); chmd->close(chmd, chm1); } mspack_destroy_chm_decompressor(chmd); } /* check extracting bad files doesn't crash */ void chmd_extract_test_01() { struct mschm_decompressor *chmd; struct mschmd_header *chm; struct mschmd_file *f; unsigned int i; const char *files[] = { "test_files/chmd/cve-2015-4467-reset-interval-zero.chm", }; chmd = mspack_create_chm_decompressor(NULL); TEST(chmd != NULL); for (i = 0; i < (sizeof(files)/sizeof(char *)); i++) { chm = chmd->open(chmd, files[i]); TEST(chm != NULL); for (f = chm->files; f; f = f->next) { chmd->extract(chmd, f, "/dev/null"); } chmd->close(chmd, chm); } mspack_destroy_chm_decompressor(chmd); } int main() { int selftest; MSPACK_SYS_SELFTEST(selftest); TEST(selftest == MSPACK_ERR_OK); chmd_open_test_01(); chmd_open_test_02(); chmd_search_test_01(); chmd_extract_test_01(); printf("ALL %d TESTS PASSED.\n", test_count); return 0; }