1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-30 11:03:19 +03:00

Adjust datetime parsing to be more robust. We now pass the length of the

working buffer into ParseDateTime() and reject too-long input there,
rather than checking the length of the input string before calling
ParseDateTime(). The old method was bogus because ParseDateTime() can use
a variable amount of working space, depending on the content of the
input string (e.g. how many fields need to be NUL terminated). This fixes
a minor stack overrun -- I don't _think_ it's exploitable, although I
won't claim to be an expert.

Along the way, fix a bug reported by Mark Dilger: the working buffer
allocated by interval_in() was too short, which resulted in rejecting
some perfectly valid interval input values. I added a regression test for
this fix.
This commit is contained in:
Neil Conway
2005-05-26 02:04:14 +00:00
parent 15e4d1e2a7
commit 63e0d612f5
7 changed files with 86 additions and 75 deletions

View File

@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/nabstime.c,v 1.131 2005/05/24 02:09:45 momjian Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/nabstime.c,v 1.132 2005/05/26 02:04:13 neilc Exp $
*
*-------------------------------------------------------------------------
*/
@ -306,15 +306,13 @@ abstimein(PG_FUNCTION_ARGS)
*tm = &date;
int dterr;
char *field[MAXDATEFIELDS];
char lowstr[MAXDATELEN + 1];
char workbuf[MAXDATELEN + 1];
int dtype;
int nf,
ftype[MAXDATEFIELDS];
if (strlen(str) >= sizeof(lowstr))
dterr = DTERR_BAD_FORMAT;
else
dterr = ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf);
dterr = ParseDateTime(str, workbuf, sizeof(workbuf),
field, ftype, MAXDATEFIELDS, &nf);
if (dterr == 0)
dterr = DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tz);
if (dterr != 0)
@ -711,12 +709,10 @@ reltimein(PG_FUNCTION_ARGS)
char *field[MAXDATEFIELDS];
int nf,
ftype[MAXDATEFIELDS];
char lowstr[MAXDATELEN + 1];
char workbuf[MAXDATELEN + 1];
if (strlen(str) >= sizeof(lowstr))
dterr = DTERR_BAD_FORMAT;
else
dterr = ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf);
dterr = ParseDateTime(str, workbuf, sizeof(workbuf),
field, ftype, MAXDATEFIELDS, &nf);
if (dterr == 0)
dterr = DecodeInterval(field, ftype, nf, &dtype, tm, &fsec);
if (dterr != 0)