| From: | Feng Wu <wufengwufengwufeng(at)gmail(dot)com> |
|---|---|
| To: | pgsql-hackers(at)lists(dot)postgresql(dot)org |
| Subject: | [PATCH] Avoid internal error for invalid interval typmods |
| Date: | 2026-06-30 04:18:36 |
| Message-ID: | CACK3murBjJ6Ei_XJy-DQWS2eZmm6MEyhzEawNksF4G6CbdtA=A@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Hi,
While fuzzing PostgreSQL, I noticed that the interval length-coercion
function can report an internal error for user-supplied input:
SELECT pg_catalog.interval(interval '1 day', 1539);
Currently this fails with:
ERROR: unrecognized interval typmod: 1539
The error is raised with elog(ERROR) in AdjustIntervalForTypmod(), so it
is reported as SQLSTATE XX000. Since pg_catalog.interval(interval, int4)
is callable from SQL, arbitrary typmod values can reach this path.
The patch below changes that case to report
ERRCODE_INVALID_PARAMETER_VALUE instead, matching the nearby precision
validation in the same function. It also adds a regression test that
catches the error as invalid_parameter_value.
Tested with the interval regression test.
Regards,
Feng
src/backend/utils/adt/timestamp.c | 4 +++-
src/test/regress/expected/interval.out | 10 ++++++++++
src/test/regress/sql/interval.sql | 9 +++++++++
3 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/src/backend/utils/adt/timestamp.c
b/src/backend/utils/adt/timestamp.c
index a20e7ea1..01b9ed52 100644
--- a/src/backend/utils/adt/timestamp.c
+++ b/src/backend/utils/adt/timestamp.c
@@ -1489,7 +1489,9 @@ AdjustIntervalForTypmod(Interval *interval, int32 typmod,
/* fractional-second rounding will be dealt with below */
}
else
- elog(ERROR, "unrecognized interval typmod: %d", typmod);
+ ereturn(escontext, false,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("unrecognized interval typmod: %d", typmod)));
/* Need to adjust sub-second precision? */
if (precision != INTERVAL_FULL_PRECISION)
diff --git a/src/test/regress/expected/interval.out
b/src/test/regress/expected/interval.out
index a16e3ccd..c5e10482 100644
--- a/src/test/regress/expected/interval.out
+++ b/src/test/regress/expected/interval.out
@@ -857,6 +857,16 @@ SELECT interval(2) '1 day 01:23:45.6789';
1 day 01:23:45.68
(1 row)
+-- invalid typmods passed to the length-coercion function are user errors,
+-- not internal errors
+DO $$
+BEGIN
+ PERFORM pg_catalog.interval(interval '1 day', 1539);
+EXCEPTION WHEN invalid_parameter_value THEN
+ RAISE NOTICE 'invalid interval typmod rejected';
+END
+$$;
+NOTICE: invalid interval typmod rejected
SELECT interval '12:34.5678' minute to second(2); -- per SQL spec
interval
-------------
diff --git a/src/test/regress/sql/interval.sql
b/src/test/regress/sql/interval.sql
index 43bc7939..88794c21 100644
--- a/src/test/regress/sql/interval.sql
+++ b/src/test/regress/sql/interval.sql
@@ -257,6 +257,15 @@ SELECT interval '123 2:03 -2:04'; -- not ok,
redundant hh:mm fields
-- test syntaxes for restricted precision
SELECT interval(0) '1 day 01:23:45.6789';
SELECT interval(2) '1 day 01:23:45.6789';
+-- invalid typmods passed to the length-coercion function are user errors,
+-- not internal errors
+DO $$
+BEGIN
+ PERFORM pg_catalog.interval(interval '1 day', 1539);
+EXCEPTION WHEN invalid_parameter_value THEN
+ RAISE NOTICE 'invalid interval typmod rejected';
+END
+$$;
SELECT interval '12:34.5678' minute to second(2); -- per SQL spec
SELECT interval '1.234' second;
SELECT interval '1.234' second(2);
| From | Date | Subject | |
|---|---|---|---|
| Next Message | jian he | 2026-06-30 04:20:57 | Re: statatt_build_stavalues->LOCAL_FCINFO wrong number |
| Previous Message | solai v | 2026-06-30 04:08:29 | Re: [SP-]GiST IOS visibility bug (was: Why doens't GiST require super-exclusive lock) |