Do not overallocate on the stack. Threaded code might use custom stack
size. Reported by: many Tested by: Jeremie Le Hen <jeremie@le-hen.org> (previous version) Reviewed by: jilles Approved by: re (bz) MFC after: 2 weeks
This commit is contained in:
parent
87eac1ceb9
commit
8046e2fda0
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=225677
@ -380,13 +380,16 @@ register const int doextend;
|
|||||||
int fid;
|
int fid;
|
||||||
int stored;
|
int stored;
|
||||||
int nread;
|
int nread;
|
||||||
|
int res;
|
||||||
union {
|
union {
|
||||||
struct tzhead tzhead;
|
struct tzhead tzhead;
|
||||||
char buf[2 * sizeof(struct tzhead) +
|
char buf[2 * sizeof(struct tzhead) +
|
||||||
2 * sizeof *sp +
|
2 * sizeof *sp +
|
||||||
4 * TZ_MAX_TIMES];
|
4 * TZ_MAX_TIMES];
|
||||||
} u;
|
} *u;
|
||||||
|
|
||||||
|
u = NULL;
|
||||||
|
res = -1;
|
||||||
sp->goback = sp->goahead = FALSE;
|
sp->goback = sp->goahead = FALSE;
|
||||||
|
|
||||||
/* XXX The following is from OpenBSD, and I'm not sure it is correct */
|
/* XXX The following is from OpenBSD, and I'm not sure it is correct */
|
||||||
@ -406,16 +409,24 @@ register const int doextend;
|
|||||||
** to hold the longest file name string that the implementation
|
** to hold the longest file name string that the implementation
|
||||||
** guarantees can be opened."
|
** guarantees can be opened."
|
||||||
*/
|
*/
|
||||||
char fullname[FILENAME_MAX + 1];
|
char *fullname;
|
||||||
|
|
||||||
|
fullname = malloc(FILENAME_MAX + 1);
|
||||||
|
if (fullname == NULL)
|
||||||
|
goto out;
|
||||||
|
|
||||||
if (name[0] == ':')
|
if (name[0] == ':')
|
||||||
++name;
|
++name;
|
||||||
doaccess = name[0] == '/';
|
doaccess = name[0] == '/';
|
||||||
if (!doaccess) {
|
if (!doaccess) {
|
||||||
if ((p = TZDIR) == NULL)
|
if ((p = TZDIR) == NULL) {
|
||||||
|
free(fullname);
|
||||||
return -1;
|
return -1;
|
||||||
if ((strlen(p) + 1 + strlen(name) + 1) >= sizeof fullname)
|
}
|
||||||
|
if (strlen(p) + 1 + strlen(name) >= FILENAME_MAX) {
|
||||||
|
free(fullname);
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
(void) strcpy(fullname, p);
|
(void) strcpy(fullname, p);
|
||||||
(void) strcat(fullname, "/");
|
(void) strcat(fullname, "/");
|
||||||
(void) strcat(fullname, name);
|
(void) strcat(fullname, name);
|
||||||
@ -426,37 +437,45 @@ register const int doextend;
|
|||||||
doaccess = TRUE;
|
doaccess = TRUE;
|
||||||
name = fullname;
|
name = fullname;
|
||||||
}
|
}
|
||||||
if (doaccess && access(name, R_OK) != 0)
|
if (doaccess && access(name, R_OK) != 0) {
|
||||||
|
free(fullname);
|
||||||
return -1;
|
return -1;
|
||||||
if ((fid = _open(name, OPEN_MODE)) == -1)
|
}
|
||||||
|
if ((fid = _open(name, OPEN_MODE)) == -1) {
|
||||||
|
free(fullname);
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
if ((_fstat(fid, &stab) < 0) || !S_ISREG(stab.st_mode)) {
|
if ((_fstat(fid, &stab) < 0) || !S_ISREG(stab.st_mode)) {
|
||||||
|
free(fullname);
|
||||||
_close(fid);
|
_close(fid);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nread = _read(fid, u.buf, sizeof u.buf);
|
u = malloc(sizeof(*u));
|
||||||
|
if (u == NULL)
|
||||||
|
goto out;
|
||||||
|
nread = _read(fid, u->buf, sizeof u->buf);
|
||||||
if (_close(fid) < 0 || nread <= 0)
|
if (_close(fid) < 0 || nread <= 0)
|
||||||
return -1;
|
goto out;
|
||||||
for (stored = 4; stored <= 8; stored *= 2) {
|
for (stored = 4; stored <= 8; stored *= 2) {
|
||||||
int ttisstdcnt;
|
int ttisstdcnt;
|
||||||
int ttisgmtcnt;
|
int ttisgmtcnt;
|
||||||
|
|
||||||
ttisstdcnt = (int) detzcode(u.tzhead.tzh_ttisstdcnt);
|
ttisstdcnt = (int) detzcode(u->tzhead.tzh_ttisstdcnt);
|
||||||
ttisgmtcnt = (int) detzcode(u.tzhead.tzh_ttisgmtcnt);
|
ttisgmtcnt = (int) detzcode(u->tzhead.tzh_ttisgmtcnt);
|
||||||
sp->leapcnt = (int) detzcode(u.tzhead.tzh_leapcnt);
|
sp->leapcnt = (int) detzcode(u->tzhead.tzh_leapcnt);
|
||||||
sp->timecnt = (int) detzcode(u.tzhead.tzh_timecnt);
|
sp->timecnt = (int) detzcode(u->tzhead.tzh_timecnt);
|
||||||
sp->typecnt = (int) detzcode(u.tzhead.tzh_typecnt);
|
sp->typecnt = (int) detzcode(u->tzhead.tzh_typecnt);
|
||||||
sp->charcnt = (int) detzcode(u.tzhead.tzh_charcnt);
|
sp->charcnt = (int) detzcode(u->tzhead.tzh_charcnt);
|
||||||
p = u.tzhead.tzh_charcnt + sizeof u.tzhead.tzh_charcnt;
|
p = u->tzhead.tzh_charcnt + sizeof u->tzhead.tzh_charcnt;
|
||||||
if (sp->leapcnt < 0 || sp->leapcnt > TZ_MAX_LEAPS ||
|
if (sp->leapcnt < 0 || sp->leapcnt > TZ_MAX_LEAPS ||
|
||||||
sp->typecnt <= 0 || sp->typecnt > TZ_MAX_TYPES ||
|
sp->typecnt <= 0 || sp->typecnt > TZ_MAX_TYPES ||
|
||||||
sp->timecnt < 0 || sp->timecnt > TZ_MAX_TIMES ||
|
sp->timecnt < 0 || sp->timecnt > TZ_MAX_TIMES ||
|
||||||
sp->charcnt < 0 || sp->charcnt > TZ_MAX_CHARS ||
|
sp->charcnt < 0 || sp->charcnt > TZ_MAX_CHARS ||
|
||||||
(ttisstdcnt != sp->typecnt && ttisstdcnt != 0) ||
|
(ttisstdcnt != sp->typecnt && ttisstdcnt != 0) ||
|
||||||
(ttisgmtcnt != sp->typecnt && ttisgmtcnt != 0))
|
(ttisgmtcnt != sp->typecnt && ttisgmtcnt != 0))
|
||||||
return -1;
|
goto out;
|
||||||
if (nread - (p - u.buf) <
|
if (nread - (p - u->buf) <
|
||||||
sp->timecnt * stored + /* ats */
|
sp->timecnt * stored + /* ats */
|
||||||
sp->timecnt + /* types */
|
sp->timecnt + /* types */
|
||||||
sp->typecnt * 6 + /* ttinfos */
|
sp->typecnt * 6 + /* ttinfos */
|
||||||
@ -464,7 +483,7 @@ register const int doextend;
|
|||||||
sp->leapcnt * (stored + 4) + /* lsinfos */
|
sp->leapcnt * (stored + 4) + /* lsinfos */
|
||||||
ttisstdcnt + /* ttisstds */
|
ttisstdcnt + /* ttisstds */
|
||||||
ttisgmtcnt) /* ttisgmts */
|
ttisgmtcnt) /* ttisgmts */
|
||||||
return -1;
|
goto out;
|
||||||
for (i = 0; i < sp->timecnt; ++i) {
|
for (i = 0; i < sp->timecnt; ++i) {
|
||||||
sp->ats[i] = (stored == 4) ?
|
sp->ats[i] = (stored == 4) ?
|
||||||
detzcode(p) : detzcode64(p);
|
detzcode(p) : detzcode64(p);
|
||||||
@ -473,7 +492,7 @@ register const int doextend;
|
|||||||
for (i = 0; i < sp->timecnt; ++i) {
|
for (i = 0; i < sp->timecnt; ++i) {
|
||||||
sp->types[i] = (unsigned char) *p++;
|
sp->types[i] = (unsigned char) *p++;
|
||||||
if (sp->types[i] >= sp->typecnt)
|
if (sp->types[i] >= sp->typecnt)
|
||||||
return -1;
|
goto out;
|
||||||
}
|
}
|
||||||
for (i = 0; i < sp->typecnt; ++i) {
|
for (i = 0; i < sp->typecnt; ++i) {
|
||||||
struct ttinfo * ttisp;
|
struct ttinfo * ttisp;
|
||||||
@ -483,11 +502,11 @@ register const int doextend;
|
|||||||
p += 4;
|
p += 4;
|
||||||
ttisp->tt_isdst = (unsigned char) *p++;
|
ttisp->tt_isdst = (unsigned char) *p++;
|
||||||
if (ttisp->tt_isdst != 0 && ttisp->tt_isdst != 1)
|
if (ttisp->tt_isdst != 0 && ttisp->tt_isdst != 1)
|
||||||
return -1;
|
goto out;
|
||||||
ttisp->tt_abbrind = (unsigned char) *p++;
|
ttisp->tt_abbrind = (unsigned char) *p++;
|
||||||
if (ttisp->tt_abbrind < 0 ||
|
if (ttisp->tt_abbrind < 0 ||
|
||||||
ttisp->tt_abbrind > sp->charcnt)
|
ttisp->tt_abbrind > sp->charcnt)
|
||||||
return -1;
|
goto out;
|
||||||
}
|
}
|
||||||
for (i = 0; i < sp->charcnt; ++i)
|
for (i = 0; i < sp->charcnt; ++i)
|
||||||
sp->chars[i] = *p++;
|
sp->chars[i] = *p++;
|
||||||
@ -512,7 +531,7 @@ register const int doextend;
|
|||||||
ttisp->tt_ttisstd = *p++;
|
ttisp->tt_ttisstd = *p++;
|
||||||
if (ttisp->tt_ttisstd != TRUE &&
|
if (ttisp->tt_ttisstd != TRUE &&
|
||||||
ttisp->tt_ttisstd != FALSE)
|
ttisp->tt_ttisstd != FALSE)
|
||||||
return -1;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i = 0; i < sp->typecnt; ++i) {
|
for (i = 0; i < sp->typecnt; ++i) {
|
||||||
@ -525,7 +544,7 @@ register const int doextend;
|
|||||||
ttisp->tt_ttisgmt = *p++;
|
ttisp->tt_ttisgmt = *p++;
|
||||||
if (ttisp->tt_ttisgmt != TRUE &&
|
if (ttisp->tt_ttisgmt != TRUE &&
|
||||||
ttisp->tt_ttisgmt != FALSE)
|
ttisp->tt_ttisgmt != FALSE)
|
||||||
return -1;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -558,11 +577,11 @@ register const int doextend;
|
|||||||
/*
|
/*
|
||||||
** If this is an old file, we're done.
|
** If this is an old file, we're done.
|
||||||
*/
|
*/
|
||||||
if (u.tzhead.tzh_version[0] == '\0')
|
if (u->tzhead.tzh_version[0] == '\0')
|
||||||
break;
|
break;
|
||||||
nread -= p - u.buf;
|
nread -= p - u->buf;
|
||||||
for (i = 0; i < nread; ++i)
|
for (i = 0; i < nread; ++i)
|
||||||
u.buf[i] = p[i];
|
u->buf[i] = p[i];
|
||||||
/*
|
/*
|
||||||
** If this is a narrow integer time_t system, we're done.
|
** If this is a narrow integer time_t system, we're done.
|
||||||
*/
|
*/
|
||||||
@ -570,39 +589,43 @@ register const int doextend;
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (doextend && nread > 2 &&
|
if (doextend && nread > 2 &&
|
||||||
u.buf[0] == '\n' && u.buf[nread - 1] == '\n' &&
|
u->buf[0] == '\n' && u->buf[nread - 1] == '\n' &&
|
||||||
sp->typecnt + 2 <= TZ_MAX_TYPES) {
|
sp->typecnt + 2 <= TZ_MAX_TYPES) {
|
||||||
struct state ts;
|
struct state *ts;
|
||||||
register int result;
|
register int result;
|
||||||
|
|
||||||
u.buf[nread - 1] = '\0';
|
ts = malloc(sizeof(*ts));
|
||||||
result = tzparse(&u.buf[1], &ts, FALSE);
|
if (ts == NULL)
|
||||||
if (result == 0 && ts.typecnt == 2 &&
|
goto out;
|
||||||
sp->charcnt + ts.charcnt <= TZ_MAX_CHARS) {
|
u->buf[nread - 1] = '\0';
|
||||||
|
result = tzparse(&u->buf[1], ts, FALSE);
|
||||||
|
if (result == 0 && ts->typecnt == 2 &&
|
||||||
|
sp->charcnt + ts->charcnt <= TZ_MAX_CHARS) {
|
||||||
for (i = 0; i < 2; ++i)
|
for (i = 0; i < 2; ++i)
|
||||||
ts.ttis[i].tt_abbrind +=
|
ts->ttis[i].tt_abbrind +=
|
||||||
sp->charcnt;
|
sp->charcnt;
|
||||||
for (i = 0; i < ts.charcnt; ++i)
|
for (i = 0; i < ts->charcnt; ++i)
|
||||||
sp->chars[sp->charcnt++] =
|
sp->chars[sp->charcnt++] =
|
||||||
ts.chars[i];
|
ts->chars[i];
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < ts.timecnt &&
|
while (i < ts->timecnt &&
|
||||||
ts.ats[i] <=
|
ts->ats[i] <=
|
||||||
sp->ats[sp->timecnt - 1])
|
sp->ats[sp->timecnt - 1])
|
||||||
++i;
|
++i;
|
||||||
while (i < ts.timecnt &&
|
while (i < ts->timecnt &&
|
||||||
sp->timecnt < TZ_MAX_TIMES) {
|
sp->timecnt < TZ_MAX_TIMES) {
|
||||||
sp->ats[sp->timecnt] =
|
sp->ats[sp->timecnt] =
|
||||||
ts.ats[i];
|
ts->ats[i];
|
||||||
sp->types[sp->timecnt] =
|
sp->types[sp->timecnt] =
|
||||||
sp->typecnt +
|
sp->typecnt +
|
||||||
ts.types[i];
|
ts->types[i];
|
||||||
++sp->timecnt;
|
++sp->timecnt;
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
sp->ttis[sp->typecnt++] = ts.ttis[0];
|
sp->ttis[sp->typecnt++] = ts->ttis[0];
|
||||||
sp->ttis[sp->typecnt++] = ts.ttis[1];
|
sp->ttis[sp->typecnt++] = ts->ttis[1];
|
||||||
}
|
}
|
||||||
|
free(ts);
|
||||||
}
|
}
|
||||||
if (sp->timecnt > 1) {
|
if (sp->timecnt > 1) {
|
||||||
for (i = 1; i < sp->timecnt; ++i)
|
for (i = 1; i < sp->timecnt; ++i)
|
||||||
@ -620,7 +643,10 @@ register const int doextend;
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
res = 0;
|
||||||
|
out:
|
||||||
|
free(u);
|
||||||
|
return (res);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
Loading…
Reference in New Issue
Block a user