When compiling the latest tz code with GCC 4.0.2 on Solaris 8 (64-bit), I got some warnings that looked like this: zic.c:979: warning: comparison between signed and unsigned zic.c:1086: warning: comparison between signed and unsigned asctime.c:106: warning: '0' flag ignored with precision and '%d' printf format Here are proposed patches to remove all the places where I observed problems in this area. Not all the size_t-related problems were caught by GCC, but I expect other compilers might have similar complaints, so I figured I might as well fix them all while I was thinking about it. Since the affected quantities are all too small to be worried about overflowing a signed 16-bit quantity on practical machines, I don't think this patch fixes any real-world bugs or changes any real-world behavior, except perhaps that it makes the code a bit smaller and faster on 64-bit hosts because we don't keep converting 64-bit quantities to 32 bits and back. =================================================================== RCS file: RCS/private.h,v retrieving revision 2006.2.0.1 retrieving revision 2006.2.0.2 diff -pu -r2006.2.0.1 -r2006.2.0.2 --- private.h 2006/02/21 21:07:30 2006.2.0.1 +++ private.h 2006/02/22 00:24:05 2006.2.0.2 @@ -236,8 +236,8 @@ extern char * asctime_r(); char * icalloc P((int nelem, int elsize)); char * icatalloc P((char * old, const char * new)); char * icpyalloc P((const char * string)); -char * imalloc P((int n)); -void * irealloc P((void * pointer, int size)); +char * imalloc P((size_t n)); +void * irealloc P((void * pointer, size_t size)); void icfree P((char * pointer)); void ifree P((char * pointer)); const char * scheck P((const char * string, const char * format)); =================================================================== RCS file: RCS/ialloc.c,v retrieving revision 1997.3 retrieving revision 1997.3.0.1 diff -pu -r1997.3 -r1997.3.0.1 --- ialloc.c 1997/03/07 21:06:34 1997.3 +++ ialloc.c 2006/02/22 00:27:00 1997.3.0.1 @@ -12,9 +12,9 @@ static char elsieid[] = "@(#)ialloc.c 8. char * imalloc(n) -const int n; +const size_t n; { - return malloc((size_t) nonzero(n)); + return malloc(nonzero(n)); } char * @@ -30,11 +30,11 @@ int elsize; void * irealloc(pointer, size) void * const pointer; -const int size; +const size_t size; { if (pointer == NULL) return imalloc(size); - return realloc((void *) pointer, (size_t) nonzero(size)); + return realloc((void *) pointer, nonzero(size)); } char * @@ -43,7 +43,7 @@ char * const old; const char * const new; { register char * result; - register int oldsize, newsize; + register size_t oldsize, newsize; newsize = (new == NULL) ? 0 : strlen(new); if (old == NULL) =================================================================== RCS file: RCS/localtime.c,v retrieving revision 2006.2.0.1 retrieving revision 2006.2.0.2 diff -pu -r2006.2.0.1 -r2006.2.0.2 --- localtime.c 2006/02/21 21:07:30 2006.2.0.1 +++ localtime.c 2006/02/22 00:24:05 2006.2.0.2 @@ -340,8 +340,9 @@ register const int doextend; register const char * p; register int i; register int fid; - register int stored; - register int nread; + register int read_return; + register size_t stored; + register size_t nread; union { struct tzhead tzhead; char buf[2 * sizeof(struct tzhead) + @@ -385,12 +386,14 @@ register const int doextend; if ((fid = open(name, OPEN_MODE)) == -1) return -1; } - nread = read(fid, u.buf, sizeof u.buf); - if (close(fid) < 0 || nread <= 0) + read_return = read(fid, u.buf, sizeof u.buf); + if (close(fid) < 0 || read_return <= 0) return -1; + nread = read_return; for (stored = 4; stored <= 8; stored *= 2) { int ttisstdcnt; int ttisgmtcnt; + size_t j; ttisstdcnt = (int) detzcode(u.tzhead.tzh_ttisstdcnt); ttisgmtcnt = (int) detzcode(u.tzhead.tzh_ttisgmtcnt); @@ -511,12 +514,12 @@ register const int doextend; if (u.tzhead.tzh_version[0] == '\0') break; nread -= p - u.buf; - for (i = 0; i < nread; ++i) - u.buf[i] = p[i]; + for (j = 0; j < nread; ++j) + u.buf[j] = p[j]; /* ** If this is a narrow integer time_t system, we're done. */ - if (stored >= (int) sizeof(time_t) && TYPE_INTEGRAL(time_t)) + if (stored >= sizeof(time_t) && TYPE_INTEGRAL(time_t)) break; } if (doextend && nread > 2 && =================================================================== RCS file: RCS/scheck.c,v retrieving revision 2006.2 retrieving revision 2006.2.0.1 diff -pu -r2006.2 -r2006.2.0.1 --- scheck.c 2006/02/20 15:08:17 2006.2 +++ scheck.c 2006/02/22 00:24:05 2006.2.0.1 @@ -23,7 +23,7 @@ const char * const format; result = ""; if (string == NULL || format == NULL) return result; - fbuf = imalloc((int) (2 * strlen(format) + 4)); + fbuf = imalloc(2 * strlen(format) + 4); if (fbuf == NULL) return result; fp = format; =================================================================== RCS file: RCS/zic.c,v retrieving revision 2006.2 retrieving revision 2006.2.0.1 diff -pu -r2006.2 -r2006.2.0.1 --- zic.c 2006/02/20 15:08:17 2006.2 +++ zic.c 2006/02/22 00:24:05 2006.2.0.1 @@ -167,8 +167,8 @@ static int leapseen; static int leapminyear; static int leapmaxyear; static int linenum; -static int max_abbrvar_len; -static int max_format_len; +static size_t max_abbrvar_len; +static size_t max_format_len; static zic_t max_time; static int max_year; static zic_t min_time; @@ -979,7 +979,7 @@ const int nfields; if (max_abbrvar_len < strlen(r.r_abbrvar)) max_abbrvar_len = strlen(r.r_abbrvar); rules = (struct rule *) (void *) erealloc((char *) rules, - (int) ((nrules + 1) * sizeof *rules)); + (nrules + 1) * sizeof *rules); rules[nrules++] = r; } @@ -996,7 +996,7 @@ const int nfields; return FALSE; } if (strcmp(fields[ZF_NAME], TZDEFAULT) == 0 && lcltime != NULL) { - buf = erealloc(buf, (int) (132 + strlen(TZDEFAULT))); + buf = erealloc(buf, 132 + strlen(TZDEFAULT)); (void) sprintf(buf, _("\"Zone %s\" line and -l option are mutually exclusive"), TZDEFAULT); @@ -1004,7 +1004,7 @@ _("\"Zone %s\" line and -l option are mu return FALSE; } if (strcmp(fields[ZF_NAME], TZDEFRULES) == 0 && psxrules != NULL) { - buf = erealloc(buf, (int) (132 + strlen(TZDEFRULES))); + buf = erealloc(buf, 132 + strlen(TZDEFRULES)); (void) sprintf(buf, _("\"Zone %s\" line and -p option are mutually exclusive"), TZDEFRULES); @@ -1014,7 +1014,7 @@ _("\"Zone %s\" line and -p option are mu for (i = 0; i < nzones; ++i) if (zones[i].z_name != NULL && strcmp(zones[i].z_name, fields[ZF_NAME]) == 0) { - buf = erealloc(buf, (int) (132 + + buf = erealloc(buf, (132 + strlen(fields[ZF_NAME]) + strlen(zones[i].z_filename))); (void) sprintf(buf, @@ -1112,7 +1112,7 @@ const int iscont; } } zones = (struct zone *) (void *) erealloc((char *) zones, - (int) ((nzones + 1) * sizeof *zones)); + (nzones + 1) * sizeof *zones); zones[nzones++] = z; /* ** If there was an UNTIL field on this line, @@ -1249,7 +1249,7 @@ const int nfields; l.l_from = ecpyalloc(fields[LF_FROM]); l.l_to = ecpyalloc(fields[LF_TO]); links = (struct link *) (void *) erealloc((char *) links, - (int) ((nlinks + 1) * sizeof *links)); + (nlinks + 1) * sizeof *links); links[nlinks++] = l; } @@ -1557,7 +1557,7 @@ const char * const string; ++leapi32; } fullname = erealloc(fullname, - (int) (strlen(directory) + 1 + strlen(name) + 1)); + strlen(directory) + 1 + strlen(name) + 1); (void) sprintf(fullname, "%s/%s", directory, name); /* ** Remove old file, if any, to snap links. @@ -1942,8 +1942,8 @@ const int zonecount; register char * startbuf; register char * ab; register char * envvar; - register int max_abbr_len; - register int max_envvar_len; + register size_t max_abbr_len; + register size_t max_envvar_len; max_abbr_len = 2 + max_format_len + max_abbrvar_len; max_envvar_len = 2 * max_abbr_len + 5 * 9; @@ -2310,7 +2310,7 @@ const char * const type; if (type == NULL || *type == '\0') return TRUE; - buf = erealloc(buf, (int) (132 + strlen(yitcommand) + strlen(type))); + buf = erealloc(buf, 132 + strlen(yitcommand) + strlen(type)); (void) sprintf(buf, "%s %d %s", yitcommand, year, type); result = system(buf); if (WIFEXITED(result)) switch (WEXITSTATUS(result)) { @@ -2401,7 +2401,7 @@ register char * cp; if (cp == NULL) return NULL; array = (char **) (void *) - emalloc((int) ((strlen(cp) + 1) * sizeof *array)); + emalloc((strlen(cp) + 1) * sizeof *array); nsubs = 0; for ( ; ; ) { while (isascii((unsigned char) *cp) && =================================================================== RCS file: RCS/asctime.c,v retrieving revision 2006.2 retrieving revision 2006.2.0.1 diff -pu -r2006.2 -r2006.2.0.1 --- asctime.c 2006/02/20 15:08:17 2006.2 +++ asctime.c 2006/02/22 00:24:05 2006.2.0.1 @@ -37,14 +37,24 @@ static char elsieid[] = "@(#)asctime.c 8 ** The ISO C 1999 and POSIX 1003.1-2004 standards prohibit padding the year, ** but many implementations pad anyway; most likely the standards are buggy. */ +#ifdef __GNUC__ +/* Avoid "warning: '0' flag ignored with precision and '%d' printf format". */ +#define ASCTIME_FMT "%.3s %.3s%3d %2.2d:%2.2d:%2.2d %-4s\n" +#else #define ASCTIME_FMT "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %-4s\n" +#endif /* ** For years that are more than four digits we put extra spaces before the year ** so that code trying to overwrite the newline won't end up overwriting ** a digit within a year and truncating the year (operating on the assumption ** that no output is better than wrong output). */ +#ifdef __GNUC__ +/* Avoid "warning: '0' flag ignored with precision and '%d' printf format". */ +#define ASCTIME_FMT_B "%.3s %.3s%3d %2.2d:%2.2d:%2.2d %s\n" +#else #define ASCTIME_FMT_B "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %s\n" +#endif #define STD_ASCTIME_BUF_SIZE 26 /*