* [PATCH v3 1/2] libuuid: Refactor UUID time conversion for pre-epoch dates
2025-12-16 23:21 ` Thomas Weißschuh
@ 2025-12-17 20:42 ` Kiran Rangoon
2025-12-17 20:59 ` Kiran Rangoon
2025-12-18 21:31 ` Kiran Rangoon
2 siblings, 0 replies; 19+ messages in thread
From: Kiran Rangoon @ 2025-12-17 20:42 UTC (permalink / raw)
To: util-linux; +Cc: thomas, Kiran Rangoon
I revised the code in response to your feedback.
> Looking at this more closely: __uuid_time() is directly exposed to users
> of libuuid as uuid_time(). This means that any change of the function's
> contract would break all external users and should be avoided at all
> costs.
Reversed the change there.
> Fortunately it turns out that the timestamps embedded in UUIDs
> only use 60 bits. This means that the calculation can be performed in an
> int64_t without any risk of over- or underflow. Please try to implement
> it that way instead.
I'm using signed int64_t here as suggested.
> It might be useful to change the signature of gregorian_to_unix() to
> "static void gregorian_to_unix(uint64_t ts, struct timeval *tv)".
I revised the code to use a struct timeval now.
> Also please perform each logical step in a dedicated commit.
I made two commits, one for the code change and the other for tests, but
if there is a way you would perfer me to do it I could change it.
---
libuuid/src/uuid_time.c | 25 +++++++++----------------
1 file changed, 9 insertions(+), 16 deletions(-)
diff --git a/libuuid/src/uuid_time.c b/libuuid/src/uuid_time.c
index f0d2c8f36..293fc7e68 100644
--- a/libuuid/src/uuid_time.c
+++ b/libuuid/src/uuid_time.c
@@ -60,34 +60,29 @@
/* prototype to make compiler happy */
time_t __uuid_time(const uuid_t uu, struct timeval *ret_tv);
-static int64_t gregorian_to_unix(uint64_t ts)
+static void gregorian_to_unix(uint64_t ts, struct timeval *tv)
{
- const uint64_t offset = 0x01B21DD213814000ULL;
+ const uint64_t offset = 0x01B21DD213814000ULL;
+ int64_t t = (int64_t) ts - (int64_t) offset;
- if (ts < offset) {
- errno = EOVERFLOW;
- return -1;
- }
-
- return ts - offset;
+ tv->tv_sec = t / 10000000;
+ tv->tv_usec = (t % 10000000) / 10;
}
static void uuid_time_v1(const struct uuid *uuid, struct timeval *tv)
{
uint32_t high;
- int64_t clock_reg;
+ uint64_t clock_reg;
high = uuid->time_mid | ((uuid->time_hi_and_version & 0xFFF) << 16);
clock_reg = uuid->time_low | ((uint64_t) high << 32);
- clock_reg = gregorian_to_unix(clock_reg);
- tv->tv_sec = clock_reg / 10000000;
- tv->tv_usec = (clock_reg % 10000000) / 10;
+ gregorian_to_unix(clock_reg, tv);
}
static void uuid_time_v6(const struct uuid *uuid, struct timeval *tv)
{
- int64_t clock_reg;
+ uint64_t clock_reg;
clock_reg = uuid->time_low;
clock_reg <<= 16;
@@ -95,9 +90,7 @@ static void uuid_time_v6(const struct uuid *uuid, struct timeval *tv)
clock_reg <<= 12;
clock_reg |= uuid->time_hi_and_version & 0xFFF;
- clock_reg = gregorian_to_unix(clock_reg);
- tv->tv_sec = clock_reg / 10000000;
- tv->tv_usec = (clock_reg % 10000000) / 10;
+ gregorian_to_unix(clock_reg, tv);
}
static void uuid_time_v7(const struct uuid *uuid, struct timeval *tv)
--
2.47.3
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH v3 1/2] libuuid: Refactor UUID time conversion for pre-epoch dates
2025-12-16 23:21 ` Thomas Weißschuh
2025-12-17 20:42 ` [PATCH v3 1/2] libuuid: Refactor UUID time conversion for pre-epoch dates Kiran Rangoon
@ 2025-12-17 20:59 ` Kiran Rangoon
2025-12-18 21:31 ` Kiran Rangoon
2 siblings, 0 replies; 19+ messages in thread
From: Kiran Rangoon @ 2025-12-17 20:59 UTC (permalink / raw)
To: util-linux; +Cc: thomas, Kiran Rangoon
I revised the code in response to your feedback.
> Looking at this more closely: __uuid_time() is directly exposed to users
> of libuuid as uuid_time(). This means that any change of the function's
> contract would break all external users and should be avoided at all
> costs.
Reversed the change there.
> Fortunately it turns out that the timestamps embedded in UUIDs
> only use 60 bits. This means that the calculation can be performed in an
> int64_t without any risk of over- or underflow. Please try to implement
> it that way instead.
I'm using signed int64_t here as suggested.
> It might be useful to change the signature of gregorian_to_unix() to
> "static void gregorian_to_unix(uint64_t ts, struct timeval *tv)".
I revised the code to use a struct timeval now.
> Also please perform each logical step in a dedicated commit.
I made two commits, one for the code change and the other for tests, but
if there is a way you would perfer me to do it I could change it.
---
libuuid/src/uuid_time.c | 25 +++++++++----------------
1 file changed, 9 insertions(+), 16 deletions(-)
diff --git a/libuuid/src/uuid_time.c b/libuuid/src/uuid_time.c
index f0d2c8f36..293fc7e68 100644
--- a/libuuid/src/uuid_time.c
+++ b/libuuid/src/uuid_time.c
@@ -60,34 +60,29 @@
/* prototype to make compiler happy */
time_t __uuid_time(const uuid_t uu, struct timeval *ret_tv);
-static int64_t gregorian_to_unix(uint64_t ts)
+static void gregorian_to_unix(uint64_t ts, struct timeval *tv)
{
- const uint64_t offset = 0x01B21DD213814000ULL;
+ const uint64_t offset = 0x01B21DD213814000ULL;
+ int64_t t = (int64_t) ts - (int64_t) offset;
- if (ts < offset) {
- errno = EOVERFLOW;
- return -1;
- }
-
- return ts - offset;
+ tv->tv_sec = t / 10000000;
+ tv->tv_usec = (t % 10000000) / 10;
}
static void uuid_time_v1(const struct uuid *uuid, struct timeval *tv)
{
uint32_t high;
- int64_t clock_reg;
+ uint64_t clock_reg;
high = uuid->time_mid | ((uuid->time_hi_and_version & 0xFFF) << 16);
clock_reg = uuid->time_low | ((uint64_t) high << 32);
- clock_reg = gregorian_to_unix(clock_reg);
- tv->tv_sec = clock_reg / 10000000;
- tv->tv_usec = (clock_reg % 10000000) / 10;
+ gregorian_to_unix(clock_reg, tv);
}
static void uuid_time_v6(const struct uuid *uuid, struct timeval *tv)
{
- int64_t clock_reg;
+ uint64_t clock_reg;
clock_reg = uuid->time_low;
clock_reg <<= 16;
@@ -95,9 +90,7 @@ static void uuid_time_v6(const struct uuid *uuid, struct timeval *tv)
clock_reg <<= 12;
clock_reg |= uuid->time_hi_and_version & 0xFFF;
- clock_reg = gregorian_to_unix(clock_reg);
- tv->tv_sec = clock_reg / 10000000;
- tv->tv_usec = (clock_reg % 10000000) / 10;
+ gregorian_to_unix(clock_reg, tv);
}
static void uuid_time_v7(const struct uuid *uuid, struct timeval *tv)
--
2.47.3
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH v3 1/2] libuuid: Refactor UUID time conversion for pre-epoch dates
2025-12-16 23:21 ` Thomas Weißschuh
2025-12-17 20:42 ` [PATCH v3 1/2] libuuid: Refactor UUID time conversion for pre-epoch dates Kiran Rangoon
2025-12-17 20:59 ` Kiran Rangoon
@ 2025-12-18 21:31 ` Kiran Rangoon
2025-12-19 11:40 ` Thomas Weißschuh
2 siblings, 1 reply; 19+ messages in thread
From: Kiran Rangoon @ 2025-12-18 21:31 UTC (permalink / raw)
To: util-linux; +Cc: thomas, Kiran Rangoon
I revised the code in response to your feedback.
> Looking at this more closely: __uuid_time() is directly exposed to users
> of libuuid as uuid_time(). This means that any change of the function's
> contract would break all external users and should be avoided at all
> costs.
Reversed the change there.
> Fortunately it turns out that the timestamps embedded in UUIDs
> only use 60 bits. This means that the calculation can be performed in an
> int64_t without any risk of over- or underflow. Please try to implement
> it that way instead.
I'm using signed int64_t here as suggested.
> It might be useful to change the signature of gregorian_to_unix() to
> "static void gregorian_to_unix(uint64_t ts, struct timeval *tv)".
I revised the code to use a struct timeval now.
> Also please perform each logical step in a dedicated commit.
I made two commits, one for the code change and the other for tests, but
if there is a way you would perfer me to do it I could change it.
---
libuuid/src/uuid_time.c | 25 +++++++++----------------
1 file changed, 9 insertions(+), 16 deletions(-)
diff --git a/libuuid/src/uuid_time.c b/libuuid/src/uuid_time.c
index f0d2c8f36..293fc7e68 100644
--- a/libuuid/src/uuid_time.c
+++ b/libuuid/src/uuid_time.c
@@ -60,34 +60,29 @@
/* prototype to make compiler happy */
time_t __uuid_time(const uuid_t uu, struct timeval *ret_tv);
-static int64_t gregorian_to_unix(uint64_t ts)
+static void gregorian_to_unix(uint64_t ts, struct timeval *tv)
{
- const uint64_t offset = 0x01B21DD213814000ULL;
+ const uint64_t offset = 0x01B21DD213814000ULL;
+ int64_t t = (int64_t) ts - (int64_t) offset;
- if (ts < offset) {
- errno = EOVERFLOW;
- return -1;
- }
-
- return ts - offset;
+ tv->tv_sec = t / 10000000;
+ tv->tv_usec = (t % 10000000) / 10;
}
static void uuid_time_v1(const struct uuid *uuid, struct timeval *tv)
{
uint32_t high;
- int64_t clock_reg;
+ uint64_t clock_reg;
high = uuid->time_mid | ((uuid->time_hi_and_version & 0xFFF) << 16);
clock_reg = uuid->time_low | ((uint64_t) high << 32);
- clock_reg = gregorian_to_unix(clock_reg);
- tv->tv_sec = clock_reg / 10000000;
- tv->tv_usec = (clock_reg % 10000000) / 10;
+ gregorian_to_unix(clock_reg, tv);
}
static void uuid_time_v6(const struct uuid *uuid, struct timeval *tv)
{
- int64_t clock_reg;
+ uint64_t clock_reg;
clock_reg = uuid->time_low;
clock_reg <<= 16;
@@ -95,9 +90,7 @@ static void uuid_time_v6(const struct uuid *uuid, struct timeval *tv)
clock_reg <<= 12;
clock_reg |= uuid->time_hi_and_version & 0xFFF;
- clock_reg = gregorian_to_unix(clock_reg);
- tv->tv_sec = clock_reg / 10000000;
- tv->tv_usec = (clock_reg % 10000000) / 10;
+ gregorian_to_unix(clock_reg, tv);
}
static void uuid_time_v7(const struct uuid *uuid, struct timeval *tv)
--
2.47.3
^ permalink raw reply related [flat|nested] 19+ messages in thread* Re: [PATCH v3 1/2] libuuid: Refactor UUID time conversion for pre-epoch dates
2025-12-18 21:31 ` Kiran Rangoon
@ 2025-12-19 11:40 ` Thomas Weißschuh
2025-12-23 18:00 ` [PATCH v4 0/4] libuuid: Fix pre-1970 UUID timestamp overflow Kiran Rangoon
` (2 more replies)
0 siblings, 3 replies; 19+ messages in thread
From: Thomas Weißschuh @ 2025-12-19 11:40 UTC (permalink / raw)
To: Kiran Rangoon; +Cc: util-linux
Hi Kiran,
On 2025-12-18 16:31:21-0500, Kiran Rangoon wrote:
> I revised the code in response to your feedback.
Thanks!
> > Looking at this more closely: __uuid_time() is directly exposed to users
> > of libuuid as uuid_time(). This means that any change of the function's
> > contract would break all external users and should be avoided at all
> > costs.
>
> Reversed the change there.
Your new revision is based on top of your old series.
Instead it should always be based on upstream code.
In this case the util-linux master branch.
> > Fortunately it turns out that the timestamps embedded in UUIDs
> > only use 60 bits. This means that the calculation can be performed in an
> > int64_t without any risk of over- or underflow. Please try to implement
> > it that way instead.
>
> I'm using signed int64_t here as suggested.
>
> > It might be useful to change the signature of gregorian_to_unix() to
> > "static void gregorian_to_unix(uint64_t ts, struct timeval *tv)".
>
> I revised the code to use a struct timeval now.
That looks good. However that refactoring should be in its own commit.
More on that below.
> > Also please perform each logical step in a dedicated commit.
>
> I made two commits, one for the code change and the other for tests, but
> if there is a way you would perfer me to do it I could change it.
The test is a bad candidate to split out. After each commit the
repository needs to be in a consistent state, which means that the code
builds and the tests pass. As the code change breaks the existing test,
the test needs to be adapted in lockstep.
I see the following commits:
1) Switch to the simpler constant definition
2) Pass 'struct timeval' to gregorian_to_unix()
3) Fix the overflow, adapt the existing test
4) Add a hand full of additional testcases.
Also this patch now lost its useful commit message which got replaced by
our discussion. This should not happen. Each commit should explain why
it is being done.
> ---
> libuuid/src/uuid_time.c | 25 +++++++++----------------
> 1 file changed, 9 insertions(+), 16 deletions(-)
>
> diff --git a/libuuid/src/uuid_time.c b/libuuid/src/uuid_time.c
> index f0d2c8f36..293fc7e68 100644
> --- a/libuuid/src/uuid_time.c
> +++ b/libuuid/src/uuid_time.c
> @@ -60,34 +60,29 @@
> /* prototype to make compiler happy */
> time_t __uuid_time(const uuid_t uu, struct timeval *ret_tv);
>
> -static int64_t gregorian_to_unix(uint64_t ts)
> +static void gregorian_to_unix(uint64_t ts, struct timeval *tv)
> {
> - const uint64_t offset = 0x01B21DD213814000ULL;
> + const uint64_t offset = 0x01B21DD213814000ULL;
> + int64_t t = (int64_t) ts - (int64_t) offset;
Whitespace corruption?
> - if (ts < offset) {
> - errno = EOVERFLOW;
> - return -1;
> - }
> -
> - return ts - offset;
> + tv->tv_sec = t / 10000000;
> + tv->tv_usec = (t % 10000000) / 10;
> }
(...)
Thomas
^ permalink raw reply [flat|nested] 19+ messages in thread* [PATCH v4 0/4] libuuid: Fix pre-1970 UUID timestamp overflow
2025-12-19 11:40 ` Thomas Weißschuh
@ 2025-12-23 18:00 ` Kiran Rangoon
2025-12-23 18:00 ` [PATCH v4 1/4] libuuid: simplify gregorian-to-unix offset calculation Kiran Rangoon
` (4 more replies)
2025-12-23 18:04 ` [PATCH v4 3/4] libuuid: fix timestamp overflow for pre-1970 dates Kiran Rangoon
2025-12-23 18:05 ` [PATCH v4 4/4] tests: correct UUID timestamp test expectations Kiran Rangoon
2 siblings, 5 replies; 19+ messages in thread
From: Kiran Rangoon @ 2025-12-23 18:00 UTC (permalink / raw)
To: util-linux; +Cc: thomas, Kiran Rangoon
> On 2025-12-18 16:31:21-0500, Kiran Rangoon wrote:
> > I revised the code in response to your feedback.
> Thanks!
> > > Looking at this more closely: __uuid_time() is directly exposed to users
> > > of libuuid as uuid_time(). This means that any change of the function's
> > > contract would break all external users and should be avoided at all
> > > costs.
> >
> > Reversed the change there.
>
> Your new revision is based on top of your old series.
> Instead it should always be based on upstream code.
> In this case the util-linux master branch.
Fixed in v4: I rebased directly on origin/master instead of building
on my previous patch series.
>
> > > Fortunately it turns out that the timestamps embedded in UUIDs
> > > only use 60 bits. This means that the calculation can be performed in an
> > > int64_t without any risk of over- or underflow. Please try to implement
> > > it that way instead.
> >
> > I'm using signed int64_t here as suggested.
> >
> > > It might be useful to change the signature of gregorian_to_unix() to
> > > "static void gregorian_to_unix(uint64_t ts, struct timeval *tv)".
> >
> > I revised the code to use a struct timeval now.
>
> That looks good. However that refactoring should be in its own commit.
> More on that below.
Fixed in v4: The refactoring is now in its own dedicated commit (patch 2/4).
>
> > > Also please perform each logical step in a dedicated commit.
> >
> > > I made two commits, one for the code change and the other for tests, but
> > > if there is a way you would perfer me to do it I could change it.
> >
> The test is a bad candidate to split out. After each commit the
> repository needs to be in a consistent state, which means that the code
> builds and the tests pass. As the code change breaks the existing test,
> the test needs to be adapted in lockstep.
Understood. In v4, the test updates are included with the code changes
that require them, maintaining repository consistency at each commit.
>
> I see the following commits:
>
> 1) Switch to the simpler constant definition
> 2) Pass 'struct timeval' to gregorian_to_unix()
> 3) Fix the overflow, adapt the existing test
> 4) Add a hand full of additional testcases.
Implemented exactly as suggested in v4.
> Also this patch now lost its useful commit message which got replaced by
> our discussion. This should not happen. Each commit should explain why
> it is being done.
Fixed in v4: All commits now have proper descriptive messages explaining
the rationale for each change.
>
> > + const uint64_t offset = 0x01B21DD213814000ULL;
> > + int64_t t = (int64_t) ts - (int64_t) offset;
>
> Whitespace corruption?
Fixed in v4: Proper tab indentation is used throughout.
---
This v4 patch series addresses all the feedback points above:
Kiran Rangoon (4):
libuuid: simplify gregorian-to-unix offset calculation
libuuid: refactor gregorian_to_unix to populate timeval directly
libuuid: fix timestamp overflow for pre-1970 dates
tests: correct UUID timestamp test expectations
libuuid/src/uuid_time.c | 15 +++++++--------
tests/expected/uuid/uuidparse | 5 ++++-
tests/ts/uuid/uuidparse | 3 +++
3 files changed, 14 insertions(+), 9 deletions(-)
--
2.47.3
^ permalink raw reply [flat|nested] 19+ messages in thread* [PATCH v4 1/4] libuuid: simplify gregorian-to-unix offset calculation
2025-12-23 18:00 ` [PATCH v4 0/4] libuuid: Fix pre-1970 UUID timestamp overflow Kiran Rangoon
@ 2025-12-23 18:00 ` Kiran Rangoon
2025-12-23 18:00 ` [PATCH v4 2/4] libuuid: refactor gregorian_to_unix to populate timeval directly Kiran Rangoon
` (3 subsequent siblings)
4 siblings, 0 replies; 19+ messages in thread
From: Kiran Rangoon @ 2025-12-23 18:00 UTC (permalink / raw)
To: util-linux; +Cc: thomas, Kiran Rangoon
Replace complex bit-shift offset calculation with a simple constant
definition for better readability and maintainability.
Signed-off-by: Kiran Rangoon <kiranrangoon0@gmail.com>
---
libuuid/src/uuid_time.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libuuid/src/uuid_time.c b/libuuid/src/uuid_time.c
index c7516152b..e2b991d74 100644
--- a/libuuid/src/uuid_time.c
+++ b/libuuid/src/uuid_time.c
@@ -62,7 +62,8 @@ time_t __uuid_time(const uuid_t uu, struct timeval *ret_tv);
static uint64_t gregorian_to_unix(uint64_t ts)
{
- return ts - ((((uint64_t) 0x01B21DD2) << 32) + 0x13814000);
+ const uint64_t offset = 0x01B21DD213814000ULL;
+ return ts - offset;
}
static void uuid_time_v1(const struct uuid *uuid, struct timeval *tv)
--
2.47.3
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH v4 2/4] libuuid: refactor gregorian_to_unix to populate timeval directly
2025-12-23 18:00 ` [PATCH v4 0/4] libuuid: Fix pre-1970 UUID timestamp overflow Kiran Rangoon
2025-12-23 18:00 ` [PATCH v4 1/4] libuuid: simplify gregorian-to-unix offset calculation Kiran Rangoon
@ 2025-12-23 18:00 ` Kiran Rangoon
2025-12-23 18:03 ` [PATCH v4 1/4] libuuid: simplify gregorian-to-unix offset calculation Kiran Rangoon
` (2 subsequent siblings)
4 siblings, 0 replies; 19+ messages in thread
From: Kiran Rangoon @ 2025-12-23 18:00 UTC (permalink / raw)
To: util-linux; +Cc: thomas, Kiran Rangoon
Change function signature to take struct timeval pointer and populate
it directly, eliminating duplicate conversion code in callers.
Signed-off-by: Kiran Rangoon <kiranrangoon0@gmail.com>
---
libuuid/src/uuid_time.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/libuuid/src/uuid_time.c b/libuuid/src/uuid_time.c
index e2b991d74..2f7c6652c 100644
--- a/libuuid/src/uuid_time.c
+++ b/libuuid/src/uuid_time.c
@@ -60,10 +60,12 @@
/* prototype to make compiler happy */
time_t __uuid_time(const uuid_t uu, struct timeval *ret_tv);
-static uint64_t gregorian_to_unix(uint64_t ts)
+static void gregorian_to_unix(uint64_t ts, struct timeval *tv)
{
const uint64_t offset = 0x01B21DD213814000ULL;
- return ts - offset;
+ uint64_t clock_reg = ts - offset;
+ tv->tv_sec = clock_reg / 10000000;
+ tv->tv_usec = (clock_reg % 10000000) / 10;
}
static void uuid_time_v1(const struct uuid *uuid, struct timeval *tv)
@@ -74,9 +76,7 @@ static void uuid_time_v1(const struct uuid *uuid, struct timeval *tv)
high = uuid->time_mid | ((uuid->time_hi_and_version & 0xFFF) << 16);
clock_reg = uuid->time_low | ((uint64_t) high << 32);
- clock_reg = gregorian_to_unix(clock_reg);
- tv->tv_sec = clock_reg / 10000000;
- tv->tv_usec = (clock_reg % 10000000) / 10;
+ gregorian_to_unix(clock_reg, tv);
}
static void uuid_time_v6(const struct uuid *uuid, struct timeval *tv)
@@ -89,9 +89,7 @@ static void uuid_time_v6(const struct uuid *uuid, struct timeval *tv)
clock_reg <<= 12;
clock_reg |= uuid->time_hi_and_version & 0xFFF;
- clock_reg = gregorian_to_unix(clock_reg);
- tv->tv_sec = clock_reg / 10000000;
- tv->tv_usec = (clock_reg % 10000000) / 10;
+ gregorian_to_unix(clock_reg, tv);
}
static void uuid_time_v7(const struct uuid *uuid, struct timeval *tv)
--
2.47.3
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH v4 1/4] libuuid: simplify gregorian-to-unix offset calculation
2025-12-23 18:00 ` [PATCH v4 0/4] libuuid: Fix pre-1970 UUID timestamp overflow Kiran Rangoon
2025-12-23 18:00 ` [PATCH v4 1/4] libuuid: simplify gregorian-to-unix offset calculation Kiran Rangoon
2025-12-23 18:00 ` [PATCH v4 2/4] libuuid: refactor gregorian_to_unix to populate timeval directly Kiran Rangoon
@ 2025-12-23 18:03 ` Kiran Rangoon
2025-12-23 18:22 ` [PATCH v4 0/4] libuuid: Fix pre-1970 UUID timestamp overflow Thomas Weißschuh
2025-12-28 8:47 ` Thomas Weißschuh
4 siblings, 0 replies; 19+ messages in thread
From: Kiran Rangoon @ 2025-12-23 18:03 UTC (permalink / raw)
To: util-linux; +Cc: thomas, Kiran Rangoon
Replace complex bit-shift offset calculation with a simple constant
definition for better readability and maintainability.
Signed-off-by: Kiran Rangoon <kiranrangoon0@gmail.com>
---
libuuid/src/uuid_time.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libuuid/src/uuid_time.c b/libuuid/src/uuid_time.c
index c7516152b..e2b991d74 100644
--- a/libuuid/src/uuid_time.c
+++ b/libuuid/src/uuid_time.c
@@ -62,7 +62,8 @@ time_t __uuid_time(const uuid_t uu, struct timeval *ret_tv);
static uint64_t gregorian_to_unix(uint64_t ts)
{
- return ts - ((((uint64_t) 0x01B21DD2) << 32) + 0x13814000);
+ const uint64_t offset = 0x01B21DD213814000ULL;
+ return ts - offset;
}
static void uuid_time_v1(const struct uuid *uuid, struct timeval *tv)
--
2.47.3
^ permalink raw reply related [flat|nested] 19+ messages in thread* Re: [PATCH v4 0/4] libuuid: Fix pre-1970 UUID timestamp overflow
2025-12-23 18:00 ` [PATCH v4 0/4] libuuid: Fix pre-1970 UUID timestamp overflow Kiran Rangoon
` (2 preceding siblings ...)
2025-12-23 18:03 ` [PATCH v4 1/4] libuuid: simplify gregorian-to-unix offset calculation Kiran Rangoon
@ 2025-12-23 18:22 ` Thomas Weißschuh
2025-12-28 8:47 ` Thomas Weißschuh
4 siblings, 0 replies; 19+ messages in thread
From: Thomas Weißschuh @ 2025-12-23 18:22 UTC (permalink / raw)
To: Kiran Rangoon; +Cc: util-linux
Dec 23, 2025 19:01:03 Kiran Rangoon <kiranrangoon0@gmail.com>:
(...)
>> > This v4 patch series addresses all the feedback points above:
>
> Kiran Rangoon (4):
> libuuid: simplify gregorian-to-unix offset calculation
> libuuid: refactor gregorian_to_unix to populate timeval directly
> libuuid: fix timestamp overflow for pre-1970 dates
> tests: correct UUID timestamp test expectations
>
> libuuid/src/uuid_time.c | 15 +++++++--------
> tests/expected/uuid/uuidparse | 5 ++++-
> tests/ts/uuid/uuidparse | 3 +++
> 3 files changed, 14 insertions(+), 9 deletions(-)
Thanks!
For the series, given it passes CI:
Reviewed-by: Thomas Weißschuh <thomas@t-8ch.de>
^ permalink raw reply [flat|nested] 19+ messages in thread* Re: [PATCH v4 0/4] libuuid: Fix pre-1970 UUID timestamp overflow
2025-12-23 18:00 ` [PATCH v4 0/4] libuuid: Fix pre-1970 UUID timestamp overflow Kiran Rangoon
` (3 preceding siblings ...)
2025-12-23 18:22 ` [PATCH v4 0/4] libuuid: Fix pre-1970 UUID timestamp overflow Thomas Weißschuh
@ 2025-12-28 8:47 ` Thomas Weißschuh
4 siblings, 0 replies; 19+ messages in thread
From: Thomas Weißschuh @ 2025-12-28 8:47 UTC (permalink / raw)
To: Kiran Rangoon; +Cc: util-linux
Hi Kiran,
On 2025-12-23 13:00:51-0500, Kiran Rangoon wrote:
(...)
> Kiran Rangoon (4):
> libuuid: simplify gregorian-to-unix offset calculation
> libuuid: refactor gregorian_to_unix to populate timeval directly
> libuuid: fix timestamp overflow for pre-1970 dates
> tests: correct UUID timestamp test expectations
>
> libuuid/src/uuid_time.c | 15 +++++++--------
> tests/expected/uuid/uuidparse | 5 ++++-
> tests/ts/uuid/uuidparse | 3 +++
> 3 files changed, 14 insertions(+), 9 deletions(-)
The series can't be applied as is. There are two 'PATCH 1/4' and the
'In-Reply-To' headers are broken. How did you send the patches?
Please just use 'git send-email' or 'b4' [0].
Also don't make your v5 a reply to the v4, it makes things messy.
Just start a new thread.
Thomas
[0] https://b4.docs.kernel.org/en/latest/
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v4 3/4] libuuid: fix timestamp overflow for pre-1970 dates
2025-12-19 11:40 ` Thomas Weißschuh
2025-12-23 18:00 ` [PATCH v4 0/4] libuuid: Fix pre-1970 UUID timestamp overflow Kiran Rangoon
@ 2025-12-23 18:04 ` Kiran Rangoon
2025-12-23 18:05 ` [PATCH v4 4/4] tests: correct UUID timestamp test expectations Kiran Rangoon
2 siblings, 0 replies; 19+ messages in thread
From: Kiran Rangoon @ 2025-12-23 18:04 UTC (permalink / raw)
To: util-linux; +Cc: thomas, Kiran Rangoon
Use int64_t arithmetic to correctly handle timestamps before Unix epoch.
This fixes the overflow that was causing UUID timestamps from 1582 to
appear as far-future dates. Update test expectations accordingly.
Signed-off-by: Kiran Rangoon <kiranrangoon0@gmail.com>
---
libuuid/src/uuid_time.c | 2 +-
tests/expected/uuid/uuidparse | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/libuuid/src/uuid_time.c b/libuuid/src/uuid_time.c
index 2f7c6652c..63179fd76 100644
--- a/libuuid/src/uuid_time.c
+++ b/libuuid/src/uuid_time.c
@@ -63,7 +63,7 @@ time_t __uuid_time(const uuid_t uu, struct timeval *ret_tv);
static void gregorian_to_unix(uint64_t ts, struct timeval *tv)
{
const uint64_t offset = 0x01B21DD213814000ULL;
- uint64_t clock_reg = ts - offset;
+ int64_t clock_reg = (int64_t)(ts - offset);
tv->tv_sec = clock_reg / 10000000;
tv->tv_usec = (clock_reg % 10000000) / 10;
}
diff --git a/tests/expected/uuid/uuidparse b/tests/expected/uuid/uuidparse
index 9edb05e4e..e44964b30 100644
--- a/tests/expected/uuid/uuidparse
+++ b/tests/expected/uuid/uuidparse
@@ -11,7 +11,7 @@ UUID VARIANT TYPE TIME
00000000-0000-3000-8000-000000000000 DCE name-based
00000000-0000-4000-8000-000000000000 DCE random
00000000-0000-5000-8000-000000000000 DCE sha1-based
-00000000-0000-6000-8000-000000000000 DCE time-v6 60038-03-11 05:36:10,955161+00:00
+00000000-0000-6000-8000-000000000000 DCE time-v6 1582-10-15 00:00:00,000000+00:00
00000000-0000-0000-d000-000000000000 Microsoft
00000000-0000-1000-d000-000000000000 Microsoft
00000000-0000-2000-d000-000000000000 Microsoft
--
2.47.3
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH v4 4/4] tests: correct UUID timestamp test expectations
2025-12-19 11:40 ` Thomas Weißschuh
2025-12-23 18:00 ` [PATCH v4 0/4] libuuid: Fix pre-1970 UUID timestamp overflow Kiran Rangoon
2025-12-23 18:04 ` [PATCH v4 3/4] libuuid: fix timestamp overflow for pre-1970 dates Kiran Rangoon
@ 2025-12-23 18:05 ` Kiran Rangoon
2 siblings, 0 replies; 19+ messages in thread
From: Kiran Rangoon @ 2025-12-23 18:05 UTC (permalink / raw)
To: util-linux; +Cc: thomas, Kiran Rangoon
Update expected timestamps for additional test UUIDs to match actual
output. These test cases provide coverage for various timestamp ranges
including pre-epoch, historical, and far-future dates.
Signed-off-by: Kiran Rangoon <kiranrangoon0@gmail.com>
---
tests/expected/uuid/uuidparse | 3 +++
tests/ts/uuid/uuidparse | 3 +++
2 files changed, 6 insertions(+)
diff --git a/tests/expected/uuid/uuidparse b/tests/expected/uuid/uuidparse
index e44964b30..61b49ef66 100644
--- a/tests/expected/uuid/uuidparse
+++ b/tests/expected/uuid/uuidparse
@@ -29,6 +29,9 @@ UUID VARIANT TYPE TIME
9b274c46-544a-11e7-a972-00037f500001 DCE time-based 2017-06-18 17:21:46,544647+00:00
1ec9414c-232a-6b00-b3c8-9f6bdeced846 DCE time-v6 2022-02-22 19:22:22,000000+00:00
017f22e2-79b2-7cc3-98c4-dc0c0c07398f DCE time-v7 2022-02-22 19:22:22,002000+00:00
+bf2eb110-d788-1003-aa59-ce1e9e293641 DCE time-based 1586-03-19 15:05:26,3611398+00:00
+f81d4fae-7dec-11d0-a765-00a0c91e6bf6 DCE time-based 1997-02-03 17:43:12,216875+00:00
+01234567-89ab-1def-8000-123456789abc DCE time-based 4764-11-18 19:35:47,841162+00:00
5c146b14-3c52-8afd-938a-375d0df1fbf6 DCE vendor
invalid-input invalid invalid invalid
return value: 0
diff --git a/tests/ts/uuid/uuidparse b/tests/ts/uuid/uuidparse
index 2903ce56d..f131986ba 100755
--- a/tests/ts/uuid/uuidparse
+++ b/tests/ts/uuid/uuidparse
@@ -56,6 +56,9 @@ echo '00000000-0000-0000-0000-000000000000
9b274c46-544a-11e7-a972-00037f500001
1ec9414c-232a-6b00-b3c8-9f6bdeced846
017f22e2-79b2-7cc3-98c4-dc0c0c07398f
+bf2eb110-d788-1003-aa59-ce1e9e293641
+f81d4fae-7dec-11d0-a765-00a0c91e6bf6
+01234567-89ab-1def-8000-123456789abc
5c146b14-3c52-8afd-938a-375d0df1fbf6
invalid-input' | $TS_CMD_UUIDPARSE >> $TS_OUTPUT 2>> $TS_ERRLOG
--
2.47.3
^ permalink raw reply related [flat|nested] 19+ messages in thread