aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2023-02-12 12:50:55 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2023-02-12 12:50:55 -0500
commit0ef65d0f55e5cec81fe98aba7c907dfc1b93923f (patch)
tree34da4fb9ca142a2377724cf194e1c286c6dcf6aa
parentecb01e6ebb5a67f3fc00840695682a8b1ba40461 (diff)
downloadpostgresql-0ef65d0f55e5cec81fe98aba7c907dfc1b93923f.tar.gz
postgresql-0ef65d0f55e5cec81fe98aba7c907dfc1b93923f.zip
Avoid dereferencing an undefined pointer in DecodeInterval().
Commit e39f99046 moved some code up closer to the start of DecodeInterval(), without noticing that it had been implicitly relying on previous checks to reject the case of empty input. Given empty input, we'd now dereference a pointer that hadn't been set, possibly leading to a core dump. (But if we fail to provoke a SIGSEGV, nothing bad happens, and the expected syntax error is thrown a bit later.) Per bug #17788 from Alexander Lakhin. Back-patch to v15 where the fault was introduced. Discussion: https://postgr.es/m/17788-dabac9f98f7eafd5@postgresql.org
-rw-r--r--src/backend/utils/adt/datetime.c2
-rw-r--r--src/test/regress/expected/interval.out5
-rw-r--r--src/test/regress/sql/interval.sql3
3 files changed, 9 insertions, 1 deletions
diff --git a/src/backend/utils/adt/datetime.c b/src/backend/utils/adt/datetime.c
index a3cfd54409b..cebc1172744 100644
--- a/src/backend/utils/adt/datetime.c
+++ b/src/backend/utils/adt/datetime.c
@@ -3365,7 +3365,7 @@ DecodeInterval(char **field, int *ftype, int nf, int range,
* to dump in postgres style, not SQL style.)
*----------
*/
- if (IntervalStyle == INTSTYLE_SQL_STANDARD && *field[0] == '-')
+ if (IntervalStyle == INTSTYLE_SQL_STANDARD && nf > 0 && *field[0] == '-')
{
force_negative = true;
/* Check for additional explicit signs */
diff --git a/src/test/regress/expected/interval.out b/src/test/regress/expected/interval.out
index 00885acd1df..78c1fab2b63 100644
--- a/src/test/regress/expected/interval.out
+++ b/src/test/regress/expected/interval.out
@@ -857,6 +857,11 @@ SELECT interval '-23 hours 45 min 12.34 sec',
-23:45:12.34 | -1 23:45:12.34 | -1-2 -1 -23:45:12.34 | -0-10 +1 +23:45:12.34
(1 row)
+-- edge case for sign-matching rules
+SELECT interval ''; -- error
+ERROR: invalid input syntax for type interval: ""
+LINE 1: SELECT interval '';
+ ^
-- test outputting iso8601 intervals
SET IntervalStyle to iso_8601;
select interval '0' AS "zero",
diff --git a/src/test/regress/sql/interval.sql b/src/test/regress/sql/interval.sql
index 97d33a13236..55a449b6179 100644
--- a/src/test/regress/sql/interval.sql
+++ b/src/test/regress/sql/interval.sql
@@ -277,6 +277,9 @@ SELECT interval '-23 hours 45 min 12.34 sec',
interval '-1 year 2 months 1 day 23 hours 45 min 12.34 sec',
interval '-1 year 2 months 1 day 23 hours 45 min +12.34 sec';
+-- edge case for sign-matching rules
+SELECT interval ''; -- error
+
-- test outputting iso8601 intervals
SET IntervalStyle to iso_8601;
select interval '0' AS "zero",