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?= <[email protected]>
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