]> granicus.if.org Git - postgresql/commitdiff
Fix some incorrect parsing of time with time zone strings
authorMichael Paquier <michael@paquier.xyz>
Wed, 7 Aug 2019 09:16:31 +0000 (18:16 +0900)
committerMichael Paquier <michael@paquier.xyz>
Wed, 7 Aug 2019 09:16:31 +0000 (18:16 +0900)
When parsing a timetz string with a dynamic timezone abbreviation or a
timezone not specified, it was possible to generate incorrect timestamps
based on a date which uses some non-initialized variables if the input
string did not specify fully a date to parse.  This is already checked
when a full timezone spec is included in the input string, but the two
other cases mentioned above missed the same checks.

This gets fixed by generating an error as this input is invalid, or in
short when a date is not fully specified.

Valgrind was complaining about this problem.

Bug: #15910
Author: Alexander Lakhin
Discussion: https://postgr.es/m/15910-2eba5106b9aa0c61@postgresql.org
Backpatch-through: 9.4

src/backend/utils/adt/datetime.c
src/test/regress/expected/timetz.out
src/test/regress/sql/timetz.sql

index 972fcd26a24c74388fb3b4af8fb589d5197781ca..e38bd930543f9e1a1462d6b330e7e1637660884b 100644 (file)
@@ -2280,6 +2280,9 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
                        GetCurrentDateTime(tmp);
                else
                {
+                       /* a date has to be specified */
+                       if ((fmask & DTK_DATE_M) != DTK_DATE_M)
+                               return DTERR_BAD_FORMAT;
                        tmp->tm_year = tm->tm_year;
                        tmp->tm_mon = tm->tm_mon;
                        tmp->tm_mday = tm->tm_mday;
@@ -2307,6 +2310,9 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
                        GetCurrentDateTime(tmp);
                else
                {
+                       /* a date has to be specified */
+                       if ((fmask & DTK_DATE_M) != DTK_DATE_M)
+                               return DTERR_BAD_FORMAT;
                        tmp->tm_year = tm->tm_year;
                        tmp->tm_mon = tm->tm_mon;
                        tmp->tm_mday = tm->tm_mday;
index 33ff8e18c9d53bbed1a74fb1215acdf98bd31f8e..482a3463b3c48d4630d9e33a2f02955a74991578 100644 (file)
@@ -19,6 +19,16 @@ INSERT INTO TIMETZ_TBL VALUES ('15:36:39 America/New_York');
 ERROR:  invalid input syntax for type time with time zone: "15:36:39 America/New_York"
 LINE 1: INSERT INTO TIMETZ_TBL VALUES ('15:36:39 America/New_York');
                                        ^
+-- this should fail (timezone not specified without a date)
+INSERT INTO TIMETZ_TBL VALUES ('15:36:39 m2');
+ERROR:  invalid input syntax for type time with time zone: "15:36:39 m2"
+LINE 1: INSERT INTO TIMETZ_TBL VALUES ('15:36:39 m2');
+                                       ^
+-- this should fail (dynamic timezone abbreviation without a date)
+INSERT INTO TIMETZ_TBL VALUES ('15:36:39 MSK m2');
+ERROR:  invalid input syntax for type time with time zone: "15:36:39 MSK m2"
+LINE 1: INSERT INTO TIMETZ_TBL VALUES ('15:36:39 MSK m2');
+                                       ^
 SELECT f1 AS "Time TZ" FROM TIMETZ_TBL;
     Time TZ     
 ----------------
index c41686a5e2f050ca86c31381724e45f082e3bd1f..2ad4948e85008e0a4c78a08ace8c6432ca6c76b3 100644 (file)
@@ -19,6 +19,11 @@ INSERT INTO TIMETZ_TBL VALUES ('2003-03-07 15:36:39 America/New_York');
 INSERT INTO TIMETZ_TBL VALUES ('2003-07-07 15:36:39 America/New_York');
 -- this should fail (the timezone offset is not known)
 INSERT INTO TIMETZ_TBL VALUES ('15:36:39 America/New_York');
+-- this should fail (timezone not specified without a date)
+INSERT INTO TIMETZ_TBL VALUES ('15:36:39 m2');
+-- this should fail (dynamic timezone abbreviation without a date)
+INSERT INTO TIMETZ_TBL VALUES ('15:36:39 MSK m2');
+
 
 SELECT f1 AS "Time TZ" FROM TIMETZ_TBL;