Skip to content

Commit

Permalink
Introduce new struct for dos time stamps.
Browse files Browse the repository at this point in the history
  • Loading branch information
dillof committed Apr 22, 2024
1 parent e49c545 commit ecc7f52
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 53 deletions.
4 changes: 2 additions & 2 deletions lib/zip_close.c
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
zip_stat_t st_mtime;
zip_stat_init(&st_mtime);
st_mtime.valid = ZIP_STAT_MTIME;
st_mtime.mtime = _zip_d2u_time(de->last_mod_time, de->last_mod_date);
st_mtime.mtime = _zip_d2u_time(&de->last_mod);
if ((src_tmp = _zip_source_window_new(src_final, 0, -1, &st_mtime, 0, NULL, NULL, 0, true, &za->error)) == NULL) {
zip_source_free(src_final);
return -1;
Expand Down Expand Up @@ -536,7 +536,7 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
else {
time(&mtime);
}
if (_zip_u2d_time(st.mtime, &de->last_mod_time, &de->last_mod_date, &za->error) < 0) {
if (_zip_u2d_time(st.mtime, &de->last_mod.time, &de->last_mod.date, &za->error) < 0) {
return -1;
}
}
Expand Down
35 changes: 17 additions & 18 deletions lib/zip_dirent.c
Original file line number Diff line number Diff line change
Expand Up @@ -290,8 +290,8 @@ _zip_dirent_init(zip_dirent_t *de) {
de->version_needed = 10; /* 1.0 */
de->bitflags = 0;
de->comp_method = ZIP_CM_DEFAULT;
de->last_mod_date = 0;
de->last_mod_time = 0;
de->last_mod.date = 0;
de->last_mod.time = 0;
de->crc = 0;
de->comp_size = 0;
de->uncomp_size = 0;
Expand Down Expand Up @@ -381,8 +381,8 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo
zde->comp_method = _zip_buffer_get_16(buffer);

/* convert to time_t */
zde->last_mod_time = _zip_buffer_get_16(buffer);
zde->last_mod_date = _zip_buffer_get_16(buffer);
zde->last_mod.time = _zip_buffer_get_16(buffer);
zde->last_mod.date = _zip_buffer_get_16(buffer);

zde->crc = _zip_buffer_get_32(buffer);
zde->comp_size = _zip_buffer_get_32(buffer);
Expand Down Expand Up @@ -778,7 +778,7 @@ _zip_dirent_size(zip_source_t *src, zip_uint16_t flags, zip_error_t *error) {

int
_zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) {
zip_uint16_t dostime, dosdate;
zip_dostime_t dostime;
zip_encoding_type_t com_enc, name_enc;
zip_extra_field_t *ef;
zip_extra_field_t *ef64;
Expand Down Expand Up @@ -917,15 +917,14 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) {
}

if (ZIP_WANT_TORRENTZIP(za)) {
dostime = 0xbc00;
dosdate = 0x2198;
dostime.time = 0xbc00;
dostime.date = 0x2198;
}
else {
dostime = de->last_mod_time;
dosdate = de->last_mod_date;
dostime = de->last_mod;
}
_zip_buffer_put_16(buffer, dostime);
_zip_buffer_put_16(buffer, dosdate);
_zip_buffer_put_16(buffer, dostime.time);
_zip_buffer_put_16(buffer, dostime.date);

if (is_winzip_aes && de->uncomp_size < 20) {
_zip_buffer_put_32(buffer, 0);
Expand Down Expand Up @@ -1026,21 +1025,21 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) {


time_t
_zip_d2u_time(zip_uint16_t dtime, zip_uint16_t ddate) {
_zip_d2u_time(const zip_dostime_t* dtime) {
struct tm tm;

memset(&tm, 0, sizeof(tm));

/* let mktime decide if DST is in effect */
tm.tm_isdst = -1;

tm.tm_year = ((ddate >> 9) & 127) + 1980 - 1900;
tm.tm_mon = ((ddate >> 5) & 15) - 1;
tm.tm_mday = ddate & 31;
tm.tm_year = ((dtime->date >> 9) & 127) + 1980 - 1900;
tm.tm_mon = ((dtime->date >> 5) & 15) - 1;
tm.tm_mday = dtime->date & 31;

tm.tm_hour = (dtime >> 11) & 31;
tm.tm_min = (dtime >> 5) & 63;
tm.tm_sec = (dtime << 1) & 62;
tm.tm_hour = (dtime->time >> 11) & 31;
tm.tm_min = (dtime->time >> 5) & 63;
tm.tm_sec = (dtime->time << 1) & 62;

return mktime(&tm);
}
Expand Down
4 changes: 2 additions & 2 deletions lib/zip_file_set_mtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ zip_file_set_dostime(zip_t *za, zip_uint64_t idx, zip_uint16_t dtime, zip_uint16
}
}

e->changes->last_mod_time = dtime;
e->changes->last_mod_date = ddate;
e->changes->last_mod.time = dtime;
e->changes->last_mod.date = ddate;
e->changes->changed |= ZIP_DIRENT_LAST_MOD;

return 0;
Expand Down
4 changes: 2 additions & 2 deletions lib/zip_open.c
Original file line number Diff line number Diff line change
Expand Up @@ -525,8 +525,8 @@ _zip_headercomp(const zip_dirent_t *central, const zip_dirent_t *local) {
|| (central->bitflags != local->bitflags)
#endif
|| (central->comp_method != local->comp_method)
|| (central->last_mod_date != local->last_mod_date)
|| (central->last_mod_time != local->last_mod_time)
|| (central->last_mod.time != local->last_mod.time)
|| (central->last_mod.date != local->last_mod.date)
|| !_zip_string_equal(central->filename, local->filename))
return -1;

Expand Down
38 changes: 16 additions & 22 deletions lib/zip_source_get_dostime.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
zip_source_stat.c -- get meta information from zip_source
Copyright (C) 2009-2021 Dieter Baron and Thomas Klausner
zip_source_get_dostime.c -- get modification time in DOS format from source
Copyright (C) 2025 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <[email protected]>
Expand Down Expand Up @@ -34,13 +34,13 @@

#include "zipint.h"


/* Returns -1 on error, 0 on no dostime avaialable, 1 for dostime returned */
ZIP_EXTERN int
zip_source_get_dos_time(zip_source_t *src, zip_uint16_t *dos_time, zip_uint16_t *dos_date) {
zip_source_get_dos_time(zip_source_t *src, zip_dostime_t *dos_time) {
if (src->source_closed) {
return -1;
}
if (dos_time == NULL || dos_date == NULL) {
if (dos_time == NULL) {
zip_error_set(&src->error, ZIP_ER_INVAL, 0);
return -1;
}
Expand All @@ -50,29 +50,23 @@ zip_source_get_dos_time(zip_source_t *src, zip_uint16_t *dos_time, zip_uint16_t
}

if (zip_source_supports(src) & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_GET_DOS_TIME)) {
zip_uint16_t data[2];
if (_zip_source_call(src, data, sizeof(data), ZIP_SOURCE_GET_DOS_TIME) < 0) {
return -1;
}
*dos_time = data[0];
*dos_date = data[1];
return 0;
}
else {
zip_stat_t st;
zip_stat_init(&st);
zip_int64_t n = _zip_source_call(src, dos_time, sizeof(*dos_time), ZIP_SOURCE_GET_DOS_TIME);

if (zip_source_stat(src, &st) < 0) {
if (n < 0) {
return -1;
}

if (!(st.valid & ZIP_STAT_MTIME)) {
*dos_time = 0;
*dos_date = 0;
else if (n == 0) {
return 0;
}
else if (n == sizeof(*dos_time)) {
return 1;
}
else {
return _zip_u2d_time(st.mtime, dos_time, dos_date, &src->error);
zip_error_set(&src->error, ZIP_ER_INTERNAL, 0);
return -1;
}
}
else {
return 0;
}
}
7 changes: 4 additions & 3 deletions lib/zip_stat_index.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ zip_stat_index(zip_t *za, zip_uint64_t index, zip_flags_t flags, zip_stat_t *st)
}

if (entry->changes != NULL && entry->changes->changed & ZIP_DIRENT_LAST_MOD) {
st->mtime = _zip_d2u_time(de->last_mod_time, de->last_mod_date);
st->mtime = _zip_d2u_time(&de->last_mod);
st->valid |= ZIP_STAT_MTIME;
}
}
Expand All @@ -86,7 +86,7 @@ zip_stat_index(zip_t *za, zip_uint64_t index, zip_flags_t flags, zip_stat_t *st)

st->crc = de->crc;
st->size = de->uncomp_size;
st->mtime = _zip_d2u_time(de->last_mod_time, de->last_mod_date);
st->mtime = _zip_d2u_time(&de->last_mod);
st->comp_size = de->comp_size;
st->comp_method = (zip_uint16_t)de->comp_method;
st->encryption_method = de->encryption_method;
Expand All @@ -97,8 +97,9 @@ zip_stat_index(zip_t *za, zip_uint64_t index, zip_flags_t flags, zip_stat_t *st)
}

if ((za->ch_flags & ZIP_AFL_WANT_TORRENTZIP) && (flags & ZIP_FL_UNCHANGED) == 0) {
zip_dostime_t dostime = {0xbc00, 0x2198};
st->comp_method = ZIP_CM_DEFLATE;
st->mtime = _zip_d2u_time(0xbc00, 0x2198);
st->mtime = _zip_d2u_time(&dostime);
st->valid |= ZIP_STAT_MTIME | ZIP_STAT_COMP_METHOD;
st->valid &= ~ZIP_STAT_COMP_SIZE;
}
Expand Down
13 changes: 9 additions & 4 deletions lib/zipint.h
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ struct zip_hash;
struct zip_progress;

typedef struct zip_cdir zip_cdir_t;
typedef struct zip_dostime zip_dostime_t;
typedef struct zip_dirent zip_dirent_t;
typedef struct zip_entry zip_entry_t;
typedef struct zip_extra_field zip_extra_field_t;
Expand Down Expand Up @@ -328,6 +329,11 @@ struct zip_file {
#define ZIP_DIRENT_PASSWORD 0x0080u
#define ZIP_DIRENT_ALL ZIP_UINT32_MAX

struct zip_dostime {
zip_uint16_t time;
zip_uint16_t date;
};

struct zip_dirent {
zip_uint32_t changed;
bool local_extra_fields_read; /* whether we already read in local header extra fields */
Expand All @@ -339,8 +345,7 @@ struct zip_dirent {
zip_uint16_t version_needed; /* (cl) version needed to extract */
zip_uint16_t bitflags; /* (cl) general purpose bit flag */
zip_int32_t comp_method; /* (cl) compression method used (uint16 and ZIP_CM_DEFAULT (-1)) */
zip_uint16_t last_mod_time; /* (cl) time of last modification */
zip_uint16_t last_mod_date; /* (cl) date of last modification */
zip_dostime_t last_mod; /* (cl) time of last modification */
zip_uint32_t crc; /* (cl) CRC-32 of uncompressed data */
zip_uint64_t comp_size; /* (cl) size of compressed data */
zip_uint64_t uncomp_size; /* (cl) size of uncompressed data */
Expand Down Expand Up @@ -529,7 +534,7 @@ void _zip_cdir_free(zip_cdir_t *);
bool _zip_cdir_grow(zip_cdir_t *cd, zip_uint64_t additional_entries, zip_error_t *error);
zip_cdir_t *_zip_cdir_new(zip_uint64_t, zip_error_t *);
zip_int64_t _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivors);
time_t _zip_d2u_time(zip_uint16_t, zip_uint16_t);
time_t _zip_d2u_time(const zip_dostime_t*);
void _zip_deregister_source(zip_t *za, zip_source_t *src);

void _zip_dirent_apply_attributes(zip_dirent_t *, zip_file_attributes_t *, bool, zip_uint32_t);
Expand Down Expand Up @@ -612,7 +617,7 @@ void _zip_set_open_error(int *zep, const zip_error_t *err, int ze);
bool zip_source_accept_empty(zip_source_t *src);
zip_int64_t _zip_source_call(zip_source_t *src, void *data, zip_uint64_t length, zip_source_cmd_t command);
bool _zip_source_eof(zip_source_t *);
int zip_source_get_dos_time(zip_source_t *src, zip_uint16_t *dos_time, zip_uint16_t *dos_date);
int zip_source_get_dos_time(zip_source_t *src, zip_dostime_t *dos_time);

zip_source_t *_zip_source_file_or_p(const char *, FILE *, zip_uint64_t, zip_int64_t, const zip_stat_t *, zip_error_t *error);
bool _zip_source_had_error(zip_source_t *);
Expand Down

0 comments on commit ecc7f52

Please sign in to comment.