Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 1 addition & 18 deletions src/htsbauth.c
Original file line number Diff line number Diff line change
Expand Up @@ -350,31 +350,14 @@ hts_boolean cookie_max_age_time(const char *value, int64_t now, int64_t *when) {
return HTS_TRUE;
}

/* Return the Unix time of the UTC date in tm, in 64 bits because a 32-bit
time_t ends in 2038. The calendar year must be 1 or later, and tm_mon 0 to
11, as convert_time_rfc822_pivot yields them. */
static int64_t cookie_utc_seconds(const struct tm *tm) {
// days from the civil date, counting years from March (Howard Hinnant)
const int64_t y = (int64_t) tm->tm_year + 1900 - (tm->tm_mon < 2 ? 1 : 0);
const int64_t era = y / 400;
const int64_t yoe = y - era * 400;
const int64_t doy = (153 * (int64_t) ((tm->tm_mon + 10) % 12) + 2) / 5 +
(int64_t) tm->tm_mday - 1;
const int64_t days =
era * 146097 + yoe * 365 + yoe / 4 - yoe / 100 + doy - 719468;

return days * 86400 + (int64_t) tm->tm_hour * 3600 +
(int64_t) tm->tm_min * 60 + tm->tm_sec;
}

/* See htsbauth.h. */
hts_boolean cookie_expires_time(const char *value, int64_t now, int64_t *when) {
struct tm tm;

// RFC 6265 5.1.1 reads a two-digit year below 70 as 20xx
if (convert_time_rfc822_pivot(&tm, value, 69) == NULL)
return HTS_FALSE;
*when = cookie_bound_expiry(cookie_utc_seconds(&tm), now);
*when = cookie_bound_expiry(hts_utc_seconds(&tm), now);
return HTS_TRUE;
}

Expand Down
2 changes: 1 addition & 1 deletion src/htscoremain.c
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ static hts_boolean write_progress_lock(httrackp *opt, const char *path,
fprintf(fp, "UID=%d\n", (int) getuid());
fprintf(fp, "GID=%d\n", (int) getuid());
#endif
fprintf(fp, "START=%d\n", (int) time(NULL));
fprintf(fp, "START=" LLintP "\n", (LLint) time(NULL));
#endif
fclose(fp);
/* Whole-second filesystems tie two files written in the same second, and the
Expand Down
54 changes: 54 additions & 0 deletions src/htsdate.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ Please visit our Website: http://www.httrack.com

#include <ctype.h>
#include <limits.h>
#include <stdint.h>
#include <string.h>

/* hts_lowcase() lives in the library proxytrack does not link. */
Expand Down Expand Up @@ -150,3 +151,56 @@ struct tm *convert_time_rfc822_pivot(struct tm *result, const char *s,
}
return NULL;
}

/* See htsdate.h. */
int64_t hts_utc_seconds(const struct tm *tm) {
// days from the civil date, counting years from March (Howard Hinnant)
int64_t y = (int64_t) tm->tm_year + 1900 + tm->tm_mon / 12;
int64_t m = tm->tm_mon % 12;
int64_t era, yoe, doy, days;

if (m < 0) {
m += 12;
y--;
}
if (m < 2)
y--;
era = (y >= 0 ? y : y - 399) / 400;
yoe = y - era * 400;
doy = (153 * ((m + 10) % 12) + 2) / 5 + (int64_t) tm->tm_mday - 1;
days = era * 146097 + yoe * 365 + yoe / 4 - yoe / 100 + doy - 719468;
return days * 86400 + (int64_t) tm->tm_hour * 3600 +
(int64_t) tm->tm_min * 60 + tm->tm_sec;
}

/* See htsdate.h. */
time_t hts_time_clip(int64_t t) {
if (sizeof(time_t) < sizeof(int64_t)) {
if (t > INT32_MAX)
return (time_t) INT32_MAX;
if (t < INT32_MIN)
return (time_t) INT32_MIN;
}
return (time_t) t;
}

/* See htsdate.h. */
hts_boolean hts_time_exact(int64_t t, time_t *out) {
const time_t clipped = hts_time_clip(t);

if ((int64_t) clipped != t)
return HTS_FALSE;
*out = clipped;
return HTS_TRUE;
}

/* See htsdate.h. */
hts_boolean hts_tm_filetime(const struct tm *tm, time_t *out) {
const int64_t t = hts_utc_seconds(tm);

if (t == -1 || t == 0)
return HTS_FALSE;
// A date past what time_t holds stamps its last second, never 1901.
*out = hts_time_clip(t);
return HTS_TRUE;
}
22 changes: 20 additions & 2 deletions src/htsdate.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,35 @@ Please visit our Website: http://www.httrack.com
#ifndef HTSDATE_DEFH
#define HTSDATE_DEFH

#include "htsglobal.h"

#include <stdint.h>
#include <time.h>

/* Parse an RFC822 date such as "Sun, 06 Nov 1994 08:49:37 GMT" into "result",
which is returned, or NULL if "s" does not parse. The fields are GMT, so a
caller wanting a time_t uses timegm(), never mktime() (#1491). Its own file
so proxytrack, which does not link the library, can share it. */
caller wanting seconds uses hts_utc_seconds(), never mktime() (#1491). This
file is separate so proxytrack, which does not link the library, can share
it. */
struct tm *convert_time_rfc822(struct tm *result, const char *s);

/* As convert_time_rfc822, but a two-digit year up to PIVOT means 20xx and one
above it 19xx. HTTP dates use 50, and cookies use 69 (RFC 6265 5.1.1). */
struct tm *convert_time_rfc822_pivot(struct tm *result, const char *s,
int pivot);

/* Return the Unix time of the UTC date in tm, in 64 bits because a 32-bit
time_t ends in 2038. Out-of-range fields carry over as with timegm(). */
int64_t hts_utc_seconds(const struct tm *tm);

/* Return t as a time_t, clipped to the range this platform's time_t holds. */
time_t hts_time_clip(int64_t t);

/* Does t fit this platform's time_t exactly? If so, store it in *out. */
hts_boolean hts_time_exact(int64_t t, time_t *out);

/* Store the file time for the UTC date in tm in *out, clipped to time_t. False
when the date is the epoch or one second before it, which mean no date. */
hts_boolean hts_tm_filetime(const struct tm *tm, time_t *out);

#endif
5 changes: 4 additions & 1 deletion src/htsftp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1025,7 +1025,10 @@ int run_launch_ftp(FTPDownloadStruct * pStruct) {
strlncatbuff(back->r.lastmodified, date,
sizeof(back->r.lastmodified),
sizeof(back->r.lastmodified) - 1);
remote_mtime = timegm(&remote_tm);
// a clipped date cannot prove the copy matches
if (!hts_time_exact(hts_utc_seconds(&remote_tm),
&remote_mtime))
remote_mtime = (time_t) -1;
}
}

Expand Down
30 changes: 9 additions & 21 deletions src/htslib.c
Original file line number Diff line number Diff line change
Expand Up @@ -3731,22 +3731,12 @@ void time_local_rfc822(char *s) {
s[0] = '\0';
}

/* convertir une chaine en temps */
static time_t getGMT(struct tm *tm) {
time_t t = timegm(tm);

if (t != (time_t) - 1 && t != (time_t) 0) {
return (time_t) t;
}
return (time_t) -1;
}

/* sets file time. -1 if error */
/* Note: utf-8 */
int set_filetime(const char *file, struct tm *tm_time) {
time_t t = getGMT(tm_time);
time_t t;

if (t != (time_t) - 1) {
if (hts_tm_filetime(tm_time, &t)) {
STRUCT_UTIMBUF tim;

memset(&tim, 0, sizeof(tim));
Expand Down Expand Up @@ -3779,26 +3769,24 @@ int hts_parse_retry_after(const char *value, time_t now) {
}

{
const time_t when = hts_parse_date(p, 50);
const int64_t when = hts_parse_date(p, 50);

if (when == (time_t) -1)
if (when == -1)
return -1;
if (when <= now)
if (when <= (int64_t) now)
return 0;
/* widen before subtracting: two time_t values can differ by more than an
int holds */
if ((LLint) when - (LLint) now > (LLint) INT_MAX)
if (when - (int64_t) now > INT_MAX)
return INT_MAX;
return (int) (when - now);
return (int) (when - (int64_t) now);
}
}

/* See htslib.h. */
time_t hts_parse_date(const char *s, int pivot) {
int64_t hts_parse_date(const char *s, int pivot) {
struct tm buffer;
struct tm *const tm_s = convert_time_rfc822_pivot(&buffer, s, pivot);

return tm_s != NULL ? timegm(tm_s) : (time_t) -1;
return tm_s != NULL ? hts_utc_seconds(tm_s) : -1;
}

/* sets file time from RFC822 date+time, -1 if error*/
Expand Down
7 changes: 3 additions & 4 deletions src/htslib.h
Original file line number Diff line number Diff line change
Expand Up @@ -246,9 +246,9 @@ void hts_init_htsblk(htsblk * r);
no usable delay. `now` dates the HTTP-date form, and the caller caps. */
int hts_parse_retry_after(const char *value, time_t now);

/* Read the HTTP date S as a time_t, with a two-digit year up to PIVOT in 20xx
(see convert_time_rfc822_pivot). (time_t) -1 when S is not a date. */
time_t hts_parse_date(const char *s, int pivot);
/* Read the HTTP date S as Unix seconds, with a two-digit year up to PIVOT in
20xx (see convert_time_rfc822_pivot). -1 when S is not a date. */
int64_t hts_parse_date(const char *s, int pivot);

// attach specific project log to hachtable logger
void hts_set_hash_handler(coucal hashtable, httrackp *opt);
Expand Down Expand Up @@ -843,7 +843,6 @@ HTS_STATIC int strcmpnocase(const char *a, const char *b) {
#ifdef _MSC_VER
#define fseeko _fseeki64
#define ftello _ftelli64
#define timegm _mkgmtime
#endif

#define strfield2(f,s) ( (strlen(f)!=strlen(s)) ? 0 : (strfield(f,s)) )
Expand Down
Loading
Loading