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

Reply via email to