summaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/date.c
diff options
context:
space:
mode:
authorNeil Conway <neilc@samurai.com>2005-05-26 02:04:14 +0000
committerNeil Conway <neilc@samurai.com>2005-05-26 02:04:14 +0000
commit63e0d612f5a53d76218d4e59a35287391e284561 (patch)
tree1acd1cc27ec9fd5855a6878f5f0d93f0683863e0 /src/backend/utils/adt/date.c
parent15e4d1e2a7f565d805692daad895a07802279aea (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.c26
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)