Hello,

  ParseVariableDouble() in src/bin/psql/variables.c is asymmetric in how
  it handles the [min, max] bounds it documents. The lower-bound branch
  correctly returns false, but the upper-bound branch logs the error and
  then falls through to assign *result and return true. The function's
  contract ("the value must be within the range [min,max] in order to be
  considered valid"; "if unsuccessful, *result isn't clobbered") is
  broken on the upper-bound path.

  The only caller today is watch_interval_hook, so the user-visible
  effect is that an out-of-range WATCH_INTERVAL is reported as invalid
  yet still assigned.

  Reproducer:

  $ psql
# \set WATCH_INTERVAL 99999999
invalid value "99999999" for variable "WATCH_INTERVAL": must be less than
1000000.00
# \echo :WATCH_INTERVAL
99999999
  The error is printed, but the variable is set anyway.

Regards,
Sven Klemm
From dde5e00fe368a323b685e154896ef2905f91176e Mon Sep 17 00:00:00 2001
From: Sven Klemm <[email protected]>
Date: Fri, 8 May 2026 17:24:51 +0200
Subject: [PATCH] psql: Make ParseVariableDouble reject values above max

When the parsed value exceeded max, ParseVariableDouble logged the
"must be less than" error but then fell through to assign *result and
return true, contradicting both its docstring (caller's *result is
left untouched on failure) and the documented [min,max] contract. The
lower-bound branch already returns false; mirror that behavior on the
upper bound.
---
 src/bin/psql/variables.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/bin/psql/variables.c b/src/bin/psql/variables.c
index f2a28bc9820..8060f2959cc 100644
--- a/src/bin/psql/variables.c
+++ b/src/bin/psql/variables.c
@@ -224,6 +224,7 @@ ParseVariableDouble(const char *value, const char *name, double *result, double
 			if (name)
 				pg_log_error("invalid value \"%s\" for variable \"%s\": must be less than %.2f",
 							 value, name, max);
+			return false;
 		}
 		*result = dblval;
 		return true;
-- 
2.54.0

Reply via email to