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:
@ -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)
|
||||
|
Reference in New Issue
Block a user