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

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.123 2005/05/24 02:09:45 momjian Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.124 2005/05/26 02:04:13 neilc Exp $
*
*-------------------------------------------------------------------------
*/
@ -77,12 +77,10 @@ timestamp_in(PG_FUNCTION_ARGS)
int dterr;
char *field[MAXDATEFIELDS];
int ftype[MAXDATEFIELDS];
char lowstr[MAXDATELEN + MAXDATEFIELDS];
char workbuf[MAXDATELEN + 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)
@ -317,12 +315,10 @@ timestamptz_in(PG_FUNCTION_ARGS)
int dterr;
char *field[MAXDATEFIELDS];
int ftype[MAXDATEFIELDS];
char lowstr[MAXDATELEN + MAXDATEFIELDS];
char workbuf[MAXDATELEN + 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)
@ -493,7 +489,7 @@ interval_in(PG_FUNCTION_ARGS)
int dterr;
char *field[MAXDATEFIELDS];
int ftype[MAXDATEFIELDS];
char lowstr[MAXDATELEN + MAXDATEFIELDS];
char workbuf[256];
tm->tm_year = 0;
tm->tm_mon = 0;
@ -503,10 +499,8 @@ interval_in(PG_FUNCTION_ARGS)
tm->tm_sec = 0;
fsec = 0;
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)