Skip to content

Commit

Permalink
Keep separate DOS time/date objects.
Browse files Browse the repository at this point in the history
  • Loading branch information
0-wiz-0 committed Mar 15, 2024
1 parent f0eff80 commit 7a53a1a
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 31 deletions.
18 changes: 12 additions & 6 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 = de->last_mod;
st_mtime.mtime = _zip_d2u_time(de->last_mod_time, de->last_mod_date);
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 @@ -529,10 +529,16 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
}

if ((de->changed & ZIP_DIRENT_LAST_MOD) == 0) {
if (st.valid & ZIP_STAT_MTIME)
de->last_mod = st.mtime;
else
time(&de->last_mod);
time_t mtime;
if (st.valid & ZIP_STAT_MTIME) {
mtime = st.mtime;
}
else {
time(&mtime);
}
if (_zip_u2d_time(st.mtime, &de->last_mod_time, &de->last_mod_date, &za->error) < 0) {
return -1;
}
}
de->comp_method = st.comp_method;
de->crc = st.crc;
Expand Down Expand Up @@ -748,4 +754,4 @@ static int torrentzip_compare_names(const void *a, const void *b) {
}

return strcasecmp(aname, bname);
}
}
24 changes: 15 additions & 9 deletions lib/zip_dirent.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include <time.h>
#include <zlib.h>

#include "zip.h"
#include "zipint.h"

static zip_string_t *_zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string_t *str);
Expand Down Expand Up @@ -289,7 +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 = 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 @@ -340,7 +342,6 @@ _zip_dirent_new(void) {
zip_int64_t
_zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, bool local, zip_error_t *error) {
zip_uint8_t buf[CDENTRYSIZE];
zip_uint16_t dostime, dosdate;
zip_uint32_t size, variable_size;
zip_uint16_t filename_len, comment_len, ef_len;

Expand Down Expand Up @@ -380,9 +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 */
dostime = _zip_buffer_get_16(buffer);
dosdate = _zip_buffer_get_16(buffer);
zde->last_mod = _zip_d2u_time(dostime, dosdate);
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 @@ -921,7 +921,8 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) {
dosdate = 0x2198;
}
else {
_zip_u2d_time(de->last_mod, &dostime, &dosdate);
dostime = de->last_mod_time;
dosdate = de->last_mod_date;
}
_zip_buffer_put_16(buffer, dostime);
_zip_buffer_put_16(buffer, dosdate);
Expand Down Expand Up @@ -1110,23 +1111,28 @@ _zip_get_dirent(zip_t *za, zip_uint64_t idx, zip_flags_t flags, zip_error_t *err
}


void
_zip_u2d_time(time_t intime, zip_uint16_t *dtime, zip_uint16_t *ddate) {
int
_zip_u2d_time(time_t intime, zip_uint16_t *dtime, zip_uint16_t *ddate, zip_error_t *ze) {
struct tm *tpm;
struct tm tm;
tpm = zip_localtime(&intime, &tm);
if (tpm == NULL) {
/* if localtime fails, return an arbitrary date (1980-01-01 00:00:00) */
*ddate = (1 << 5) + 1;
*dtime = 0;
return;
if (ze) {
zip_error_set(ze, ZIP_ER_INVAL, errno);
}
return -1;
}
if (tpm->tm_year < 80) {
tpm->tm_year = 80;
}

*ddate = (zip_uint16_t)(((tpm->tm_year + 1900 - 1980) << 9) + ((tpm->tm_mon + 1) << 5) + tpm->tm_mday);
*dtime = (zip_uint16_t)(((tpm->tm_hour) << 11) + ((tpm->tm_min) << 5) + ((tpm->tm_sec) >> 1));

return 0;
}


Expand Down
25 changes: 16 additions & 9 deletions lib/zip_file_set_mtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,16 @@
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "zip.h"
#include "zipint.h"

ZIP_EXTERN int
zip_file_set_dostime(zip_t *za, zip_uint64_t idx, zip_uint16_t dtime, zip_uint16_t ddate, zip_flags_t flags) {
time_t mtime;
mtime = _zip_d2u_time(dtime, ddate);
return zip_file_set_mtime(za, idx, mtime, flags);
}

ZIP_EXTERN int
zip_file_set_mtime(zip_t *za, zip_uint64_t idx, time_t mtime, zip_flags_t flags) {
zip_entry_t *e;

if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
if (_zip_get_dirent(za, idx, 0, NULL) == NULL) {
return -1;
}

if (ZIP_IS_RDONLY(za)) {
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
Expand All @@ -70,8 +65,20 @@ zip_file_set_mtime(zip_t *za, zip_uint64_t idx, time_t mtime, zip_flags_t flags)
}
}

e->changes->last_mod = mtime;
e->changes->last_mod_time = dtime;
e->changes->last_mod_date = ddate;
e->changes->changed |= ZIP_DIRENT_LAST_MOD;

return 0;
}

ZIP_EXTERN int
zip_file_set_mtime(zip_t *za, zip_uint64_t idx, time_t mtime, zip_flags_t flags) {
zip_uint16_t ddate, dtime;

if (_zip_u2d_time(mtime, &dtime, &ddate, &za->error) < 0) {
return -1;
}

return zip_file_set_dostime(za, idx, dtime, ddate, flags);
}
5 changes: 4 additions & 1 deletion lib/zip_open.c
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,10 @@ _zip_headercomp(const zip_dirent_t *central, const zip_dirent_t *local) {
and global headers for the bitflags */
|| (central->bitflags != local->bitflags)
#endif
|| (central->comp_method != local->comp_method) || (central->last_mod != local->last_mod) || !_zip_string_equal(central->filename, local->filename))
|| (central->comp_method != local->comp_method)
|| (central->last_mod_date != local->last_mod_date)
|| (central->last_mod_time != local->last_mod_time)
|| !_zip_string_equal(central->filename, local->filename))
return -1;

if ((central->crc != local->crc) || (central->comp_size != local->comp_size) || (central->uncomp_size != local->uncomp_size)) {
Expand Down
4 changes: 3 additions & 1 deletion lib/zip_source_pkware_decode.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,9 @@ decrypt_header(zip_source_t *src, struct trad_pkware *ctx) {

if (st.valid & ZIP_STAT_MTIME) {
unsigned short dostime, dosdate;
_zip_u2d_time(st.mtime, &dostime, &dosdate);
if (_zip_u2d_time(st.mtime, &dostime, &dosdate, &ctx->error) < 0) {
return -1;
}
if (header[ZIP_CRYPTO_PKWARE_HEADERLEN - 1] == dostime >> 8) {
ok = true;
}
Expand Down
4 changes: 3 additions & 1 deletion lib/zip_source_pkware_encode.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,9 @@ encrypt_header(zip_source_t *src, struct trad_pkware *ctx) {
set_mtime(ctx, &st);
}

_zip_u2d_time(ctx->mtime, &dostime, &dosdate);
if (_zip_u2d_time(ctx->mtime, &dostime, &dosdate, &ctx->error) < 0) {
return -1;
}

if ((ctx->buffer = _zip_buffer_new(NULL, ZIP_CRYPTO_PKWARE_HEADERLEN)) == NULL) {
zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0);
Expand Down
4 changes: 2 additions & 2 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 = de->last_mod;
st->mtime = _zip_d2u_time(de->last_mod_time, de->last_mod_date);
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 = de->last_mod;
st->mtime = _zip_d2u_time(de->last_mod_time, de->last_mod_date);
st->comp_size = de->comp_size;
st->comp_method = (zip_uint16_t)de->comp_method;
st->encryption_method = de->encryption_method;
Expand Down
5 changes: 3 additions & 2 deletions lib/zipint.h
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,8 @@ 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)) */
time_t last_mod; /* (cl) time of last modification */
zip_uint16_t last_mod_time; /* (cl) time of last modification */
zip_uint16_t last_mod_date; /* (cl) date 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 @@ -647,7 +648,7 @@ zip_t *_zip_new(zip_error_t *);

zip_int64_t _zip_file_replace(zip_t *, zip_uint64_t, const char *, zip_source_t *, zip_flags_t);
int _zip_set_name(zip_t *, zip_uint64_t, const char *, zip_flags_t);
void _zip_u2d_time(time_t, zip_uint16_t *, zip_uint16_t *);
int _zip_u2d_time(time_t, zip_uint16_t *, zip_uint16_t *, zip_error_t *);
int _zip_unchange(zip_t *, zip_uint64_t, int);
void _zip_unchange_data(zip_entry_t *);
int _zip_write(zip_t *za, const void *data, zip_uint64_t length);
Expand Down

0 comments on commit 7a53a1a

Please sign in to comment.