mailing list of musl libc
 help / color / mirror / code / Atom feed
* [musl] strptime(s, "%Y-%j", &tm) does not update month and day
@ 2024-05-11 15:24 Petr Pisar
  2024-05-11 21:28 ` Rich Felker
  0 siblings, 1 reply; 5+ messages in thread
From: Petr Pisar @ 2024-05-11 15:24 UTC (permalink / raw)
  To: musl

[-- Attachment #1: Type: text/plain, Size: 1476 bytes --]

Hello,

When debugging a libisds test failure with musl-1.2.5
<https://bugs.gentoo.org/show_bug.cgi?id=928107>, I found that musl's
strptime() does not handle "%Y-%j" properly. It accepts the format, it parses
the input string, it returns a correct pointer past the input string, but it
does not update tm.tm_mon and tm.tm_mday fileds of the third argument.

A reproducer:

#define _XOPEN_SOURCE
#include <time.h>
#include <stdio.h>
#include <stddef.h>

int main(void) {
    const char *input = "2001-34"; /* 34th day of 2001 year, i.e. 2001-02-03 */
    struct tm time = {.tm_year=42, .tm_mon=42, .tm_mday=42, }; /* To detect changes */
    char *ret = strptime(input, "%Y-%j", &time);
    printf("Expected: ret=%p(%p+%td) tm_year=%d, tm_mon=%d, tm_mday=%d\n",
            input + 7, input, (ptrdiff_t)7, 101, 1, 3);
    printf("Got:      ret=%p(%p+%td) tm_year=%d, tm_mon=%d, tm_mday=%d\n",
            ret, input, ret - input, time.tm_year, time.tm_mon, time.tm_mday);
    return 0;
}

$ gcc test.c && ./a.out
Expected: ret=0x560c1cd64007(0x560c1cd64000+7) tm_year=101, tm_mon=1, tm_mday=3
Got:      ret=0x560c1cd64007(0x560c1cd64000+7) tm_year=101, tm_mon=42, tm_mday=42

Compare to glibc-2.38:

$ gcc test.c && ./a.out
Expected: ret=0x55fd94c4f00f(0x55fd94c4f008+7) tm_year=101, tm_mon=1, tm_mday=3
Got:      ret=0x55fd94c4f00f(0x55fd94c4f008+7) tm_year=101, tm_mon=1, tm_mday=3

Tested on x86_64 platform with gcc-13.2.1_p20240210, binutils-2.42 and
musl-1.2.5

-- Petr

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [musl] strptime(s, "%Y-%j", &tm) does not update month and day
  2024-05-11 15:24 [musl] strptime(s, "%Y-%j", &tm) does not update month and day Petr Pisar
@ 2024-05-11 21:28 ` Rich Felker
  2024-05-12  7:54   ` Petr Pisar
  0 siblings, 1 reply; 5+ messages in thread
From: Rich Felker @ 2024-05-11 21:28 UTC (permalink / raw)
  To: Petr Pisar; +Cc: musl

On Sat, May 11, 2024 at 05:24:59PM +0200, Petr Pisar wrote:
> Hello,
> 
> When debugging a libisds test failure with musl-1.2.5
> <https://bugs.gentoo.org/show_bug.cgi?id=928107>, I found that musl's
> strptime() does not handle "%Y-%j" properly. It accepts the format, it parses
> the input string, it returns a correct pointer past the input string, but it
> does not update tm.tm_mon and tm.tm_mday fileds of the third argument.

This is behaving as specified. Previously, the behavior was
unspecified. POSIX has amended it for future issues as the resolution
of https://austingroupbugs.net/view.php?id=1727 to read:

    The tm_yday member of the tm structure pointed to by tm shall be
    set to this number minus 1.

strptime generally does not behave like mktime, doing
normalizations/conversions.

Rich

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [musl] strptime(s, "%Y-%j", &tm) does not update month and day
  2024-05-11 21:28 ` Rich Felker
@ 2024-05-12  7:54   ` Petr Pisar
  2024-05-13 12:18     ` Rich Felker
  0 siblings, 1 reply; 5+ messages in thread
From: Petr Pisar @ 2024-05-12  7:54 UTC (permalink / raw)
  To: musl

[-- Attachment #1: Type: text/plain, Size: 1351 bytes --]

V Sat, May 11, 2024 at 05:28:54PM -0400, Rich Felker napsal(a):
> On Sat, May 11, 2024 at 05:24:59PM +0200, Petr Pisar wrote:
> > Hello,
> > 
> > When debugging a libisds test failure with musl-1.2.5
> > <https://bugs.gentoo.org/show_bug.cgi?id=928107>, I found that musl's
> > strptime() does not handle "%Y-%j" properly. It accepts the format, it parses
> > the input string, it returns a correct pointer past the input string, but it
> > does not update tm.tm_mon and tm.tm_mday fileds of the third argument.
> 
> This is behaving as specified. Previously, the behavior was
> unspecified. POSIX has amended it for future issues as the resolution
> of https://austingroupbugs.net/view.php?id=1727 to read:
> 
>     The tm_yday member of the tm structure pointed to by tm shall be
>     set to this number minus 1.
> 
> strptime generally does not behave like mktime, doing
> normalizations/conversions.
> 
I see. I thought that strptime() does the normalization. Reading
mktime() specification reveals it has a side effect of normalizing tm_yday
from tm_year, tm_mon, and tm_mday.

However, I need the oposite and I cannot find any standard library function
for that. I will probaly resort to my own implementation with the drawback
of assumption that rules for leap years in Gregorian calendar won't change.

-- Petr

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [musl] strptime(s, "%Y-%j", &tm) does not update month and day
  2024-05-12  7:54   ` Petr Pisar
@ 2024-05-13 12:18     ` Rich Felker
  2024-05-13 21:18       ` Thorsten Glaser
  0 siblings, 1 reply; 5+ messages in thread
From: Rich Felker @ 2024-05-13 12:18 UTC (permalink / raw)
  To: musl

On Sun, May 12, 2024 at 09:54:13AM +0200, Petr Pisar wrote:
> V Sat, May 11, 2024 at 05:28:54PM -0400, Rich Felker napsal(a):
> > On Sat, May 11, 2024 at 05:24:59PM +0200, Petr Pisar wrote:
> > > Hello,
> > > 
> > > When debugging a libisds test failure with musl-1.2.5
> > > <https://bugs.gentoo.org/show_bug.cgi?id=928107>, I found that musl's
> > > strptime() does not handle "%Y-%j" properly. It accepts the format, it parses
> > > the input string, it returns a correct pointer past the input string, but it
> > > does not update tm.tm_mon and tm.tm_mday fileds of the third argument.
> > 
> > This is behaving as specified. Previously, the behavior was
> > unspecified. POSIX has amended it for future issues as the resolution
> > of https://austingroupbugs.net/view.php?id=1727 to read:
> > 
> >     The tm_yday member of the tm structure pointed to by tm shall be
> >     set to this number minus 1.
> > 
> > strptime generally does not behave like mktime, doing
> > normalizations/conversions.
> > 
> I see. I thought that strptime() does the normalization. Reading
> mktime() specification reveals it has a side effect of normalizing tm_yday
> from tm_year, tm_mon, and tm_mday.
> 
> However, I need the oposite and I cannot find any standard library function
> for that. I will probaly resort to my own implementation with the drawback
> of assumption that rules for leap years in Gregorian calendar won't change.

That's certainly an option. I think you can also use mktime, though,
if you want. Starting from a valid struct tm for Jan 1, then adding
the tm_yday number to tm_mday, should get you most of the way there,
short of timezone/dst mess. You could avoid that by using timegm, or
if you assume POSIX-compatible time_t, just adding 86400*tm_yday to
the time_t.

Rich

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [musl] strptime(s, "%Y-%j", &tm) does not update month and day
  2024-05-13 12:18     ` Rich Felker
@ 2024-05-13 21:18       ` Thorsten Glaser
  0 siblings, 0 replies; 5+ messages in thread
From: Thorsten Glaser @ 2024-05-13 21:18 UTC (permalink / raw)
  To: musl

Rich Felker dixit:

>if you assume POSIX-compatible time_t, just adding 86400*tm_yday to
>the time_t.

AIUI, POSIX (Issue 8) suggests to add 86400*tm_yday to tm_sec and
using mktime to normalise it.

If you don’t start at 00:00:00 UTC, it should even work for systems
that honour leap seconds (say start at 1st January, 12:00:00 UTC;
the result may than be not at 12:00:00, but the day should be right).

bye,
//mirabilos
-- 
“It is inappropriate to require that a time represented as
 seconds since the Epoch precisely represent the number of
 seconds between the referenced time and the Epoch.”
	-- IEEE Std 1003.1b-1993 (POSIX) Section B.2.2.2

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2024-05-13 21:20 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-05-11 15:24 [musl] strptime(s, "%Y-%j", &tm) does not update month and day Petr Pisar
2024-05-11 21:28 ` Rich Felker
2024-05-12  7:54   ` Petr Pisar
2024-05-13 12:18     ` Rich Felker
2024-05-13 21:18       ` Thorsten Glaser

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).