Skip to content

Commit 7a53a1a

Browse files
committed
Keep separate DOS time/date objects.
1 parent f0eff80 commit 7a53a1a

File tree

8 files changed

+58
-31
lines changed

8 files changed

+58
-31
lines changed

lib/zip_close.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,7 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
471471
zip_stat_t st_mtime;
472472
zip_stat_init(&st_mtime);
473473
st_mtime.valid = ZIP_STAT_MTIME;
474-
st_mtime.mtime = de->last_mod;
474+
st_mtime.mtime = _zip_d2u_time(de->last_mod_time, de->last_mod_date);
475475
if ((src_tmp = _zip_source_window_new(src_final, 0, -1, &st_mtime, 0, NULL, NULL, 0, true, &za->error)) == NULL) {
476476
zip_source_free(src_final);
477477
return -1;
@@ -529,10 +529,16 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
529529
}
530530

531531
if ((de->changed & ZIP_DIRENT_LAST_MOD) == 0) {
532-
if (st.valid & ZIP_STAT_MTIME)
533-
de->last_mod = st.mtime;
534-
else
535-
time(&de->last_mod);
532+
time_t mtime;
533+
if (st.valid & ZIP_STAT_MTIME) {
534+
mtime = st.mtime;
535+
}
536+
else {
537+
time(&mtime);
538+
}
539+
if (_zip_u2d_time(st.mtime, &de->last_mod_time, &de->last_mod_date, &za->error) < 0) {
540+
return -1;
541+
}
536542
}
537543
de->comp_method = st.comp_method;
538544
de->crc = st.crc;
@@ -748,4 +754,4 @@ static int torrentzip_compare_names(const void *a, const void *b) {
748754
}
749755

750756
return strcasecmp(aname, bname);
751-
}
757+
}

lib/zip_dirent.c

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include <time.h>
4040
#include <zlib.h>
4141

42+
#include "zip.h"
4243
#include "zipint.h"
4344

4445
static zip_string_t *_zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string_t *str);
@@ -289,7 +290,8 @@ _zip_dirent_init(zip_dirent_t *de) {
289290
de->version_needed = 10; /* 1.0 */
290291
de->bitflags = 0;
291292
de->comp_method = ZIP_CM_DEFAULT;
292-
de->last_mod = 0;
293+
de->last_mod_date = 0;
294+
de->last_mod_time = 0;
293295
de->crc = 0;
294296
de->comp_size = 0;
295297
de->uncomp_size = 0;
@@ -340,7 +342,6 @@ _zip_dirent_new(void) {
340342
zip_int64_t
341343
_zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, bool local, zip_error_t *error) {
342344
zip_uint8_t buf[CDENTRYSIZE];
343-
zip_uint16_t dostime, dosdate;
344345
zip_uint32_t size, variable_size;
345346
zip_uint16_t filename_len, comment_len, ef_len;
346347

@@ -380,9 +381,8 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo
380381
zde->comp_method = _zip_buffer_get_16(buffer);
381382

382383
/* convert to time_t */
383-
dostime = _zip_buffer_get_16(buffer);
384-
dosdate = _zip_buffer_get_16(buffer);
385-
zde->last_mod = _zip_d2u_time(dostime, dosdate);
384+
zde->last_mod_time = _zip_buffer_get_16(buffer);
385+
zde->last_mod_date = _zip_buffer_get_16(buffer);
386386

387387
zde->crc = _zip_buffer_get_32(buffer);
388388
zde->comp_size = _zip_buffer_get_32(buffer);
@@ -921,7 +921,8 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) {
921921
dosdate = 0x2198;
922922
}
923923
else {
924-
_zip_u2d_time(de->last_mod, &dostime, &dosdate);
924+
dostime = de->last_mod_time;
925+
dosdate = de->last_mod_date;
925926
}
926927
_zip_buffer_put_16(buffer, dostime);
927928
_zip_buffer_put_16(buffer, dosdate);
@@ -1110,23 +1111,28 @@ _zip_get_dirent(zip_t *za, zip_uint64_t idx, zip_flags_t flags, zip_error_t *err
11101111
}
11111112

11121113

1113-
void
1114-
_zip_u2d_time(time_t intime, zip_uint16_t *dtime, zip_uint16_t *ddate) {
1114+
int
1115+
_zip_u2d_time(time_t intime, zip_uint16_t *dtime, zip_uint16_t *ddate, zip_error_t *ze) {
11151116
struct tm *tpm;
11161117
struct tm tm;
11171118
tpm = zip_localtime(&intime, &tm);
11181119
if (tpm == NULL) {
11191120
/* if localtime fails, return an arbitrary date (1980-01-01 00:00:00) */
11201121
*ddate = (1 << 5) + 1;
11211122
*dtime = 0;
1122-
return;
1123+
if (ze) {
1124+
zip_error_set(ze, ZIP_ER_INVAL, errno);
1125+
}
1126+
return -1;
11231127
}
11241128
if (tpm->tm_year < 80) {
11251129
tpm->tm_year = 80;
11261130
}
11271131

11281132
*ddate = (zip_uint16_t)(((tpm->tm_year + 1900 - 1980) << 9) + ((tpm->tm_mon + 1) << 5) + tpm->tm_mday);
11291133
*dtime = (zip_uint16_t)(((tpm->tm_hour) << 11) + ((tpm->tm_min) << 5) + ((tpm->tm_sec) >> 1));
1134+
1135+
return 0;
11301136
}
11311137

11321138

lib/zip_file_set_mtime.c

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,21 +31,16 @@
3131
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3232
*/
3333

34+
#include "zip.h"
3435
#include "zipint.h"
3536

3637
ZIP_EXTERN int
3738
zip_file_set_dostime(zip_t *za, zip_uint64_t idx, zip_uint16_t dtime, zip_uint16_t ddate, zip_flags_t flags) {
38-
time_t mtime;
39-
mtime = _zip_d2u_time(dtime, ddate);
40-
return zip_file_set_mtime(za, idx, mtime, flags);
41-
}
42-
43-
ZIP_EXTERN int
44-
zip_file_set_mtime(zip_t *za, zip_uint64_t idx, time_t mtime, zip_flags_t flags) {
4539
zip_entry_t *e;
4640

47-
if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
41+
if (_zip_get_dirent(za, idx, 0, NULL) == NULL) {
4842
return -1;
43+
}
4944

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

73-
e->changes->last_mod = mtime;
68+
e->changes->last_mod_time = dtime;
69+
e->changes->last_mod_date = ddate;
7470
e->changes->changed |= ZIP_DIRENT_LAST_MOD;
7571

7672
return 0;
7773
}
74+
75+
ZIP_EXTERN int
76+
zip_file_set_mtime(zip_t *za, zip_uint64_t idx, time_t mtime, zip_flags_t flags) {
77+
zip_uint16_t ddate, dtime;
78+
79+
if (_zip_u2d_time(mtime, &dtime, &ddate, &za->error) < 0) {
80+
return -1;
81+
}
82+
83+
return zip_file_set_dostime(za, idx, dtime, ddate, flags);
84+
}

lib/zip_open.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -524,7 +524,10 @@ _zip_headercomp(const zip_dirent_t *central, const zip_dirent_t *local) {
524524
and global headers for the bitflags */
525525
|| (central->bitflags != local->bitflags)
526526
#endif
527-
|| (central->comp_method != local->comp_method) || (central->last_mod != local->last_mod) || !_zip_string_equal(central->filename, local->filename))
527+
|| (central->comp_method != local->comp_method)
528+
|| (central->last_mod_date != local->last_mod_date)
529+
|| (central->last_mod_time != local->last_mod_time)
530+
|| !_zip_string_equal(central->filename, local->filename))
528531
return -1;
529532

530533
if ((central->crc != local->crc) || (central->comp_size != local->comp_size) || (central->uncomp_size != local->uncomp_size)) {

lib/zip_source_pkware_decode.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,9 @@ decrypt_header(zip_source_t *src, struct trad_pkware *ctx) {
108108

109109
if (st.valid & ZIP_STAT_MTIME) {
110110
unsigned short dostime, dosdate;
111-
_zip_u2d_time(st.mtime, &dostime, &dosdate);
111+
if (_zip_u2d_time(st.mtime, &dostime, &dosdate, &ctx->error) < 0) {
112+
return -1;
113+
}
112114
if (header[ZIP_CRYPTO_PKWARE_HEADERLEN - 1] == dostime >> 8) {
113115
ok = true;
114116
}

lib/zip_source_pkware_encode.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,9 @@ encrypt_header(zip_source_t *src, struct trad_pkware *ctx) {
9595
set_mtime(ctx, &st);
9696
}
9797

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

100102
if ((ctx->buffer = _zip_buffer_new(NULL, ZIP_CRYPTO_PKWARE_HEADERLEN)) == NULL) {
101103
zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0);

lib/zip_stat_index.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ zip_stat_index(zip_t *za, zip_uint64_t index, zip_flags_t flags, zip_stat_t *st)
7777
}
7878

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

8787
st->crc = de->crc;
8888
st->size = de->uncomp_size;
89-
st->mtime = de->last_mod;
89+
st->mtime = _zip_d2u_time(de->last_mod_time, de->last_mod_date);
9090
st->comp_size = de->comp_size;
9191
st->comp_method = (zip_uint16_t)de->comp_method;
9292
st->encryption_method = de->encryption_method;

lib/zipint.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,8 @@ struct zip_dirent {
339339
zip_uint16_t version_needed; /* (cl) version needed to extract */
340340
zip_uint16_t bitflags; /* (cl) general purpose bit flag */
341341
zip_int32_t comp_method; /* (cl) compression method used (uint16 and ZIP_CM_DEFAULT (-1)) */
342-
time_t last_mod; /* (cl) time of last modification */
342+
zip_uint16_t last_mod_time; /* (cl) time of last modification */
343+
zip_uint16_t last_mod_date; /* (cl) date of last modification */
343344
zip_uint32_t crc; /* (cl) CRC-32 of uncompressed data */
344345
zip_uint64_t comp_size; /* (cl) size of compressed data */
345346
zip_uint64_t uncomp_size; /* (cl) size of uncompressed data */
@@ -647,7 +648,7 @@ zip_t *_zip_new(zip_error_t *);
647648

648649
zip_int64_t _zip_file_replace(zip_t *, zip_uint64_t, const char *, zip_source_t *, zip_flags_t);
649650
int _zip_set_name(zip_t *, zip_uint64_t, const char *, zip_flags_t);
650-
void _zip_u2d_time(time_t, zip_uint16_t *, zip_uint16_t *);
651+
int _zip_u2d_time(time_t, zip_uint16_t *, zip_uint16_t *, zip_error_t *);
651652
int _zip_unchange(zip_t *, zip_uint64_t, int);
652653
void _zip_unchange_data(zip_entry_t *);
653654
int _zip_write(zip_t *za, const void *data, zip_uint64_t length);

0 commit comments

Comments
 (0)