Skip to content

Commit 93da4d4

Browse files
authored
Merge pull request #13 from Bilb/fix-timestamp-always-seconds
feat: forgive timestamps provided as ms/μs
2 parents 00ef03c + c45ca57 commit 93da4d4

File tree

11 files changed

+164
-51
lines changed

11 files changed

+164
-51
lines changed

include/session/config/contacts.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,11 @@ struct contact_info {
6262
// conversation.
6363
notify_mode notifications = notify_mode::defaulted;
6464
int64_t mute_until = 0; // If non-zero, disable notifications until the given unix timestamp
65-
// (overriding whatever the current `notifications` value is until the
66-
// timestamp expires).
65+
// (seconds, overriding whatever the current `notifications` value is
66+
// until the timestamp expires).
6767
expiration_mode exp_mode = expiration_mode::none; // The expiry time; none if not expiring.
6868
std::chrono::seconds exp_timer{0}; // The expiration timer (in seconds)
69-
int64_t created = 0; // Unix timestamp when this contact was added
69+
int64_t created = 0; // Unix timestamp (seconds) when this contact was added
7070

7171
explicit contact_info(std::string sid);
7272

include/session/config/groups/info.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -239,8 +239,8 @@ class Info : public ConfigBase {
239239
/// the closed group history with a timestamp earlier than this value. Returns nullopt if no
240240
/// delete-before timestamp is set.
241241
///
242-
/// The given value is not checked for sanity (e.g. if you pass milliseconds it will be
243-
/// interpreted as deleting everything for the next 50000+ years). Be careful!
242+
/// The given value is checked for sanity (e.g. if you pass milliseconds it will be
243+
/// interpreted as such)
244244
///
245245
/// Inputs:
246246
/// - `timestamp` -- the new unix timestamp before which clients should delete messages. Pass 0
@@ -267,8 +267,8 @@ class Info : public ConfigBase {
267267
/// that) from any messages older than the given timestamp. Returns nullopt if no
268268
/// delete-attachments-before timestamp is set.
269269
///
270-
/// The given value is not checked for sanity (e.g. if you pass milliseconds it will be
271-
/// interpreted as deleting all attachments for the next 50000+ years). Be careful!
270+
/// The given value is checked for sanity (e.g. if you pass milliseconds it will be
271+
/// interpreted as such)
272272
///
273273
/// Inputs:
274274
/// - `timestamp` -- the new unix timestamp before which clients should delete attachments. Pass

include/session/config/user_groups.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ typedef struct ugroups_legacy_group_info {
3030
int64_t disappearing_timer; // Seconds. 0 == disabled.
3131
int priority; // pinned conversation priority; 0 = unpinned, negative = hidden, positive =
3232
// pinned (with higher meaning pinned higher).
33-
int64_t joined_at; // unix timestamp when joined (or re-joined)
33+
int64_t joined_at; // unix timestamp (seconds) when joined (or re-joined)
3434
CONVO_NOTIFY_MODE notifications; // When the user wants notifications
35-
int64_t mute_until; // Mute notifications until this timestamp (overrides `notifications`
36-
// setting until the timestamp)
35+
int64_t mute_until; // Mute notifications until this timestamp (seconds, overrides
36+
// `notifications` setting until the timestamp)
3737

3838
bool invited; // True if this is in the invite-but-not-accepted state.
3939

@@ -60,10 +60,10 @@ typedef struct ugroups_group_info {
6060

6161
int priority; // pinned conversation priority; 0 = unpinned, negative = hidden, positive =
6262
// pinned (with higher meaning pinned higher).
63-
int64_t joined_at; // unix timestamp when joined (or re-joined)
63+
int64_t joined_at; // unix timestamp (seconds) when joined (or re-joined)
6464
CONVO_NOTIFY_MODE notifications; // When the user wants notifications
65-
int64_t mute_until; // Mute notifications until this timestamp (overrides `notifications`
66-
// setting until the timestamp)
65+
int64_t mute_until; // Mute notifications until this timestamp (seconds, overrides
66+
// `notifications` setting until the timestamp)
6767

6868
bool invited; // True if this is in the invite-but-not-accepted state.
6969

@@ -81,10 +81,10 @@ typedef struct ugroups_community_info {
8181

8282
int priority; // pinned conversation priority; 0 = unpinned, negative = hidden, positive =
8383
// pinned (with higher meaning pinned higher).
84-
int64_t joined_at; // unix timestamp when joined (or re-joined)
84+
int64_t joined_at; // unix timestamp (seconds) when joined (or re-joined)
8585
CONVO_NOTIFY_MODE notifications; // When the user wants notifications
86-
int64_t mute_until; // Mute notifications until this timestamp (overrides `notifications`
87-
// setting until the timestamp)
86+
int64_t mute_until; // Mute notifications until this timestamp (seconds, overrides
87+
// `notifications` setting until the timestamp)
8888

8989
bool invited; // True if this is in the invite-but-not-accepted state.
9090

include/session/util.hpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ inline ustring_view to_unsigned_sv(std::basic_string_view<std::byte> v) {
6363
return {to_unsigned(v.data()), v.size()};
6464
}
6565
inline ustring_view to_unsigned_sv(ustring_view v) {
66-
return v; // no-op, but helps with template metaprogamming
66+
return v; // no-op, but helps with template metaprogramming
6767
}
6868
inline std::string_view from_unsigned_sv(ustring_view v) {
6969
return {from_unsigned(v.data()), v.size()};
@@ -81,10 +81,6 @@ inline std::basic_string_view<Char> to_sv(const std::array<Char, N>& v) {
8181
return {v.data(), N};
8282
}
8383

84-
inline uint64_t get_timestamp() {
85-
return std::chrono::steady_clock::now().time_since_epoch().count();
86-
}
87-
8884
/// Returns true if the first string is equal to the second string, compared case-insensitively.
8985
inline bool string_iequal(std::string_view s1, std::string_view s2) {
9086
return std::equal(s1.begin(), s1.end(), s2.begin(), s2.end(), [](char a, char b) {
@@ -215,4 +211,12 @@ inline std::string utf8_truncate(std::string val, size_t n) {
215211
return val;
216212
}
217213

214+
// Helper function to transform a timestamp provided in seconds, milliseconds or microseconds to
215+
// seconds
216+
inline int64_t to_epoch_seconds(int64_t timestamp) {
217+
return timestamp > 9'000'000'000'000 ? timestamp / 1'000'000
218+
: timestamp > 9'000'000'000 ? timestamp / 1'000
219+
: timestamp;
220+
}
221+
218222
} // namespace session

src/config/contacts.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ void contact_info::load(const dict& info_dict) {
9797
} else {
9898
notifications = notify_mode::defaulted;
9999
}
100-
mute_until = maybe_int(info_dict, "!").value_or(0);
100+
mute_until = to_epoch_seconds(maybe_int(info_dict, "!").value_or(0));
101101

102102
int exp_mode_ = maybe_int(info_dict, "e").value_or(0);
103103
if (exp_mode_ >= static_cast<int>(expiration_mode::none) &&
@@ -118,7 +118,7 @@ void contact_info::load(const dict& info_dict) {
118118
}
119119
}
120120

121-
created = maybe_int(info_dict, "j").value_or(0);
121+
created = to_epoch_seconds(maybe_int(info_dict, "j").value_or(0));
122122
}
123123

124124
void contact_info::into(contacts_contact& c) const {
@@ -136,12 +136,12 @@ void contact_info::into(contacts_contact& c) const {
136136
c.blocked = blocked;
137137
c.priority = priority;
138138
c.notifications = static_cast<CONVO_NOTIFY_MODE>(notifications);
139-
c.mute_until = mute_until;
139+
c.mute_until = to_epoch_seconds(mute_until);
140140
c.exp_mode = static_cast<CONVO_EXPIRATION_MODE>(exp_mode);
141141
c.exp_seconds = exp_timer.count();
142142
if (c.exp_seconds <= 0 && c.exp_mode != CONVO_EXPIRATION_NONE)
143143
c.exp_mode = CONVO_EXPIRATION_NONE;
144-
c.created = created;
144+
c.created = to_epoch_seconds(created);
145145
}
146146

147147
contact_info::contact_info(const contacts_contact& c) : session_id{c.session_id, 66} {
@@ -159,12 +159,12 @@ contact_info::contact_info(const contacts_contact& c) : session_id{c.session_id,
159159
blocked = c.blocked;
160160
priority = c.priority;
161161
notifications = static_cast<notify_mode>(c.notifications);
162-
mute_until = c.mute_until;
162+
mute_until = to_epoch_seconds(c.mute_until);
163163
exp_mode = static_cast<expiration_mode>(c.exp_mode);
164164
exp_timer = exp_mode == expiration_mode::none ? 0s : std::chrono::seconds{c.exp_seconds};
165165
if (exp_timer <= 0s && exp_mode != expiration_mode::none)
166166
exp_mode = expiration_mode::none;
167-
created = c.created;
167+
created = to_epoch_seconds(c.created);
168168
}
169169

170170
std::optional<contact_info> Contacts::get(std::string_view pubkey_hex) const {
@@ -237,7 +237,7 @@ void Contacts::set(const contact_info& contact) {
237237
if (notify == notify_mode::mentions_only)
238238
notify = notify_mode::all;
239239
set_positive_int(info["@"], static_cast<int>(notify));
240-
set_positive_int(info["!"], contact.mute_until);
240+
set_positive_int(info["!"], to_epoch_seconds(contact.mute_until));
241241

242242
set_pair_if(
243243
contact.exp_mode != expiration_mode::none && contact.exp_timer > 0s,
@@ -246,7 +246,7 @@ void Contacts::set(const contact_info& contact) {
246246
info["E"],
247247
contact.exp_timer.count());
248248

249-
set_positive_int(info["j"], contact.created);
249+
set_positive_int(info["j"], to_epoch_seconds(contact.created));
250250
}
251251

252252
LIBSESSION_C_API bool contacts_set(config_object* conf, const contacts_contact* contact) {
@@ -317,7 +317,7 @@ void Contacts::set_expiry(
317317

318318
void Contacts::set_created(std::string_view session_id, int64_t timestamp) {
319319
auto c = get_or_construct(session_id);
320-
c.created = timestamp;
320+
c.created = to_epoch_seconds(timestamp);
321321
set(c);
322322
}
323323

src/config/groups/info.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,32 +83,32 @@ void Info::set_expiry_timer(std::chrono::seconds expiration_timer) {
8383
}
8484

8585
void Info::set_created(int64_t timestamp) {
86-
set_positive_int(data["c"], timestamp);
86+
set_positive_int(data["c"], to_epoch_seconds(timestamp));
8787
}
8888

8989
std::optional<int64_t> Info::get_created() const {
9090
if (auto* ts = data["c"].integer())
91-
return *ts;
91+
return to_epoch_seconds(*ts);
9292
return std::nullopt;
9393
}
9494

9595
void Info::set_delete_before(int64_t timestamp) {
96-
set_positive_int(data["d"], timestamp);
96+
set_positive_int(data["d"], to_epoch_seconds(timestamp));
9797
}
9898

9999
std::optional<int64_t> Info::get_delete_before() const {
100100
if (auto* ts = data["d"].integer())
101-
return *ts;
101+
return to_epoch_seconds(*ts);
102102
return std::nullopt;
103103
}
104104

105105
void Info::set_delete_attach_before(int64_t timestamp) {
106-
set_positive_int(data["D"], timestamp);
106+
set_positive_int(data["D"], to_epoch_seconds(timestamp));
107107
}
108108

109109
std::optional<int64_t> Info::get_delete_attach_before() const {
110110
if (auto* ts = data["D"].integer())
111-
return *ts;
111+
return to_epoch_seconds(*ts);
112112
return std::nullopt;
113113
}
114114

src/config/user_groups.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,18 +36,18 @@ namespace session::config {
3636
template <typename T>
3737
static void base_into(const base_group_info& self, T& c) {
3838
c.priority = self.priority;
39-
c.joined_at = self.joined_at;
39+
c.joined_at = to_epoch_seconds(self.joined_at);
4040
c.notifications = static_cast<CONVO_NOTIFY_MODE>(self.notifications);
41-
c.mute_until = self.mute_until;
41+
c.mute_until = to_epoch_seconds(self.mute_until);
4242
c.invited = self.invited;
4343
}
4444

4545
template <typename T>
4646
static void base_from(base_group_info& self, const T& c) {
4747
self.priority = c.priority;
48-
self.joined_at = c.joined_at;
48+
self.joined_at = to_epoch_seconds(c.joined_at);
4949
self.notifications = static_cast<notify_mode>(c.notifications);
50-
self.mute_until = c.mute_until;
50+
self.mute_until = to_epoch_seconds(c.mute_until);
5151
self.invited = c.invited;
5252
}
5353

@@ -129,15 +129,15 @@ void legacy_group_info::into(ugroups_legacy_group_info& c) && {
129129

130130
void base_group_info::load(const dict& info_dict) {
131131
priority = maybe_int(info_dict, "+").value_or(0);
132-
joined_at = std::max<int64_t>(0, maybe_int(info_dict, "j").value_or(0));
132+
joined_at = to_epoch_seconds(std::max<int64_t>(0, maybe_int(info_dict, "j").value_or(0)));
133133

134134
int notify = maybe_int(info_dict, "@").value_or(0);
135135
if (notify >= 0 && notify <= 3)
136136
notifications = static_cast<notify_mode>(notify);
137137
else
138138
notifications = notify_mode::defaulted;
139139

140-
mute_until = maybe_int(info_dict, "!").value_or(0);
140+
mute_until = to_epoch_seconds(maybe_int(info_dict, "!").value_or(0));
141141

142142
invited = maybe_int(info_dict, "i").value_or(0);
143143
}
@@ -407,9 +407,9 @@ void UserGroups::set(const community_info& c) {
407407

408408
void UserGroups::set_base(const base_group_info& bg, DictFieldProxy& info) const {
409409
set_nonzero_int(info["+"], bg.priority);
410-
set_positive_int(info["j"], bg.joined_at);
410+
set_positive_int(info["j"], to_epoch_seconds(bg.joined_at));
411411
set_positive_int(info["@"], static_cast<int>(bg.notifications));
412-
set_positive_int(info["!"], bg.mute_until);
412+
set_positive_int(info["!"], to_epoch_seconds(bg.mute_until));
413413
set_flag(info["i"], bg.invited);
414414
// We don't set n here because it's subtly different in the three group types
415415
}

tests/test_config_contacts.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@ TEST_CASE("Contacts", "[config][contacts]") {
6565
c.set_nickname("Joey");
6666
c.approved = true;
6767
c.approved_me = true;
68-
c.created = created_ts;
68+
c.created = created_ts * 1'000;
6969
c.notifications = session::config::notify_mode::all;
70-
c.mute_until = now + 1800;
70+
c.mute_until = (now + 1800) * 1'000'000;
7171

7272
contacts.set(c);
7373

0 commit comments

Comments
 (0)