rmyorston / busybox-w32

WIN32 native port of BusyBox.
https://frippery.org/busybox
Other
697 stars 126 forks source link

Y2038 support #446

Closed ale5000-git closed 3 months ago

ale5000-git commented 3 months ago

This seems to be not supported: date -s "2038-01-19 03:14:10"

Is it possible to support it?

avih commented 3 months ago

Seems to work in 64 bit build.

ale5000-git commented 3 months ago

64-bit builds usually never had these date problems (even in other apps) because they have 64-bit data types. The one that need the fix is the 32-bit build.

avih commented 3 months ago

64-bit builds usually never had these date problems

Then next time mention the info you have when you report the issue, because you didn't say "only 32 bits builds". It's important info to have and it can save time when trying to fix it.

ale5000-git commented 3 months ago

It just came to my minds after your reply and it reminded me a similar issue in 32-bit PHP in the past.

rmyorston commented 3 months ago

This wasn't right on 64-bit:

~ $ date -d "2038-01-19 03:14:10" +%s
-2147483646
~ $ 

It should be fixed now (PRE-5455):

~ $ date -d "2038-01-19 03:14:10" +%s
2147483650
~ $

Still looking at 32-bit...

rmyorston commented 3 months ago

The 32-bit build now uses 64-bit time values. 64-bit builds should be completely unaffected.

There are prereleases, PRE-5456 or above.

ale5000-git commented 3 months ago

Thanks, the date now works correctly. But I have noticed a different issue, when setting date fails it doesn't return an error code:

$ date -s "2038-01-19 03:14:10"; echo $?
date: can't set date: Operation not permitted
Tue Jan 19 03:14:10 UTC 2038
0
rmyorston commented 3 months ago

date -s not returning an error code is an upstream issue.

It's been reported on the mailing list, with a patch, but it hasn't been applied yet.

ale5000-git commented 3 months ago

The main issue was fixed, for the latter I will wait upstream. Thanks.

ale5000-git commented 2 months ago

@rmyorston Hi, I was testing the limits and this works:

date -u -d '@32535244799'; echo $?

and return:

Thu Jan  1 07:59:59 UTC 3001
0

but instead the opposite doesn't work:

date -u -d 'Thu Jan  1 07:59:59 UTC 3001' -- '+%s'; echo $?

Edit: According to https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/localtime-localtime32-localtime64?view=msvc-170 the limit of __time64_t is 23:59:59, December 31, 3000, UTC.

rmyorston commented 2 months ago

the limit of __time64_t is 23:59:59, December 31, 3000, UTC

__time64_t supports an enormous time range, so it's more accurate to say the limit applies to Microsoft's _localtime64() . It doesn't handle times before the Unix epoch either.

It would be possible to provide a replacement function that handles the full range of times that can be represented in a struct tm. But using the Microsoft function is enough to get us past 2038 without any additional code.

(The related timegm() function has already been imported from musl. In commit 48ddce5e9a063d89689ffe4be1680767186e13ee it was cut down to only support the range of Microsoft's localtime().)

ale5000-git commented 2 months ago

@rmyorston I'm not asking to avoid the limit of 32535244799 (or whatever is it), but what I'm asking is to have the same limit in both directions.

Currently: 32535244799 => Thu Jan 1 07:59:59 UTC 3001 (works) Thu Jan 1 07:59:59 UTC 3001 => 32535244799 (fail)

rmyorston commented 2 months ago

I'd prefer not to enforce the limitations of Microsoft's _localtime64() on code paths that don't use it.

ale5000-git commented 2 months ago

@rmyorston This should be inside the limit but it still doesn't work: date -u -d "Wed Dec 31 23:59:59 UTC 3000" -- '+%s'

Why?

rmyorston commented 2 months ago

Upstream only supports a limited number of formats for the date string.

Specifically, the source file libbb/time.c lists these formats:

        "%R" "\0"               /* HH:MM */
        "%T" "\0"               /* HH:MM:SS */
        "%m.%d-%R" "\0"         /* mm.dd-HH:MM */
        "%m.%d-%T" "\0"         /* mm.dd-HH:MM:SS */
        "%Y.%m.%d-%R" "\0"      /* yyyy.mm.dd-HH:MM */
        "%Y.%m.%d-%T" "\0"      /* yyyy.mm.dd-HH:MM:SS */
        "%b %d %T %Y" "\0"      /* month_name d HH:MM:SS YYYY */
        "%Y-%m-%d %R" "\0"      /* yyyy-mm-dd HH:MM */
        "%Y-%m-%d %T" "\0"      /* yyyy-mm-dd HH:MM:SS */
# if ENABLE_FEATURE_TIMEZONE
        "%Y-%m-%d %R %z" "\0"   /* yyyy-mm-dd HH:MM TZ */
        "%Y-%m-%d %T %z" "\0"   /* yyyy-mm-dd HH:MM:SS TZ */
# endif
        "%Y-%m-%d %H" "\0"      /* yyyy-mm-dd HH */
        "%Y-%m-%d" "\0"         /* yyyy-mm-dd */
ale5000-git commented 2 months ago

@rmyorston

The command: date -u -d '@32535215999' output: Wed Dec 31 23:59:59 UTC 3000

So this means that by default it output a format that itself doesn't support? But I guess this is a problem that need to be fixed upstream.