* NEWS: Mention this.
* localtime.c (tzloadbody): If the TZif file’s TZ string would
exceed our abbreviation capacity, return EOVERFLOW rather than
silently misbehaving.
---
NEWS | 4 ++++
localtime.c | 14 +++++++-------
2 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/NEWS b/NEWS
index 513ca2c7..35696fcb 100644
--- a/NEWS
+++ b/NEWS
@@ -52,6 +52,10 @@ Unreleased, experimental changes
zic now ports to systems that report lack of link support via
EINVAL, ENOSYS or EPERM errno values. (Thanks to Tom Lane.)
+ When tzset and related functions encounter a TZif file that is too
+ large for them, they now consistently fail instead of sometimes
+ silently ignoring excess parts of the file.
+
Changes to documentation
URLs for release tarballs in tz-link.html have been updated to
diff --git a/localtime.c b/localtime.c
index 20e88c35..8044f1a0 100644
--- a/localtime.c
+++ b/localtime.c
@@ -1246,7 +1246,6 @@ tzloadbody(char const *name, struct state *sp, char
tzloadflags,
AHDT YST AKDT AKST) and ts->charcnt equals 10
(for AKST AKDT). Reusing means sp->charcnt can
stay 40 in this example. */
- int gotabbr = 0;
int charcnt = sp->charcnt;
for (i = 0; i < ts->typecnt; i++) {
char *tsabbr = ts->chars + ts->ttis[i].tt_desigidx;
@@ -1254,24 +1253,25 @@ tzloadbody(char const *name, struct state *sp, char
tzloadflags,
for (j = 0; j < charcnt; j++)
if (strcmp(sp->chars + j, tsabbr) == 0) {
ts->ttis[i].tt_desigidx = j;
- gotabbr++;
break;
}
if (! (j < charcnt)) {
int tsabbrlen = strnlen(tsabbr, TZ_MAX_CHARS - j);
- if (j + tsabbrlen < TZ_MAX_CHARS) {
+ if (TZ_MAX_CHARS <= j + tsabbrlen)
+ return EOVERFLOW;
+ else {
char *cp = sp->chars + j;
cp = mempcpy(cp, tsabbr, tsabbrlen);
*cp = '\0';
charcnt = j + tsabbrlen + 1;
ts->ttis[i].tt_desigidx = j;
- gotabbr++;
}
}
}
- if (gotabbr == ts->typecnt) {
- if (TZ_MAX_TYPES - sp->typecnt < ts->typecnt)
- return EOVERFLOW;
+
+ if (TZ_MAX_TYPES - sp->typecnt < ts->typecnt)
+ return EOVERFLOW;
+ else {
sp->charcnt = charcnt;
/* Ignore any trailing, no-op transitions generated
--
2.55.0