diff options
author | Neil Conway <neilc@samurai.com> | 2005-05-26 02:04:14 +0000 |
---|---|---|
committer | Neil Conway <neilc@samurai.com> | 2005-05-26 02:04:14 +0000 |
commit | 63e0d612f5a53d76218d4e59a35287391e284561 (patch) | |
tree | 1acd1cc27ec9fd5855a6878f5f0d93f0683863e0 /src/backend/utils/adt/date.c | |
parent | 15e4d1e2a7f565d805692daad895a07802279aea (diff) |
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.
Diffstat (limited to 'src/backend/utils/adt/date.c')
-rw-r--r-- | src/backend/utils/adt/date.c | 26 |
1 files changed, 10 insertions, 16 deletions
diff --git a/src/backend/utils/adt/date.c b/src/backend/utils/adt/date.c index 1e54f3877e8..5371c64250a 100644 --- a/src/backend/utils/adt/date.c +++ b/src/backend/utils/adt/date.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.108 2005/05/24 02:09:45 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.109 2005/05/26 02:04:13 neilc Exp $ * *------------------------------------------------------------------------- */ @@ -65,12 +65,10 @@ date_in(PG_FUNCTION_ARGS) int dterr; char *field[MAXDATEFIELDS]; int 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 = DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tzp); if (dterr != 0) @@ -894,15 +892,13 @@ time_in(PG_FUNCTION_ARGS) int tz; int nf; int dterr; - char lowstr[MAXDATELEN + 1]; + char workbuf[MAXDATELEN + 1]; char *field[MAXDATEFIELDS]; int dtype; int 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 = DecodeTimeOnly(field, ftype, nf, &dtype, tm, &fsec, &tz); if (dterr != 0) @@ -1733,15 +1729,13 @@ timetz_in(PG_FUNCTION_ARGS) int tz; int nf; int dterr; - char lowstr[MAXDATELEN + 1]; + char workbuf[MAXDATELEN + 1]; char *field[MAXDATEFIELDS]; int dtype; int 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 = DecodeTimeOnly(field, ftype, nf, &dtype, tm, &fsec, &tz); if (dterr != 0) |