test_permissions.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/stat.h>
  4. #include <zip.h>
  5. #include "minunit.h"
  6. #if defined(_WIN32) || defined(_WIN64)
  7. #define MKTEMP _mktemp
  8. #define UNLINK _unlink
  9. #else
  10. #define MKTEMP mkstemp
  11. #define UNLINK unlink
  12. #endif
  13. static char ZIPNAME[L_tmpnam + 1] = {0};
  14. static char XFILE[L_tmpnam + 1] = {0};
  15. static char RFILE[L_tmpnam + 1] = {0};
  16. static char WFILE[L_tmpnam + 1] = {0};
  17. void test_setup(void) {
  18. strncpy(ZIPNAME, "z-XXXXXX\0", L_tmpnam);
  19. strncpy(XFILE, "x-XXXXXX\0", L_tmpnam);
  20. strncpy(RFILE, "r-XXXXXX\0", L_tmpnam);
  21. strncpy(WFILE, "w-XXXXXX\0", L_tmpnam);
  22. MKTEMP(ZIPNAME);
  23. MKTEMP(XFILE);
  24. MKTEMP(RFILE);
  25. MKTEMP(WFILE);
  26. }
  27. void test_teardown(void) {
  28. UNLINK(WFILE);
  29. UNLINK(RFILE);
  30. UNLINK(XFILE);
  31. UNLINK(ZIPNAME);
  32. }
  33. #if defined(_MSC_VER) || defined(__MINGW32__)
  34. #define MZ_FILE_STAT_STRUCT _stat
  35. #define MZ_FILE_STAT _stat
  36. #else
  37. #define MZ_FILE_STAT_STRUCT stat
  38. #define MZ_FILE_STAT stat
  39. #endif
  40. #define XMODE 0100777
  41. #define RMODE 0100444
  42. #define WMODE 0100666
  43. #define UNIXMODE 0100600
  44. MU_TEST(test_exe_permissions) {
  45. struct MZ_FILE_STAT_STRUCT file_stats;
  46. const char *filenames[] = {XFILE};
  47. FILE *f = fopen(XFILE, "w");
  48. fclose(f);
  49. chmod(XFILE, XMODE);
  50. mu_assert_int_eq(0, zip_create(ZIPNAME, filenames, 1));
  51. remove(XFILE);
  52. mu_assert_int_eq(0, zip_extract(ZIPNAME, ".", NULL, NULL));
  53. mu_assert_int_eq(0, MZ_FILE_STAT(XFILE, &file_stats));
  54. mu_assert_int_eq(XMODE, file_stats.st_mode);
  55. }
  56. MU_TEST(test_read_permissions) {
  57. struct MZ_FILE_STAT_STRUCT file_stats;
  58. const char *filenames[] = {RFILE};
  59. FILE *f = fopen(RFILE, "w");
  60. fclose(f);
  61. chmod(RFILE, RMODE);
  62. mu_assert_int_eq(0, zip_create(ZIPNAME, filenames, 1));
  63. remove(RFILE);
  64. mu_assert_int_eq(0, zip_extract(ZIPNAME, ".", NULL, NULL));
  65. mu_assert_int_eq(0, MZ_FILE_STAT(RFILE, &file_stats));
  66. mu_assert_int_eq(RMODE, file_stats.st_mode);
  67. // chmod from 444 to 666 to be able delete the file on windows
  68. chmod(RFILE, WMODE);
  69. }
  70. MU_TEST(test_write_permissions) {
  71. struct MZ_FILE_STAT_STRUCT file_stats;
  72. const char *filenames[] = {WFILE};
  73. FILE *f = fopen(WFILE, "w");
  74. fclose(f);
  75. chmod(WFILE, WMODE);
  76. mu_assert_int_eq(0, zip_create(ZIPNAME, filenames, 1));
  77. remove(WFILE);
  78. mu_assert_int_eq(0, zip_extract(ZIPNAME, ".", NULL, NULL));
  79. mu_assert_int_eq(0, MZ_FILE_STAT(WFILE, &file_stats));
  80. mu_assert_int_eq(WMODE, file_stats.st_mode);
  81. }
  82. #define TESTDATA1 "Some test data 1...\0"
  83. MU_TEST(test_unix_permissions) {
  84. // UNIX or APPLE
  85. struct MZ_FILE_STAT_STRUCT file_stats;
  86. struct zip_t *zip = zip_open(ZIPNAME, ZIP_DEFAULT_COMPRESSION_LEVEL, 'w');
  87. mu_check(zip != NULL);
  88. mu_assert_int_eq(0, zip_entry_open(zip, RFILE));
  89. mu_assert_int_eq(0, zip_entry_write(zip, TESTDATA1, strlen(TESTDATA1)));
  90. mu_assert_int_eq(0, zip_entry_close(zip));
  91. zip_close(zip);
  92. mu_assert_int_eq(0, zip_extract(ZIPNAME, ".", NULL, NULL));
  93. mu_assert_int_eq(0, MZ_FILE_STAT(RFILE, &file_stats));
  94. mu_assert_int_eq(UNIXMODE, file_stats.st_mode);
  95. }
  96. MU_TEST(test_mtime) {
  97. struct MZ_FILE_STAT_STRUCT file_stat1, file_stat2;
  98. const char *filename = "test.data";
  99. FILE *stream = NULL;
  100. struct zip_t *zip = NULL;
  101. #if defined(_MSC_VER)
  102. if (0 != fopen_s(&stream, filename, "w+"))
  103. #else
  104. if (!(stream = fopen(filename, "w+")))
  105. #endif
  106. {
  107. mu_fail("Cannot open filename\n");
  108. }
  109. fwrite(TESTDATA1, sizeof(char), strlen(TESTDATA1), stream);
  110. mu_assert_int_eq(0, fclose(stream));
  111. memset(&file_stat1, 0, sizeof(file_stat1));
  112. memset(&file_stat2, 0, sizeof(file_stat2));
  113. zip = zip_open(ZIPNAME, ZIP_DEFAULT_COMPRESSION_LEVEL, 'w');
  114. mu_check(zip != NULL);
  115. mu_assert_int_eq(0, zip_entry_open(zip, filename));
  116. mu_assert_int_eq(0, zip_entry_fwrite(zip, filename));
  117. mu_assert_int_eq(0, zip_entry_close(zip));
  118. zip_close(zip);
  119. mu_assert_int_eq(0, MZ_FILE_STAT(filename, &file_stat1));
  120. remove(filename);
  121. mu_assert_int_eq(0, zip_extract(ZIPNAME, ".", NULL, NULL));
  122. mu_assert_int_eq(0, MZ_FILE_STAT(filename, &file_stat2));
  123. remove(filename);
  124. fprintf(stdout, "file_stat1.st_mtime: %lu\n", file_stat1.st_mtime);
  125. fprintf(stdout, "file_stat2.st_mtime: %lu\n", file_stat2.st_mtime);
  126. mu_check(labs(file_stat1.st_mtime - file_stat2.st_mtime) <= 1);
  127. }
  128. MU_TEST_SUITE(test_permissions_suite) {
  129. MU_SUITE_CONFIGURE(&test_setup, &test_teardown);
  130. #if defined(_WIN32) || defined(__WIN32__)
  131. #else
  132. MU_RUN_TEST(test_exe_permissions);
  133. MU_RUN_TEST(test_read_permissions);
  134. MU_RUN_TEST(test_write_permissions);
  135. MU_RUN_TEST(test_unix_permissions);
  136. #endif
  137. MU_RUN_TEST(test_mtime);
  138. }
  139. #define UNUSED(x) (void)x
  140. int main(int argc, char *argv[]) {
  141. UNUSED(argc);
  142. UNUSED(argv);
  143. MU_RUN_SUITE(test_permissions_suite);
  144. MU_REPORT();
  145. return MU_EXIT_CODE;
  146. }