Control: tags 907348 + patch upstream
Dear Maintainer, I tried to have a look and tracked it down into the file lib/leap-seconds.def which is generated by ltrcc. Unfortunately this generator seems not prepared for at least i386. With attached patch the generated file is equal to one generated at amd64, and the tests pass on both architectures. Could not find an matching upstream bug. Kind regards, Bernhard
>From 6f653805ee528e9068d3108af7227dea685f88ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= <bernha...@mailbox.org> Date: Tue, 7 May 2019 19:13:21 +0200 Subject: [PATCH] Use unsigned type for leap second conversion. https://bugs.debian.org/907348 --- lib/ltrcc.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/lib/ltrcc.c b/lib/ltrcc.c index 20c0e38..11c8a74 100644 --- a/lib/ltrcc.c +++ b/lib/ltrcc.c @@ -55,10 +55,10 @@ #include "version.c" -static __attribute__((pure, const)) long int -ntp_to_unix_epoch(long int x) +static __attribute__((pure, const)) unsigned long int +ntp_to_unix_epoch(unsigned long int x) { - return x - 25567L * 86400L; + return x - 25567U * 86400U; } @@ -68,7 +68,7 @@ ntp_to_unix_epoch(long int x) static int pr_line_corr(const char *line, size_t llen, va_list UNUSED(vap)) { - static long int cor; + static unsigned long int cor; char *sp, *ep; if (llen == PROLOGUE) { @@ -96,7 +96,7 @@ const int32_t %s[] = {\n\ /* otherwise process */ if ((sp = memchr(line, '\t', llen)) == NULL) { return -1; - } else if ((ep = NULL, cor = strtol(++sp, &ep, 10), ep == NULL)) { + } else if ((ep = NULL, cor = strtoul(++sp, &ep, 10), ep == NULL || cor == ULONG_MAX)) { return -1; } @@ -108,10 +108,10 @@ const int32_t %s[] = {\n\ static int pr_line_d(const char *line, size_t llen, va_list vap) { - static long int cor; + static unsigned long int cor; struct dt_d_s d; dt_dtyp_t typ; - long int val; + unsigned long int val; int colp; char *ep; @@ -155,7 +155,7 @@ const uint32_t %s[] = {\n\ return 0; } /* otherwise process */ - if ((ep = NULL, val = strtol(line, &ep, 10), ep == NULL)) { + if ((ep = NULL, val = strtoul(line, &ep, 10), ep == NULL || val == ULONG_MAX)) { return -1; } @@ -164,7 +164,7 @@ const uint32_t %s[] = {\n\ d = dt_dconv(typ, d); if (!colp) { - if ((cor = strtol(ep, &ep, 10), ep == NULL)) { + if ((cor = strtoul(ep, &ep, 10), ep == NULL || val == ULONG_MAX)) { return -1; } /* just output the line then */ @@ -179,9 +179,9 @@ const uint32_t %s[] = {\n\ static int pr_line_dt(const char *line, size_t llen, va_list vap) { - static long int cor; + static unsigned long int cor; dt_dtyp_t __attribute__((unused)) typ; - long int val; + unsigned long int val; int colp; char *ep; @@ -225,7 +225,7 @@ const int32_t %s[] = {\n\ return 0; } /* otherwise process */ - if ((ep = NULL, val = strtol(line, &ep, 10), ep == NULL)) { + if ((ep = NULL, val = strtoul(line, &ep, 10), ep == NULL || val == ULONG_MAX)) { return -1; } @@ -234,15 +234,15 @@ const int32_t %s[] = {\n\ val = ntp_to_unix_epoch(val); if (!colp) { - if ((cor = strtol(ep, &ep, 10), ep == NULL)) { + if ((cor = strtoul(ep, &ep, 10), ep == NULL || cor == ULONG_MAX)) { return -1; } /* just output the line then */ - fprintf(stdout, "\t{0x%xU/* %li */, %li},\n", - (uint32_t)val, val, cor); + fprintf(stdout, "\t{0x%lxU/* %li */, %li},\n", + val, val, cor); } else { /* column-oriented mode */ - fprintf(stdout, "\t0x%xU/* %li */,\n", (uint32_t)val, val); + fprintf(stdout, "\t0x%lxU/* %li */,\n", val, val); } return 0; } @@ -250,12 +250,12 @@ const int32_t %s[] = {\n\ static int pr_line_t(const char *line, size_t llen, va_list vap) { - static long int cor; + static unsigned long int cor; struct dt_t_s t = dt_t_initialiser(); dt_dtyp_t typ; int colp; char *ep; - long int val; + unsigned long int val; /* extract type from inner list */ typ = va_arg(vap, dt_dtyp_t); @@ -292,7 +292,7 @@ const uint32_t %s[] = {\n\ return 0; } /* otherwise process */ - if ((ep = NULL, val = strtol(line, &ep, 10), ep == NULL)) { + if ((ep = NULL, val = strtoul(line, &ep, 10), ep == NULL || val == ULONG_MAX)) { return -1; } val--; @@ -303,7 +303,7 @@ const uint32_t %s[] = {\n\ t.hms.h = val % 24L; /* read correction */ - if ((val = strtol(ep, &ep, 10), ep == NULL)) { + if ((val = strtoul(ep, &ep, 10), ep == NULL || val == ULONG_MAX)) { return -1; } -- 2.20.1
# Unstable i386 qemu VM 2019-05-07 # Unstable amd64 qemu VM 2019-05-07 apt update apt dist-upgrade apt install systemd-coredump fakeroot gdb git strace apt build-dep dateutils mkdir /home/benutzer/source/dateutils/orig -p cd /home/benutzer/source/dateutils/orig apt source dateutils cd cd /home/benutzer/source/dateutils cp orig try1 -a cd try1/dateutils-0.4.5 dpkg-buildpackage i386: # TOTAL: 855 # PASS: 841 # SKIP: 0 # XFAIL: 0 # FAIL: 14 # XPASS: 0 # ERROR: 0 .. contents:: :depth: 2 FAIL: dtcore-conv ================= VALUES DIFFER 1341100836 v 1341100833 VALUES DIFFER 1341100837 v 1341100835 FAIL dtcore-conv (exit status: 1) amd64: passed ########## gdb -q --ex 'set width 0' -ex 'set pagination off' -ex 'b main' -ex run --args test/dtcore-conv b 119 cont b find_before_si32 cont step b ignore 4 1 display max display min display i display nv cont next next display/i $pc stepi ########## i386 benutzer@debian:~/source/dateutils/try2/dateutils-0.4.5$ gdb -q --ex 'set width 0' -ex 'set pagination off' -ex 'b main' -ex run --args test/dtcore-conv Reading symbols from test/dtcore-conv...done. Breakpoint 1 at 0x1220: file dtcore-conv.c, line 53. Starting program: /home/benutzer/source/dateutils/try2/dateutils-0.4.5/test/dtcore-conv Breakpoint 1, main () at dtcore-conv.c:53 53 { (gdb) b 119 Breakpoint 2 at 0x401397: file dtcore-conv.c, line 119. (gdb) cont Continuing. Breakpoint 2, main () at dtcore-conv.c:119 119 if (res = dt_dtconv(DT_SEXYTAI, t), conv_chk(res, chk)) { (gdb) b find_before_si32 Breakpoint 3 at 0x4085a5: file leaps.c, line 137. (gdb) cont Continuing. Breakpoint 3, find_before_si32 (min=0, max=29, i=14, key=1341100799, nv=30, v=0x4149c0 <leaps_s>) at leaps.c:137 137 return find_before_si32(fld, nfld, key, this, min, max); (gdb) step 99 lo = v[i]; (gdb) b Breakpoint 4 at 0x4085c0: file leaps.c, line 99. (gdb) ignore 4 1 Will ignore next crossing of breakpoint 4. (gdb) display max 1: max = 29 (gdb) display min 2: min = 0 (gdb) display i 3: i = 14 (gdb) display nv 4: nv = 30 (gdb) cont Continuing. Breakpoint 4, find_before_si32 (min=22, max=29, i=25, key=1341100799, nv=30, v=0x4149c0 <leaps_s>) at leaps.c:99 99 lo = v[i]; 1: max = 29 2: min = 22 3: i = 25 4: nv = 30 (gdb) next 100 up = v[i + 1]; 1: max = 29 2: min = 22 3: i = 25 4: nv = 30 (gdb) next 102 if (key > lo && key <= up) { 1: max = 29 2: min = 22 3: i = 25 4: nv = 30 (gdb) display/i $pc 5: x/i $pc => 0x4085d2 <leaps_before_si32+66>: cmp %esi,%ecx (gdb) stepi 0x004085d4 102 if (key > lo && key <= up) { 1: max = 29 2: min = 22 3: i = 25 4: nv = 30 5: x/i $pc => 0x4085d4 <leaps_before_si32+68>: jle 0x4085da <leaps_before_si32+74> (gdb) print/x $esi $1 = 0xfc55817e (gdb) print/x $ecx $2 = 0x4fef92ff (gdb) info local lo = -61505154 up = -61505154 (gdb) print $esi $3 = -61505154 (gdb) print $ecx $4 = 1341100799 (gdb) print sizeof(lo) $5 = 4 (gdb) print sizeof(up) $6 = 4 (gdb) print v[i] $7 = -61505154 (gdb) print v[i+1] $8 = -61505154 (gdb) ptype v type = const int * (gdb) ptype lo type = int (gdb) up #1 leaps_before_si32 (fld=0x4149c0 <leaps_s>, nfld=30, key=1341100799) at leaps.c:137 137 return find_before_si32(fld, nfld, key, this, min, max); (gdb) print fld $9 = (const int32_t *) 0x4149c0 <leaps_s> (gdb) print fld[0] $10 = -2147483648 (gdb) down #0 0x004085d4 in find_before_si32 (min=22, max=29, i=25, key=1341100799, nv=30, v=0x4149c0 <leaps_s>) at leaps.c:102 102 if (key > lo && key <= up) { (gdb) print i $11 = 25 (gdb) up #1 leaps_before_si32 (fld=0x4149c0 <leaps_s>, nfld=30, key=1341100799) at leaps.c:137 137 return find_before_si32(fld, nfld, key, this, min, max); (gdb) print fld[25] $12 = -61505154 (gdb) ptype fld type = const int * amd64 benutzer@debian:~/source/dateutils/try2/dateutils-0.4.5$ gdb -q --ex 'set width 0' -ex 'set pagination off' -ex 'b main' -ex run --args test/dtcore-conv Reading symbols from test/dtcore-conv...done. Breakpoint 1 at 0x2200: file dtcore-conv.c, line 53. Starting program: /home/benutzer/source/dateutils/try2/dateutils-0.4.5/test/dtcore-conv Breakpoint 1, main () at dtcore-conv.c:53 53 { (gdb) b 119 Breakpoint 2 at 0x555555556350: file dtcore-conv.c, line 119. (gdb) cont Continuing. Breakpoint 2, main () at dtcore-conv.c:119 119 if (res = dt_dtconv(DT_SEXYTAI, t), conv_chk(res, chk)) { (gdb) b find_before_si32 Breakpoint 3 at 0x55555555c50d: file leaps.c, line 137. (gdb) cont Continuing. Breakpoint 3, find_before_si32 (min=0, max=29, i=14, key=1341100799, nv=30, v=0x555555567a00 <leaps_s>) at leaps.c:137 137 return find_before_si32(fld, nfld, key, this, min, max); (gdb) step 99 lo = v[i]; (gdb) b Breakpoint 4 at 0x55555555c523: file leaps.c, line 99. (gdb) ignore 4 1 Will ignore next crossing of breakpoint 4. (gdb) display max 1: max = 29 (gdb) display min 2: min = 0 (gdb) display i 3: i = 14 (gdb) display nv 4: nv = 30 (gdb) cont Continuing. Breakpoint 4, find_before_si32 (min=22, max=29, i=25, key=1341100799, nv=30, v=0x555555567a00 <leaps_s>) at leaps.c:99 99 lo = v[i]; 1: max = 29 2: min = 22 3: i = 25 4: nv = 30 (gdb) next 100 up = v[i + 1]; 1: max = 29 2: min = 22 3: i = 25 4: nv = 30 (gdb) next 102 if (key > lo && key <= up) { 1: max = 29 2: min = 22 3: i = 25 4: nv = 30 (gdb) display/i $pc 5: x/i $pc => 0x55555555c530 <leaps_before_si32+48>: cmp %r9d,%edx (gdb) stepi 0x000055555555c533 102 if (key > lo && key <= up) { 1: max = 29 2: min = 22 3: i = 25 4: nv = 30 5: x/i $pc => 0x55555555c533 <leaps_before_si32+51>: jle 0x55555555c53a <leaps_before_si32+58> (gdb) print/x $r9d $1 = 0x495c077f (gdb) print/x $edx $2 = 0x4fef92ff (gdb) info local lo = 1230767999 up = 1341100799 (gdb) print $r9d $3 = 1230767999 (gdb) print $edx $4 = 1341100799 (gdb) print sizeof(lo) $5 = 4 (gdb) print sizeof(up) $6 = 4 (gdb) print v[i] $7 = 1230767999 (gdb) print v[i+1] $8 = 1341100799 (gdb) print sizeof(v[i]) $9 = 4 (gdb) print sizeof(v[i+1]) $10 = 4 (gdb) ptype v type = const int * (gdb) ptype lo type = int (gdb) up #1 leaps_before_si32 (fld=0x555555567a00 <leaps_s>, nfld=30, key=key@entry=1341100799) at leaps.c:137 137 return find_before_si32(fld, nfld, key, this, min, max); (gdb) print fld $11 = (const int32_t *) 0x555555567a00 <leaps_s> (gdb) print fld[0] $12 = -2147483648 (gdb) down #0 0x000055555555c533 in find_before_si32 (min=22, max=29, i=25, key=1341100799, nv=30, v=0x555555567a00 <leaps_s>) at leaps.c:102 102 if (key > lo && key <= up) { (gdb) print i $13 = 25 (gdb) up #1 leaps_before_si32 (fld=0x555555567a00 <leaps_s>, nfld=30, key=key@entry=1341100799) at leaps.c:137 137 return find_before_si32(fld, nfld, key, this, min, max); (gdb) print fld[25] $14 = 1230767999 (gdb) ptype fld type = const int * ############ i386 benutzer@debian:~/source/dateutils/try2/dateutils-0.4.5$ cat ./lib/leap-seconds.def /*** autogenerated by: ltrcc leap-seconds.list */ ... const int32_t leaps_s[] = { INT32_MIN, 0xfc55817eU/* -61505154 */, 0xfc55817eU/* -61505154 */, 0xfc55817eU/* -61505154 */, 0xfc55817eU/* -61505154 */, 0xfc55817eU/* -61505154 */, 0xfc55817eU/* -61505154 */, 0xfc55817eU/* -61505154 */, 0xfc55817eU/* -61505154 */, 0xfc55817eU/* -61505154 */, 0xfc55817eU/* -61505154 */, 0xfc55817eU/* -61505154 */, 0xfc55817eU/* -61505154 */, 0xfc55817eU/* -61505154 */, 0xfc55817eU/* -61505154 */, 0xfc55817eU/* -61505154 */, 0xfc55817eU/* -61505154 */, 0xfc55817eU/* -61505154 */, 0xfc55817eU/* -61505154 */, 0xfc55817eU/* -61505154 */, 0xfc55817eU/* -61505154 */, 0xfc55817eU/* -61505154 */, 0xfc55817eU/* -61505154 */, 0xfc55817eU/* -61505154 */, 0xfc55817eU/* -61505154 */, 0xfc55817eU/* -61505154 */, 0xfc55817eU/* -61505154 */, 0xfc55817eU/* -61505154 */, 0xfc55817eU/* -61505154 */, INT32_MAX }; const size_t nleaps_s = countof(leaps_s); amd64 benutzer@debian:~/source/dateutils/try2/dateutils-0.4.5$ cat ./lib/leap-seconds.def /*** autogenerated by: ltrcc leap-seconds.list */ ... const int32_t leaps_s[] = { INT32_MIN, 0x3c266ffU/* 63071999 */, 0x4b257ffU/* 78796799 */, 0x5a4ebffU/* 94694399 */, 0x7861f7fU/* 126230399 */, 0x96752ffU/* 157766399 */, 0xb48867fU/* 189302399 */, 0xd2b0b7fU/* 220924799 */, 0xf0c3effU/* 252460799 */, 0x10ed727fU/* 283996799 */, 0x12cea5ffU/* 315532799 */, 0x159fca7fU/* 362793599 */, 0x1780fdffU/* 394329599 */, 0x1962317fU/* 425865599 */, 0x1d25e9ffU/* 489023999 */, 0x21dae4ffU/* 567993599 */, 0x259e9d7fU/* 631151999 */, 0x277fd0ffU/* 662687999 */, 0x2a50f57fU/* 709948799 */, 0x2c3228ffU/* 741484799 */, 0x2e135c7fU/* 773020799 */, 0x30e723ffU/* 820454399 */, 0x33b8487fU/* 867715199 */, 0x368c0fffU/* 915148799 */, 0x43b71b7fU/* 1136073599 */, 0x495c077fU/* 1230767999 */, 0x4fef92ffU/* 1341100799 */, 0x55932d7fU/* 1435708799 */, 0x5868467fU/* 1483228799 */, INT32_MAX }; const size_t nleaps_s = countof(leaps_s); ############ gdb -q --ex 'set width 0' -ex 'set pagination off' -ex 'b main' -ex run --args lib/ltrcc -C lib/leap-seconds.list set width 0 set pagination off b parse_file cont b 228 cont (gdb) bt #0 pr_line_dt (line=0x4196e0 "2272060800\t10\t# 1 Jan 1972\n", llen=27, vap=0xbffff544 "\256\345@") at ltrcc.c:228 #1 0x00401f3b in pr_file (fp=0x419170, var=0x40e5d6 "leaps_s", cb=0x401ad0 <pr_line_dt>) at ltrcc.c:334 #2 0x004014ef in parse_file (file=<optimized out>) at ltrcc.c:392 #3 main (argc=<optimized out>, argv=<optimized out>) at ltrcc.c:425 ########### i386 benutzer@debian:~/source/dateutils/try2/dateutils-0.4.5$ gdb -q --ex 'set width 0' -ex 'set pagination off' -ex 'b main' -ex run --args lib/ltrcc -C lib/leap-seconds.list ... (gdb) print sizeof(val) $5 = 4 (gdb) ptype val type = long