Fix converting YYYY-DDD date string on musl
commitbb749f6b02fb68002205c0412698adbf93356ffd
authorPetr Písař <petr.pisar@atlas.cz>
Sun, 12 May 2024 08:59:14 +0000 (12 10:59 +0200)
committerPetr Písař <petr.pisar@atlas.cz>
Sun, 12 May 2024 10:48:36 +0000 (12 12:48 +0200)
tree5453fa16814a41afcf01685bdb315b322b2a1829
parentb3d23135f7bcf1a9f52d643446f87731459e3f22
Fix converting YYYY-DDD date string on musl

isds-datestring2tm test failed on musl C library:

    FAIL: isds-datestring2tm
    ========================

    Testing unit: ISO date string to tm conversion
    2001-02-03: passed
    20010203: passed
    2001-34: failed
    reason: Returned struct tm differs in tm_mon: expected=1, got=34
    2001-02-03T05:06: passed
    foo bar: passed
    Empty input: passed
    NULL input pointer: passed
    NULL output pointer: passed
    Test results: unit = ISO date string to tm conversion, passed = 7, failed = 1, skipped = 0

The cause was that strptime() does not populate tm.tm_mon and tm.tm_mday when
parsing "%Y-%j" on musl, in contrast to glibc. The musl behavior seems
to be in-line with a drafted POSIX update
<https://austingroupbugs.net/view.php?id=1727>.

Since there seems to be no standard interface for computing those fields
from a day of year, this patch resorts to an libisds implementation.
Because there was already one in win32 backend, this patch moves the
implementation from yday2mday() into _isds_yday2mday().

Implementation note: It turns a modifiable heap array into a stack one
to improve thread safety. One could use two constant arrays and switch
between them with a pointer. But I prefer the stack aproach to increase
locality. It's faster according my benchmarks.

https://www.openwall.com/lists/musl/2024/05/11/5
https://bugs.gentoo.org/show_bug.cgi?id=928107
src/unix.c
src/utils.c
src/utils.h
src/win32.c