Standardize epoch time calculation.
This commit is contained in:
parent
2bb190f49a
commit
86775f1c75
@ -35,10 +35,11 @@ char *mpw_get_token(const char **in, const char *eol, char *delim) {
|
|||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
time_t mpw_mktime(
|
time_t mpw_timegm(
|
||||||
const char *time) {
|
const char *time) {
|
||||||
|
|
||||||
// TODO: Support for parsing non-UTC time strings
|
// TODO: Support for parsing non-UTC time strings
|
||||||
|
// Parse time as a UTC timestamp, into a tm.
|
||||||
struct tm tm = { .tm_isdst = -1 };
|
struct tm tm = { .tm_isdst = -1 };
|
||||||
if (time && sscanf( time, "%4d-%2d-%2dT%2d:%2d:%2dZ",
|
if (time && sscanf( time, "%4d-%2d-%2dT%2d:%2d:%2dZ",
|
||||||
&tm.tm_year, &tm.tm_mon, &tm.tm_mday,
|
&tm.tm_year, &tm.tm_mon, &tm.tm_mday,
|
||||||
@ -46,8 +47,9 @@ time_t mpw_mktime(
|
|||||||
tm.tm_year -= 1900; // tm_year 0 = rfc3339 year 1900
|
tm.tm_year -= 1900; // tm_year 0 = rfc3339 year 1900
|
||||||
tm.tm_mon -= 1; // tm_mon 0 = rfc3339 month 1
|
tm.tm_mon -= 1; // tm_mon 0 = rfc3339 month 1
|
||||||
|
|
||||||
// mktime converts tm to local, setting tm_gmtoff; use it to offset the result back to UTC.
|
// mktime interprets tm as being local, we need to offset back to UTC (timegm/tm_gmtoff are non-standard).
|
||||||
return mktime( &tm ) + tm.tm_gmtoff;
|
time_t local_time = mktime( &tm ), local_dst = tm.tm_isdst > 0? 3600: 0;
|
||||||
|
return local_time + local_dst - mktime( gmtime( &local_time ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
char *mpw_get_token(
|
char *mpw_get_token(
|
||||||
const char **in, const char *eol, char *delim);
|
const char **in, const char *eol, char *delim);
|
||||||
/** Convert an RFC 3339 time string into epoch time. */
|
/** Convert an RFC 3339 time string into epoch time. */
|
||||||
time_t mpw_mktime(
|
time_t mpw_timegm(
|
||||||
const char *time);
|
const char *time);
|
||||||
|
|
||||||
/// JSON parsing.
|
/// JSON parsing.
|
||||||
|
@ -407,7 +407,7 @@ static void mpw_marshal_read_flat_info(
|
|||||||
if (strcmp( headerName, "Passwords" ) == 0)
|
if (strcmp( headerName, "Passwords" ) == 0)
|
||||||
info->redacted = strcmp( headerValue, "VISIBLE" ) != 0;
|
info->redacted = strcmp( headerValue, "VISIBLE" ) != 0;
|
||||||
if (strcmp( headerName, "Date" ) == 0)
|
if (strcmp( headerName, "Date" ) == 0)
|
||||||
info->date = mpw_mktime( headerValue );
|
info->date = mpw_timegm( headerValue );
|
||||||
|
|
||||||
mpw_free_strings( &headerName, &headerValue, NULL );
|
mpw_free_strings( &headerName, &headerValue, NULL );
|
||||||
continue;
|
continue;
|
||||||
@ -580,7 +580,7 @@ static MPMarshalledUser *mpw_marshal_read_flat(
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
MPAlgorithmVersion siteAlgorithm = (MPAlgorithmVersion)value;
|
MPAlgorithmVersion siteAlgorithm = (MPAlgorithmVersion)value;
|
||||||
time_t siteLastUsed = mpw_mktime( str_lastUsed );
|
time_t siteLastUsed = mpw_timegm( str_lastUsed );
|
||||||
if (!siteLastUsed) {
|
if (!siteLastUsed) {
|
||||||
*error = (MPMarshalError){ MPMarshalErrorIllegal, mpw_str( "Invalid site last used: %s: %s", siteName, str_lastUsed ) };
|
*error = (MPMarshalError){ MPMarshalErrorIllegal, mpw_str( "Invalid site last used: %s: %s", siteName, str_lastUsed ) };
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -650,7 +650,7 @@ static void mpw_marshal_read_json_info(
|
|||||||
if (fileFormat < 1)
|
if (fileFormat < 1)
|
||||||
return;
|
return;
|
||||||
info->redacted = mpw_get_json_boolean( json_file, "export.redacted", true );
|
info->redacted = mpw_get_json_boolean( json_file, "export.redacted", true );
|
||||||
info->date = mpw_mktime( mpw_get_json_string( json_file, "export.date", NULL ) );
|
info->date = mpw_timegm( mpw_get_json_string( json_file, "export.date", NULL ) );
|
||||||
|
|
||||||
// Section: "user"
|
// Section: "user"
|
||||||
info->algorithm = (MPAlgorithmVersion)mpw_get_json_int( json_file, "user.algorithm", MPAlgorithmVersionCurrent );
|
info->algorithm = (MPAlgorithmVersion)mpw_get_json_int( json_file, "user.algorithm", MPAlgorithmVersionCurrent );
|
||||||
@ -707,7 +707,7 @@ static MPMarshalledUser *mpw_marshal_read_json(
|
|||||||
*error = (MPMarshalError){ MPMarshalErrorIllegal, mpw_str( "Invalid user default type: %u", defaultType ) };
|
*error = (MPMarshalError){ MPMarshalErrorIllegal, mpw_str( "Invalid user default type: %u", defaultType ) };
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
time_t lastUsed = mpw_mktime( str_lastUsed );
|
time_t lastUsed = mpw_timegm( str_lastUsed );
|
||||||
if (!lastUsed) {
|
if (!lastUsed) {
|
||||||
*error = (MPMarshalError){ MPMarshalErrorIllegal, mpw_str( "Invalid user last used: %s", str_lastUsed ) };
|
*error = (MPMarshalError){ MPMarshalErrorIllegal, mpw_str( "Invalid user last used: %s", str_lastUsed ) };
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -760,7 +760,7 @@ static MPMarshalledUser *mpw_marshal_read_json(
|
|||||||
MPResultType siteLoginType = (MPResultType)mpw_get_json_int( json_site.val, "login_type", MPResultTypeTemplateName );
|
MPResultType siteLoginType = (MPResultType)mpw_get_json_int( json_site.val, "login_type", MPResultTypeTemplateName );
|
||||||
unsigned int siteUses = (unsigned int)mpw_get_json_int( json_site.val, "uses", 0 );
|
unsigned int siteUses = (unsigned int)mpw_get_json_int( json_site.val, "uses", 0 );
|
||||||
str_lastUsed = mpw_get_json_string( json_site.val, "last_used", NULL );
|
str_lastUsed = mpw_get_json_string( json_site.val, "last_used", NULL );
|
||||||
time_t siteLastUsed = mpw_mktime( str_lastUsed );
|
time_t siteLastUsed = mpw_timegm( str_lastUsed );
|
||||||
if (!siteLastUsed) {
|
if (!siteLastUsed) {
|
||||||
*error = (MPMarshalError){ MPMarshalErrorIllegal, mpw_str( "Invalid site last used: %s: %s", siteName, str_lastUsed ) };
|
*error = (MPMarshalError){ MPMarshalErrorIllegal, mpw_str( "Invalid site last used: %s: %s", siteName, str_lastUsed ) };
|
||||||
return NULL;
|
return NULL;
|
||||||
|
Loading…
Reference in New Issue
Block a user