[comp.sources.d] Bug found in PD 'localtime'

sewilco@datapg.DataPg.MN.ORG (Scot E. Wilcoxon) (04/14/88)

I found the bug which I earlier mentioned.  I'll leave comp.sources.bugs
for the author to post an official fix.

My symptom was 'zic' creating small files with zeroes instead of data for
zones with DST (ie, EST5 OK and EST5EDT bad).

The problem turned out to be "min_year" and "max_year" were both 2038 A.D.,
caused by a bug in gmtime(3) where called by setboundaries() in zic.  A note
in 'timemk.c' says there is a bug in System VR2.0 and BSD4.3 localtime(3),
so many people might notice it.

I fixed it by hardwiring 1970 for min_year in setboundaries() via a #define.
This machine is an AT&T 3B1, with CT-flavored System V.
-- 
Scot E. Wilcoxon  sewilco@DataPg.MN.ORG    {amdahl|hpda}!bungia!datapg!sewilco
Data Progress	  UNIX consulting    +1 612-825-2607      uunet!datapg!sewilco

ado@elsie.UUCP (Arthur David Olson) (04/18/88)

> The PD version of ctime(3) which was recently posted has a problem in
> generating its data files on. . .this AT&T/Convergent 3B1 (System V).
> I have defined USG_COMPAT (and examined the few lines affected in
> localtime.c). . .
>
> My symptom was 'zic' creating small files with zeroes instead of data for
> zones with DST (ie, EST5 OK and EST5EDT bad).
> 
> The problem turned out to be "min_year" and "max_year" were both 2038 A.D.,
> caused by a bug in gmtime(3) where called by setboundaries() in zic.  A note
> in 'timemk.c' says there is a bug in System VR2.0 and BSD4.3 localtime(3),
> so many people might notice it.

Hmmm. . .the bug in System V's gmtime/localtime shouldn't cause problems with
zic, since it uses the public-domain versions of these functions.

If someone out there with a 3B1 could compile the attached program and send me
the results, it might help in tracking down the problem.
-- 
	ado@ncifcrf.gov			ADO is a trademark of Ampex.

#include "stdio.h"

#define TRUE	1
#define FALSE	0

static long		lmin;
static long		lmax;
static int		lsigned;
static unsigned long	ulmin;
static unsigned long	ulmax;
static int		ulsigned;

main()
{
	register long		lbit;
	register unsigned long	ulbit;

	for (lbit = 1; lbit > 0; lbit <<= 1)
		;
	if (lbit == 0) {
		lsigned = FALSE;
		lmin = 0;
		lmax = ~(long) 0;
	} else {
		lsigned = TRUE;
		lmin = lbit;
		lmax = lbit;
		++lmax;
		lmax = -lmax;
	}
	(void) printf("lbit %ld lsigned %d lmin %ld lmax %ld\n",
		lbit, lsigned, lmin, lmax);
	for (ulbit = 1; ulbit > 0; ulbit <<= 1)
		;
	if (ulbit == 0) {
		ulsigned = FALSE;
		ulmin = 0;
		ulmax = ~(unsigned long) 0;
	} else {
		ulsigned = TRUE;
		ulmin = ulbit;
		ulmax = ulbit;
		++ulmax;
		ulmax = -ulmax;
	}
	(void) printf("ulbit %lu ulsigned %d ulmin %lu ulmax %lu\n",
		ulbit, ulsigned, ulmin, ulmax);
	return 0;
}