permissions xattr. logic from zip info (#227)

This commit is contained in:
Kuba Podgórski 2022-01-10 23:19:36 +01:00 committed by GitHub
parent 9a52cfc458
commit 11cc5c6d30
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 90 additions and 34 deletions

View File

@ -1357,11 +1357,10 @@ MINIZ_EXPORT mz_bool mz_zip_reader_init_file_v2(mz_zip_archive *pZip,
mz_uint64 file_start_ofs,
mz_uint64 archive_size);
MINIZ_EXPORT mz_bool mz_zip_reader_init_file_v2_rpb(mz_zip_archive *pZip,
const char *pFilename,
mz_uint flags,
mz_uint64 file_start_ofs,
mz_uint64 archive_size);
const char *pFilename,
mz_uint flags,
mz_uint64 file_start_ofs,
mz_uint64 archive_size);
/* Read an archive from an already opened FILE, beginning at the current file
* position. */
@ -1625,9 +1624,8 @@ MINIZ_EXPORT mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip,
MINIZ_EXPORT mz_bool mz_zip_writer_init_from_reader_v2(mz_zip_archive *pZip,
const char *pFilename,
mz_uint flags);
MINIZ_EXPORT mz_bool mz_zip_writer_init_from_reader_v2_noreopen(mz_zip_archive *pZip,
const char *pFilename,
mz_uint flags);
MINIZ_EXPORT mz_bool mz_zip_writer_init_from_reader_v2_noreopen(
mz_zip_archive *pZip, const char *pFilename, mz_uint flags);
/* Adds the contents of a memory buffer to an archive. These functions record
* the current local time into the archive. */
@ -5010,6 +5008,13 @@ static int mz_mkdir(const char *pDirname) {
#endif /* #ifdef _MSC_VER */
#endif /* #ifdef MINIZ_NO_STDIO */
#ifndef CHMOD
// Upon successful completion, a value of 0 is returned.
// Otherwise, a value of -1 is returned and errno is set to indicate the error.
// int chmod(const char *path, mode_t mode);
#define CHMOD(f, m) chmod(f, m)
#endif
#define MZ_TOLOWER(c) ((((c) >= 'A') && ((c) <= 'Z')) ? ((c) - 'A' + 'a') : (c))
/* Various ZIP archive enums. To completely avoid cross platform compiler
@ -5975,9 +5980,10 @@ mz_bool mz_zip_reader_init_file_v2(mz_zip_archive *pZip, const char *pFilename,
return MZ_TRUE;
}
mz_bool mz_zip_reader_init_file_v2_rpb(mz_zip_archive *pZip, const char *pFilename,
mz_uint flags, mz_uint64 file_start_ofs,
mz_uint64 archive_size) {
mz_bool mz_zip_reader_init_file_v2_rpb(mz_zip_archive *pZip,
const char *pFilename, mz_uint flags,
mz_uint64 file_start_ofs,
mz_uint64 archive_size) {
mz_uint64 file_size;
MZ_FILE *pFile;
@ -8055,8 +8061,8 @@ mz_bool mz_zip_writer_init_from_reader_v2(mz_zip_archive *pZip,
}
mz_bool mz_zip_writer_init_from_reader_v2_noreopen(mz_zip_archive *pZip,
const char *pFilename,
mz_uint flags) {
const char *pFilename,
mz_uint flags) {
mz_zip_internal_state *pState;
if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING))
@ -8368,8 +8374,7 @@ mz_bool mz_zip_writer_add_mem_ex_v2(
mz_uint user_extra_data_central_len) {
mz_uint16 method = 0, dos_time = 0, dos_date = 0;
mz_uint level, ext_attributes = 0, num_alignment_padding_bytes;
mz_uint64 local_dir_header_ofs = 0,
cur_archive_file_ofs = 0, comp_size = 0;
mz_uint64 local_dir_header_ofs = 0, cur_archive_file_ofs = 0, comp_size = 0;
size_t archive_name_size;
mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE];
tdefl_compressor *pComp = NULL;
@ -8679,8 +8684,8 @@ mz_bool mz_zip_writer_add_read_buf_callback(
: MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR;
mz_uint uncomp_crc32 = MZ_CRC32_INIT, level, num_alignment_padding_bytes;
mz_uint16 method = 0, dos_time = 0, dos_date = 0;
mz_uint64 local_dir_header_ofs, cur_archive_file_ofs = 0,
uncomp_size = 0, comp_size = 0;
mz_uint64 local_dir_header_ofs, cur_archive_file_ofs = 0, uncomp_size = 0,
comp_size = 0;
size_t archive_name_size;
mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE];
mz_uint8 *pExtra_data = NULL;

View File

@ -66,6 +66,14 @@
} \
} while (0)
#define UNX_IFDIR 0040000 /* Unix directory */
#define UNX_IFREG 0100000 /* Unix regular file */
#define UNX_IFSOCK 0140000 /* Unix socket (BSD, not SysV or Amiga) */
#define UNX_IFLNK 0120000 /* Unix symbolic link (not SysV, Amiga) */
#define UNX_IFBLK 0060000 /* Unix block special (not Amiga) */
#define UNX_IFCHR 0020000 /* Unix character special (not Amiga) */
#define UNX_IFIFO 0010000 /* Unix fifo (BCC, not MSC or Amiga) */
struct zip_entry_t {
int index;
char *name;
@ -375,8 +383,8 @@ static int zip_archive_extract(mz_zip_archive *zip_archive, const char *dir,
(void)xattr; // unused
#else
xattr = (info.m_external_attr >> 16) & 0xFFFF;
if (xattr > 0) {
if (chmod(path, (mode_t)xattr) < 0) {
if (xattr > 0 && xattr <= MZ_UINT16_MAX) {
if (CHMOD(path, (mode_t)xattr) < 0) {
err = ZIP_ENOPERM;
goto out;
}
@ -830,7 +838,8 @@ struct zip_t *zip_open(const char *zipname, int level, char mode) {
goto cleanup;
}
if ((mode == 'a' || mode == 'd')) {
if (!mz_zip_writer_init_from_reader_v2_noreopen(&(zip->archive), zipname, 0)) {
if (!mz_zip_writer_init_from_reader_v2_noreopen(&(zip->archive), zipname,
0)) {
mz_zip_reader_end(&(zip->archive));
goto cleanup;
}
@ -957,7 +966,7 @@ int zip_entry_open(struct zip_t *zip, const char *entryname) {
// UNIX or APPLE
#if MZ_PLATFORM == 3 || MZ_PLATFORM == 19
// regular file with rw-r--r-- persmissions
// regular file with rw-r--r-- permissions
zip->entry.external_attr = (mz_uint32)(0100644) << 16;
#else
zip->entry.external_attr = 0;
@ -1315,6 +1324,7 @@ int zip_entry_fwrite(struct zip_t *zip, const char *filename) {
MZ_FILE *stream = NULL;
mz_uint8 buf[MZ_ZIP_MAX_IO_BUF_SIZE];
struct MZ_FILE_STAT_STRUCT file_stat;
mz_uint16 modes;
if (!zip) {
// zip_t handler is not initialized
@ -1328,11 +1338,32 @@ int zip_entry_fwrite(struct zip_t *zip, const char *filename) {
return ZIP_ENOENT;
}
if ((file_stat.st_mode & 0200) == 0) {
// MS-DOS read-only attribute
zip->entry.external_attr |= 0x01;
#if defined(_WIN32) || defined(__WIN32__)
(void)modes; // unused
#else
/* Initialize with permission bits--which are not implementation-optional */
modes = file_stat.st_mode &
(S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID | S_ISVTX);
if (S_ISDIR(file_stat.st_mode))
modes |= UNX_IFDIR;
if (S_ISREG(file_stat.st_mode))
modes |= UNX_IFREG;
if (S_ISLNK(file_stat.st_mode))
modes |= UNX_IFLNK;
if (S_ISBLK(file_stat.st_mode))
modes |= UNX_IFBLK;
if (S_ISCHR(file_stat.st_mode))
modes |= UNX_IFCHR;
if (S_ISFIFO(file_stat.st_mode))
modes |= UNX_IFIFO;
if (S_ISSOCK(file_stat.st_mode))
modes |= UNX_IFSOCK;
zip->entry.external_attr = (modes << 16) | !(file_stat.st_mode & S_IWRITE);
if ((file_stat.st_mode & S_IFMT) == S_IFDIR) {
zip->entry.external_attr |= MZ_ZIP_DOS_DIR_ATTRIBUTE_BITFLAG;
}
zip->entry.external_attr |= (mz_uint32)((file_stat.st_mode & 0xFFFF) << 16);
#endif
zip->entry.m_time = file_stat.st_mtime;
if (!(stream = MZ_FOPEN(filename, "rb"))) {
@ -1440,8 +1471,8 @@ int zip_entry_fread(struct zip_t *zip, const char *filename) {
}
xattr = (info.m_external_attr >> 16) & 0xFFFF;
if (xattr > 0) {
if (chmod(filename, (mode_t)xattr) < 0) {
if (xattr > 0 && xattr <= MZ_UINT16_MAX) {
if (CHMOD(filename, (mode_t)xattr) < 0) {
return ZIP_ENOPERM;
}
}
@ -1607,6 +1638,7 @@ int zip_create(const char *zipname, const char *filenames[], size_t len) {
mz_zip_archive zip_archive;
struct MZ_FILE_STAT_STRUCT file_stat;
mz_uint32 ext_attributes = 0;
mz_uint16 modes;
if (!zipname || strlen(zipname) < 1) {
// zip_t archive name is empty or NULL
@ -1641,11 +1673,32 @@ int zip_create(const char *zipname, const char *filenames[], size_t len) {
break;
}
if ((file_stat.st_mode & 0200) == 0) {
// MS-DOS read-only attribute
ext_attributes |= 0x01;
#if defined(_WIN32) || defined(__WIN32__)
(void)modes; // unused
#else
/* Initialize with permission bits--which are not implementation-optional */
modes = file_stat.st_mode &
(S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID | S_ISVTX);
if (S_ISDIR(file_stat.st_mode))
modes |= UNX_IFDIR;
if (S_ISREG(file_stat.st_mode))
modes |= UNX_IFREG;
if (S_ISLNK(file_stat.st_mode))
modes |= UNX_IFLNK;
if (S_ISBLK(file_stat.st_mode))
modes |= UNX_IFBLK;
if (S_ISCHR(file_stat.st_mode))
modes |= UNX_IFCHR;
if (S_ISFIFO(file_stat.st_mode))
modes |= UNX_IFIFO;
if (S_ISSOCK(file_stat.st_mode))
modes |= UNX_IFSOCK;
ext_attributes = (modes << 16) | !(file_stat.st_mode & S_IWRITE);
if ((file_stat.st_mode & S_IFMT) == S_IFDIR) {
ext_attributes |= MZ_ZIP_DOS_DIR_ATTRIBUTE_BITFLAG;
}
ext_attributes |= (mz_uint32)((file_stat.st_mode & 0xFFFF) << 16);
#endif
if (!mz_zip_writer_add_file(&zip_archive, zip_basename(name), name, "", 0,
ZIP_DEFAULT_COMPRESSION_LEVEL,

View File

@ -24,9 +24,7 @@ void test_setup(void) {
zip_close(zip);
}
void test_teardown(void) {
remove(ZIPNAME);
}
void test_teardown(void) { remove(ZIPNAME); }
#define TESTDATA2 "Some test data 2...\0"
#define CRC32DATA2 2532008468